Transaction Hash:
Block:
16012118 at Nov-20-2022 03:27:59 PM +UTC
Transaction Fee:
0.002614703297748737 ETH
$5.94
Gas Used:
183,209 Gas / 14.271696793 Gwei
Emitted Events:
308 |
ethTCGCoin20.Transfer( from=[Receiver] PoolStakingLock, to=[Sender] 0x31c0b202eb94018ffdc6366160626dede2f858f3, value=51044647860 )
|
309 |
PoolStakingLock.Harvest( user=[Sender] 0x31c0b202eb94018ffdc6366160626dede2f858f3, amount=51044647860 )
|
310 |
ethTCGCoin20.Transfer( from=[Receiver] PoolStakingLock, to=[Sender] 0x31c0b202eb94018ffdc6366160626dede2f858f3, value=499001010100 )
|
311 |
PoolStakingLock.Withdraw( user=[Sender] 0x31c0b202eb94018ffdc6366160626dede2f858f3, amount=499001010100 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x0d31DF7d...3aBCC3A5A | |||||
0x31C0b202...de2F858F3 |
0.363670075511830242 Eth
Nonce: 20
|
0.361055372214081505 Eth
Nonce: 21
| 0.002614703297748737 | ||
0xDAFEA492...692c98Bc5
Miner
| (Flashbots: Builder) | 1.196861152708800267 Eth | 1.197135966208800267 Eth | 0.0002748135 | |
0xe550AF09...E66745fc6 |
Execution Trace
PoolStakingLock.withdraw( _amount=499001010100 )
-
ethTCGCoin20.balanceOf( account=0xe550AF09aFc9292Bb26616C9e74ABA8E66745fc6 ) => ( 119892897645485 )
-
ethTCGCoin20.transfer( recipient=0x31C0b202Eb94018Ffdc6366160626Dede2F858F3, amount=51044647860 ) => ( True )
-
ethTCGCoin20.transfer( recipient=0x31C0b202Eb94018Ffdc6366160626Dede2F858F3, amount=499001010100 ) => ( True )
withdraw[PoolStakingLock (ln:181)]
poolWIsLock[PoolStakingLock (ln:183)]
_getBlockNumber[PoolStakingLock (ln:244)]
_getBlockNumber[PoolStakingLock (ln:245)]
_updatePool[PoolStakingLock (ln:185)]
_getBlockNumber[PoolStakingLock (ln:424)]
_getBlockNumber[PoolStakingLock (ln:429)]
_getMultiplier[PoolStakingLock (ln:432)]
_getBlockNumber[PoolStakingLock (ln:432)]
mul[PoolStakingLock (ln:433)]
add[PoolStakingLock (ln:434)]
div[PoolStakingLock (ln:435)]
mul[PoolStakingLock (ln:435)]
_getBlockNumber[PoolStakingLock (ln:437)]
payOrLockupPending[PoolStakingLock (ln:187)]
poolHIsLock[PoolStakingLock (ln:377)]
_getBlockNumber[PoolStakingLock (ln:234)]
_getBlockNumber[PoolStakingLock (ln:235)]
sub[PoolStakingLock (ln:378)]
div[PoolStakingLock (ln:378)]
mul[PoolStakingLock (ln:378)]
add[PoolStakingLock (ln:383)]
sub[PoolStakingLock (ln:387)]
rewardBalance[PoolStakingLock (ln:392)]
safeTransfer[PoolStakingLock (ln:395)]
Harvest[PoolStakingLock (ln:399)]
safeTransfer[PoolStakingLock (ln:401)]
Harvest[PoolStakingLock (ln:405)]
add[PoolStakingLock (ln:410)]
add[PoolStakingLock (ln:411)]
safeTransfer[PoolStakingLock (ln:190)]
sub[PoolStakingLock (ln:191)]
sub[PoolStakingLock (ln:192)]
revert[PoolStakingLock (ln:195)]
_updateRewardDebt[PoolStakingLock (ln:197)]
Withdraw[PoolStakingLock (ln:198)]
File 1 of 2: PoolStakingLock
File 2 of 2: ethTCGCoin20
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "./imports/IBEP20.sol"; import "./imports/SafeBEP20.sol"; contract PoolStakingLock is Ownable, ReentrancyGuard { using SafeMath for uint256; using SafeBEP20 for IBEP20; // The address of retrostaking factory address public POOL_STAKING_FACTORY; // Whether a limit is set for users bool public hasUserLimit; // Whether a limit is set for Pool bool public hasPoolLimit; // Whether a HarvestLock bool public hasPoolHL; // Whether a WithdrawLock bool public hasPoolWL; // Whether it is initialized bool public isInitialized; // Accrued token per share uint256 public accTokenPerShare; // The block number when mining ends. uint256 public bonusEndBlock; // The block number when mining starts. uint256 public startBlock; // The block number of the last pool update uint256 public lastRewardBlock; // The pool limit (0 if none) uint256 public poolLimitPerUser; // The pool limit global staking (0 if none) uint256 public poolLimitGlobal; // The pool minimum limit for amount deposited uint256 public poolMinDeposit; // Tokens created per block. uint256 public rewardPerBlock; // Total locked up rewards uint256 public totalLockedUpRewards; // The precision factor uint256 public PRECISION_FACTOR; // Keep track of number of tokens staked in case the contract earns reflect fees uint256 public totalStaked = 0; // The reward token IBEP20 public rewardToken; // The staked token IBEP20 public stakedToken; // Info of each user that stakes tokens (stakedToken) mapping(address => UserInfo) public userInfo; struct UserInfo { uint256 amount; // How many staked tokens the user has provided uint256 rewardDebt; // Reward debt uint256 rewardLockedUp; //Reward locked up } event AdminTokenRecovery(address tokenRecovered, uint256 amount); event Deposit(address indexed user, uint256 amount); event EmergencyWithdraw(address indexed user, uint256 amount); event NewStartAndEndBlocks(uint256 startBlock, uint256 endBlock); event NewRewardPerBlock(uint256 rewardPerBlock); event NewPoolLimit(uint256 poolLimitPerUser); event RewardsStop(uint256 blockNumber); event Withdraw(address indexed user, uint256 amount); event Harvest(address indexed user, uint256 amount); constructor() { POOL_STAKING_FACTORY = msg.sender; } /* * @notice Initialize the contract * @param _stakedToken: staked token address * @param _rewardToken: reward token address * @param _rewardPerBlock: reward per block (in rewardToken) * @param _startBlock: start block * @param _bonusEndBlock: end block * @param _poolLimitPerUser: pool limit per user in stakedToken (if any, else 0) * @param _poolLimitGlobal: pool limit global in stakedToken (if any, else 0) * @param _poolMinDeposit: pool minimal limit for deposited amount * @param _poolHarvestLock: pool Harvest is locked (if true is enable, else false is disable) * @param _poolWithdrawLock: pool Withdraw is locked (if true is enable, else false is disable) * @param _admin: admin address with ownership */ function initialize( IBEP20 _stakedToken, IBEP20 _rewardToken, uint256 _rewardPerBlock, uint256 _startBlock, uint256 _bonusEndBlock, uint256 _poolLimitPerUser, uint256 _poolLimitGlobal, uint256 _poolMinDeposit, bool _poolHarvestLock, bool _poolWithdrawLock, address _admin ) external { require(!isInitialized, "Already initialized"); require(msg.sender == POOL_STAKING_FACTORY, "Not factory"); // Make this contract initialized isInitialized = true; stakedToken = _stakedToken; rewardToken = _rewardToken; rewardPerBlock = _rewardPerBlock; startBlock = _startBlock; bonusEndBlock = _bonusEndBlock; if (_poolLimitPerUser > 0) { hasUserLimit = true; poolLimitPerUser = _poolLimitPerUser; } if (_poolLimitGlobal > 0) { hasPoolLimit = true; poolLimitGlobal = _poolLimitGlobal; } if (_poolMinDeposit > 0) { poolMinDeposit = _poolMinDeposit; } if (_poolHarvestLock) { hasPoolHL = true; } if (_poolWithdrawLock) { hasPoolWL = true; } uint256 decimalsRewardToken = uint256(rewardToken.decimals()); require(decimalsRewardToken < 30, "Must be inferior to 30"); PRECISION_FACTOR = uint256(10**(uint256(30).sub(decimalsRewardToken))); // Set the lastRewardBlock as the startBlock lastRewardBlock = startBlock; // Transfer ownership to the admin address who becomes owner of the contract transferOwnership(_admin); } /* * @notice Deposit staked tokens and collect reward tokens (if any) * @param _amount: amount to withdraw (in rewardToken) */ function deposit(uint256 _amount) external nonReentrant { UserInfo storage user = userInfo[msg.sender]; require( _getBlockNumber() < bonusEndBlock, "Cannot deposit after the last reward block" ); uint256 finalDepositAmount = 0; if (hasUserLimit) { require( _amount.add(user.amount) <= poolLimitPerUser, "User amount above limit" ); } if (hasPoolLimit) { require( _amount.add(totalStaked) <= poolLimitGlobal, "Global amount above limit" ); } require( user.amount + _amount >= poolMinDeposit, "Amount under limit" ); _updatePool(); if (user.amount > 0) { payOrLockupPending(user); } if (_amount > 0) { uint256 preStakeBalance = stakedToken.balanceOf(address(this)); stakedToken.safeTransferFrom( address(msg.sender), address(this), _amount ); finalDepositAmount = stakedToken.balanceOf(address(this)).sub( preStakeBalance ); user.amount = user.amount.add(finalDepositAmount); totalStaked = totalStaked.add(finalDepositAmount); } _updateRewardDebt(user); emit Deposit(msg.sender, _amount); } /* * @notice Withdraw staked tokens and collect reward tokens * @param _amount: amount to withdraw (in rewardToken) */ function withdraw(uint256 _amount) external nonReentrant { UserInfo storage user = userInfo[msg.sender]; bool poolStatusWithdraw = poolWIsLock(); require(user.amount >= _amount, "Amount to withdraw too high"); _updatePool(); // Withdraw pending AUTO payOrLockupPending(user); if (!poolStatusWithdraw) { if (_amount > 0) { stakedToken.safeTransfer(address(msg.sender), _amount); user.amount = user.amount.sub(_amount); totalStaked = totalStaked.sub(_amount); } } else { revert("Pool locked"); } _updateRewardDebt(user); emit Withdraw(msg.sender, _amount); } function harvest() external nonReentrant { UserInfo storage user = userInfo[msg.sender]; _updatePool(); // Withdraw pending AUTO require(payOrLockupPending(user), "Harvests locked"); _updateRewardDebt(user); } /* * @notice Withdraw staked tokens without caring about rewards * @dev Needs to be for emergency. */ function emergencyWithdraw() external nonReentrant { UserInfo storage user = userInfo[msg.sender]; uint256 amountToTransfer = user.amount; user.amount = 0; user.rewardDebt = 0; if (amountToTransfer > 0) { stakedToken.safeTransfer(address(msg.sender), amountToTransfer); totalStaked = totalStaked.sub(amountToTransfer); } emit EmergencyWithdraw(msg.sender, user.amount); } function rewardBalance() public view returns (uint256) { uint256 balance = rewardToken.balanceOf(address(this)); if (stakedToken == rewardToken) return balance.sub(totalStaked); return balance; } function totalStakeTokenBalance() public view returns (uint256) { if (stakedToken == rewardToken) return totalStaked; return stakedToken.balanceOf(address(this)); } function poolHIsLock() public view returns (bool) { bool statusPool; if (hasPoolHL) { statusPool = bonusEndBlock >= _getBlockNumber(); if (startBlock >= _getBlockNumber()) { statusPool = false; } } return statusPool; } function poolWIsLock() public view returns (bool) { bool statusPool; if (hasPoolWL) { statusPool = bonusEndBlock >= _getBlockNumber(); if (startBlock >= _getBlockNumber()) { statusPool = false; } } return statusPool; } function poolChangeHLock(bool _value) public onlyOwner { hasPoolHL = _value; } function poolChangeWLock(bool _value) public onlyOwner { hasPoolWL = _value; } /* * @notice Stop rewards * @dev Only callable by owner. Needs to be for emergency. */ function emergencyRewardWithdraw(uint256 _amount) external onlyOwner { require(_amount <= rewardBalance(), "not enough rewards"); rewardToken.safeTransfer(address(msg.sender), _amount); } /** * @notice It allows the admin to recover wrong tokens sent to the contract * @param _tokenAddress: the address of the token to withdraw * @param _tokenAmount: the number of tokens to withdraw * @dev This function is only callable by admin. */ function recoverWrongTokens(address _tokenAddress, uint256 _tokenAmount) external onlyOwner { require( _tokenAddress != address(stakedToken), "Cannot be staked token" ); IBEP20(_tokenAddress).safeTransfer(address(msg.sender), _tokenAmount); emit AdminTokenRecovery(_tokenAddress, _tokenAmount); } /* * @notice Stop rewards * @dev Only callable by owner */ function stopReward() external onlyOwner { bonusEndBlock = _getBlockNumber(); } /* * @notice Update pool limit per user * @dev Only callable by owner. * @param _hasUserLimit: whether the limit remains forced * @param _poolLimitPerUser: new pool limit per user */ function updatePoolLimitPerUser( bool _hasUserLimit, uint256 _poolLimitPerUser ) external onlyOwner { require(hasUserLimit, "Must be set"); if (_hasUserLimit) { require( _poolLimitPerUser > poolLimitPerUser, "New limit must be higher" ); poolLimitPerUser = _poolLimitPerUser; } else { hasUserLimit = _hasUserLimit; poolLimitPerUser = 0; } emit NewPoolLimit(poolLimitPerUser); } /* * @notice Update reward per block * @dev Only callable by owner. * @param _rewardPerBlock: the reward per block */ function updateRewardPerBlock(uint256 _rewardPerBlock) external onlyOwner { require(_getBlockNumber() < startBlock, "Pool has started"); rewardPerBlock = _rewardPerBlock; emit NewRewardPerBlock(_rewardPerBlock); } /** * @notice It allows the admin to update start and end blocks * @dev This function is only callable by owner. * @param _startBlock: the new start block * @param _bonusEndBlock: the new end block */ function updateStartAndEndBlocks( uint256 _startBlock, uint256 _bonusEndBlock ) external onlyOwner { require(_getBlockNumber() < startBlock, "Pool has started"); require( _startBlock < _bonusEndBlock, "New startBlock must be lower than new endBlock" ); require( _getBlockNumber() < _startBlock, "New startBlock must be higher than current block" ); startBlock = _startBlock; bonusEndBlock = _bonusEndBlock; // Set the lastRewardBlock as the startBlock lastRewardBlock = startBlock; emit NewStartAndEndBlocks(_startBlock, _bonusEndBlock); } /* * @notice View function to see pending reward on frontend. * @param _user: user address * @return Pending reward for a given user */ function pendingReward(address _user) external view returns (uint256) { UserInfo storage user = userInfo[_user]; uint256 stakedTokenSupply = totalStaked; if (_getBlockNumber() > lastRewardBlock && stakedTokenSupply != 0) { uint256 multiplier = _getMultiplier(lastRewardBlock, _getBlockNumber()); uint256 reward = multiplier.mul(rewardPerBlock); uint256 adjustedTokenPerShare = accTokenPerShare.add( reward.mul(PRECISION_FACTOR).div(stakedTokenSupply) ); uint256 pending = user .amount .mul(adjustedTokenPerShare) .div(PRECISION_FACTOR) .sub(user.rewardDebt); return pending.add(user.rewardLockedUp); } else { uint256 pending = user .amount .mul(accTokenPerShare) .div(PRECISION_FACTOR) .sub(user.rewardDebt); return pending.add(user.rewardLockedUp); } } function payOrLockupPending(UserInfo storage user) internal returns(bool) { bool poolStatusHarvest = poolHIsLock(); uint256 pending = user .amount .mul(accTokenPerShare) .div(PRECISION_FACTOR) .sub(user.rewardDebt); uint256 totalRewards = pending.add(user.rewardLockedUp); if (!poolStatusHarvest) { if (totalRewards > 0) { // reset lockup totalLockedUpRewards = totalLockedUpRewards.sub( user.rewardLockedUp ); user.rewardLockedUp = 0; // send rewards uint256 currentRewardBalance = rewardBalance(); if (currentRewardBalance > 0) { if (totalRewards > currentRewardBalance) { rewardToken.safeTransfer( address(msg.sender), currentRewardBalance ); emit Harvest(msg.sender, currentRewardBalance); } else { rewardToken.safeTransfer( address(msg.sender), totalRewards ); emit Harvest(msg.sender, totalRewards); } } } } else if (pending > 0) { user.rewardLockedUp = user.rewardLockedUp.add(pending); totalLockedUpRewards = totalLockedUpRewards.add(pending); } return !poolStatusHarvest; } function _updateRewardDebt(UserInfo storage user) internal { user.rewardDebt = user.amount.mul(accTokenPerShare).div( PRECISION_FACTOR ); } /* * @notice Update reward variables of the given pool to be up-to-date. */ function _updatePool() internal { if (_getBlockNumber() <= lastRewardBlock) { return; } uint256 stakedTokenSupply = totalStaked; if (stakedTokenSupply == 0) { lastRewardBlock = _getBlockNumber(); return; } uint256 multiplier = _getMultiplier(lastRewardBlock, _getBlockNumber()); uint256 reward = multiplier.mul(rewardPerBlock); accTokenPerShare = accTokenPerShare.add( reward.mul(PRECISION_FACTOR).div(stakedTokenSupply) ); lastRewardBlock = _getBlockNumber(); } /* * @notice Return reward multiplier over the given _from to _to block. * @param _from: block to start * @param _to: block to finish */ function _getMultiplier(uint256 _from, uint256 _to) internal view returns (uint256) { if (_to <= bonusEndBlock) { return _to.sub(_from); } else if (_from >= bonusEndBlock) { return 0; } else { return bonusEndBlock.sub(_from); } } function _getBlockNumber() internal view virtual returns(uint256) { return block.number; } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.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() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { 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 { _transferOwnership(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"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol) pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // 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 (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @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) { return a + b; } /** * @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 a - b; } /** * @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) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting 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 a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting 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) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * 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) { unchecked { require(b > 0, errorMessage); return a % b; } } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; interface IBEP20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the token decimals. */ function decimals() external view returns (uint8); /** * @dev Returns the token symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the token name. */ function name() external view returns (string memory); /** * @dev Returns the bep token owner. */ function getOwner() external view returns (address); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address _owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval( address indexed owner, address indexed spender, uint256 value ); }pragma solidity >=0.8.0; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "./IBEP20.sol"; /** * @title SafeBEP20 * @dev Wrappers around BEP20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeBEP20 for IBEP20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeBEP20 { using SafeMath for uint256; using Address for address; function safeTransfer( IBEP20 token, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transfer.selector, to, value) ); } function safeTransferFrom( IBEP20 token, address from, address to, uint256 value ) internal { _callOptionalReturn( token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value) ); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IBEP20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IBEP20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeBEP20: approve from non-zero to non-zero allowance" ); _callOptionalReturn( token, abi.encodeWithSelector(token.approve.selector, spender, value) ); } function safeIncreaseAllowance( IBEP20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender).add( value ); _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } function safeDecreaseAllowance( IBEP20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender).sub( value, "SafeBEP20: decreased allowance below zero" ); _callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IBEP20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall( data, "SafeBEP20: low-level call failed" ); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require( abi.decode(returndata, (bool)), "SafeBEP20: BEP20 operation did not succeed" ); } } }// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @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) { return msg.data; } }
File 2 of 2: ethTCGCoin20
/** * author: BlockCzech R&D Lab <[email protected]> * * *░░████████╗░█████╗░░██████╗░░░░█████╗░░█████╗░██╗███╗░░██╗░░██████╗░░░░░█████╗░░░ *░░╚══██╔══╝██╔══██╗██╔════╝░░░██╔══██╗██╔══██╗██║████╗░██║░░╚════██╗░░░██╔══██╗░░ *░░░░░██║░░░██║░░╚═╝██║░░██╗░░░██║░░╚═╝██║░░██║██║██╔██╗██║░░░░███╔═╝░░░██║░░██║░░ *░░░░░██║░░░██║░░██╗██║░░╚██╗░░██║░░██╗██║░░██║██║██║╚████║░░██╔══╝░░░░░██║░░██║░░ *░░░░░██║░░░╚█████╔╝╚██████╔╝░░╚█████╔╝╚█████╔╝██║██║░╚███║░░███████╗██╗╚█████╔╝░░ *░░░░░╚═╝░░░░╚════╝░░╚═════╝░░░░╚════╝░░╚════╝░╚═╝╚═╝░░╚══╝░░╚══════╝╚═╝░╚════╝░░░ * * * The TCGCoin20 [ETH] is based on the Automatic Liquidity Pool & Custom Fees Architecture. * * * SPDX-License-Identifier: MIT * */ pragma solidity 0.8.11; abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } interface IUniswapV2Factory { event PairCreated(address indexed token0, address indexed token1, address pair, uint); function feeTo() external view returns (address); function feeToSetter() external view returns (address); function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint) external view returns (address pair); function allPairsLength() external view returns (uint); function createPair(address tokenA, address tokenB) external returns (address pair); function setFeeTo(address) external; function setFeeToSetter(address) external; function INIT_CODE_PAIR_HASH() external view returns (bytes32); } 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; } interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; } library SafeMath { function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // 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 (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } } contract Ownable is Context { address private _owner; address private _previousOwner; uint256 private _lockTime; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); constructor () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } function owner() public view returns (address) { return _owner; } modifier onlyOwner() { require(_owner == _msgSender(), "Ownable: caller is not the owner"); _; } function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } function getUnlockTime() public view returns (uint256) { return _lockTime; } function lock(uint256 time) public virtual onlyOwner { _previousOwner = _owner; _owner = address(0); _lockTime = block.timestamp + time; emit OwnershipTransferred(_owner, address(0)); } function unlock() public virtual { require(_previousOwner == msg.sender, "You don't have permission to unlock"); require(block.timestamp > _lockTime , "Contract is locked until 7 days"); emit OwnershipTransferred(_owner, _previousOwner); _owner = _previousOwner; } } library Address { function isContract(address account) internal view returns (bool) { bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } interface IERC20 { 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); } contract ethTCGCoin20 is Context, IERC20, Ownable { using Address for address; using SafeMath for uint256; mapping (address => uint256) private _reflectOwned; mapping (address => uint256) private _takeOwned; mapping (address => mapping (address => uint256)) private _allowances; mapping (address => bool) private _isExcludedFromFee; mapping (address => bool) private _isExcluded; mapping (address => bool) private _isBot; address[] private _excluded; mapping (address => bool) private _isDEXBuyFee; mapping (address => bool) private _isDEXSellFee; uint256 private constant MAX = ~uint256(0); uint256 private _takeTotal = 280 * 10**6 * 10**9; uint256 private _reflectTotal = (MAX - (MAX % _takeTotal)); uint256 private _takeFeeTotal; string private constant _name = "TCG 2.0 ETH"; string private constant _symbol = "ethTCG2"; uint8 private constant _decimals = 9; bool public _taxFeeFlag = false; uint256 public _taxFee = 0; uint256 private _previousTaxFee = _taxFee; uint256 public _liquidityFee = 10; uint256 private _previousLiquidityFee = _liquidityFee; uint256 public _liquiditySellFee = 10; uint256 private _previousLiquiditySellFee = _liquiditySellFee; IUniswapV2Router02 public uniswapRouter; address public uniswapPair; bool public isIntoLiquifySwap; bool public swapAndLiquifyEnabled = true; uint256 private _maxLoopCount = 100; uint256 public _maximumValueOfTransaction = 280 * 10**6 * 10**9 ; uint256 public numTokensSellToAddToLiquidity = 10 * 10**9 ; event SwapAndLiquifyEvent( uint256 coinsForSwapping, uint256 bnbIsReceived, uint256 coinsThatWasAddedIntoLiquidity ); event LiquifySwapUpdatedEnabled(bool enabled); event SetTaxFeePercent(uint value); event SetTaxFeeFlag(bool flag); event SetMaxLoopCount(uint value); event SetMaxTxPercent(uint value); event SetLiquidityFeePercent(uint value); event SetSellFeeLiquidity(uint value); event ExcludedFromFee(address _address); event IncludeInFee(address _address); event ETHReceived(address _address); event Delivery(address _address, uint256 amount); event AddLiquidity(uint256 coin_amount, uint256 bnb_amount); event SwapAndLiquifyEnabled(bool flag); event RouterSet(address indexed router); modifier lockSwaping { isIntoLiquifySwap = true; _; isIntoLiquifySwap = false; } constructor () { _reflectOwned[_msgSender()] = _reflectTotal; _setRouterAddress(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D,0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f); _isExcludedFromFee[owner()] = true; _isExcludedFromFee[address(this)] = true; emit Transfer(address(0), _msgSender(), _takeTotal); } function _setRouterAddressByOwner(address router, address factory) external onlyOwner() { _setRouterAddress(router, factory); } function _setRouterAddress(address router, address factory) private { IUniswapV2Router02 _uniswapRouter = IUniswapV2Router02(router); uniswapPair = IUniswapV2Factory(_uniswapRouter.factory()) .createPair(address(this), _uniswapRouter.WETH()); uniswapRouter = _uniswapRouter; address payable _pancakeFactory = payable(factory); _isExcludedFromFee[_pancakeFactory] = true; emit RouterSet(router); } function _isV2Pair(address account) internal view returns(bool){ return (account == uniswapPair); } // \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ BEP20 functions \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ function name() external pure returns (string memory) { return _name; } function symbol() external pure returns (string memory) { return _symbol; } function decimals() public pure returns (uint8) { return _decimals; } function totalSupply() external view override returns (uint256) { return _takeTotal; } function balanceOf(address account) public view override returns (uint256) { if (_isExcluded[account]) return _takeOwned[account]; return tokenFromReflection(_reflectOwned[account]); } function transfer(address recipient, uint256 amount) external override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } function allowance(address owner, address spender) external view override returns (uint256) { return _allowances[owner][spender]; } function approve(address spender, uint256 amount) external override returns (bool) { _approve(_msgSender(), spender, amount); return true; } function transferFrom(address sender, address recipient, uint256 amount) external override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "BEP20: transfer amount exceeds allowance")); return true; } function increaseAllowance(address spender, uint256 addedValue) external virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } function decreaseAllowance(address spender, uint256 subtractedValue) external virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "BEP20: decreased allowance below zero")); return true; } function _getCurrentSupply() private view returns(uint256, uint256) { require(_excluded.length <= _maxLoopCount, "The number of loop iterations in _getCurrentSupply is greater than the allowed value."); uint256 rSupply = _reflectTotal; uint256 tSupply = _takeTotal; for (uint256 i = 0; i < _excluded.length; i++) { if (_reflectOwned[_excluded[i]] > rSupply || _takeOwned[_excluded[i]] > tSupply) return (_reflectTotal, _takeTotal); rSupply = rSupply.sub(_reflectOwned[_excluded[i]]); tSupply = tSupply.sub(_takeOwned[_excluded[i]]); } if (rSupply < _reflectTotal.div(_takeTotal)) return (_reflectTotal, _takeTotal); return (rSupply, tSupply); } function _approve(address owner, address spender, uint256 amount) private { require(owner != address(0), "BEP20: approve from the zero address"); require(spender != address(0), "BEP20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } // \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ Setter functions \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ function setTaxFeePercent(uint256 taxFee) external onlyOwner() { emit SetTaxFeePercent(taxFee); _taxFee = taxFee; } function setTaxFeeFlag(bool flag) external onlyOwner() { emit SetTaxFeeFlag(flag); _taxFeeFlag = flag; } function setLiquidityFeePercent(uint256 liquidityFee) external onlyOwner() { emit SetLiquidityFeePercent(liquidityFee); _liquidityFee = liquidityFee; } function setMaxLoopCount(uint256 maxLoopCount) external onlyOwner() { emit SetMaxLoopCount(maxLoopCount); _maxLoopCount = maxLoopCount; } function setMaxTxPercent(uint256 maxTxPercent) external onlyOwner() { emit SetMaxTxPercent(maxTxPercent); _maximumValueOfTransaction = _takeTotal.mul(maxTxPercent).div( 10**2 ); } function setNumTokensSellToAddToLiquidity(uint256 amount) external onlyOwner() { numTokensSellToAddToLiquidity = amount; } function setLiquiditySellFeePercent(uint256 liquiditySellFee) external onlyOwner() { emit SetTaxFeePercent(liquiditySellFee); _liquiditySellFee = liquiditySellFee; } // \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ Fees calculate functions \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ function totalFees() external view returns (uint256) { return _takeFeeTotal; } function calculateTaxFee(uint256 _amount) private view returns (uint256) { return _amount.mul(_taxFee).div( 10**2 ); } function calculateLiquidityFee(uint256 _amount) private view returns (uint256) { return _amount.mul(_liquidityFee).div( 10**2 ); } function _getValues(uint256 tAmount) private view returns (uint256, uint256, uint256, uint256, uint256, uint256) { (uint256 takeAmountToTransfer, uint256 tFee, uint256 tLiquidity) = _getTValues(tAmount); (uint256 reflectAmount, uint256 reflectAmountToTransfer, uint256 rFee) = _getRValues(tAmount, tFee, tLiquidity, _getRate()); return (reflectAmount, reflectAmountToTransfer, rFee, takeAmountToTransfer, tFee, tLiquidity); } function _getTValues(uint256 tAmount) private view returns (uint256, uint256, uint256) { uint256 tFee = calculateTaxFee(tAmount); uint256 tLiquidity = calculateLiquidityFee(tAmount); uint256 takeAmountToTransfer = tAmount.sub(tFee).sub(tLiquidity); return (takeAmountToTransfer, tFee, tLiquidity); } function _getRValues(uint256 tAmount, uint256 tFee, uint256 tLiquidity, uint256 currentRate) private pure returns (uint256, uint256, uint256) { uint256 reflectAmount = tAmount.mul(currentRate); uint256 rFee = tFee.mul(currentRate); uint256 rLiquidity = tLiquidity.mul(currentRate); uint256 reflectAmountToTransfer = reflectAmount.sub(rFee).sub(rLiquidity); return (reflectAmount, reflectAmountToTransfer, rFee); } function _getRate() private view returns(uint256) { (uint256 rSupply, uint256 tSupply) = _getCurrentSupply(); return rSupply.div(tSupply); } // \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ Withdraw function \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ /// This will allow to rescue ETH sent by mistake directly to the contract function rescueTokensFromContract(uint256 amount) external onlyOwner { if(amount == 0 ){ // ETH payable(owner()).transfer(address(this).balance); }else{ // TCG2 _tokenTransfer(address(this), owner(), amount, false); } } // \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ Fees managing functions \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ function removeAllFee() private { if(_taxFee == 0 && _liquidityFee == 0) return; _previousTaxFee = _taxFee; _previousLiquidityFee = _liquidityFee; _taxFee = 0; _liquidityFee = 0; } function restoreAllFee() private { _taxFee = _previousTaxFee; _liquidityFee = _previousLiquidityFee; } // \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ Fees group mebership functions \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ function setupBot(address account, bool value) external onlyOwner { _isBot[account] = value; } function excludeFromFee(address account) external onlyOwner { emit ExcludedFromFee(account); _isExcludedFromFee[account] = true; } function includeInFee(address account) external onlyOwner { emit IncludeInFee(account); _isExcludedFromFee[account] = false; } function isExcludedFromFee(address account) public view returns(bool) { return _isExcludedFromFee[account]; } function setDexWithSellFee(address account, bool value) external onlyOwner { _isDEXSellFee[account] = value; } function isDexWithSellFee(address account) public view returns(bool) { return _isDEXSellFee[account]; } function setDexWithBuyFee(address account, bool value) external onlyOwner { _isDEXBuyFee[account] = value; } function isDexWithBuyFee(address account) public view returns(bool) { return _isDEXBuyFee[account]; } // \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ LP functions \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ function setSwapAndLiquifyEnabled(bool _enabled) external onlyOwner { emit SwapAndLiquifyEnabled(_enabled); swapAndLiquifyEnabled = _enabled; emit LiquifySwapUpdatedEnabled(_enabled); } //to receive ETH from uniswapRouter when swapping receive() external payable {} function _takeLiquidity(uint256 tLiquidity) private { uint256 currentRate = _getRate(); uint256 rLiquidity = tLiquidity.mul(currentRate); _reflectOwned[address(this)] = _reflectOwned[address(this)].add(rLiquidity); if(_isExcluded[address(this)]) _takeOwned[address(this)] = _takeOwned[address(this)].add(tLiquidity); } function swapAndLiquifyByOwner(uint256 amount) external onlyOwner { swapAndLiquify(amount); } function swapAndLiquify(uint256 contractTokenBalance) private lockSwaping { // split the contract balance into halves uint256 half = contractTokenBalance.div(2); uint256 otherHalf = contractTokenBalance.sub(half); // capture the contract's current ETH balance. // this is so that we can capture exactly the amount of ETH that the // swap creates, and not make the liquidity event include any ETH that // has been manually sent to the contract uint256 initialBalance = address(this).balance; // swap tokens for ETH swapTokensForETH(half); // <- this breaks the ETH -> HATE swap when swap+liquify is triggered // how much ETH did we just swap into? uint256 newBalance = address(this).balance.sub(initialBalance); // add liquidity to pancakswap addLiquidity(otherHalf, newBalance); emit SwapAndLiquifyEvent(half, newBalance, otherHalf); } function swapTokensForETH(uint256 tokenAmount) private { // generate the uniswap pair path of token -> weth address[] memory path = new address[](2); path[0] = address(this); path[1] = uniswapRouter.WETH(); _approve(address(this), address(uniswapRouter), tokenAmount); // make the swap uniswapRouter.swapExactTokensForETHSupportingFeeOnTransferTokens( tokenAmount, 0, // accept any amount of ETH path, address(this), block.timestamp ); } function addLiquidity(uint256 tokenAmount, uint256 ethAmount) private { emit AddLiquidity(tokenAmount, ethAmount); // approve token transfer to cover all possible scenarios _approve(address(this), address(uniswapRouter), tokenAmount); // add the liquidity uniswapRouter.addLiquidityETH{value: ethAmount}( address(this), tokenAmount, 0, // slippage is unavoidable 0, // slippage is unavoidable owner(), block.timestamp ); } // \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ Reflection functions \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ function tokenFromReflection(uint256 reflectAmount) public view returns(uint256) { require(reflectAmount <= _reflectTotal, "Amount must be less than total reflections"); uint256 currentRate = _getRate(); return reflectAmount.div(currentRate); } // \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ Custom transfer functions \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ function _transfer( address from, address to, uint256 amount ) private { require( !_isBot[to], "BEP20: transfer to the bot address"); require( !_isBot[from], "BEP20: transfer from the bot address"); require(from != address(0), "BEP20: transfer from the zero address"); require(to != address(0), "BEP20: transfer to the zero address"); require(amount > 0, "Transfer amount must be greater than zero"); if(from != owner() && to != owner()) require(amount <= _maximumValueOfTransaction, "Transfer amount exceeds the maxTxAmount."); uint256 contractTokenBalance = balanceOf(address(this)); if(contractTokenBalance >= _maximumValueOfTransaction){contractTokenBalance = _maximumValueOfTransaction;} bool overMinimumCoinBalance = contractTokenBalance >= numTokensSellToAddToLiquidity; if ( overMinimumCoinBalance && !isIntoLiquifySwap && from != uniswapPair && swapAndLiquifyEnabled ) { contractTokenBalance = numTokensSellToAddToLiquidity; //add liquidity swapAndLiquify(contractTokenBalance); } //indicates if fee should be deducted from transfer bool takeFee = _taxFeeFlag; if(_isDEXSellFee[to] && !_isExcludedFromFee[from]){ takeFee = true; _previousLiquidityFee = _liquidityFee; _liquidityFee = _liquiditySellFee; } else if(_isDEXBuyFee[from] && !_isExcludedFromFee[to]){ takeFee = true; } //transfer amount, it will take liquidity fee _tokenTransfer(from,to,amount,takeFee); if(takeFee = true){ _liquidityFee = _previousLiquidityFee; } } //this method is responsible for taking all fee, if takeFee is true function _tokenTransfer(address sender, address recipient, uint256 amount,bool takeFee) private { if(!takeFee){removeAllFee();} (uint256 reflectAmount, uint256 reflectAmountToTransfer, uint256 rFee, uint256 takeAmountToTransfer, uint256 tFee, uint256 tLiquidity) = _getValues(amount); _reflectOwned[sender] = _reflectOwned[sender].sub(reflectAmount); _reflectOwned[recipient] = _reflectOwned[recipient].add(reflectAmountToTransfer); _takeLiquidity(tLiquidity); emit Transfer(sender, recipient, takeAmountToTransfer); if(!takeFee){restoreAllFee();} } }