Token

Description:

Multi-signature wallet contract requiring multiple confirmations for transaction execution.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "settings": {
    "optimizer": {
      "enabled": true,
      "runs": 10000
    },
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    },
    "remappings": []
  },
  "sources": {
    "ProofStandardWhitelist.sol": {
      "content": "// SPDX-License-Identifier: None\r
\r
pragma solidity ^0.8.24;\r
\r
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";\r
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";\r
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";\r
import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";\r
import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol";\r
import "./interfaces/IERC721A.sol";\r
import "./interfaces/ITeamFinanceLocker.sol";\r
import "./interfaces/ITokenWhitelist.sol";\r
\r
/// This token was incubated and launched by PROOF: https://proofplatform.io/projects.\r
\r
contract Token is\r
    ITokenWhitelist,\r
    Initializable,\r
    ERC20Upgradeable,\r
    OwnableUpgradeable\r
{\r
    struct UserInfo {\r
        bool isFeeExempt;\r
        bool isTxLimitExempt;\r
        bool isWhitelisted;\r
    }\r
\r
    struct BuyInfo {\r
        uint32 lastBlock;\r
        uint8 count;\r
    }\r
\r
    address public pair;\r
    address payable public mainWallet;\r
    address payable public secondaryWallet;\r
    address public futureOwner;\r
    IUniswapV2Router02 public uniswapV2Router;\r
\r
    uint256 public whitelistEndTime;\r
    uint256 public whitelistDuration;\r
    uint256 public launchedAt;\r
    uint256 public maxWallet;\r
    uint256 public initMaxWallet;\r
    uint256 public swapping;\r
    uint256 public swapTokensAtAmount;\r
    uint256 public maxSwapsPerBlock;\r
    uint256 public restingBuyTotal;\r
    uint256 public restingSellTotal;\r
    uint256 public lockID;\r
    uint256 public lpLockDuration;\r
    uint8 public maxBuysPerBlock;\r
\r
    bool public isWhitelistActive;\r
    bool public checkMaxHoldings = true;\r
    bool public maxWalletChanged;\r
    bool public swapEnabled;\r
    bool public buyTaxesSettled;\r
    bool public sellTaxesSettled;\r
    bool public proofFeeReduced;\r
    bool public proofFeeRemoved;\r
    bool public cancelled;\r
    bool public buysPerBlockLimited = false;\r
\r
    FeeInfo public feeTokens;\r
    FeeInfo public buyFees;\r
    FeeInfo public sellFees;\r
\r
    mapping(address => UserInfo) public userInfo;\r
    mapping(uint256 => uint256) public swapThrottle;\r
    mapping(address => BuyInfo) private _buyInfo; // per-origin rolling counter\r
\r
    IDataStore public immutable DATA_STORE;\r
    DataStoreAddressResponse public addresses;\r
    DataStoreLimitsResponse public limits;\r
\r
    event SwapAndLiquify(uint256 tokensAutoLiq, uint256 ethAutoLiq);\r
    event SwapAndLiquifyEnabledUpdated(bool enabled);\r
    event TokenCancelled(uint256 returnedETH);\r
\r
    constructor(IDataStore dataStore) {\r
        DATA_STORE = dataStore;\r
        _disableInitializers();\r
    }\r
\r
    function initialize(\r
        bytes calldata params\r
    ) public payable initializer lockTheSwap {\r
        TokenInfo memory token = abi.decode(params, (TokenInfo));\r
        __ERC20_init(token.name, token.symbol);\r
        __Ownable_init(token.owner);\r
        futureOwner = token.futureOwner;\r
        DataStoreLimitsResponse memory _limits = DATA_STORE.getLimits();\r
        limits = _limits;\r
\r
        restingBuyTotal = token.buyFees.total * 100;\r
        restingSellTotal = token.sellFees.total * 100;\r
        (token.buyFees.proof, token.sellFees.proof) = (700, 700); // Start at 5% (500 basis points) instead of 2%\r
        token.buyFees.liquidity *= 100;\r
        token.buyFees.secondary *= 100;\r
        token.sellFees.liquidity *= 100;\r
        token.sellFees.secondary *= 100;\r
\r
        //fees validate based on 100th precision and recalculates total\r
        _validateFees(token.buyFees, token.sellFees);\r
        token.buyFees.main =\r
            2000 -\r
            token.buyFees.proof -\r
            token.buyFees.secondary -\r
            token.buyFees.liquidity; // Start at 20% (2000 basis points) instead of 15%\r
        token.buyFees.total = 2000; // Start at 20% (2000 basis points) instead of 15%\r
        token.sellFees.main =\r
            2500 -\r
            token.sellFees.proof -\r
            token.sellFees.secondary -\r
            token.sellFees.liquidity; // Start at 25% (2500 basis points) instead of 20%\r
        token.sellFees.total = 2500; // Start at 25% (2500 basis points) instead of 20%\r
\r
        buyFees = token.buyFees;\r
        sellFees = token.sellFees;\r
\r
        // set addresses\r
        mainWallet = payable(token.mainWallet);\r
        secondaryWallet = payable(token.secondaryWallet);\r
\r
        DataStoreAddressResponse memory _addresses = DATA_STORE\r
            .getPlatformAddresses();\r
        addresses = _addresses;\r
\r
        IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(\r
            _addresses.router\r
        );\r
        uniswapV2Router = _uniswapV2Router;\r
\r
        pair = IUniswapV2Factory(_uniswapV2Router.factory()).createPair(\r
            address(this),\r
            _uniswapV2Router.WETH()\r
        );\r
\r
        // set basic data\r
\r
        lpLockDuration = token.lpLockDuration;\r
        swapTokensAtAmount =\r
            (token.totalSupply * _limits.swapTokensAtAmount) /\r
            _limits.denominator; // 125 / 100000\r
\r
        initMaxWallet = token.initMaxWallet;\r
        maxWallet = (token.totalSupply * token.initMaxWallet) / 100000; // 100 = .1%\r
        maxSwapsPerBlock = 4;\r
\r
        userInfo[address(this)] = UserInfo(true, true, true);\r
        userInfo[pair].isTxLimitExempt = true;\r
        userInfo[pair].isWhitelisted = true;\r
\r
        whitelistDuration = token.whitelistDuration;\r
        _setWhitelisted(token.whitelist);\r
\r
        uint256 amountToPair = (token.totalSupply * token.percentToLP) / 100;\r
        super._update(address(0), address(this), amountToPair); // mint to contract for liquidity\r
        super._update(address(0), owner(), token.totalSupply - amountToPair); // mint to proof wallet for distribution\r
        _approve(address(this), address(uniswapV2Router), type(uint256).max);\r
        addLiquidity(amountToPair, msg.value, address(this));\r
    }\r
\r
    function launch(\r
        uint256 bundleBuyAmount,\r
        uint256 lastBlockTimestamp,\r
        bytes32 lastBlockParentHash\r
    ) external payable onlyOwner lockTheSwap {\r
        require(\r
            block.timestamp <= lastBlockTimestamp + 12 &&\r
                blockhash(block.number - 1) == lastBlockParentHash,\r
            "Forked Block"\r
        );\r
        if (launchedAt != 0 || cancelled) {\r
            revert InvalidConfiguration();\r
        }\r
        // enable trading\r
        checkMaxHoldings = true;\r
        swapEnabled = true;\r
        whitelistEndTime = block.timestamp + whitelistDuration;\r
        isWhitelistActive = true;\r
        buysPerBlockLimited = true;\r
        maxBuysPerBlock = 3;\r
        launchedAt = block.timestamp;\r
\r
        if (bundleBuyAmount != 0) {\r
            //execute bundle buy\r
            address[] memory path = new address[](2);\r
            path[0] = uniswapV2Router.WETH();\r
            path[1] = address(this);\r
            uniswapV2Router.swapExactETHForTokens{value: bundleBuyAmount}(\r
                0,\r
                path,\r
                futureOwner,\r
                block.timestamp\r
            );\r
        }\r
\r
        // lock liquidity\r
        uint256 lpBalance = IERC20(pair).balanceOf(address(this));\r
        IERC20(pair).approve(addresses.locker, lpBalance);\r
\r
        lockID = ITeamFinanceLocker(addresses.locker).lockToken{\r
            value: address(this).balance\r
        }(\r
            pair,\r
            futureOwner,\r
            lpBalance,\r
            block.timestamp + lpLockDuration,\r
            false,\r
            address(0)\r
        );\r
    }\r
\r
    function cancel() external onlyOwner lockTheSwap {\r
        if (launchedAt != 0) {\r
            revert InvalidConfiguration();\r
        }\r
\r
        IERC20(pair).approve(\r
            address(uniswapV2Router),\r
            IERC20(pair).balanceOf(address(this))\r
        );\r
        uint256 ethAmt = uniswapV2Router\r
            .removeLiquidityETHSupportingFeeOnTransferTokens(\r
                address(this),\r
                IERC20(pair).balanceOf(address(this)),\r
                0, // liq pool should be untouchable\r
                0, // liq pool should be untouchable\r
                msg.sender,\r
                block.timestamp\r
            );\r
        emit TokenCancelled(ethAmt);\r
\r
        cancelled = true;\r
\r
        // send the tokens and eth back to the owner\r
        uint256 bal = address(this).balance;\r
        if (bal > 0) {\r
            address(msg.sender).call{value: bal}("");\r
        }\r
    }\r
\r
    function _update(\r
        address from,\r
        address to,\r
        uint256 amount\r
    ) internal override {\r
        //tx.origin allows 2-step locker\r
        if (\r
            swapping == 2 ||\r
            from == address(this) ||\r
            to == futureOwner ||\r
            amount == 0 ||\r
            tx.origin == owner()\r
        ) {\r
            //Allows Proof or the futureOwner to transfer tokens pre-launch\r
            super._update(from, to, amount);\r
            return;\r
        }\r
\r
        if (launchedAt == 0) {\r
            revert TradingNotEnabled();\r
        }\r
\r
        UserInfo memory sender = userInfo[from];\r
        UserInfo memory recipient = userInfo[to];\r
\r
        if (isWhitelistActive) {\r
            if (block.timestamp < whitelistEndTime) {\r
                if (!sender.isWhitelisted || !recipient.isWhitelisted) {\r
                    revert NotWhitelisted();\r
                }\r
            } else {\r
                isWhitelistActive = false;\r
                buysPerBlockLimited = false;\r
            }\r
        }\r
\r
        if (buysPerBlockLimited && from == pair) {\r
            address origin = tx.origin;\r
            BuyInfo storage info = _buyInfo[origin];\r
\r
            if (info.lastBlock != uint32(block.number)) {\r
                info.lastBlock = uint32(block.number);\r
                info.count = 0;\r
            }\r
\r
            unchecked {\r
                info.count++;\r
            }\r
            require(\r
                info.count <= maxBuysPerBlock,\r
                "Too many buys in this block from one origin"\r
            );\r
        }\r
\r
        //start at anywhere from 0.1% to 0.5%, increase by 0.1%, every 10 blocks, until it reaches 1%\r
        if (!maxWalletChanged) {\r
            uint256 secondsPassed = block.timestamp - launchedAt;\r
            uint256 percentage = initMaxWallet + (100 * (secondsPassed / 120));\r
            if (percentage > 950) {\r
                percentage = 1000;\r
                maxWalletChanged = true;\r
                checkMaxHoldings = false;\r
                maxWallet = totalSupply();\r
            } else {\r
                uint256 newMax = (totalSupply() * percentage) / 100000;\r
                if (newMax != maxWallet) {\r
                    maxWallet = newMax;\r
                }\r
            }\r
        }\r
\r
        if (checkMaxHoldings) {\r
            if (\r
                !recipient.isTxLimitExempt && amount + balanceOf(to) > maxWallet\r
            ) {\r
                revert ExceedsMaxWalletAmount();\r
            }\r
        }\r
\r
        uint256 total = feeTokens.total;\r
        bool canSwap = total >= swapTokensAtAmount;\r
\r
        if (\r
            canSwap &&\r
            swapEnabled &&\r
            to == pair &&\r
            swapThrottle[block.number] < maxSwapsPerBlock\r
        ) {\r
            ++swapThrottle[block.number];\r
            if (swapTokensAtAmount > amount) {\r
                processFees(total, amount);\r
            } else {\r
                processFees(total, swapTokensAtAmount);\r
            }\r
        }\r
\r
        if (!sender.isFeeExempt && !recipient.isFeeExempt) {\r
            FeeInfo storage _buyFees = buyFees;\r
            FeeInfo storage _sellFees = sellFees;\r
\r
            if (!proofFeeRemoved) {\r
                uint256 secondsPassed = block.timestamp - launchedAt;\r
                if (!proofFeeReduced && secondsPassed > 1 days) {\r
                    uint256 totalBuy = _buyFees.total - _buyFees.proof;\r
                    if (totalBuy == 0) {\r
                        _buyFees.total = 0;\r
                        _buyFees.proof = 0;\r
                    } else {\r
                        _buyFees.main = _buyFees.main + 100; //move proof fee to main fee, total doesn't change (100 basis points = 1%)\r
                        _buyFees.proof = 100; //decrementing proof fee to 1% (100 basis points)\r
                    }\r
                    uint256 totalSell = _sellFees.total - _sellFees.proof;\r
                    if (totalSell == 0) {\r
                        _sellFees.total = 0;\r
                        _sellFees.proof = 0;\r
                    } else {\r
                        _sellFees.main = _sellFees.main + 100; //same as the buy fee logic (100 basis points = 1%)\r
                        _sellFees.proof = 100; //decrementing proof fee to 1% (100 basis points)\r
                    }\r
                    proofFeeReduced = true;\r
                } else if (secondsPassed > 61 days) {\r
                    // Extended from 31 days to 61 days\r
                    //move proof fee to main fee\r
                    _buyFees.main += _buyFees.proof;\r
                    _sellFees.main += _sellFees.proof;\r
                    _buyFees.proof = 0;\r
                    _sellFees.proof = 0;\r
                    proofFeeRemoved = true;\r
                } else {\r
                    if (!buyTaxesSettled) {\r
                        uint256 restingTotal = restingBuyTotal;\r
                        uint256 feeTotal;\r
                        if (secondsPassed < 1801) {\r
                            // 30 minutes (1800 seconds) for buy tax degradation\r
                            //fee starts at 20% (2000 basis points), decreases by 1% (100 basis points) every 2 minutes until we reach the restingTotal.\r
                            feeTotal = 2000 - ((secondsPassed / 120) * 100);\r
                        }\r
                        if (feeTotal <= restingTotal) {\r
                            uint256 proofVal = proofFeeRemoved\r
                                ? 0\r
                                : proofFeeReduced\r
                                ? 100\r
                                : 200;\r
                            _buyFees.total = restingTotal;\r
                            _buyFees.proof = proofVal;\r
                            _buyFees.main =\r
                                restingTotal -\r
                                _buyFees.liquidity -\r
                                _buyFees.secondary -\r
                                _buyFees.proof;\r
                            buyTaxesSettled = true;\r
                        } else if (feeTotal != _buyFees.total) {\r
                            _buyFees.total = feeTotal;\r
                            //700 = starting proof fee\r
                            //500 = amount we are going down to get to 2%,\r
                            //2000 = starting fee\r
                            //1500 = total amount we are decreasing the total fee by\r
                            _buyFees.proof =\r
                                700 -\r
                                (500 * (2000 - feeTotal)) /\r
                                1500; // at minute 19: 500 - (300 - (2000 - 1900) / 1500)\r
                            //extra fees get sent to the main wallet\r
                            _buyFees.main =\r
                                feeTotal -\r
                                _buyFees.liquidity -\r
                                _buyFees.secondary -\r
                                _buyFees.proof;\r
                        }\r
                    }\r
                    if (!sellTaxesSettled) {\r
                        uint256 restingTotal = restingSellTotal;\r
                        uint256 feeTotal;\r
                        if (secondsPassed < 2401) {\r
                            // 40 minutes (2400 seconds) for sell tax degradation\r
                            feeTotal = 2500 - ((secondsPassed / 120) * 100); // 25% (2500 basis points) decreases by 1% (100 basis points) every 2 minutes\r
                        }\r
                        if (feeTotal <= restingTotal) {\r
                            uint256 proofVal = proofFeeRemoved\r
                                ? 0\r
                                : proofFeeReduced\r
                                ? 100\r
                                : 200;\r
                            _sellFees.total = restingTotal;\r
                            _sellFees.proof = proofVal;\r
                            _sellFees.main =\r
                                restingTotal -\r
                                _sellFees.liquidity -\r
                                _sellFees.secondary -\r
                                _sellFees.proof;\r
                            sellTaxesSettled = true;\r
                        } else if (feeTotal != _sellFees.total) {\r
                            _sellFees.total = feeTotal;\r
                            //700 = starting proof fee\r
                            //500 = amount we are going down to get to 2%,\r
                            //2500 = starting fee\r
                            //2000 = total amount we are decreasing the total fee by\r
                            _sellFees.proof =\r
                                700 -\r
                                (500 * (2500 - feeTotal)) /\r
                                2000; // at minute 19: 500 - (300 - (2000 - 1900) / 1500)\r
                            //extra fees get sent to the main wallet\r
                            _sellFees.main =\r
                                feeTotal -\r
                                _sellFees.liquidity -\r
                                _sellFees.secondary -\r
                                _sellFees.proof;\r
                        }\r
                    }\r
                }\r
            }\r
\r
            uint256 fees;\r
            if (to == pair) {\r
                //sell\r
                fees = _calculateFees(_sellFees, amount);\r
            } else if (from == pair) {\r
                //buy\r
                fees = _calculateFees(_buyFees, amount);\r
            }\r
            if (fees > 0) {\r
                amount -= fees;\r
                super._update(from, address(this), fees);\r
            }\r
        }\r
\r
        super._update(from, to, amount);\r
    }\r
\r
    function _calculateFees(\r
        FeeInfo memory feeRate,\r
        uint256 amount\r
    ) internal returns (uint256 fees) {\r
        if (feeRate.total != 0) {\r
            fees = (amount * feeRate.total) / 10000; // Divide by 10000 for basis points (100% = 10000 basis points)\r
\r
            FeeInfo storage _feeTokens = feeTokens;\r
            _feeTokens.main += (fees * feeRate.main) / feeRate.total;\r
            _feeTokens.secondary += (fees * feeRate.secondary) / feeRate.total;\r
            _feeTokens.liquidity += (fees * feeRate.liquidity) / feeRate.total;\r
            _feeTokens.proof += (fees * feeRate.proof) / feeRate.total;\r
            _feeTokens.total += fees;\r
        }\r
    }\r
\r
    function processFees(\r
        uint256 total,\r
        uint256 amountToSwap\r
    ) internal lockTheSwap {\r
        FeeInfo storage _feeTokens = feeTokens;\r
\r
        FeeInfo memory swapTokens;\r
        swapTokens.main = (amountToSwap * _feeTokens.main) / total;\r
        swapTokens.secondary = (amountToSwap * _feeTokens.secondary) / total;\r
        swapTokens.liquidity = (amountToSwap * _feeTokens.liquidity) / total;\r
        swapTokens.proof = (amountToSwap * _feeTokens.proof) / total;\r
\r
        uint256 amountToPair = swapTokens.liquidity / 2;\r
\r
        swapTokens.total = amountToSwap - amountToPair;\r
\r
        uint256 ethBalance = swapTokensForETH(swapTokens.total);\r
\r
        FeeInfo memory ethSplit;\r
\r
        ethSplit.main = (ethBalance * swapTokens.main) / swapTokens.total;\r
        if (ethSplit.main > 0) {\r
            address(mainWallet).call{value: ethSplit.main}("");\r
        }\r
\r
        ethSplit.secondary =\r
            (ethBalance * swapTokens.secondary) /\r
            swapTokens.total;\r
        if (ethSplit.secondary > 0) {\r
            address(secondaryWallet).call{value: ethSplit.secondary}("");\r
        }\r
\r
        ethSplit.proof = (ethBalance * swapTokens.proof) / swapTokens.total;\r
        if (ethSplit.proof > 0) {\r
            uint256 revenueSplit = (ethSplit.proof * 3) / 4; // 75% to PROOF revenue wallet\r
            uint256 stakingSplit = ethSplit.proof - revenueSplit; // 25% to PROOF Staking Contract\r
\r
            address(addresses.proofStaking).call{value: stakingSplit}("");\r
            address(addresses.proofWallet).call{value: revenueSplit}("");\r
        }\r
\r
        uint256 amountPaired;\r
        ethSplit.liquidity = address(this).balance;\r
        if (amountToPair > 0 && ethSplit.liquidity > 0) {\r
            amountPaired = addLiquidity(\r
                amountToPair,\r
                ethSplit.liquidity,\r
                address(0xdead)\r
            );\r
            emit SwapAndLiquify(amountToPair, ethSplit.liquidity);\r
        }\r
\r
        uint256 liquidityAdjustment = swapTokens.liquidity -\r
            (amountToPair - amountPaired);\r
\r
        _feeTokens.main -= swapTokens.main;\r
        _feeTokens.secondary -= swapTokens.secondary;\r
        _feeTokens.liquidity -= liquidityAdjustment;\r
        _feeTokens.proof -= swapTokens.proof;\r
        _feeTokens.total -=\r
            swapTokens.main +\r
            swapTokens.secondary +\r
            swapTokens.proof +\r
            liquidityAdjustment;\r
    }\r
\r
    function swapTokensForETH(\r
        uint256 tokenAmount\r
    ) internal returns (uint256 ethBalance) {\r
        uint256 ethBalBefore = address(this).balance;\r
\r
        address[] memory path = new address[](2);\r
        path[0] = address(this);\r
        path[1] = uniswapV2Router.WETH();\r
\r
        uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(\r
            tokenAmount,\r
            0, // accept any amount of ETH\r
            path,\r
            address(this),\r
            block.timestamp\r
        );\r
\r
        ethBalance = address(this).balance - ethBalBefore;\r
    }\r
\r
    function addLiquidity(\r
        uint256 tokenAmount,\r
        uint256 ethAmount,\r
        address recipient\r
    ) private returns (uint256) {\r
        (uint256 amountA, , ) = uniswapV2Router.addLiquidityETH{\r
            value: ethAmount\r
        }(\r
            address(this),\r
            tokenAmount,\r
            0, // slippage is unavoidable\r
            0, // slippage is unavoidable\r
            recipient,\r
            block.timestamp\r
        );\r
        return amountA;\r
    }\r
\r
    function changeFees(\r
        uint256 liquidityBuy,\r
        uint256 mainBuy,\r
        uint256 secondaryBuy,\r
        uint256 liquiditySell,\r
        uint256 mainSell,\r
        uint256 secondarySell\r
    ) external onlyOwner {\r
        if (!buyTaxesSettled || !sellTaxesSettled) {\r
            revert InvalidConfiguration();\r
        }\r
        liquidityBuy *= 100;\r
        mainBuy *= 100;\r
        secondaryBuy *= 100;\r
        liquiditySell *= 100;\r
        mainSell *= 100;\r
        secondarySell *= 100;\r
\r
        FeeInfo memory _buyFees;\r
        _buyFees.liquidity = liquidityBuy;\r
        _buyFees.main = mainBuy;\r
        _buyFees.secondary = secondaryBuy;\r
\r
        FeeInfo memory _sellFees;\r
        _sellFees.liquidity = liquiditySell;\r
        _sellFees.main = mainSell;\r
        _sellFees.secondary = secondarySell;\r
\r
        (_buyFees.proof, _sellFees.proof) = _calculateProofFee();\r
        _validateFees(_buyFees, _sellFees);\r
        buyFees = _buyFees;\r
        sellFees = _sellFees;\r
    }\r
\r
    function _calculateProofFee() internal returns (uint256, uint256) {\r
        uint256 secondsPassed = block.timestamp - launchedAt;\r
        if (secondsPassed > 61 days) {\r
            proofFeeRemoved = true;\r
            return (0, 0);\r
        } else if (secondsPassed > 1 days) {\r
            proofFeeReduced = true;\r
            return (100, 100); // 1% (100 basis points)\r
        } else {\r
            return (200, 200);\r
        }\r
    }\r
\r
    function _validateFees(\r
        FeeInfo memory _buyFees,\r
        FeeInfo memory _sellFees\r
    ) internal view {\r
        _buyFees.total =\r
            _buyFees.liquidity +\r
            _buyFees.main +\r
            _buyFees.secondary;\r
        if (_buyFees.total == 0) {\r
            _buyFees.proof = 0;\r
        } else {\r
            if (_buyFees.proof == 700) {\r
                _buyFees.total += 200;\r
            } else {\r
                _buyFees.total += _buyFees.proof;\r
            }\r
        }\r
\r
        _sellFees.total =\r
            _sellFees.liquidity +\r
            _sellFees.main +\r
            _sellFees.secondary;\r
        if (_sellFees.total == 0) {\r
            _sellFees.proof = 0;\r
        } else {\r
            if (_sellFees.proof == 700) {\r
                _sellFees.total += 200;\r
            } else {\r
                _sellFees.total += _sellFees.proof;\r
            }\r
        }\r
\r
        if (\r
            _buyFees.total > limits.maxBuyFee * 100 ||\r
            _sellFees.total > limits.maxSellFee * 100\r
        ) {\r
            revert InvalidConfiguration();\r
        }\r
    }\r
\r
    function addToWhitelist(address[] memory accounts) external onlyOwner {\r
        uint256 len = accounts.length;\r
        for (uint256 i; i < len; i++) {\r
            userInfo[accounts[i]].isWhitelisted = true;\r
        }\r
    }\r
\r
    function removeFromWhitelist(address[] memory accounts) external onlyOwner {\r
        uint256 len = accounts.length;\r
        for (uint256 i; i < len; i++) {\r
            userInfo[accounts[i]].isWhitelisted = false;\r
        }\r
    }\r
\r
    function setFeeExempt(address account, bool value) public onlyOwner {\r
        userInfo[account].isFeeExempt = value;\r
    }\r
\r
    function setFeeExempt(address[] memory accounts) public onlyOwner {\r
        uint256 len = accounts.length;\r
        for (uint256 i; i < len; i++) {\r
            userInfo[accounts[i]].isFeeExempt = true;\r
        }\r
    }\r
\r
    function setTxLimitExempt(address account, bool value) public onlyOwner {\r
        userInfo[account].isTxLimitExempt = value;\r
    }\r
\r
    function setTxLimitExempt(address[] memory accounts) public onlyOwner {\r
        uint256 len = accounts.length;\r
        for (uint256 i; i < len; i++) {\r
            userInfo[accounts[i]].isTxLimitExempt = true;\r
        }\r
    }\r
\r
    function setMainWallet(address newWallet) external onlyOwner {\r
        mainWallet = payable(newWallet);\r
    }\r
\r
    function setSecondaryWallet(address newWallet) external onlyOwner {\r
        secondaryWallet = payable(newWallet);\r
    }\r
\r
    function setSwapAndLiquifyEnabled(bool _enabled) external onlyOwner {\r
        swapEnabled = _enabled;\r
        emit SwapAndLiquifyEnabledUpdated(_enabled);\r
    }\r
\r
    function setSwapAtAmount(uint256 amount) external onlyOwner {\r
        swapTokensAtAmount = amount;\r
    }\r
\r
    function setMaxSwapsPerBlock(uint256 _maxSwaps) external onlyOwner {\r
        maxSwapsPerBlock = _maxSwaps;\r
    }\r
\r
    function manualSwapBack(uint256 percentTimesTen) external onlyOwner {\r
        uint256 _amountToSwap = (feeTokens.total * percentTimesTen) / 1000; //allows for .1% precision\r
        processFees(feeTokens.total, _amountToSwap);\r
    }\r
\r
    function _setWhitelisted(address[] memory accounts) internal {\r
        uint256 len = accounts.length;\r
        for (uint256 i; i < len; i++) {\r
            userInfo[accounts[i]].isWhitelisted = true;\r
        }\r
    }\r
\r
    function withdrawStuckTokens() external onlyOwner {\r
        super._update(\r
            address(this),\r
            _msgSender(),\r
            balanceOf(address(this)) - feeTokens.total\r
        );\r
    }\r
\r
    function getCirculatingSupply() external view returns (uint256) {\r
        return totalSupply() - balanceOf(address(0xdead));\r
    }\r
\r
    modifier lockTheSwap() {\r
        swapping = 2;\r
        _;\r
        swapping = 1;\r
    }\r
\r
    function decimals() public view virtual override returns (uint8) {\r
        return 9;\r
    }\r
\r
    function version() public pure returns (uint8) {\r
        return 4;\r
    }\r
\r
    function withdrawkETH() external onlyOwner {\r
        require(address(this).balance > 0, "No ETH balance");\r
        payable(msg.sender).transfer(address(this).balance);\r
    }\r
\r
    function withdrawToken(address tokenAddress) external onlyOwner {\r
        IERC20 token = IERC20(tokenAddress);\r
        uint256 balance = token.balanceOf(address(this));\r
        require(balance > 0, "No token balance");\r
        require(token.transfer(msg.sender, balance), "Transfer failed");\r
    }\r
\r
    receive() external payable {}\r
\r
    fallback() external payable {}\r
}\r
"
    },
    "interfaces/ITokenWhitelist.sol": {
      "content": "// SPDX-License-Identifier: None\r
\r
pragma solidity ^0.8.24;\r
\r
import "./IDataStore.sol";\r
\r
interface ITokenWhitelist is IDataStoreResponse {\r
    \r
    struct TokenInfo {\r
        string name;\r
        string symbol;\r
        address owner;\r
        address mainWallet;\r
        address secondaryWallet;\r
        uint256 totalSupply;\r
        uint256 percentToLP;\r
        uint256 lpLockDuration;\r
        uint256 initMaxWallet;\r
        FeeInfo buyFees;\r
        FeeInfo sellFees;\r
        address[] whitelist;\r
        uint256 whitelistDuration;\r
        address rewardToken;\r
        address futureOwner;\r
    }\r
\r
    struct FeeInfo {\r
        uint256 main;      // Stored in basis points (1 = 0.01%)\r
        uint256 secondary; // Stored in basis points (1 = 0.01%)\r
        uint256 liquidity; // Stored in basis points (1 = 0.01%)\r
        uint256 proof;     // Stored in basis points (1 = 0.01%)\r
        uint256 total;     // Stored in basis points (1 = 0.01%)\r
    }\r
\r
    error ExceedsMaxTxAmount();\r
    error ExceedsMaxWalletAmount();\r
    error InvalidConfiguration();\r
    error TradingNotEnabled();\r
    error NotWhitelisted();\r
\r
}"
    },
    "interfaces/ITeamFinanceLocker.sol": {
      "content": "// SPDX-License-Identifier: None\r
\r
pragma solidity ^0.8.24;\r
\r
interface ITeamFinanceLocker {\r
    function lockToken(\r
        address _tokenAddress,\r
        address _withdrawalAddress,\r
        uint256 _amount,\r
        uint256 _unlockTime,\r
        bool _mintNFT, \r
        address referrer\r
    ) external payable returns (uint256 _id);\r
}"
    },
    "interfaces/IERC721A.sol": {
      "content": "// SPDX-License-Identifier: None\r
\r
pragma solidity ^0.8.24;\r
\r
interface IERC721A {\r
    function totalSupply() external returns (uint256);\r
    function ownerOf(uint256) external returns (address);\r
}"
    },
    "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol": {
      "content": "pragma solidity >=0.5.0;

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;
}
"
    },
    "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol": {
      "content": "pragma solidity >=0.6.2;

import './IUniswapV2Router01.sol';

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;
}
"
    },
    "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (proxy/utils/Initializable.sol)

