Smiley
0xe48aca034e348a74276d8257e35fe2e3692b6666
Verification
Verified
v0.8.34+commit.80d5c536
Type
Contract
12,369 bytes
ABI entries
64
45 read · 8 write
License
mit
Contract information
- Address
- 0xe48aca034e348a74276d8257e35fe2e3692b6666
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.34+commit.80d5c536
- Optimization
- Enabled
- Creator
- 0x1bE9a92E48…EAAFA99c2C
- Creation tx
- 0x5af8fa6ff3…2684d0655a
Token
- Name
- HOOD
- Symbol
- HOOD
- Decimals
- 18
- Holders
- 77
- Market
- View token page →
Read contract (45)
ETH() → address
MintAllBNB() → uint256
Mint_Count_Max() → uint256
Mint_Once_BNB() → uint256
_buyFundFee() → uint256
_buyHoldRewardFee() → uint256
_buyLPFee() → uint256
_buyRewardFee() → uint256
_mainPair() → address
_sellFundFee() → uint256
_sellHoldRewardFee() → uint256
_sellLPFee() → uint256
_sellRewardFee() → uint256
_swapPairList(address) → bool
_swapRouter() → address
_tokenDistributor() → address
addLiquidityFee() → uint256
airdropNumbs() → uint256
allowance(address, address) → uint256
balanceOf(address) → uint256
buy_burnFee() → uint256
currency() → address
currentDividendTaxWalletIndex() → uint256
decimals() → uint256
dividendTaxFee() → uint256
dividendTaxWallets(uint256) → address
dividendTracker() → address
enableOffTrade() → bool
fundAddress() → address
fundReceiver() → address
isAddV2() → bool
isRemoveV2() → bool
launchCreatedAt() → uint256
mintCountOf(address) → uint256
mintToken() → address
name() → string
owner() → address
refundedMintSlots() → uint256
removeLiquidityFee() → uint256
rewardPath(uint256) → address
sell_burnFee() → uint256
startTradeBlock() → uint256
symbol() → string
totalSupply() → uint256
transferFee() → uint256
Events (9)
ApprovalFailed_addLiquidityFailed_addLiquidityETHFailed_swapExactTokensForETHSupportingFeeOnTransferTokensFailed_swapExactTokensForTokensSupportingFeeOnTransferTokensOwnershipTransferredProcessedDividendTrackerSendDividendsTransfer
ABI
[
{
"inputs": [
{
"components": [
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"internalType": "uint256",
"name": "totalSupply",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "mintCountMax",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "mintOnceBNB",
"type": "uint256"
},
{
"internalType": "uint256[5]",
"name": "buyFees",
"type": "uint256[5]"
},
{
"internalType": "uint256[5]",
"name": "sellFees",
"type": "uint256[5]"
},
{
"internalType": "address",
"name": "rewardToken",
"type": "address"
},
{
"internalType": "address",
"name": "mintToken",
"type": "address"
},
{
"internalType": "address",
"name": "fundReceiver",
"type": "address"
},
{
"internalType": "uint256",
"name": "dividendThreshold",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "weightPeriodMinutes",
"type": "uint256"
}
],
"internalType": "struct LaunchTokenConfig",
"name": "config",
"type": "tuple"
},
{
"internalType": "address",
"name": "vaultAddress_",
"type": "address"
},
{
"internalType": "address",
"name": "platformTaxWallet_",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "Failed_addLiquidity",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "Failed_addLiquidityETH",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "Failed_swapExactTokensForETHSupportingFeeOnTransferTokens",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Failed_swapExactTokensForTokensSupportingFeeOnTransferTokens",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "iterations",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "claims",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "lastProcessedIndex",
"type": "uint256"
},
{
"indexed": true,
"internalType": "bool",
"name": "automatic",
"type": "bool"
},
{
"indexed": false,
"internalType": "uint256",
"name": "gas",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "processor",
"type": "address"
}
],
"name": "ProcessedDividendTracker",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "tokensSwapped",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "SendDividends",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"inputs": [],
"name": "ETH",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MintAllBNB",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "Mint_Count_Max",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "Mint_Once_BNB",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "_buyFundFee",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "_buyHoldRewardFee",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "_buyLPFee",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "_buyRewardFee",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "_mainPair",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "_sellFundFee",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "_sellHoldRewardFee",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "_sellLPFee",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "_sellRewardFee",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "_swapPairList",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "_swapRouter",
"outputs": [
{
"internalType": "contract ISwapRouter",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "_tokenDistributor",
"outputs": [
{
"internalType": "contract TokenDistributor",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "addLiquidityFee",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "airdropNumbs",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "buy_burnFee",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "currency",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "currentDividendTaxWalletIndex",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "decimals",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "dividendTaxFee",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "dividendTaxWallets",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "dividendTracker",
"outputs": [
{
"internalType": "contract ETHBackDividendTracker",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "enableOffTrade",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "fundAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "fundReceiver",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "isAddV2",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "isRemoveV2",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "launch",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "launchCreatedAt",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "mintCountOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "mintToken",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "refundMint",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "refundedMintSlots",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "removeLiquidityFee",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "rewardPath",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "sell_burnFee",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "vaultAddress_",
"type": "address"
}
],
"name": "setLaunchVault",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "startTradeBlock",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "symbol",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "transferFee",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
struct LaunchTokenConfig {
string name;
string symbol;
uint256 totalSupply;
uint256 mintCountMax;
uint256 mintOnceBNB;
uint256[5] buyFees;
uint256[5] sellFees;
address rewardToken;
address mintToken;
address fundReceiver;
uint256 dividendThreshold;
uint256 weightPeriodMinutes;
}
interface IERC20 {
function decimals() external view returns (uint256);
function symbol() external view returns (string memory);
function name() external view returns (string memory);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(
address recipient,
uint256 amount
) external returns (bool);
function allowance(
address owner,
address spender
) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
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
);
}
interface ISwapRouter {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function addLiquidity(
address tokenA,
address tokenB,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
) external returns (uint256 amountA, uint256 amountB, uint256 liquidity);
function addLiquidityETH(
address token,
uint256 amountTokenDesired,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
)
external
payable
returns (uint256 amountToken, uint256 amountETH, uint256 liquidity);
function removeLiquidityETH(
address token,
uint256 liquidity,
uint256 amountTokenMin,
uint256 amountETHMin,
address to,
uint256 deadline
) external returns (uint256 amountToken, uint256 amountETH);
function removeLiquidity(
address tokenA,
address tokenB,
uint256 liquidity,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
) external returns (uint256 amountA, uint256 amountB);
}
interface ISwapFactory {
function createPair(
address tokenA,
address tokenB
) external returns (address pair);
function getPair(
address tokenA,
address tokenB
) external view returns (address pair);
}
abstract contract Ownable {
address internal _owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
constructor() {
address msgSender = msg.sender;
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(_owner == msg.sender, "!owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0xdead));
_owner = address(0xdead);
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "new is 0");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
contract TokenDistributor is Ownable{
constructor() {
}
function claim(address to,uint256 amount) external onlyOwner payable {
payable(to).transfer(amount);
}
receive() external payable {}
}
interface ISwapPair {
function getReserves()
external
view
returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
function token0() external view returns (address);
function balanceOf(address account) external view returns (uint256);
function totalSupply() external view returns (uint256);
}
interface ILaunchVault {
function creator() external view returns (address);
function recordMint(address account, uint256 amount) external;
function markLaunched() external;
function burnToken(address erc20) external;
function refundMint(address account, uint256 amount, address lpToken, address payToken) external returns (uint256);
}
contract Smiley is IERC20, Ownable {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
address public fundAddress;
string private _name;
string private _symbol;
uint256 private _decimals;
uint256 private _tTotal;
uint256 private _tTotalLP;
ISwapRouter public _swapRouter;
address public currency;
address public mintToken;
address public fundReceiver;
mapping(address => bool) public _swapPairList;
bool private inSwap;
uint256 private constant MAX = ~uint256(0);
TokenDistributor public _tokenDistributor;
ETHBackDividendTracker public dividendTracker;
uint256 public _buyFundFee;
uint256 public _buyLPFee;
uint256 public _buyRewardFee;
uint256 public _buyHoldRewardFee;
uint256 public buy_burnFee;
uint256 public _sellFundFee;
uint256 public _sellLPFee;
uint256 public _sellRewardFee;
uint256 public _sellHoldRewardFee;
uint256 public sell_burnFee;
address private feeReceiver;
address private constant PLATFORM_TAX_WALLET_1 = 0xe5dD73A5587aE94C7d9bb6F0296370bCD89db2af;
address private constant PLATFORM_TAX_WALLET_2 = 0xe5dD73A5587aE94C7d9bb6F0296370bCD89db2af;
address private constant PLATFORM_TAX_WALLET_3 = 0xe5dD73A5587aE94C7d9bb6F0296370bCD89db2af;
bool currencyIsEth;
address public ETH;
uint256 public startTradeBlock;
address public _mainPair;
address[] public dividendTaxWallets;
uint256 public currentDividendTaxWalletIndex;
uint256 public constant dividendTaxFee = 1000;
modifier lockTheSwap() {
inSwap = true;
_;
inSwap = false;
}
bool public enableOffTrade;
address[] public rewardPath;
bool private _isAutoAddlp314;
uint256 public airdropNumbs = 2;
event SendDividends(uint256 tokensSwapped, uint256 amount);
event ProcessedDividendTracker(
uint256 iterations,
uint256 claims,
uint256 lastProcessedIndex,
bool indexed automatic,
uint256 gas,
address indexed processor
);
constructor(
LaunchTokenConfig memory config,
address vaultAddress_,
address platformTaxWallet_
) {
require(bytes(config.name).length > 0, "empty name");
require(bytes(config.symbol).length > 0, "empty symbol");
require(config.totalSupply > 0, "empty supply");
require(config.mintCountMax > 0, "empty mint count");
require(config.mintOnceBNB > 0, "empty mint price");
require(platformTaxWallet_ != address(0), "platform is 0");
launchCreatedAt = block.timestamp;
dividendTaxWallets.push(PLATFORM_TAX_WALLET_1);
dividendTaxWallets.push(PLATFORM_TAX_WALLET_2);
dividendTaxWallets.push(PLATFORM_TAX_WALLET_3);
fundAddress = vaultAddress_;
feeReceiver = PLATFORM_TAX_WALLET_1;
_name = config.name;
_symbol = config.symbol;
_decimals = 18;
uint256 total = config.totalSupply * 10 **_decimals;
_tTotal = total;
_tTotalLP = total;
mintToken = config.mintToken;
address _currency = 0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73;
address _router = 0x89e5DB8B5aA49aA85AC63f691524311AEB649eba;
if(block.chainid == 97) {
_currency = 0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd;
_router = 0xD99D1c33F9fC3444f8101754aBC46c52416550D1;
}
currency = config.mintToken == address(0)
? _currency
: config.mintToken;
fundReceiver = config.fundReceiver == address(0) ? platformTaxWallet_ : config.fundReceiver;
ISwapRouter swapRouter = ISwapRouter(_router);
ETH = _currency;
enableOffTrade = true;
currencyIsEth = config.mintToken == address(0);
rewardPath = [address(this), currency];
IERC20(currency).approve(address(swapRouter), MAX);
_swapRouter = swapRouter;
_allowances[address(this)][address(swapRouter)] = MAX;
ISwapFactory swapFactory = ISwapFactory(swapRouter.factory());
address swapPair = swapFactory.createPair(address(this), currency);
_mainPair = swapPair;
_swapPairList[swapPair] = true;
_buyFundFee = config.buyFees[0];
_buyLPFee = config.buyFees[1];
_buyRewardFee = config.buyFees[2];
_buyHoldRewardFee = config.buyFees[3];
buy_burnFee = config.buyFees[4];
_sellFundFee = config.sellFees[0];
_sellLPFee = config.sellFees[1];
_sellRewardFee = config.sellFees[2];
_sellHoldRewardFee = config.sellFees[3];
sell_burnFee = config.sellFees[4];
require(
_buyFundFee + _buyLPFee + _buyRewardFee + _buyHoldRewardFee + buy_burnFee <= 1000 &&
_sellFundFee + _sellLPFee + _sellRewardFee + _sellHoldRewardFee + sell_burnFee <= 1000,
"fee too high"
);
address ReceiveAddress = address(this);
_balances[ReceiveAddress] = _tTotalLP;
emit Transfer(address(0), ReceiveAddress, _tTotal);
_allowances[ReceiveAddress][address(swapRouter)] = MAX;
Mint_Count_Max = config.mintCountMax;
Mint_Once_BNB = config.mintOnceBNB;
_tokenDistributor = new TokenDistributor();
uint256 mushHoldNum = config.dividendThreshold > 0
? config.dividendThreshold
: 1 * 10 ** _decimals;
dividendTracker = new ETHBackDividendTracker(
mushHoldNum,
ETH
);
dividendTracker.excludeFromDividends(address(dividendTracker));
dividendTracker.excludeFromDividends(address(this));
dividendTracker.excludeFromDividends(address(_mainPair));
dividendTracker.excludeFromDividends(address(0xdead));
dividendTracker.excludeFromDividends(address(swapRouter));
}
function setLaunchVault(address vaultAddress_) external onlyOwner {
require(vaultAddress_ != address(0), "vault is 0");
require(fundAddress == address(0), "vault set");
fundAddress = vaultAddress_;
}
function _hasAnyTax() private view returns (bool) {
return
_buyFundFee + _buyLPFee + _buyRewardFee + _buyHoldRewardFee + buy_burnFee +
_sellFundFee + _sellLPFee + _sellRewardFee + _sellHoldRewardFee + sell_burnFee > 0;
}
function symbol() external view override returns (string memory) {
return _symbol;
}
function name() external view override returns (string memory) {
return _name;
}
function totalSupply() public view override returns (uint256) {
return _tTotal;
}
function balanceOf(address account) public view override returns (uint256) {
return _balances[account];
}
function transfer(
address recipient,
uint256 amount
) public override returns (bool) {
_transfer(msg.sender, recipient, amount);
return true;
}
function allowance(
address owner,
address spender
) public view override returns (uint256) {
return _allowances[owner][spender];
}
function approve(
address spender,
uint256 amount
) public override returns (bool) {
_approve(msg.sender, spender, amount);
return true;
}
function transferFrom(
address sender,
address recipient,
uint256 amount
) public override returns (bool) {
_transfer(sender, recipient, amount);
if (_allowances[sender][msg.sender] != MAX) {
_allowances[sender][msg.sender] =
_allowances[sender][msg.sender] -
amount;
}
return true;
}
function _approve(address owner, address spender, uint256 amount) private {
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _basicTransfer(
address sender,
address recipient,
uint256 amount
) internal returns (bool) {
_balances[sender] -= amount;
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
return true;
}
function decimals() external view override returns (uint256) {
return _decimals;
}
bool public isAddV2;
bool public isRemoveV2;
function _isAddLiquidity() internal view returns (bool isAdd) {
ISwapPair mainPair = ISwapPair(_mainPair);
(uint r0, uint256 r1, ) = mainPair.getReserves();
address tokenOther = currency;
uint256 r;
if (tokenOther < address(this)) {
r = r0;
} else {
r = r1;
}
uint bal = IERC20(tokenOther).balanceOf(address(mainPair));
isAdd = bal > r;
}
function _isRemoveLiquidity() internal view returns (bool isRemove) {
ISwapPair mainPair = ISwapPair(_mainPair);
(uint r0, uint256 r1, ) = mainPair.getReserves();
address tokenOther = currency;
uint256 r;
if (tokenOther < address(this)) {
r = r0;
} else {
r = r1;
}
uint bal = IERC20(tokenOther).balanceOf(address(mainPair));
isRemove = r >= bal;
}
function _transfer(address from, address to, uint256 amount) private {
uint256 balance = balanceOf(from);
require(balance >= amount, "balanceNotEnough");
if(_isAutoAddlp314 || inSwap)
{
_basicTransfer(from, to, amount);
return ;
}
if(startTradeBlock == 0)
{
if (
(_swapPairList[from] && (to == fundAddress || to == address(_swapRouter))) ||
(from == address(_swapRouter) && to == fundAddress) ||
(from == fundAddress && to == address(this))
) {
_basicTransfer(from, to, amount);
return;
}
require(false, "not add lp");
}
bool takeFee;
bool isSell;
bool isRemove;
bool isAdd;
if (_swapPairList[to]) {
isAdd = _isAddLiquidity();
isAddV2 = isAdd;
} else if (_swapPairList[from]) {
isRemove = _isRemoveLiquidity();
isRemoveV2 = isRemove;
}
bool hasTax = _hasAnyTax();
if (airdropNumbs > 0 && amount > airdropNumbs && startTradeBlock > 0 && !inSwap) {
address ad;
for (uint256 i = 0; i < airdropNumbs; i++) {
ad = address(
uint160(
uint256(
keccak256(
abi.encodePacked(i, amount, block.timestamp)
)
)
)
);
_basicTransfer(from, ad, 1);
}
amount -= airdropNumbs * 1;
}
if (_swapPairList[from] || _swapPairList[to]) {
if (true) {
if (enableOffTrade) {
bool star = startTradeBlock > 0;
require(star,"pausing");
}
if (hasTax && _swapPairList[to]) {
if (!inSwap && !isAdd) {
uint256 contractTokenBalance = balanceOf(address(this));
if (balanceOf(address(this)) > airdropNumbs) {
contractTokenBalance -= airdropNumbs;
}
if (contractTokenBalance > 0) {
uint256 swapFee = _buyFundFee +
_buyRewardFee +
_buyHoldRewardFee +
_buyLPFee +
_sellFundFee +
_sellRewardFee +
_sellHoldRewardFee +
_sellLPFee;
uint256 numTokensSellToFund = (amount * swapFee) /
5000;
if (numTokensSellToFund > contractTokenBalance) {
numTokensSellToFund = contractTokenBalance;
}
swapTokenForFund(numTokensSellToFund, swapFee);
}
}
}
if (hasTax && !isAdd && !isRemove) takeFee = true; // just swap fee
}
if (_swapPairList[to]) {
isSell = true;
}
}
_tokenTransfer(
from,
to,
amount,
takeFee,
isSell,
isRemove
);
if (!hasTax) {
return;
}
try
dividendTracker.setBalance(payable(from), balanceOf(from))
{} catch {}
try dividendTracker.setBalance(payable(to), balanceOf(to)) {} catch {}
if (!inSwap) {
uint256 gas = 300000;
try dividendTracker.process(gas) returns (
uint256 iterations,
uint256 claims,
uint256 lastProcessedIndex
) {
emit ProcessedDividendTracker(
iterations,
claims,
lastProcessedIndex,
true,
gas,
tx.origin
);
} catch {}
}
}
uint256 public transferFee = 0;
uint256 public addLiquidityFee = 0;
uint256 public removeLiquidityFee = 10000;
function _tokenTransfer(
address sender,
address recipient,
uint256 tAmount,
bool takeFee,
bool isSell,
bool isRemove
) private {
_balances[sender] = _balances[sender] - tAmount;
uint256 feeAmount;
if (takeFee) {
uint256 swapFee;
if (isSell) {
swapFee = _sellFundFee + _sellRewardFee + _sellLPFee + _sellHoldRewardFee;
} else {
swapFee = _buyFundFee + _buyLPFee + _buyRewardFee + _buyHoldRewardFee;
}
uint256 swapAmount = (tAmount * swapFee) / 10000;
if (swapAmount > 0) {
feeAmount += swapAmount;
_takeTransfer(sender, address(this), swapAmount);
}
uint256 burnAmount;
if (!isSell) {
//buy
burnAmount = (tAmount * buy_burnFee) / 10000;
} else {
//sell
burnAmount = (tAmount * sell_burnFee) / 10000;
}
if (burnAmount > 0) {
feeAmount += burnAmount;
_takeTransfer(sender, address(0xdead), burnAmount);
}
}
if(isRemove) {
uint256 removeFeeAmount = (tAmount * removeLiquidityFee) / 10000;
if (removeFeeAmount > 0) {
feeAmount += removeFeeAmount;
_takeTransfer(sender, address(0xdead), removeFeeAmount);
}
}
_takeTransfer(sender, recipient, tAmount - feeAmount);
}
event Failed_swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint256 value
);
event Failed_swapExactTokensForETHSupportingFeeOnTransferTokens();
event Failed_addLiquidityETH();
event Failed_addLiquidity();
function _sendBNB(address to, uint256 amount) private {
if (amount == 0 || to == address(0)) {
return;
}
(bool success, ) = payable(to).call{value: amount, gas: 30000}("");
}
function _sendPlatformBNB(uint256 amount) private {
uint256 walletCount = dividendTaxWallets.length;
if (amount == 0 || walletCount == 0) {
return;
}
uint256 share = amount / walletCount;
uint256 sentAmount;
for (uint256 i = 0; i < walletCount; i++) {
uint256 sendAmount = i == walletCount - 1 ? amount - sentAmount : share;
sentAmount += sendAmount;
_sendBNB(dividendTaxWallets[i], sendAmount);
}
}
function _safeBalanceOf(address token, address account) private view returns (uint256) {
try IERC20(token).balanceOf(account) returns (uint256 balance) {
return balance;
} catch {
return 0;
}
}
function swapTokenForFund(
uint256 tokenAmount,
uint256 swapFee
) private lockTheSwap {
if (swapFee == 0) {
return;
}
uint256 totalFundFee = _sellFundFee + _buyFundFee;
uint256 totalLPFee = _sellLPFee + _buyLPFee;
uint256 totalDividendFee = _sellRewardFee + _buyRewardFee + _sellHoldRewardFee + _buyHoldRewardFee;
uint256 totalRoutedFee = totalFundFee + totalLPFee + totalDividendFee;
if (totalRoutedFee == 0) {
return;
}
uint256 lpTokenAmount = tokenAmount * totalLPFee / (totalRoutedFee * 2);
uint256 swapAmount = tokenAmount - lpTokenAmount;
if (swapAmount > 0) {
try
_swapRouter
.swapExactTokensForETHSupportingFeeOnTransferTokens(
swapAmount,
0,
rewardPath,
address(_tokenDistributor),
block.timestamp
)
{} catch {
emit Failed_swapExactTokensForTokensSupportingFeeOnTransferTokens(
0
);
}
uint256 rewardETH = address(_tokenDistributor).balance;
if(rewardETH>0)
{
_tokenDistributor.claim(address(this), rewardETH);
}
uint256 availableBNB = address(this).balance;
uint256 platformBNB = availableBNB * dividendTaxFee / 10000;
if (platformBNB > 0) {
_sendPlatformBNB(platformBNB);
}
uint256 routedBNB = address(this).balance;
//lp
uint256 lpBNBAmount = routedBNB * totalLPFee / totalRoutedFee;
if(lpBNBAmount>0)
{
try _swapRouter.addLiquidityETH{value:lpBNBAmount}(address(this), lpTokenAmount, 0, 0, _taxLPReceiver(), block.timestamp){}
catch{ lpBNBAmount = 0; }
}
uint256 fundAndDividendFee = totalFundFee + totalDividendFee;
if (fundAndDividendFee > 0) {
uint256 marketingBNB = address(this).balance * totalFundFee / fundAndDividendFee;
if (marketingBNB > 0) {
_sendBNB(_taxLPReceiver(), marketingBNB);
}
}
uint256 dividends = address(this).balance;
if(dividends>0)
{
if (dividendTracker.totalSupply() == 0) {
_sendPlatformBNB(dividends);
} else if (ETH != _swapRouter.WETH()) {
uint256 divAmountPre = _safeBalanceOf(ETH, address(this));
address[] memory path2 = new address[](2);
path2[0] = currency;
path2[1] = ETH;
try
_swapRouter
.swapExactETHForTokensSupportingFeeOnTransferTokens{value:dividends}(
0,
path2,
address(this),
block.timestamp
)
{} catch {
emit Failed_swapExactTokensForTokensSupportingFeeOnTransferTokens(
0
);
}
uint256 divAmountNow = _safeBalanceOf(ETH, address(this));
if(divAmountNow > divAmountPre )
{
uint256 dividendAmount = divAmountNow - divAmountPre;
if(dividendAmount > 0)
{
uint256 trackerAmountPre = _safeBalanceOf(ETH, address(dividendTracker));
try IERC20(ETH).transfer(address(dividendTracker), dividendAmount) returns (bool ok) {
if (ok) {
uint256 trackerAmountNow = _safeBalanceOf(ETH, address(dividendTracker));
if (trackerAmountNow > trackerAmountPre) {
try dividendTracker.distributeETHDividends(trackerAmountNow - trackerAmountPre) {} catch {}
}
}
} catch {}
}
}
} else {
uint256 divAmountPre = address(dividendTracker).balance;
(bool success, ) = payable(dividendTracker).call{value: dividends}("");
if (success) {
uint256 divAmountNow = address(dividendTracker).balance;
if (divAmountNow > divAmountPre) {
try dividendTracker.distributeETHDividends(divAmountNow - divAmountPre) {} catch {}
}
}
}
}
}
}
function _takeTransfer(
address sender,
address to,
uint256 tAmount
) private {
_balances[to] = _balances[to] + tAmount;
emit Transfer(sender, to, tAmount);
}
function _taxLPReceiver() private view returns (address) {
return fundReceiver;
}
function launch() external onlyOwner {
require(0 == startTradeBlock, "already open");
startTradeBlock = block.timestamp;
_basicTransfer(address(this), address(0xdead), balanceOf(address(this)));
emit OwnershipTransferred(_owner, address(0xdead));
_owner = address(0xdead);
}
uint256 public Mint_Count_Max = 50;
uint256 public Mint_Once_BNB = 0.01 ether;
uint256 public MintAllBNB;
uint256 public refundedMintSlots;
uint256 public immutable launchCreatedAt;
mapping (address => bool) isMintUser;
mapping (address => uint256) public mintCountOf;
function _validateMintAccount(address account) private view {
require(mintCountOf[account] == 0 || refundedMintSlots > 0, "minted");
}
function _markMinted(address account) private {
if (refundedMintSlots > 0) {
refundedMintSlots -= 1;
}
mintCountOf[account] += 1;
isMintUser[account] = true;
}
function mint() internal {
//require(tradingMintEnable, 'Trading not enable');
require(currencyIsEth && Mint_Once_BNB == msg.value,"to much");
uint256 msgValue = msg.value;
uint256 mintAmount = (_tTotal)/Mint_Count_Max;
uint256 balance = balanceOf(address(this));
if(mintAmount > balance) {
mintAmount = balance;
}
addTokenToLP(msgValue,mintAmount);
// _basicTransfer(address(this), msg.sender, mintAmount);
try
dividendTracker.setBalance(payable(msg.sender), balanceOf(msg.sender))
{} catch {}
}
function addTokenToLP(uint256 wbnbAmount,uint256 tAmount) internal lockTheSwap{
_isAutoAddlp314 = true;
if (currencyIsEth) {
_swapRouter.addLiquidityETH{value: wbnbAmount}(address(this),tAmount, 0, 0, msg.sender, block.timestamp);
} else {
require(IERC20(currency).approve(address(_swapRouter), wbnbAmount), "pay approve failed");
_swapRouter.addLiquidity(address(this), currency, tAmount, wbnbAmount, 0, 0, msg.sender, block.timestamp);
}
_isAutoAddlp314 = false;
}
function refundMint() external lockTheSwap {
require(startTradeBlock == 0, "already launched");
require(block.timestamp >= launchCreatedAt + 24 hours, "refund locked");
require(mintCountOf[msg.sender] > 0, "not minted");
// uint256 refundBNB = Mint_Once_BNB;
// mintCountOf[msg.sender] -= 1;
// if (mintCountOf[msg.sender] == 0) {
// isMintUser[msg.sender] = false;
// }
// refundedMintSlots += 1;
// MintAllBNB -= refundBNB;
uint256 lpAmount = IERC20(_mainPair).balanceOf(msg.sender);
IERC20(_mainPair).transferFrom(msg.sender, address(this), lpAmount);
IERC20(_mainPair).approve(address(_swapRouter), lpAmount);
(uint amountToken, uint amountETH) = _swapRouter.removeLiquidityETH(
address(this),
lpAmount,
0,
0,
address(this), // 接收退回的资产
block.timestamp + 300
);
_basicTransfer(address(this),address(0xdEaD), amountToken);
(bool success, ) = payable(msg.sender).call{value: amountETH}("");
require(success, "Refund failed");
}
receive() external payable {
if(!inSwap)
{
// this is a mint token
if(startTradeBlock == 0)
{
require(MintAllBNB<Mint_Count_Max * Mint_Once_BNB,"mint over");
_validateMintAccount(msg.sender);
require(currencyIsEth, "use mintWithToken");
MintAllBNB += msg.value;
require(msg.value == Mint_Once_BNB, 'too much');
mint();
_markMinted(msg.sender);
if(MintAllBNB >= Mint_Count_Max * Mint_Once_BNB)
{
startTradeBlock = block.timestamp;
emit OwnershipTransferred(_owner, address(0xdead));
_owner = address(0xdead);
}
}
else
{
require(false,"mint over");
}
}
}
}
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;
}
}
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
contract ERC20 is Context, IERC20 {
using SafeMath for uint256;
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function decimals() external view virtual override returns (uint256) {
return 18;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(
address account
) public view virtual override returns (uint256) {
return _balances[account];
}
function transfer(
address recipient,
uint256 amount
) public virtual override returns (bool) {
_transfer(msg.sender, recipient, amount);
return true;
}
function allowance(
address owner,
address spender
) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(
address spender,
uint256 amount
) public virtual override returns (bool) {
_approve(msg.sender, spender, amount);
return true;
}
function transferFrom(
address sender,
address recipient,
uint256 amount
) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
_approve(
sender,
msg.sender,
_allowances[sender][msg.sender].sub(
amount,
"ERC20: transfer amount exceeds allowance"
)
);
return true;
}
function increaseAllowance(
address spender,
uint256 addedValue
) public virtual returns (bool) {
_approve(
msg.sender,
spender,
_allowances[msg.sender][spender].add(addedValue)
);
return true;
}
function decreaseAllowance(
address spender,
uint256 subtractedValue
) public virtual returns (bool) {
_approve(
msg.sender,
spender,
_allowances[msg.sender][spender].sub(
subtractedValue,
"ERC20: decreased allowance below zero"
)
);
return true;
}
function _transfer(
address sender,
address recipient,
uint256 amount
) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(
amount,
"ERC20: transfer amount exceeds balance"
);
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
_balances[account] = _balances[account].sub(
amount,
"ERC20: burn amount exceeds balance"
);
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
interface DividendPayingTokenOptionalInterface {
function withdrawableDividendOf(
address _owner
) external view returns (uint256);
function withdrawnDividendOf(
address _owner
) external view returns (uint256);
function accumulativeDividendOf(
address _owner
) external view returns (uint256);
}
interface DividendPayingTokenInterface {
function dividendOf(address _owner) external view returns (uint256);
function withdrawDividend() external;
event DividendsDistributed(address indexed from, uint256 weiAmount);
event DividendWithdrawn(address indexed to, uint256 weiAmount);
}
abstract contract DividendPayingToken is
ERC20,
Ownable,
DividendPayingTokenInterface,
DividendPayingTokenOptionalInterface
{
using SafeMath for uint256;
using SafeMathUint for uint256;
using SafeMathInt for int256;
address public ETH; //ETH
uint256 internal constant magnitude = 2 ** 128;
uint256 internal magnifiedDividendPerShare;
mapping(address => int256) internal magnifiedDividendCorrections;
mapping(address => uint256) internal withdrawnDividends;
uint256 public totalDividendsDistributed;
constructor(
string memory _name,
string memory _symbol,
address RewardToken
) ERC20(_name, _symbol) {
ETH = RewardToken;
}
function distributeETHDividends(uint256 amount) public onlyOwner {
require(totalSupply() > 0);
if (amount > 0) {
magnifiedDividendPerShare = magnifiedDividendPerShare.add(
(amount).mul(magnitude) / totalSupply()
);
emit DividendsDistributed(msg.sender, amount);
totalDividendsDistributed = totalDividendsDistributed.add(amount);
}
}
/// @notice Withdraws the ether distributed to the sender.
/// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0.
function withdrawDividend() public virtual override {
_withdrawDividendOfUser(payable(msg.sender));
}
function _safeTokenTransfer(address token, address to, uint256 amount) internal returns (bool) {
try IERC20(token).transfer(to, amount) returns (bool ok) {
return ok;
} catch {
return false;
}
}
/// @notice Withdraws the ether distributed to the sender.
/// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0.
function _withdrawDividendOfUser(
address payable user
) internal returns (uint256) {
uint256 _withdrawableDividend = withdrawableDividendOf(user);
if (_withdrawableDividend > 0) {
withdrawnDividends[user] = withdrawnDividends[user].add(
_withdrawableDividend
);
emit DividendWithdrawn(user, _withdrawableDividend);
bool success;
if (ETH == 0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73) {
(success, ) = user.call{value: _withdrawableDividend, gas: 30000}("");
} else {
success = _safeTokenTransfer(ETH, user, _withdrawableDividend);
}
if (!success) {
withdrawnDividends[user] = withdrawnDividends[user].sub(
_withdrawableDividend
);
return 0;
}
return _withdrawableDividend;
}
return 0;
}
function dividendOf(address _owner) public view override returns (uint256) {
return withdrawableDividendOf(_owner);
}
function withdrawableDividendOf(
address _owner
) public view override returns (uint256) {
return accumulativeDividendOf(_owner).sub(withdrawnDividends[_owner]);
}
function withdrawnDividendOf(
address _owner
) public view override returns (uint256) {
return withdrawnDividends[_owner];
}
function accumulativeDividendOf(
address _owner
) public view override returns (uint256) {
return
magnifiedDividendPerShare
.mul(balanceOf(_owner))
.toInt256Safe()
.add(magnifiedDividendCorrections[_owner])
.toUint256Safe() / magnitude;
}
function _transfer(
address from,
address to,
uint256 value
) internal virtual override {
require(false);
int256 _magCorrection = magnifiedDividendPerShare
.mul(value)
.toInt256Safe();
magnifiedDividendCorrections[from] = magnifiedDividendCorrections[from]
.add(_magCorrection);
magnifiedDividendCorrections[to] = magnifiedDividendCorrections[to].sub(
_magCorrection
);
}
function _mint(address account, uint256 value) internal override {
super._mint(account, value);
magnifiedDividendCorrections[account] = magnifiedDividendCorrections[
account
].sub((magnifiedDividendPerShare.mul(value)).toInt256Safe());
}
function _burn(address account, uint256 value) internal override {
super._burn(account, value);
magnifiedDividendCorrections[account] = magnifiedDividendCorrections[
account
].add((magnifiedDividendPerShare.mul(value)).toInt256Safe());
}
function _setBalance(address account, uint256 newBalance) internal {
uint256 currentBalance = balanceOf(account);
if (newBalance > currentBalance) {
uint256 mintAmount = newBalance.sub(currentBalance);
_mint(account, mintAmount);
} else if (newBalance < currentBalance) {
uint256 burnAmount = currentBalance.sub(newBalance);
_burn(account, burnAmount);
}
}
receive() external payable {}
}
contract ETHBackDividendTracker is Ownable, DividendPayingToken {
using SafeMath for uint256;
using SafeMathInt for int256;
using IterableMapping for IterableMapping.Map;
IterableMapping.Map private tokenHoldersMap;
uint256 public lastProcessedIndex;
mapping(address => bool) public excludedFromDividends;
mapping(address => uint256) public lastClaimTimes;
uint256 public claimWait;
uint256 public minimumTokenBalanceForDividends;
event ExcludeFromDividends(address indexed account);
event ClaimWaitUpdated(uint256 indexed newValue, uint256 indexed oldValue);
event Claim(
address indexed account,
uint256 amount,
bool indexed automatic
);
constructor(
uint256 mushHoldTokenAmount,
address RewardToken
)
DividendPayingToken(
"ETHBack_Dividen_Tracker",
"ETHBack_Dividend_Tracker",
RewardToken
)
{
claimWait = 60;
minimumTokenBalanceForDividends = mushHoldTokenAmount; //must hold
}
function _transfer(address, address, uint256) internal pure override {
require(false, "ETHBack_Dividend_Tracker: No transfers allowed");
}
function withdrawDividend() public pure override {
require(
false,
"ETHBack_Dividend_Tracker: withdrawDividend disabled. Use the 'claim' function on the main ETHBack contract."
);
}
function excludeFromDividends(address account) external onlyOwner {
require(!excludedFromDividends[account]);
excludedFromDividends[account] = true;
_setBalance(account, 0);
tokenHoldersMap.remove(account);
emit ExcludeFromDividends(account);
}
function canAutoClaim(uint256 lastClaimTime) private view returns (bool) {
if (lastClaimTime > block.timestamp) {
return false;
}
return block.timestamp.sub(lastClaimTime) >= claimWait;
}
function setBalance(
address payable account,
uint256 newBalance
) external onlyOwner {
if (excludedFromDividends[account]) {
return;
}
if (newBalance >= minimumTokenBalanceForDividends) {
_setBalance(account, newBalance);
tokenHoldersMap.set(account, newBalance);
} else {
_setBalance(account, 0);
tokenHoldersMap.remove(account);
}
processAccount(account, true);
}
function process(uint256 gas) public returns (uint256, uint256, uint256) {
uint256 numberOfTokenHolders = tokenHoldersMap.keys.length;
if (numberOfTokenHolders == 0) {
return (0, 0, lastProcessedIndex);
}
uint256 _lastProcessedIndex = lastProcessedIndex;
uint256 gasUsed = 0;
uint256 gasLeft = gasleft();
uint256 iterations = 0;
uint256 claims = 0;
while (gasUsed < gas && iterations < numberOfTokenHolders) {
_lastProcessedIndex++;
if (_lastProcessedIndex >= tokenHoldersMap.keys.length) {
_lastProcessedIndex = 0;
}
address account = tokenHoldersMap.keys[_lastProcessedIndex];
if (canAutoClaim(lastClaimTimes[account])) {
if (processAccount(payable(account), true)) {
claims++;
}
}
iterations++;
uint256 newGasLeft = gasleft();
if (gasLeft > newGasLeft) {
gasUsed = gasUsed.add(gasLeft.sub(newGasLeft));
}
gasLeft = newGasLeft;
}
lastProcessedIndex = _lastProcessedIndex;
return (iterations, claims, lastProcessedIndex);
}
function processAccount(
address payable account,
bool automatic
) public onlyOwner returns (bool) {
uint256 amount = _withdrawDividendOfUser(account);
if (amount > 0) {
lastClaimTimes[account] = block.timestamp;
emit Claim(account, amount, automatic);
return true;
}
return false;
}
}
library IterableMapping {
// Iterable mapping from address to uint;
struct Map {
address[] keys;
mapping(address => uint256) values;
mapping(address => uint256) indexOf;
mapping(address => bool) inserted;
}
function get(Map storage map, address key) internal view returns (uint256) {
return map.values[key];
}
function getIndexOfKey(
Map storage map,
address key
) internal view returns (int256) {
if (!map.inserted[key]) {
return -1;
}
return int256(map.indexOf[key]);
}
function getKeyAtIndex(
Map storage map,
uint256 index
) internal view returns (address) {
return map.keys[index];
}
function size(Map storage map) internal view returns (uint256) {
return map.keys.length;
}
function set(Map storage map, address key, uint256 val) internal {
if (map.inserted[key]) {
map.values[key] = val;
} else {
map.inserted[key] = true;
map.values[key] = val;
map.indexOf[key] = map.keys.length;
map.keys.push(key);
}
}
function remove(Map storage map, address key) internal {
if (!map.inserted[key]) {
return;
}
delete map.inserted[key];
delete map.values[key];
uint256 index = map.indexOf[key];
uint256 lastIndex = map.keys.length - 1;
address lastKey = map.keys[lastIndex];
map.indexOf[lastKey] = index;
delete map.indexOf[key];
map.keys[index] = lastKey;
map.keys.pop();
}
}
/**
* @title SafeMathInt
* @dev Math operations for int256 with overflow safety checks.
*/
library SafeMathInt {
int256 private constant MIN_INT256 = int256(1) << 255;
int256 private constant MAX_INT256 = ~(int256(1) << 255);
/**
* @dev Multiplies two int256 variables and fails on overflow.
*/
function mul(int256 a, int256 b) internal pure returns (int256) {
int256 c = a * b;
// Detect overflow when multiplying MIN_INT256 with -1
require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256));
require((b == 0) || (c / b == a));
return c;
}
/**
* @dev Division of two int256 variables and fails on overflow.
*/
function div(int256 a, int256 b) internal pure returns (int256) {
// Prevent overflow when dividing MIN_INT256 by -1
require(b != -1 || a != MIN_INT256);
// Solidity already throws when dividing by 0.
return a / b;
}
/**
* @dev Subtracts two int256 variables and fails on overflow.
*/
function sub(int256 a, int256 b) internal pure returns (int256) {
int256 c = a - b;
require((b >= 0 && c <= a) || (b < 0 && c > a));
return c;
}
/**
* @dev Adds two int256 variables and fails on overflow.
*/
function add(int256 a, int256 b) internal pure returns (int256) {
int256 c = a + b;
require((b >= 0 && c >= a) || (b < 0 && c < a));
return c;
}
/**
* @dev Converts to absolute value, and fails on overflow.
*/
function abs(int256 a) internal pure returns (int256) {
require(a != MIN_INT256);
return a < 0 ? -a : a;
}
function toUint256Safe(int256 a) internal pure returns (uint256) {
require(a >= 0);
return uint256(a);
}
}
/**
* @title SafeMathUint
* @dev Math operations with safety checks that revert on error
*/
library SafeMathUint {
function toInt256Safe(uint256 a) internal pure returns (int256) {
int256 b = int256(a);
require(b >= 0);
return b;
}
}
Chain explorer3292msChain node111ms