ETH Price: $2,556.06 (+3.16%)

Transaction Decoder

Block:
20681036 at Sep-05-2024 01:14:59 AM +UTC
Transaction Fee:
0.00038243008305488 ETH $0.98
Gas Used:
49,372 Gas / 7.74589004 Gwei

Emitted Events:

48 TokenProxy.0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925( 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925, 0x000000000000000000000000058589ed65f03c86ec562937f9059faeb8ce0292, 0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d, ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff )

Account State Difference:

  Address   Before After State Difference Code
0x058589ED...EB8CE0292
1.518583284472246034 Eth
Nonce: 853
1.518200854389191154 Eth
Nonce: 854
0.00038243008305488
0x3EA42076...7248eBd66
(Titan Builder)
12.97862005555685956 Eth12.97871879955685956 Eth0.000098744

Execution Trace

TokenProxy.095ea7b3( )
  • TokenLogic.approve( spender=0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D, amount=115792089237316195423570985008687907853269984665640564039457584007913129639935 ) => ( True )
    File 1 of 2: TokenProxy
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.20;
    /*    
          ##########      
       ###### ## ######   
      ######  ##  ## ###  
     ##  ##   ##   ##  ## 
    ##   #    ##    #   ##
     ##  ##   ##   ##  ## 
      ### ##  ##  ## ###  
       ###### ## ######   
          ##########      
                          
    https://congrats.pro/ 
    ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────┐
    │     __  __           _         _             _______         ______                      _               │
    │    |  \\/  |         | |       | |           |__   __|       |  ____|                    (_)              │
    │    | \\  / | __ _  __| | ___   | |__  _   _     | | __ ___  _| |__ __ _ _ __ _ __ ___     _ _ __   __ _   │
    │    | |\\/| |/ _` |/ _|` |/ _ \\  | '_ \\| | | |    | |/ _` | / /  __/ _` | '__| '_ ` _ \\   | | '_ \\ / _` |  │
    │    | |  | | (_| | (_| |  __/  | |_) | |_| |    | | (_| |>  <| | | (_| | |  | | | | | |  | | | | | (_| |  │
    │    |_|  |_|\\__,_|\\__,_|\\___|  |_.__/ \\__, |    |_|\\__,_/_/\\_\\_|  \\__,_|_|  |_| |_| |_|(_)_|_| |_|\\__, |  │
    │                                       __/ |                                                      __/ |   │
    │                                      |___/                                                      |___/    │
    │                                                                                                          │
    │                                             taxfarm.ing                                                  │
    │                                                                                                          │
    └──────────────────────────────────────────────────────────────────────────────────────────────────────────┘
    */
    contract TokenProxy {
        // constant stored in runtime bytecode to ensure contract uniqueness and be able to verify it on etherscan with custom comments
        uint256 public constant uniqueId = 0x1000100000000000000000000000000000000000000000000000000000000001; // use a 32 bytes uint to ensure consistency of PUSH32 opcode, 1st byte to ensure 32 bytes length, 2 next bytes are used as a placeholder for factory version and the next 29 bytes are used as a placeholder for unique id
        address public immutable tokenLogic;
        constructor(address _tokenLogic) {
            tokenLogic = _tokenLogic;
        }
        // delegate functions call to the token logic contract
        fallback() external payable {
            address dest = tokenLogic;
            
            assembly {
                calldatacopy(0, 0, calldatasize())
                let result := delegatecall(gas(), dest, 0, calldatasize(), 0, 0)
                returndatacopy(0, 0, returndatasize())
                switch result
                case 0 {
                    revert(0, returndatasize())
                }
                default {
                    return(0, returndatasize())
                }
            }
        }
    }

    File 2 of 2: TokenLogic
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.20;
    /*    
    ┌─────────────────────────────────────────────────────────────────────────┐
    │                                                                         │
    │       _______         ______                      _                     │
    │      |__   __|       |  ____|                    (_)                    │
    │         | | __ ___  _| |__ __ _ _ __ _ __ ___     _ _ __   __ _         │
    │         | |/ _` \\ \\/ /  __/ _` | '__| '_ ` _ \\   | | '_ \\ / _` |        │
    │         | | (_| |>  <| | | (_| | |  | | | | | |  | | | | | (_| |        │
    │         |_|\\__,_/_/\\_\\_|  \\__,_|_|  |_| |_| |_|(_)_|_| |_|\\__, |        │
    │                                                            __/ |        │
    │                                                           |___/         │
    │                                                                         │
    │                               taxfarm.ing                               │
    │                                                                         │
    └─────────────────────────────────────────────────────────────────────────┘
    */
    // utils
    import {ERC20Logic} from "./utils/ERC20Logic.sol";
    import {IUniswapV2Router02} from "./utils/IUniswapV2Router02.sol";
    import {IUniswapV2Factory} from "./utils/IUniswapV2Factory.sol";
    import {IUniswapV2Pair} from "./utils/IUniswapV2Pair.sol";
    import {IWETH} from "./utils/IWETH.sol";
    interface ITokenLogic {
        function initialize(address _deployer, string memory _name, string memory _symbol) external payable;
        function launchTimestamp() external view returns(uint);
        function deployer() external view returns(address payable);
    }
    // token logic (code used by token proxies contracts)
    contract TokenLogic is ERC20Logic, ITokenLogic {
        enum FeesTier {
            HIGH_FEES, // 20/20 fees the first 5 minutes
            MEDIUM_FEES, // 5/5 fees until contract has less than 1% of the supply to sell
            LOW_FEES // 1/1 then
        }
        // - token logic constants (not colliding proxies storages)
        uint private constant HIGH_FEES_DURATION = 300; // duration of the high fees stage (20% during 5 minutes)
        uint private constant LIMITS_DURATION = 300; // duration of max tx and max wallet limits in seconds
        uint private constant BASE_TOTAL_SUPPLY = 1_000_000_000 * 10**18;
        uint public constant MAX_TX_AMOUNT = (1 * BASE_TOTAL_SUPPLY) / 100; // max tx 10M (1%)
        uint public constant MAX_WALLET_AMOUNT = (3 * BASE_TOTAL_SUPPLY) / 100; // max wallet 30M (3%)
        uint private constant LIQUIDITY_AMOUNT = (80 * BASE_TOTAL_SUPPLY) / 100; // uniswap liquidity (80%)
        address public immutable tokenFactory;
        address public immutable WETH;
        IUniswapV2Factory public immutable uniswapFactory;
        IUniswapV2Router02 constant uniswapRouter = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
        // - instance token storage (stored in each token proxies)
        bool _swapping;
        uint public launchTimestamp; // token launch timestamp
        address payable public deployer;
        address public uniswapPair;
        FeesTier public feesTier; // current token fees tier (could be outdated and updated during the transaction)
        constructor (address _tokenFactory) {
            tokenFactory = _tokenFactory;
            uniswapFactory = IUniswapV2Factory(uniswapRouter.factory());
            WETH = uniswapRouter.WETH();
        }
        modifier lockSwap {
            _swapping = true;
            _;
            _swapping = false;
        }
        // initialize new token datas (called from the factory to the token proxy delegating the call here)
        function initialize(address _deployer, string memory _name, string memory _symbol) external payable {
            require(msg.sender == tokenFactory, "Unauthorized"); // initialized only on the same deployment transaction from token factory
            require(msg.value == 1 ether, "Wrong initial liquidity");
            name = _name;
            symbol = _symbol;
            deployer = payable(_deployer);
            launchTimestamp = block.timestamp;
            _mint(address(this), BASE_TOTAL_SUPPLY - LIQUIDITY_AMOUNT); // mint clogged amount to the contract
            uniswapPair = uniswapFactory.createPair(address(this), WETH);
            _mint(uniswapPair, LIQUIDITY_AMOUNT); // mint liquidity amount to the pair
            IWETH(WETH).deposit{value: 1 ether}();
            assert(IWETH(WETH).transfer(uniswapPair, 1 ether)); // transfer weth to the pair
            IUniswapV2Pair(uniswapPair).mint(tokenFactory); // call low level mint function on pair
        }
        function _transfer(address sender, address recipient, uint256 amount) internal override {
            if (_swapping) return super._transfer(sender, recipient, amount);
            uint fees = _takeFees(sender, recipient, amount);
            if (fees != 0) {
                super._transfer(sender, address(this), fees);
                amount -= fees;
            }
            if (recipient == uniswapPair) _swapFees(amount);
            super._transfer(sender, recipient, amount);
            _forwardFees();
        }
        // return fees amount taken from the transfer (and check for tx and wallet limits)
        function _takeFees(address sender, address recipient, uint amount) private returns (uint) {
            if ((sender != uniswapPair && recipient != uniswapPair) || recipient == tokenFactory || sender == address(this) || recipient == address(uniswapRouter)) return 0;
            // ensure max tx and max wallet
            if (limitsActive() && sender == uniswapPair) {
                require(amount <= MAX_TX_AMOUNT, "Max tx amount reached");
                require(balanceOf(recipient) + amount <= MAX_WALLET_AMOUNT, "Max wallet amount reached");
            }
            // if token has low fees tier, fees are immutable at 1% 
            if (feesTier == FeesTier.LOW_FEES) return amount / 100; // 1% fees
            // else, if token has medium fees, check if we can change tier and return correct fees
            else if (feesTier == FeesTier.MEDIUM_FEES) {
                if (balanceOf(address(this)) <= totalSupply / 100) {
                    feesTier = FeesTier.LOW_FEES;
                    return amount / 100; // 1% fees
                }
                return amount / 20; // 5% fees
            }
            // else, token is at high fees tier and we check if we can change tier and return correct fees
            else {
                if (block.timestamp - launchTimestamp > HIGH_FEES_DURATION) {
                    feesTier = FeesTier.MEDIUM_FEES;
                    return amount / 20; // 5% fees
                }
                return amount / 5; // 20% fees
            }
        }
        // swap some fees tokens to eth
        function _swapFees(uint maxAmount) private lockSwap {
            uint tokenAmount = min(min(maxAmount, balanceOf(address(this))), totalSupply / 100);
            if (tokenAmount < 1e18) return; // prevent too small swaps
            address[] memory path = new address[](2);
            path[0] = address(this);
            path[1] = WETH;
            _approve(address(this), address(uniswapRouter), tokenAmount);
            uniswapRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
                tokenAmount,
                0,
                path,
                address(this),
                block.timestamp
            );
        }   
        // return true if max wallet and max tx limitations are still active
        function limitsActive() public view returns (bool) {
            return block.timestamp - launchTimestamp <= LIMITS_DURATION;
        }
        
        // forward contract fees to token factory (also try to burn liquidity)
        function _forwardFees() private {
            uint balance = address(this).balance;
            if (balance == 0) return;
            (bool result, ) = tokenFactory.call{value: balance}("");
            require(result, "Failed to forward fees");
        }
        function min(uint a, uint b) private pure returns (uint) {
            return a < b ? a : b;
        }
        receive() external payable {}
    }// SPDX-License-Identifier: MIT
    pragma solidity ^0.8.20;
    abstract contract Context {
        function _msgSender() internal view virtual returns (address) {
            return msg.sender;
        }
        function _msgData() internal view virtual returns (bytes calldata) {
            return msg.data;
        }
    }// SPDX-License-Identifier: MIT
    pragma solidity ^0.8.20;
    import {IERC20} from "./IERC20.sol";
    import {Context} from "./Context.sol";
    interface IERC20Metadata is IERC20 {
        function name() external view returns (string memory);
        function symbol() external view returns (string memory);
        function decimals() external view returns (uint8);
    }
    // contract implementing the logic of ERC20 standard (thus usable from proxies)
    contract ERC20Logic is Context, IERC20, IERC20Metadata {
        mapping(address => uint256) private _balances;
        mapping(address => mapping(address => uint256)) private _allowances;
        uint256 public totalSupply;
        string public name;
        string public symbol;
        function decimals() public view virtual override returns (uint8) {
            return 18;
        }
        function balanceOf(address account) public view virtual override returns (uint256) {
            return _balances[account];
        }
        function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
            _transfer(_msgSender(), recipient, amount);
            return true;
        }
        function allowance(address owner, address spender) public view virtual override returns (uint256) {
            return _allowances[owner][spender];
        }
        function approve(address spender, uint256 amount) public virtual override returns (bool) {
            _approve(_msgSender(), spender, amount);
            return true;
        }
        function transferFrom(
            address sender,
            address recipient,
            uint256 amount
        ) public virtual override returns (bool) {
            _transfer(sender, recipient, amount);
            uint256 currentAllowance = _allowances[sender][_msgSender()];
            require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
            unchecked {
                _approve(sender, _msgSender(), currentAllowance - amount);
            }
            return true;
        }
        function burn(uint256 value) public virtual {
            _burn(_msgSender(), value);
        }
        function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
            _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
            return true;
        }
        function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
            uint256 currentAllowance = _allowances[_msgSender()][spender];
            require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
            unchecked {
                _approve(_msgSender(), spender, currentAllowance - subtractedValue);
            }
            return true;
        }
        function _transfer(
            address sender,
            address recipient,
            uint256 amount
        ) internal virtual {
            require(sender != address(0), "ERC20: transfer from the zero address");
            require(recipient != address(0), "ERC20: transfer to the zero address");
            uint256 senderBalance = _balances[sender];
            require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
            unchecked {
                _balances[sender] = senderBalance - amount;
            }
            _balances[recipient] += amount;
            emit Transfer(sender, recipient, amount);
        }
        function _mint(address account, uint256 amount) internal virtual {
            require(account != address(0), "ERC20: mint to the zero address");
            totalSupply += amount;
            _balances[account] += amount;
            emit Transfer(address(0), account, amount);
        }
        function _burn(address account, uint256 amount) internal virtual {
            require(account != address(0), "ERC20: burn from the zero address");
            uint256 accountBalance = _balances[account];
            require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
            unchecked {
                _balances[account] = accountBalance - amount;
            }
            totalSupply -= amount;
            emit Transfer(account, address(0), amount);
        }
        function _approve(
            address owner,
            address spender,
            uint256 amount
        ) internal virtual {
            require(owner != address(0), "ERC20: approve from the zero address");
            require(spender != address(0), "ERC20: approve to the zero address");
            _allowances[owner][spender] = amount;
            emit Approval(owner, spender, amount);
        }
    }// SPDX-License-Identifier: MIT
    pragma solidity ^0.8.20;
    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);
        function burn(uint256 value) external;
        event Transfer(address indexed from, address indexed to, uint256 value);
        event Approval(address indexed owner, address indexed spender, uint256 value);
    }// SPDX-License-Identifier: MIT
    pragma solidity ^0.8.20;
    interface IUniswapV2Factory {
        function getPair(address tokenA, address tokenB) external view returns (address pair);
        function createPair(address tokenA, address tokenB) external returns (address pair);
    }// SPDX-License-Identifier: MIT
    pragma solidity ^0.8.20;
    interface IUniswapV2Pair {
        function mint(address to) external returns (uint liquidity);
    }// SPDX-License-Identifier: MIT
    pragma solidity ^0.8.20;
    interface IUniswapV2Router02 {
        function swapExactTokensForETHSupportingFeeOnTransferTokens(
            uint amountIn,
            uint amountOutMin,
            address[] calldata path,
            address to,
            uint deadline
        ) external;
        function factory() external pure returns (address);
        function WETH() external pure returns (address);
        
        function addLiquidityETH(
            address token,
            uint amountTokenDesired,
            uint amountTokenMin,
            uint amountETHMin,
            address to,
            uint deadline
        ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
        function removeLiquidityETH(
            address token,
            uint liquidity,
            uint amountTokenMin,
            uint amountETHMin,
            address to,
            uint deadline
        ) external returns (uint amountToken, uint amountETH);
    }
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.20;
    interface IWETH {
        function deposit() external payable;
        function transfer(address to, uint value) external returns (bool);
        function withdraw(uint) external;
    }