pragma solidity ^0.8.20;

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
 * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
 * case an upgrade adds a module that needs to be initialized.
 *
 * For example:
 *
 * [.hljs-theme-light.nopadding]
 * ```solidity
 * contract MyToken is ERC20Upgradeable {
 *     function initialize() initializer public {
 *         __ERC20_init("MyToken", "MTK");
 *     }
 * }
 *
 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
 *     function initializeV2() reinitializer(2) public {
 *         __ERC20Permit_init("MyToken");
 *     }
 * }
 * ```
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() {
 *     _disableInitializers();
 * }
 * ```
 * ====
 */
abstract contract Initializable {
    /**
     * @dev Storage of the initializable contract.
     *
     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
     * when using with upgradeable contracts.
     *
     * @custom:storage-location erc7201:openzeppelin.storage.Initializable
     */
    struct InitializableStorage {
        /**
         * @dev Indicates that the contract has been initialized.
         */
        uint64 _initialized;
        /**
         * @dev Indicates that the contract is in the process of being initialized.
         */
        bool _initializing;
    }

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;

    /**
     * @dev The contract is already initialized.
     */
    error InvalidInitialization();

    /**
     * @dev The contract is not initializing.
     */
    error NotInitializing();

    /**
     * @dev Triggered when the contract has been initialized or reinitialized.
     */
    event Initialized(uint64 version);

    /**
     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
     * `onlyInitializing` functions can be used to initialize parent contracts.
     *
     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
     * production.
     *
     * Emits an {Initialized} event.
     */
    modifier initializer() {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        // Cache values to avoid duplicated sloads
        bool isTopLevelCall = !$._initializing;
        uint64 initialized = $._initialized;

        // Allowed calls:
        // - initialSetup: the contract is not in the initializing state and no previous version was
        //                 initialized
        // - construction: the contract is initialized at version 1 (no reinitialization) and the
        //                 current contract is just being deployed
        bool initialSetup = initialized == 0 && isTopLevelCall;
        bool construction = initialized == 1 && address(this).code.length == 0;

        if (!initialSetup && !construction) {
            revert InvalidInitialization();
        }
        $._initialized = 1;
        if (isTopLevelCall) {
            $._initializing = true;
        }
        _;
        if (isTopLevelCall) {
            $._initializing = false;
            emit Initialized(1);
        }
    }

    /**
     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
     * used to initialize parent contracts.
     *
     * A reinitializer may be used after the original initialization step. This is essential to configure modules that
     * are added through upgrades and that require initialization.
     *
     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
     * cannot be nested. If one is invoked in the context of another, execution will revert.
     *
     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
     * a contract, executing them in the right order is up to the developer or operator.
     *
     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
     *
     * Emits an {Initialized} event.
     */
    modifier reinitializer(uint64 version) {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        if ($._initializing || $._initialized >= version) {
            revert InvalidInitialization();
        }
        $._initialized = version;
        $._initializing = true;
        _;
        $._initializing = false;
        emit Initialized(version);
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} and {reinitializer} modifiers, directly or indirectly.
     */
    modifier onlyInitializing() {
        _checkInitializing();
        _;
    }

    /**
     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
     */
    function _checkInitializing() internal view virtual {
        if (!_isInitializing()) {
            revert NotInitializing();
        }
    }

    /**
     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
     * through proxies.
     *
     * Emits an {Initialized} event the first time it is successfully executed.
     */
    function _disableInitializers() internal virtual {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        if ($._initializing) {
            revert InvalidInitialization();
        }
        if ($._initialized != type(uint64).max) {
            $._initialized = type(uint64).max;
            emit Initialized(type(uint64).max);
        }
    }

    /**
     * @dev Returns the highest version that has been initialized. See {reinitializer}.
     */
    function _getInitializedVersion() internal view returns (uint64) {
        return _getInitializableStorage()._initialized;
    }

    /**
     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
     */
    function _isInitializing() internal view returns (bool) {
        return _getInitializableStorage()._initializing;
    }

    /**
     * @dev Pointer to storage slot. Allows integrators to override it with a custom storage location.
     *
     * NOTE: Consider following the ERC-7201 formula to derive storage locations.
     */
    function _initializableStorageSlot() internal pure virtual returns (bytes32) {
        return INITIALIZABLE_STORAGE;
    }

    /**
     * @dev Returns a pointer to the storage namespace.
     */
    // solhint-disable-next-line var-name-mixedcase
    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
        bytes32 slot = _initializableStorageSlot();
        assembly {
            $.slot := slot
        }
    }
}
"
    },
    "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.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.
 *
 * The initial owner is set to the address provided by the deployer. 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 OwnableUpgradeable is Initializable, ContextUpgradeable {
    /// @custom:storage-location erc7201:openzeppelin.storage.Ownable
    struct OwnableStorage {
        address _owner;
    }

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;

    function _getOwnableStorage() private pure returns (OwnableStorage storage $) {
        assembly {
            $.slot := OwnableStorageLocation
        }
    }

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    function __Ownable_init(address initialOwner) internal onlyInitializing {
        __Ownable_init_unchained(initialOwner);
    }

    function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @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) {
        OwnableStorage storage $ = _getOwnableStorage();
        return $._owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling 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 {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        OwnableStorage storage $ = _getOwnableStorage();
        address oldOwner = $._owner;
        $._owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
"
    },
    "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {ContextUpgradeable} from "../../utils/ContextUpgradeable.sol";
import {IERC20Errors} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * The default value of {decimals} is 18. To change this, you should override
 * this function so it returns a different value.
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC-20
 * applications.
 */
abstract contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20, IERC20Metadata, IERC20Errors {
    /// @custom:storage-location erc7201:openzeppelin.storage.ERC20
    struct ERC20Storage {
        mapping(address account => uint256) _balances;

        mapping(address account => mapping(address spender => uint256)) _allowances;

        uint256 _totalSupply;

        string _name;
        string _symbol;
    }

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ERC20")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant ERC20StorageLocation = 0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00;

    function _getERC20Storage() private pure returns (ERC20Storage storage $) {
        assembly {
            $.slot := ERC20StorageLocation
        }
    }

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * Both values are immutable: they can only be set once during construction.
     */
    function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {
        __ERC20_init_unchained(name_, symbol_);
    }

    function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {
        ERC20Storage storage $ = _getERC20Storage();
        $._name = name_;
        $._symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual returns (string memory) {
        ERC20Storage storage $ = _getERC20Storage();
        return $._name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual returns (string memory) {
        ERC20Storage storage $ = _getERC20Storage();
        return $._symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the default value returned by this function, unless
     * it's overridden.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual returns (uint8) {
        return 18;
    }

    /// @inheritdoc IERC20
    function totalSupply() public view virtual returns (uint256) {
        ERC20Storage storage $ = _getERC20Storage();
        return $._totalSupply;
    }

    /// @inheritdoc IERC20
    function balanceOf(address account) public view virtual returns (uint256) {
        ERC20Storage storage $ = _getERC20Storage();
        return $._balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `value`.
     */
    function transfer(address to, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, value);
        return true;
    }

    /// @inheritdoc IERC20
    function allowance(address owner, address spender) public view virtual returns (uint256) {
        ERC20Storage storage $ = _getERC20Storage();
        return $._allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 value) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, value);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Skips emitting an {Approval} event indicating an allowance update. This is not
     * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `value`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `value`.
     */
    function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, value);
        _transfer(from, to, value);
        return true;
    }

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _transfer(address from, address to, uint256 value) internal {
        if (from == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        if (to == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(from, to, value);
    }

    /**
     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
     * this function.
     *
     * Emits a {Transfer} event.
     */
    function _update(address from, address to, uint256 value) internal virtual {
        ERC20Storage storage $ = _getERC20Storage();
        if (from == address(0)) {
            // Overflow check required: The rest of the code assumes that totalSupply never overflows
            $._totalSupply += value;
        } else {
            uint256 fromBalance = $._balances[from];
            if (fromBalance < value) {
                revert ERC20InsufficientBalance(from, fromBalance, value);
            }
            unchecked {
                // Overflow not possible: value <= fromBalance <= totalSupply.
                $._balances[from] = fromBalance - value;
            }
        }

        if (to == address(0)) {
            unchecked {
                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
                $._totalSupply -= value;
            }
        } else {
            unchecked {
                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
                $._balances[to] += value;
            }
        }

        emit Transfer(from, to, value);
    }

    /**
     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
     * Relies on the `_update` mechanism
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _mint(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(address(0), account, value);
    }

    /**
     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
     * Relies on the `_update` mechanism.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead
     */
    function _burn(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        _update(account, address(0), value);
    }

    /**
     * @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.
     *
     * This 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.
     *
     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
     */
    function _approve(address owner, address spender, uint256 value) internal {
        _approve(owner, spender, value, true);
    }

    /**
     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
     *
     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
     * `Approval` event during `transferFrom` operations.
     *
     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
     * true using the following override:
     *
     * ```solidity
     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
     *     super._approve(owner, spender, value, true);
     * }
     * ```
     *
     * Requirements are the same as {_approve}.
     */
    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
        ERC20Storage storage $ = _getERC20Storage();
        if (owner == address(0)) {
            revert ERC20InvalidApprover(address(0));
        }
        if (spender == address(0)) {
            revert ERC20InvalidSpender(address(0));
        }
        $._allowances[owner][spender] = value;
        if (emitEvent) {
            emit Approval(owner, spender, value);
        }
    }

    /**
     * @dev Updates `owner`'s allowance for `spender` based on spent `value`.
     *
     * Does not update the allowance value in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Does not emit an {Approval} event.
     */
    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance < type(uint256).max) {
            if (currentAllowance < value) {
                revert ERC20InsufficientAllowance(spender, currentAllowance, value);
            }
            unchecked {
                _approve(owner, spender, currentAllowance - value, false);
            }
        }
    }
}
"
    },
    "interfaces/IDataStore.sol": {
      "content": "// SPDX-License-Identifier: None\r
\r
pragma solidity ^0.8.24;\r
\r
interface IDataStoreResponse {\r
    struct DataStoreAddressResponse {\r
        address locker;\r
        address payable proofWallet;\r
        address payable proofStaking;\r
        address proofPassNFT;\r
        address router;\r
    }\r
\r
    struct DataStoreLimitsResponse {\r
        uint initMaxTx;\r
        uint swapTokensAtAmount;\r
        uint maxTxUpper;\r
        uint maxTxLower;\r
        uint maxWalletUpper;\r
        uint maxWalletLower;\r
        uint maxBuyFee;\r
        uint maxSellFee;\r
        uint denominator;\r
    }\r
}\r
\r
interface IDataStore is IDataStoreResponse {\r
    function getAddresses(string[] memory addrKeys) external view returns (address[] memory);\r
    function getUints(string[] memory uintKeys) external view returns (uint256[] memory);\r
    function getPlatformAddresses() external view returns (DataStoreAddressResponse memory);\r
    function getLimits() external view returns (DataStoreLimitsResponse memory);\r
}"
    },
    "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol": {
      "content": "pragma solidity >=0.6.2;

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,

Tags:
ERC20, Multisig, Swap, Liquidity, Staking, Upgradeable, Multi-Signature, Factory|addr:0xf2e77efb07cde9432e348848c325cf8c7ad081fc|verified:true|block:23613213|tx:0x3accb5420ab69bd874d4bdff9f8f405b099e7df27ddd7fb4fbb82da0939c7182|first_check:1760895601

Submitted on: 2025-10-19 19:40:03

Comments

Log in to comment.

No comments yet.