// SPDX-License-Identifier: ISC
pragma solidity ^0.8.4;
/**
* Library Like Contract. Not Required for deployment
*/
abstract contract Context {
function msgSender() internal view virtual returns(address) {
return msg.sender;
}
function msgData() internal view virtual returns(bytes calldata) {
this;
return msg.data;
}
function msgValue() internal view virtual returns(uint256) {
return msg.value;
}
}
// SPDX-License-Identifier: ISC
pragma solidity ^0.8.4;
interface IERC20 {
/**
* @dev returns the tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev returns the decimal places of a token
*/
function decimals() external view returns (uint8);
/**
* @dev returns the remaining number of tokens the `spender' can spend
* on behalf of the owner.
*
* This value changes when {approve} or {transferFrom} is executed.
*/
function allowance(address owner, address spender)
external
view
returns (uint256);
/**
* @dev transfers the `amount` of tokens from caller's account
* to the `recipient` account.
*
* returns boolean value indicating the operation status.
*
* Emits a {Transfer} event
*/
function transfer(address recipient, uint256 amount)
external
returns (bool);
/**
* @dev transfers the `amount` on behalf of `spender` to the `recipient` account.
*
* returns a boolean indicating the operation status.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address spender,
address recipient,
uint256 amount
) external returns (bool);
}
// SPDX-License-Identifier: ISC
pragma solidity ^0.8.4;
import "./interfaces/IERC20.sol";
import "./utils/Context.sol";
contract PrivateSaleV2 is Context {
/**
* @dev `_usdt` represents the USDT smart contract address.
* @dev `_usdc` represents the USDC smart contract address.
* @dev `_busd` represents the BUSD smart contract address.
* @dev `_bollycoin` represents the Bollycoin token contract.
* @dev `_settlementWallet` represents the wallet address to which tokens are sent during purcahse.
* `_admin` is the account that controls the sale.
*/
address private _usdt;
address private _usdc;
address private _busd;
address private _bollycoin;
address private _admin;
address private _settlementWallet;
uint256 public bollycoinPrice = 0.1 * 10**18; // 0.1 USD
/**
* @dev checks if `caller` is `_admin`
* reverts if the `caller` is not the `_admin` account.
*/
modifier onlyAdmin() {
require(_admin == msgSender(), "Error: caller not admin");
_;
}
/**
* @dev is emitted when a successful purchase is made.
*/
event Purchase(
address indexed buyer,
string uid,
uint256 amount,
uint256 usdValue,
bytes32 currency
);
constructor(
address _usdtAddress,
address _usdcAddress,
address _busdAddress,
address _bollyAddress,
address _settlementAddress
) {
_admin = _settlementAddress;
_usdt = _usdtAddress;
_usdc = _usdcAddress;
_busd = _busdAddress;
_bollycoin = _bollyAddress;
_settlementWallet = _settlementAddress;
}
/**
* @dev used to purchase bollycoin using USDT. Tokens are sent to the buyer.
* @param _amount - The number of bollycoin tokens to purchase
*/
function purchaseWithUSDT(uint256 _amount, string memory uid)
public
virtual
returns (bool)
{
uint256 balance = IERC20(_usdt).balanceOf(msgSender());
uint256 allowance = IERC20(_usdt).allowance(msgSender(), address(this));
uint256 totalCostInUSDT = (bollycoinPrice) * _amount;
totalCostInUSDT = totalCostInUSDT / 10**12;
require(balance >= totalCostInUSDT, "Error: insufficient USDT Balance");
require(
allowance >= totalCostInUSDT,
"Error: allowance less than spending"
);
IERC20(_usdt).transferFrom(
msgSender(),
_settlementWallet,
totalCostInUSDT
);
IERC20(_bollycoin).transfer(msgSender(), _amount * 10**18);
emit Purchase(
msgSender(),
uid,
_amount,
totalCostInUSDT,
bytes32("USDT")
);
return true;
}
/**
* @dev used to purchase bollycoin using USDC. Tokens are sent to the buyer.
* @param _amount - The number of bollycoin tokens to purchase
*/
function purchaseWithUSDC(uint256 _amount, string memory uid)
public
virtual
returns (bool)
{
uint256 balance = IERC20(_usdc).balanceOf(msgSender());
uint256 allowance = IERC20(_usdc).allowance(msgSender(), address(this));
uint256 usdValue = (bollycoinPrice) * _amount;
uint256 totalCostInUSDC = (bollycoinPrice) * _amount;
totalCostInUSDC = totalCostInUSDC / 10**12;
require(balance >= totalCostInUSDC, "Error: insufficient USDC Balance");
require(
allowance >= totalCostInUSDC,
"Error: allowance less than spending"
);
IERC20(_usdc).transferFrom(
msgSender(),
_settlementWallet,
totalCostInUSDC
);
IERC20(_bollycoin).transfer(msgSender(), _amount * 10**18);
emit Purchase(msgSender(), uid, _amount, usdValue, bytes32("USDC"));
return true;
}
/**
* @dev used to purchase bollycoin using BUSD. Tokens are sent to the buyer.
* @param _amount - The number of bollycoin tokens to purchase
*/
function purchaseWithBUSD(uint256 _amount, string memory uid)
public
virtual
returns (bool)
{
uint256 balance = IERC20(_busd).balanceOf(msgSender());
uint256 allowance = IERC20(_busd).allowance(msgSender(), address(this));
uint256 totalCostInBUSD = (bollycoinPrice) * _amount;
require(balance >= totalCostInBUSD, "Error: insufficient BUSD Balance");
require(
allowance >= totalCostInBUSD,
"Error: allowance less than spending"
);
IERC20(_busd).transferFrom(
msgSender(),
_settlementWallet,
totalCostInBUSD
);
IERC20(_bollycoin).transfer(msgSender(), _amount * 10**18);
emit Purchase(
msgSender(),
uid,
_amount,
totalCostInBUSD,
bytes32("BUSD")
);
return true;
}
/**
* @dev returns the usdt smart contract used for purchase.
*/
function usdt() public view returns (address) {
return _usdt;
}
/**
* @dev returns the usdc smart contract used for purchase.
*/
function usdc() public view returns (address) {
return _usdc;
}
/**
* @dev returns the busd smart contract used for purchase.
*/
function busd() public view returns (address) {
return _busd;
}
/**
* @dev returns the bollycoin smart contract used for purchase.
*/
function bolly() public view returns (address) {
return _bollycoin;
}
/**
* @dev returns the admin account used for purchase.
*/
function admin() public view returns (address) {
return _admin;
}
/**
* @dev returns the settlement address used for purchase.
*/
function settlementAddress() public view returns (address) {
return _settlementWallet;
}
/**
* @dev transfers ownership to a different account.
*
* Requirements:
* `newAdmin` cannot be a zero address.
* `caller` should be current admin.
*/
function transferControl(address newAdmin) public virtual onlyAdmin {
require(newAdmin != address(0), "Error: owner cannot be zero");
_admin = newAdmin;
}
/**
* @dev updates the usdt sc address.
*
* Requirements:
* `newAddress` cannot be a zero address.
* `caller` should be current admin.
*/
function updateUsdt(address newAddress) public virtual onlyAdmin {
require(newAddress != address(0), "Error: address cannot be zero");
_usdt = newAddress;
}
/**
* @dev updates the usdc sc address.
*
* Requirements:
* `newAddress` cannot be a zero address.
* `caller` should be current admin.
*/
function updateUsdc(address newAddress) public virtual onlyAdmin {
require(newAddress != address(0), "Error: address cannot be zero");
_usdc = newAddress;
}
/**
* @dev updates the bollycoin token address.
*
* Requirements:
* `newAddress` cannot be a zero address.
* `caller` should be current admin.
*/
function updateBolly(address newAddress) public virtual onlyAdmin {
require(newAddress != address(0), "Error: address cannot be zero");
_bollycoin = newAddress;
}
/**
* @dev updates the busd sc address.
*
* Requirements:
* `newAddress` cannot be a zero address.
* `caller` should be current admin.
*/
function updateBusd(address newAddress) public virtual onlyAdmin {
require(newAddress != address(0), "Error: address cannot be zero");
_busd = newAddress;
}
/**
* @dev updates the bollycoin token price.
*
* Requirements:
* `newPrice` cannot be zero.
* `caller` should be current admin.
*/
function updateBollycoinPrice(uint256 newPrice) public virtual onlyAdmin {
require(newPrice > 0, "Error: price cannot be zero");
bollycoinPrice = newPrice;
}
/**
* @dev updates the settlement wallet address
*
* Requirements:
* `settlementWallet` cannot be a zero address.
* `caller` should be current admin.
*/
function updateSettlementWallet(address newAddress)
public
virtual
onlyAdmin
{
require(newAddress != address(0), "Error: not a valid address");
_settlementWallet = newAddress;
}
/**
* @dev withdraw bollycoin from SC to any EOA.
*
* `caller` should be admin account.
* `to` cannot be zero address.
*/
function withdrawBolly(address to, uint256 amount)
public
virtual
onlyAdmin
returns (bool)
{
require(to != address(0), "Error: cannot send to zero addresss");
IERC20(_bollycoin).transfer(to, amount);
return true;
}
}
{
"compilationTarget": {
"contracts/PrivateSaleV2.sol": "PrivateSaleV2"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_usdtAddress","type":"address"},{"internalType":"address","name":"_usdcAddress","type":"address"},{"internalType":"address","name":"_busdAddress","type":"address"},{"internalType":"address","name":"_bollyAddress","type":"address"},{"internalType":"address","name":"_settlementAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"string","name":"uid","type":"string"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"usdValue","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"currency","type":"bytes32"}],"name":"Purchase","type":"event"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bolly","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bollycoinPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"busd","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"string","name":"uid","type":"string"}],"name":"purchaseWithBUSD","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"string","name":"uid","type":"string"}],"name":"purchaseWithUSDC","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"string","name":"uid","type":"string"}],"name":"purchaseWithUSDT","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"settlementAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"transferControl","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"updateBolly","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"updateBollycoinPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"updateBusd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"updateSettlementWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"updateUsdc","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"updateUsdt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"usdc","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawBolly","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]