Transaction Hash:
Block:
21092414 at Nov-01-2024 11:11:35 AM +UTC
Transaction Fee:
0.002902279876548975 ETH
$7.22
Gas Used:
496,275 Gas / 5.848128309 Gwei
Emitted Events:
231 |
ZAIBOT.Transfer( from=[Receiver] TransparentUpgradeableProxy, to=0xecbF1b7241020227b1f6E23787B753eea5ba3e8a, value=45237681700000000000000 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x4838B106...B0BAD5f97
Miner
| (Titan Builder) | 9.809923844176920944 Eth | 9.809975157014414069 Eth | 0.000051312837493125 | |
0x5880a0E3...8Ffc9c532 | |||||
0x68449870...21Fd8F101 | |||||
0xA4868098...96BEa690c |
0.370884215309546321 Eth
Nonce: 14
|
0.367981935432997346 Eth
Nonce: 15
| 0.002902279876548975 |
Execution Trace
TransparentUpgradeableProxy.e3ec5351( )
0xe1823c5a85e8d5ed385fb25cc70781ee4195bcf7.e3ec5351( )
-
ZAIBOT.transfer( recipient=0xecbF1b7241020227b1f6E23787B753eea5ba3e8a, amount=45237681700000000000000 ) => ( True )
-
File 1 of 2: TransparentUpgradeableProxy
File 2 of 2: ZAIBOT
pragma solidity ^0.6.12; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ abstract contract Proxy { /** * @dev Delegates the current call to `implementation`. * * This function does not return to its internall call site, it will return directly to the external caller. */ function _delegate(address implementation) internal { // solhint-disable-next-line no-inline-assembly assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function * and {_fallback} should delegate. */ function _implementation() internal virtual view returns (address); /** * @dev Delegates the current call to the address returned by `_implementation()`. * * This function does not return to its internall call site, it will return directly to the external caller. */ function _fallback() internal { _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback () payable external { _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data * is empty. */ receive () payable external { _delegate(_implementation()); } } /** * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an * implementation address that can be changed. This address is stored in storage in the location specified by * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the * implementation behind the proxy. * * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see * {TransparentUpgradeableProxy}. */ contract UpgradeableProxy is Proxy { /** * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`. * * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded * function call, and allows initializating the storage of the proxy like a Solidity constructor. */ constructor() public payable { assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1)); } /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Returns the current implementation address. */ function _implementation() internal override view returns (address impl) { bytes32 slot = _IMPLEMENTATION_SLOT; // solhint-disable-next-line no-inline-assembly assembly { impl := sload(slot) } } /** * @dev Upgrades the proxy to a new implementation. * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) virtual internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { address implementation = _implementation(); require(implementation != newImplementation, "Proxy: Attemps update proxy with the same implementation"); bytes32 slot = _IMPLEMENTATION_SLOT; // solhint-disable-next-line no-inline-assembly assembly { sstore(slot, newImplementation) } } } /** * @dev This contract implements a proxy that is upgradeable by an admin. * * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector * clashing], which can potentially be used in an attack, this contract uses the * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two * things that go hand in hand: * * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if * that call matches one of the admin functions exposed by the proxy itself. * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the * implementation. If the admin tries to call a function on the implementation it will fail with an error that says * "admin cannot fallback to proxy target". * * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due * to sudden errors when trying to call a function from the proxy implementation. * * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, * you should think of the `ProxyAdmin` instance as the real administrative inerface of your proxy. */ contract TransparentUpgradeableProxy is UpgradeableProxy { /** * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}. */ constructor(address admin, address implementation) public payable UpgradeableProxy() { require(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1), "Wrong admin slot"); _setAdmin(admin); _upgradeTo(implementation); } /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin. */ modifier ifAdmin() { if (msg.sender == _admin()) { _; } else { _fallback(); } } /** * @dev Returns the current admin. * * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103` */ function admin() external ifAdmin returns (address) { return _admin(); } /** * @dev Returns the current implementation. * * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` */ function implementation() external ifAdmin returns (address) { return _implementation(); } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. * * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}. */ function changeAdmin(address newAdmin) external ifAdmin { require(newAdmin != _admin(), "Proxy: new admin is the same admin."); emit AdminChanged(_admin(), newAdmin); _setAdmin(newAdmin); } /** * @dev Upgrade the implementation of the proxy. * * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}. */ function upgradeTo(address newImplementation) external ifAdmin { _upgradeTo(newImplementation); } /** * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the * proxied contract. * * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}. */ function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin { _upgradeTo(newImplementation); // solhint-disable-next-line avoid-low-level-calls (bool success,) = newImplementation.delegatecall(data); require(success); } /** * @dev Returns the current admin. */ function _admin() internal view returns (address adm) { bytes32 slot = _ADMIN_SLOT; // solhint-disable-next-line no-inline-assembly assembly { adm := sload(slot) } } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { bytes32 slot = _ADMIN_SLOT; require(newAdmin != address(0), "Proxy: Can't set admin to zero address."); // solhint-disable-next-line no-inline-assembly assembly { sstore(slot, newAdmin) } } }
File 2 of 2: ZAIBOT
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; /** THE VANGUARD OF AI BOTS. Website: https://zaibot.io/ Twitter: https://x.com/zaibotio/ Public Chat: https://t.me/zaibotpublic Announcement channel: https://t.me/zaibotann **/ /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ 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) { // Solidity only automatically asserts when dividing by 0 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 IERC20 { function totalSupply() external view returns (uint256); function decimals() external view returns (uint8); function symbol() external view returns (string memory); function name() external view returns (string memory); 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 IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); } interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; } /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ 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; } } // File: @openzeppelin/contracts/access/Ownable.sol /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } contract LGEWhitelisted is Context { struct WhitelistRound { uint256 duration; uint256 amountMax; mapping(address => bool) addresses; mapping(address => uint256) purchased; } WhitelistRound[] public _lgeWhitelistRounds; uint256 public _lgeTimestamp; address public _lgePairAddress; address public _whitelister; event WhitelisterTransferred(address indexed previousWhitelister, address indexed newWhitelister); constructor() { _whitelister = _msgSender(); } modifier onlyWhitelister() { require(_whitelister == _msgSender(), "Caller is not the whitelister"); _; } function renounceWhitelister() external onlyWhitelister { emit WhitelisterTransferred(_whitelister, address(0)); _whitelister = address(0); } function transferWhitelister(address newWhitelister) external onlyWhitelister { _transferWhitelister(newWhitelister); } function _transferWhitelister(address newWhitelister) internal { require(newWhitelister != address(0), "New whitelister is the zero address"); emit WhitelisterTransferred(_whitelister, newWhitelister); _whitelister = newWhitelister; } /* * createLGEWhitelist - Call this after initial Token Generation Event (TGE) * * pairAddress - address generated from createPair() event on DEX * durations - array of durations (seconds) for each whitelist rounds * amountsMax - array of max amounts (TOKEN decimals) for each whitelist round * */ function createLGEWhitelist( address pairAddress, uint256[] calldata durations, uint256[] calldata amountsMax ) external onlyWhitelister() { require(durations.length == amountsMax.length, "Invalid whitelist(s)"); _lgePairAddress = pairAddress; if (durations.length > 0) { delete _lgeWhitelistRounds; for (uint256 i = 0; i < durations.length; i++) { WhitelistRound storage whitelistRound = _lgeWhitelistRounds.push(); whitelistRound.duration = durations[i]; whitelistRound.amountMax = amountsMax[i]; } } } /* * modifyLGEWhitelistAddresses - Define what addresses are included/excluded from a whitelist round * * index - 0-based index of round to modify whitelist * duration - period in seconds from LGE event or previous whitelist round * amountMax - max amount (TOKEN decimals) for each whitelist round * */ function modifyLGEWhitelist( uint256 index, uint256 duration, uint256 amountMax, address[] calldata addresses, bool enabled ) external onlyWhitelister() { require(index < _lgeWhitelistRounds.length, "Invalid index"); require(amountMax > 0, "Invalid amountMax"); if (duration != _lgeWhitelistRounds[index].duration) _lgeWhitelistRounds[index].duration = duration; if (amountMax != _lgeWhitelistRounds[index].amountMax) _lgeWhitelistRounds[index].amountMax = amountMax; for (uint256 i = 0; i < addresses.length; i++) { _lgeWhitelistRounds[index].addresses[addresses[i]] = enabled; } } /* * getLGEWhitelistRound * * returns: * * 1. whitelist round number ( 0 = no active round now ) * 2. duration, in seconds, current whitelist round is active for * 3. timestamp current whitelist round closes at * 4. maximum amount a whitelister can purchase in this round * 5. is caller whitelisted * 6. how much caller has purchased in current whitelist round * */ function getLGEWhitelistRound() public view returns ( uint256, uint256, uint256, uint256, bool, uint256 ) { if (_lgeTimestamp > 0) { uint256 wlCloseTimestampLast = _lgeTimestamp; for (uint256 i = 0; i < _lgeWhitelistRounds.length; i++) { WhitelistRound storage wlRound = _lgeWhitelistRounds[i]; wlCloseTimestampLast = wlCloseTimestampLast + wlRound.duration; if (block.timestamp <= wlCloseTimestampLast) return ( i + 1, wlRound.duration, wlCloseTimestampLast, wlRound.amountMax, wlRound.addresses[_msgSender()], wlRound.purchased[_msgSender()] ); } } return (0, 0, 0, 0, false, 0); } /* * _applyLGEWhitelist - internal function to be called initially before any transfers * */ function _applyLGEWhitelist( address sender, address recipient, uint256 amount ) internal { if (_lgePairAddress == address(0) || _lgeWhitelistRounds.length == 0) return; if (_lgeTimestamp == 0 && sender != _lgePairAddress && recipient == _lgePairAddress && amount > 0) _lgeTimestamp = block.timestamp; if (sender == _lgePairAddress && recipient != _lgePairAddress) { //buying (uint256 wlRoundNumber, , , , , ) = getLGEWhitelistRound(); if (wlRoundNumber > 0) { WhitelistRound storage wlRound = _lgeWhitelistRounds[wlRoundNumber - 1]; require(wlRound.addresses[recipient], "LGE - Buyer is not whitelisted"); uint256 amountRemaining = 0; if (wlRound.purchased[recipient] < wlRound.amountMax) amountRemaining = wlRound.amountMax - wlRound.purchased[recipient]; require(amount <= amountRemaining, "LGE - Amount exceeds whitelist maximum"); wlRound.purchased[recipient] = wlRound.purchased[recipient] + amount; } } } } contract ZAIBOT is Context, IERC20, Ownable, LGEWhitelisted { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; uint8 private _decimals; string private _symbol; string private _name; mapping(address => bool) public _feeExcluded; uint256 public _feeBurnPct; uint256 public _feeRewardPct; address public _feeRewardAddress; mapping(address => bool) public _pair; address public _router; address[] public _feeRewardSwapPath; constructor(uint256 feeBurnPct, uint256 feeRewardPct, address feeRewardAddress, address router) { _name = "ZAIBOT.io"; _symbol = "ZAI"; _decimals = 18; _totalSupply = 100000000e18; IUniswapV2Router02 r = IUniswapV2Router02(router); address[] memory feeRewardSwapPath = new address[](2); feeRewardSwapPath[0] = address(this); feeRewardSwapPath[1] = r.WETH(); setFees(feeBurnPct, feeRewardPct, feeRewardSwapPath, feeRewardAddress); _router = router; setFeeExcluded(_msgSender(), true); setFeeExcluded(address(this), true); _balances[_msgSender()] = _totalSupply; emit Transfer(address(0), _msgSender(), _totalSupply); } function setRouter(address r) public onlyOwner { _router = r; } function setPair(address a, bool pair) public onlyOwner { _pair[a] = pair; } function setFeeExcluded(address a, bool excluded) public onlyOwner { _feeExcluded[a] = excluded; } function setFees(uint256 feeBurnPct, uint256 feeRewardPct, address[] memory feeRewardSwapPath, address feeRewardAddress) public onlyOwner { require(feeBurnPct.add(feeRewardPct) <= 2500, "Fees must not total more than 100%"); require(feeRewardSwapPath.length > 1, "Invalid path"); require(feeRewardAddress != address(0), "Fee reward address must not be zero address"); _feeBurnPct = feeBurnPct; _feeRewardPct = feeRewardPct; _feeRewardSwapPath = feeRewardSwapPath; _feeRewardAddress = feeRewardAddress; } function burn(uint256 amount) external { _burn(_msgSender(), amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Returns the token decimals. */ function decimals() external view override returns (uint8) { return _decimals; } /** * @dev Returns the token symbol. */ function symbol() external view override returns (string memory) { return _symbol; } /** * @dev Returns the token name. */ function name() external view override returns (string memory) { return _name; } /** * @dev See {ERC20-totalSupply}. */ function totalSupply() external view override returns (uint256) { return _totalSupply; } /** * @dev See {ERC20-balanceOf}. */ function balanceOf(address account) external view override returns (uint256) { return _balances[account]; } /** * @dev See {ERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) external override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {ERC20-allowance}. */ function allowance(address owner, address spender) external view override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {ERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) external override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {ERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}; * * Requirements: * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for `sender`'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) external override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {ERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) external returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {ERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } function _beforeTokenTransfer(address sender, address recipient, uint256 amount) internal { LGEWhitelisted._applyLGEWhitelist(sender, recipient, amount); } function _afterTokenTransfer(address sender, address recipient, uint256 amount) internal {} /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); if(recipient == address(0x000000000000000000000000000000000000dEaD)) { _burn(sender, amount); return; } _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); if(_pair[recipient] && !_feeExcluded[sender]) { uint256 feeBurnAmount = 0; if(_feeBurnPct > 0) { feeBurnAmount = amount.mul(_feeBurnPct).div(10000); _totalSupply = _totalSupply.sub(feeBurnAmount); emit Transfer(sender, address(0), feeBurnAmount); } uint256 feeRewardAmount = 0; if(_feeRewardPct > 0 && _feeRewardAddress != address(0)) { feeRewardAmount = amount.mul(_feeRewardPct).div(10000); if(_router != address(0)) { _balances[address(this)] = _balances[address(this)].add(feeRewardAmount); emit Transfer(sender, address(this), feeRewardAmount); IUniswapV2Router02 r = IUniswapV2Router02(_router); _approve(address(this), _router, feeRewardAmount); r.swapExactTokensForTokensSupportingFeeOnTransferTokens( feeRewardAmount, 0, _feeRewardSwapPath, _feeRewardAddress, block.timestamp ); } else { _balances[_feeRewardAddress] = _balances[_feeRewardAddress].add(feeRewardAmount); emit Transfer(sender, _feeRewardAddress, feeRewardAmount); } } amount = amount.sub(feeBurnAmount).sub(feeRewardAmount); } _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. * * This is internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal { 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); } }