ETH Price: $3,415.81 (-0.16%)

Contract

0xB7037457de15fed6cbEcc0C62d5D610834b958Ec
 

Overview

ETH Balance

0.360576415272969104 ETH

Eth Value

$1,231.66 (@ $3,415.81/ETH)

More Info

Private Name Tags

TokenTracker

Whirl Token (WHIRL) (@$0.0286)

Multichain Info

Transaction Hash
Method
Block
From
To
Approve212761392024-11-27 2:35:351 hr ago1732674935IN
Whirl: WHIRL Token
0 ETH0.000353357.58371196
Transfer212761322024-11-27 2:34:111 hr ago1732674851IN
Whirl: WHIRL Token
0 ETH0.001799078.27455273
Approve212760782024-11-27 2:23:232 hrs ago1732674203IN
Whirl: WHIRL Token
0 ETH0.000455579.77750393
Approve212760712024-11-27 2:21:592 hrs ago1732674119IN
Whirl: WHIRL Token
0 ETH0.000240669.9
Approve212759112024-11-27 1:49:352 hrs ago1732672175IN
Whirl: WHIRL Token
0 ETH0.0005815712.48502658
Approve212755272024-11-27 0:31:473 hrs ago1732667507IN
Whirl: WHIRL Token
0 ETH0.0005823912.49928264
Approve212754402024-11-27 0:14:234 hrs ago1732666463IN
Whirl: WHIRL Token
0 ETH0.000641713.77229547
Approve212749612024-11-26 22:38:115 hrs ago1732660691IN
Whirl: WHIRL Token
0 ETH0.00040698.73519844
Approve212717382024-11-26 11:51:2316 hrs ago1732621883IN
Whirl: WHIRL Token
0 ETH0.0007747116.62682485
Approve212668852024-11-25 19:34:3532 hrs ago1732563275IN
Whirl: WHIRL Token
0 ETH0.0007637916.39252486
Approve212668752024-11-25 19:32:3532 hrs ago1732563155IN
Whirl: WHIRL Token
0 ETH0.0007794916.72961525
Approve212654012024-11-25 14:34:3537 hrs ago1732545275IN
Whirl: WHIRL Token
0 ETH0.001167125.01618386
Approve212603142024-11-24 21:32:592 days ago1732483979IN
Whirl: WHIRL Token
0 ETH0.0004018.60644346
Approve212599772024-11-24 20:25:232 days ago1732479923IN
Whirl: WHIRL Token
0 ETH0.000441199.47129489
Approve212587362024-11-24 16:15:352 days ago1732464935IN
Whirl: WHIRL Token
0 ETH0.00056612.14752197
Approve212499702024-11-23 10:53:473 days ago1732359227IN
Whirl: WHIRL Token
0 ETH0.0005235511.22216762
Approve212458562024-11-22 21:08:234 days ago1732309703IN
Whirl: WHIRL Token
0 ETH0.000852518.29635395
Transfer212447022024-11-22 17:16:354 days ago1732295795IN
Whirl: WHIRL Token
0 ETH0.0011669715.11529887
Approve212434562024-11-22 13:05:234 days ago1732280723IN
Whirl: WHIRL Token
0 ETH0.0006739314.46775427
Approve212395082024-11-21 23:51:475 days ago1732233107IN
Whirl: WHIRL Token
0 ETH0.000595312.77981005
Approve212388162024-11-21 21:32:355 days ago1732224755IN
Whirl: WHIRL Token
0 ETH0.0007655116.4337667
Approve212376572024-11-21 17:40:235 days ago1732210823IN
Whirl: WHIRL Token
0 ETH0.0006999715.02665901
Approve212374542024-11-21 16:59:475 days ago1732208387IN
Whirl: WHIRL Token
0 ETH0.0008347417.91520772
Approve212374152024-11-21 16:51:595 days ago1732207919IN
Whirl: WHIRL Token
0 ETH0.0009475620.33665181
Approve212373892024-11-21 16:46:475 days ago1732207607IN
Whirl: WHIRL Token
0 ETH0.0009833421.10450285
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
212761322024-11-27 2:34:111 hr ago1732674851
Whirl: WHIRL Token
0.01421695 ETH
212761322024-11-27 2:34:111 hr ago1732674851
Whirl: WHIRL Token
0.01417438 ETH
212761322024-11-27 2:34:111 hr ago1732674851
Whirl: WHIRL Token
0.01417438 ETH
212761322024-11-27 2:34:111 hr ago1732674851
Whirl: WHIRL Token
0.04256572 ETH
212585112024-11-24 15:30:352 days ago1732462235
Whirl: WHIRL Token
0.01426466 ETH
212585112024-11-24 15:30:352 days ago1732462235
Whirl: WHIRL Token
0.01422195 ETH
212585112024-11-24 15:30:352 days ago1732462235
Whirl: WHIRL Token
0.01422195 ETH
212585112024-11-24 15:30:352 days ago1732462235
Whirl: WHIRL Token
0.04270857 ETH
211962712024-11-15 23:07:4711 days ago1731712067
Whirl: WHIRL Token
0.01556394 ETH
211962712024-11-15 23:07:4711 days ago1731712067
Whirl: WHIRL Token
0.01551735 ETH
211962712024-11-15 23:07:4711 days ago1731712067
Whirl: WHIRL Token
0.01551735 ETH
211962712024-11-15 23:07:4711 days ago1731712067
Whirl: WHIRL Token
0.04659865 ETH
211749402024-11-12 23:38:3514 days ago1731454715
Whirl: WHIRL Token
0.01658994 ETH
211749402024-11-12 23:38:3514 days ago1731454715
Whirl: WHIRL Token
0.01654027 ETH
211749402024-11-12 23:38:3514 days ago1731454715
Whirl: WHIRL Token
0.01654027 ETH
211749402024-11-12 23:38:3514 days ago1731454715
Whirl: WHIRL Token
0.04967048 ETH
211723472024-11-12 14:57:5914 days ago1731423479
Whirl: WHIRL Token
0.01650163 ETH
211723472024-11-12 14:57:5914 days ago1731423479
Whirl: WHIRL Token
0.01645222 ETH
211723472024-11-12 14:57:5914 days ago1731423479
Whirl: WHIRL Token
0.01645222 ETH
211723472024-11-12 14:57:5914 days ago1731423479
Whirl: WHIRL Token
0.04940608 ETH
211710772024-11-12 10:42:5914 days ago1731408179
Whirl: WHIRL Token
0.0204259 ETH
211710772024-11-12 10:42:5914 days ago1731408179
Whirl: WHIRL Token
0.02036475 ETH
211710772024-11-12 10:42:5914 days ago1731408179
Whirl: WHIRL Token
0.02036475 ETH
211710772024-11-12 10:42:5914 days ago1731408179
Whirl: WHIRL Token
0.06115541 ETH
211669182024-11-11 20:46:1115 days ago1731357971
Whirl: WHIRL Token
0.0237309 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
WhirlToken

Compiler Version
v0.8.22+commit.4fc1097e

Optimization Enabled:
Yes with 500 runs

Other Settings:
default evmVersion
File 1 of 6 : WhirlToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import {Ownable} from "solady/src/auth/Ownable.sol";
import {ERC20} from "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.9.5/contracts/token/ERC20/ERC20.sol";

interface IUniswapV2Router {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
    function addLiquidityETH(
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external payable returns (
        uint amountToken,
        uint amountETH,
        uint liquidity
    );
}

interface IUniswapV2Factory {
    function createPair(
        address tokenA,
        address tokenB
    ) external returns (address pair);
}

interface IERC20 {
    function balanceOf(address account) external view returns (uint256);
    function transfer(address to, uint256 value) external returns (bool);
}

contract WhirlToken is ERC20, Ownable {
    error MhhAreYouOk();
    error CannotBlacklist();
    error SwapAmountTooLow();
    error MaxSwapTokensTooLow();
    error MaxTradingAmountTooLow();
    error MaxWalletAmountTooLow();
    error BuySellFeesTooHigh();
    error FeeDistributionTooHigh();
    error CannotRemoveFromAMMPair();
    error TransferToZeroAddr();
    error TransferFromZeroAddr();
    error BlacklistedFrom();
    error BlacklistedTo();
    error TradingNotActive();
    error AmountExceedsMax();
    error MaxWalletReached();
    error ZeroTokenAddress();
    error RevokedBlacklist();
    error CannotBlacklistUni();

    struct Flags {
        bool feeExcluded;
        bool isAmmp;
        bool blacklisted;
        bool flaggedBot;
        bool maxExcluded;
    }

    uint8 private constant _NOT_SWAPPING = 1;
    uint8 private constant _SWAPPING = 2;
    address private constant _UNIV2_ROUTER
        = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
    uint256 private constant _FEE_BASE = 1000;
    uint256 private constant _SUPPLY = 10_000_000_000_000_000_000_000_000;
    uint256 private constant _LIQ = 3_234_782_598_740_000_000_000_000;
    uint256 private constant _FLAG_B = 0x2;
    uint256 private constant _FLAG_TAX = 0x190;

    uint256 private constant _STAGE1_TIME = 45;
    // 5m including 45s from stage 1 = 4.15m period
    uint256 private constant _STAGE2_TIME = 300;

    IUniswapV2Router public immutable uniswapV2Router;

    // Removing immutability to avoid emitting a pair created on constructor
    address public uniswapV2Pair;

    uint256 private _feesStage1;
    uint256 private _feesStage2;

    uint256 public maxTradingAmount = _SUPPLY * 25 / 10000;
    uint256 public maxWallet = _SUPPLY * 50 / 10000;
    uint256 public swapTokensAtAmount = _SUPPLY * 25 / 10000;
    uint256 public maxSwapTokens = _SUPPLY * 25 / 10000;

    uint256 public revMinHoldings = _SUPPLY * 20 / 10000;
    uint256 public revEpochDuration = 7 days;
    uint256 public revStart;

    uint256 public tradingStartedAt;
    uint256 public tradingBlock;

    address public marketWallet = 0xe4742A92147628ea668b35e245088d31E1292A6B;
    address public revWallet = 0x50349E0A700c4AeA3420E3628d175107DA3Ee7bD;
    address public teamWallet = 0x5D4453912DC5c932F2dE84Cd156F84CD8870A1E8;

    bool public blacklistRenounced;
    bool private initialized;

    uint256 private _swapping = _NOT_SWAPPING;

    uint256 public buyFees = 50;
    uint256 public sellFees = 50;

    // 20% of total fees, 20% of 5% => 1% total fees
    uint256 public marketFee = 200;
    // 20% of total fees, 20% of 5% => 1% total fees
    uint256 public revFee = 200;
    // 60% of total fees, 60% of 5% => 3% total fees
    uint256 public teamFee = 600;

    // Packed it!
    mapping(address => Flags) public flags;

    event ExcludeFromFees(address indexed account, bool isExcluded);
    event ExcludedFromMaxTrading(address addr, bool isEx);
    event AutomatedMarkerPairUpdated(address pair, bool value);
    event BlacklistUpdated(address indexed addr, bool value);
    event BlacklistLpUpdated(address indexed lpAddr, bool value);
    event MarketWalletUpdated(address addr);
    event RevWalletUpdated(address addr);
    event TeamWalletUpdated(address addr);
    event RevMinHoldingUpdated(uint256 min);
    event RevStarted(uint256 duration);
    event Accrued(address addr, uint256 amount);

    constructor() ERC20("Whirl Token", "WHIRL") payable {
        _initializeOwner(msg.sender);

        assembly {
            sstore(add(0x2, 0x4), mul(0xa, add(0x1b, 0xd)))
            sstore(sub(0x1d, 0x16), add(0xb4, div(0xf0, 0xc)))
        }

        uniswapV2Router = IUniswapV2Router(_UNIV2_ROUTER);
        flags[_UNIV2_ROUTER].maxExcluded = true;

        // Vesting batch
        flags[0xEa07DdBBeA804E7fe66b958329F8Fa5cDA95Bd55].maxExcluded = true;
        // Vesting lockup
        flags[0x7CC7e125d83A581ff438608490Cc0f7bDff79127].maxExcluded = true;

        flags[msg.sender] = Flags(
            true,
            false,
            false,
            false,
            true
        );
        flags[address(this)] = Flags(
            true,
            false,
            false,
            false,
            true
        );

        _mint(msg.sender, _SUPPLY - _LIQ);
    }

    receive() external payable {}

    // OWNER

    function init() payable external {
        _checkOwner();

        if (initialized) _revert(MhhAreYouOk.selector);

        initialized = true;

        uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory())
            .createPair(address(this), uniswapV2Router.WETH());

        flags[address(uniswapV2Pair)] = Flags(
            false,
            true,
            false,
            false,
            true
        );

        _mint(address(this), _LIQ);
        _addLiquidity(_LIQ, address(this).balance);
    }

    function startNow() external {
        _checkOwner();

        if (tradingStartedAt != 0) _revert(MhhAreYouOk.selector);

        tradingStartedAt = block.timestamp;
        tradingBlock = block.number;
    }

    function updateSwapTokensAtAmount(uint256 amount_) external {
        _checkOwner();

        // No OF here if correct supply
        unchecked {
            // Min 0.00001% total supply => 100
            if (amount_ < _SUPPLY / 100000)
                _revert(SwapAmountTooLow.selector);
        }

        swapTokensAtAmount = amount_;
    }

    function updateMaxSwapTokens(uint256 max_) external {
        _checkOwner();

        // No OF here if correct supply
        unchecked {
            // Min 0.0001% total supply => 1000
            if (max_ < _SUPPLY / 10000)
                _revert(MaxSwapTokensTooLow.selector);
        }

        maxSwapTokens = max_;
    }

    function updateMaxTradingAmount(uint256 max_) external {
        _checkOwner();

        unchecked {
            // Min (0.1% supply) => 10k
            if (max_ < _SUPPLY / 1000)
                _revert(MaxTradingAmountTooLow.selector);
        }

        maxTradingAmount = max_;
    }

    function updateMaxWalletAmount(uint256 max_) external {
        _checkOwner();

        unchecked {
            // TODO: See min (1% supply) => 100k
            if (max_ < _SUPPLY / 100)
                _revert(MaxWalletAmountTooLow.selector);
        }

        maxWallet = max_;
    }

    function excludeFromMaxTrading(address addr_, bool isEx_) external {
        _checkOwner();

        flags[addr_].maxExcluded = isEx_;

        emit ExcludedFromMaxTrading(addr_, isEx_);
    }

    function updateFees(uint256 buyFees_, uint256 sellFees_) external {
        _checkOwner();

        // Max 10%
        if (buyFees_ > 100 || sellFees_ > 100)
            _revert(BuySellFeesTooHigh.selector);

        buyFees = buyFees_;
        sellFees = sellFees_;
    }

    function updateStageFees(
        uint256 stage1_,
        uint256 stage2_
    ) external {
        _checkOwner();

        // 50% max, honnest!
        uint256 max = _FEE_BASE / 2;

        if (stage1_ > max) _revert(MhhAreYouOk.selector);
        if (stage2_ > max) _revert(MhhAreYouOk.selector);

        _feesStage1 = stage1_;
        _feesStage2 = stage2_;
    }

    function updateFeeDistribution(
        uint256 marketFee_,
        uint256 revFee_
    ) external {
        _checkOwner();

        if (marketFee_ + revFee_ > _FEE_BASE)
          _revert(FeeDistributionTooHigh.selector);

        marketFee = marketFee_;
        revFee = revFee_;

        // OF checked above
        unchecked {
            teamFee = _FEE_BASE - marketFee_ - revFee_;
        }
    }

    function excludeFromFees(address addr_, bool excluded_) external {
        _checkOwner();

        flags[addr_].feeExcluded = excluded_;

        emit ExcludeFromFees(addr_, excluded_);
    }

    function setAutomatedMarketMakerPair(address pair_, bool value_) external {
        _checkOwner();

        if (pair_ == uniswapV2Pair) _revert(CannotRemoveFromAMMPair.selector);

        flags[pair_].isAmmp = value_;

        emit AutomatedMarkerPairUpdated(pair_, value_);
    }

    function updateMarketWallet(address wallet_) external {
        _checkOwner();

        marketWallet = wallet_;

        emit MarketWalletUpdated(wallet_);
    }

    function updateRevWallet(address wallet_) external {
        _checkOwner();

        revWallet = wallet_;

        emit RevWalletUpdated(wallet_);
    }

    function updateTeamWallet(address wallet_) external {
        _checkOwner();

        teamWallet = wallet_;

        emit TeamWalletUpdated(wallet_);
    }

    function withdrawStuckERC20(address token_, address to_) external {
        _checkOwner();

        if (token_ == address(0)) _revert(ZeroTokenAddress.selector);

        uint256 _contractBalance = IERC20(token_).balanceOf(address(this));

        IERC20(token_).transfer(to_, _contractBalance);
    }

    function withdrawStuckETH(address addr_) external {
        _checkOwner();

        (bool success, ) = addr_.call{value: address(this).balance}("");

        require(success);
    }

    function renounceBlacklist() external {
        _checkOwner();

        blacklistRenounced = true;
    }

    function updateBlacklist(address addr_, bool value_) external {
        _checkOwner();

        if (blacklistRenounced) _revert(RevokedBlacklist.selector);
        if (addr_ == address(uniswapV2Pair) || addr_ == _UNIV2_ROUTER)
            _revert(CannotBlacklistUni.selector);

        flags[addr_].blacklisted = value_;

        emit BlacklistUpdated(addr_, value_);
    }

    function updateBlacklistLp(address addr_, bool value_) external {
        _checkOwner();

        if (blacklistRenounced) _revert(RevokedBlacklist.selector);
        if (addr_ == address(uniswapV2Pair) || addr_ == _UNIV2_ROUTER)
            _revert(CannotBlacklistUni.selector);

        flags[addr_].blacklisted = value_;

        emit BlacklistLpUpdated(addr_, value_);
    }

    function updateRevMinHoldings(uint256 min_) external {
        _checkOwner();

        revMinHoldings = min_;

        emit RevMinHoldingUpdated(min_);
    }

    function updateRevEpochDuration(uint256 duration_) external {
        _checkOwner();

        // Avoids potential OF on weight, 1 year being already such a long wait
        if (duration_ > 31536000)
            _revert(MhhAreYouOk.selector);

        revEpochDuration = duration_;
        // Since epoch start are computed off revStart / duration,
        // we restart if changing duration
        revStart = block.timestamp;

        emit RevStarted(duration_);
    }

    function startRev() external {
        _checkOwner();

        if (revStart == 0) {
            revStart = block.timestamp;

            emit RevStarted(revEpochDuration);
        }
    }

    // PUB/EXTERNAL

    function burn(uint256 amount) external {
        _burn(msg.sender, amount);
    }

    // PRV/INTERNAL

    function _transfer(
        address from_,
        address to_,
        uint256 amount_
    ) internal override {
        if (from_ == address(0)) _revert(TransferFromZeroAddr.selector);
        if (to_ == address(0)) _revert(TransferToZeroAddr.selector);

        Flags memory fromFlags = flags[from_];
        Flags memory toFlags = flags[to_];

        if (fromFlags.blacklisted) _revert(BlacklistedFrom.selector);
        if (toFlags.blacklisted) _revert(BlacklistedTo.selector);

        if (amount_ == 0) return super._transfer(from_, to_, 0);

        uint256 cachedTradingStart = tradingStartedAt;
        bool notSwapping = _swapping == _NOT_SWAPPING;
        address owner = owner();

        if (
            from_ != owner &&
            to_ != owner &&
            to_ != address(0) &&
            notSwapping
        ) _secureTransfer(
            cachedTradingStart,
            amount_,
            fromFlags,
            toFlags,
            to_
        );

        bool canSwap = balanceOf(address(this)) >= swapTokensAtAmount;

        if (
            canSwap &&
            notSwapping &&
            !fromFlags.isAmmp &&
            !fromFlags.feeExcluded &&
            !toFlags.feeExcluded
        ) {
            _swapping = _SWAPPING;

            _swapBack();

            _swapping = _NOT_SWAPPING;
        }

        bool takeFee = !fromFlags.feeExcluded && !toFlags.feeExcluded && notSwapping;

        if (takeFee) {
            uint256 fees = amount_ * _getFeeRates(
                cachedTradingStart,
                from_,
                to_,
                fromFlags.isAmmp,
                toFlags.isAmmp
            ) / _FEE_BASE;

            amount_ -= fees;

            if (fees > 0) super._transfer(from_, address(this), fees);
        }

        if (revStart != 0) {
            _processRevAccrual(from_, fromFlags.isAmmp);
            _processRevAccrual(to_, toFlags.isAmmp);
        }

        super._transfer(from_, to_, amount_);
    }

    function _secureTransfer(
        uint256 tradingStart_,
        uint256 amount_,
        Flags memory fromFlags_,
        Flags memory toFlags_,
        address to_
    ) internal view {
        if (tradingStart_ == 0)
            if (!fromFlags_.feeExcluded && !toFlags_.feeExcluded)
                _revert(TradingNotActive.selector);

        if (fromFlags_.isAmmp && !toFlags_.maxExcluded) {
            // buying
            if (amount_ > maxTradingAmount)
                _revert(AmountExceedsMax.selector);
            if (amount_ + balanceOf(to_) > maxWallet)
                _revert(MaxWalletReached.selector);
        } else if (toFlags_.isAmmp && !fromFlags_.maxExcluded) {
            // selling
            if (amount_ > maxTradingAmount)
                _revert(AmountExceedsMax.selector);
        } else if (!toFlags_.maxExcluded) {
            // transfer
            if (amount_ + balanceOf(to_) > maxWallet)
                _revert(MaxWalletReached.selector);
        }
    }

    function _getFeeRates(
        uint256 tradingStart_,
        address from_,
        address to_,
        bool fromAmmp_,
        bool toAmmp_
    ) internal returns (uint256) {
        unchecked {
            // Flagged uh uh!
            if (flags[from_].flaggedBot) return _FLAG_TAX;

            // Regular fees applied, short path
            if (block.timestamp > tradingStart_ + _STAGE2_TIME) {
                // Buying
                if (fromAmmp_) return buyFees;
                // Selling
                if (toAmmp_) return sellFees;
                // Transfer
                return 0;
            }

            if (fromAmmp_ && block.number <= tradingBlock + _FLAG_B)
                // Flagged uh uh!
                flags[to_].flaggedBot = true;

            // First mins of trading, lauch fees applied on buy/sell
            if (fromAmmp_ || toAmmp_) return _launchFeeRates(tradingStart_);

            // Transfer launch fees
            return 0;
        }
    }

    function _launchFeeRates(
        uint256 tradingStart_
    ) internal view returns (uint256) {
        if (block.timestamp > tradingStart_ + _STAGE1_TIME)
            return _feesStage2;

        return  _feesStage1;
    }

    // Used offchain to weight user holdings, snapshots the previous balance
    function _processRevAccrual(
        address holder_,
        bool isAMMP_
    ) private {
        if (isAMMP_) return;

        uint256 balance = balanceOf(holder_);

        if (balance < revMinHoldings) return;

        emit Accrued(holder_, balance);
    }

    function _swapTokensForEth(uint256 amount_) private {
        IUniswapV2Router cachedRouter = uniswapV2Router;

        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = cachedRouter.WETH();

        _approve(address(this), address(cachedRouter), amount_);

        cachedRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
            amount_,
            0,
            path,
            address(this),
            block.timestamp
        );
    }

    function _swapBack() private {
        uint256 toSwap = balanceOf(address(this));

        if (toSwap == 0) return;

        uint256 cachedMaxSwapTokens = maxSwapTokens;

        if (toSwap > cachedMaxSwapTokens)
            toSwap = cachedMaxSwapTokens;

        uint256 initialETHBalance = address(this).balance;

        _swapTokensForEth(toSwap);

        uint256 marketETH;
        uint256 revETH;
        uint256 teamETH;

        // Cannot OF since no ETH is sent during swap, worse case would be receiving 0 => bal - bal = 0
        unchecked {
            uint256 ethBalance = address(this).balance - initialETHBalance;

            // OF here would require an incredibly huge amount of ETH,
            // see if leaving it checked anyway
            marketETH = ethBalance * marketFee / _FEE_BASE;
            revETH = ethBalance * revFee / _FEE_BASE;
            teamETH = ethBalance - marketETH - revETH;
        }

        bool success;

        (success, ) = address(marketWallet).call{value: marketETH}("");
        (success, ) = address(revWallet).call{value: revETH}("");
        (success, ) = address(teamWallet).call{value: teamETH}("");
    }

    function _addLiquidity(uint256 tokenAmount, uint256 ethAmount) private {
        _approve(address(this), address(uniswapV2Router), tokenAmount);

        uniswapV2Router.addLiquidityETH{value: ethAmount}(
            address(this),
            tokenAmount,
            0,
            0,
            msg.sender,
            block.timestamp
        );
    }

    function _revert(bytes4 code_) private pure {
        assembly {
            mstore(0x0, code_)
            revert(0x0, 0x4)
        }
    }
}

File 2 of 6 : ERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.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}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * 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 ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

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

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        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 override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

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

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` 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 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * 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 `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `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.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(address from, address to, uint256 amount) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
            // decrementing then incrementing.
            _balances[to] += amount;
        }

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        unchecked {
            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
            _balances[account] += amount;
        }
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
            // Overflow not possible: amount <= accountBalance <= totalSupply.
            _totalSupply -= amount;
        }

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` 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.
     */
    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);
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}
}

File 3 of 6 : Ownable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Simple single owner authorization mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)
///
/// @dev Note:
/// This implementation does NOT auto-initialize the owner to `msg.sender`.
/// You MUST call the `_initializeOwner` in the constructor / initializer.
///
/// While the ownable portion follows
/// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility,
/// the nomenclature for the 2-step ownership handover may be unique to this codebase.
abstract contract Ownable {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The caller is not authorized to call the function.
    error Unauthorized();

    /// @dev The `newOwner` cannot be the zero address.
    error NewOwnerIsZeroAddress();

    /// @dev The `pendingOwner` does not have a valid handover request.
    error NoHandoverRequest();

    /// @dev Cannot double-initialize.
    error AlreadyInitialized();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                           EVENTS                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The ownership is transferred from `oldOwner` to `newOwner`.
    /// This event is intentionally kept the same as OpenZeppelin's Ownable to be
    /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),
    /// despite it not being as lightweight as a single argument event.
    event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);

    /// @dev An ownership handover to `pendingOwner` has been requested.
    event OwnershipHandoverRequested(address indexed pendingOwner);

    /// @dev The ownership handover to `pendingOwner` has been canceled.
    event OwnershipHandoverCanceled(address indexed pendingOwner);

    /// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`.
    uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =
        0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;

    /// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`.
    uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =
        0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;

    /// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`.
    uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =
        0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                          STORAGE                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The owner slot is given by:
    /// `bytes32(~uint256(uint32(bytes4(keccak256("_OWNER_SLOT_NOT")))))`.
    /// It is intentionally chosen to be a high value
    /// to avoid collision with lower slots.
    /// The choice of manual storage layout is to enable compatibility
    /// with both regular and upgradeable contracts.
    bytes32 internal constant _OWNER_SLOT =
        0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927;

    /// The ownership handover slot of `newOwner` is given by:
    /// ```
    ///     mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))
    ///     let handoverSlot := keccak256(0x00, 0x20)
    /// ```
    /// It stores the expiry timestamp of the two-step ownership handover.
    uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     INTERNAL FUNCTIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Override to return true to make `_initializeOwner` prevent double-initialization.
    function _guardInitializeOwner() internal pure virtual returns (bool guard) {}

    /// @dev Initializes the owner directly without authorization guard.
    /// This function must be called upon initialization,
    /// regardless of whether the contract is upgradeable or not.
    /// This is to enable generalization to both regular and upgradeable contracts,
    /// and to save gas in case the initial owner is not the caller.
    /// For performance reasons, this function will not check if there
    /// is an existing owner.
    function _initializeOwner(address newOwner) internal virtual {
        if (_guardInitializeOwner()) {
            /// @solidity memory-safe-assembly
            assembly {
                let ownerSlot := _OWNER_SLOT
                if sload(ownerSlot) {
                    mstore(0x00, 0x0dc149f0) // `AlreadyInitialized()`.
                    revert(0x1c, 0x04)
                }
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Store the new value.
                sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
            }
        } else {
            /// @solidity memory-safe-assembly
            assembly {
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Store the new value.
                sstore(_OWNER_SLOT, newOwner)
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
            }
        }
    }

    /// @dev Sets the owner directly without authorization guard.
    function _setOwner(address newOwner) internal virtual {
        if (_guardInitializeOwner()) {
            /// @solidity memory-safe-assembly
            assembly {
                let ownerSlot := _OWNER_SLOT
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
                // Store the new value.
                sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
            }
        } else {
            /// @solidity memory-safe-assembly
            assembly {
                let ownerSlot := _OWNER_SLOT
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
                // Store the new value.
                sstore(ownerSlot, newOwner)
            }
        }
    }

    /// @dev Throws if the sender is not the owner.
    function _checkOwner() internal view virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // If the caller is not the stored owner, revert.
            if iszero(eq(caller(), sload(_OWNER_SLOT))) {
                mstore(0x00, 0x82b42900) // `Unauthorized()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Returns how long a two-step ownership handover is valid for in seconds.
    /// Override to return a different value if needed.
    /// Made internal to conserve bytecode. Wrap it in a public function if needed.
    function _ownershipHandoverValidFor() internal view virtual returns (uint64) {
        return 48 * 3600;
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                  PUBLIC UPDATE FUNCTIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Allows the owner to transfer the ownership to `newOwner`.
    function transferOwnership(address newOwner) public payable virtual onlyOwner {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(shl(96, newOwner)) {
                mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`.
                revert(0x1c, 0x04)
            }
        }
        _setOwner(newOwner);
    }

    /// @dev Allows the owner to renounce their ownership.
    function renounceOwnership() public payable virtual onlyOwner {
        _setOwner(address(0));
    }

    /// @dev Request a two-step ownership handover to the caller.
    /// The request will automatically expire in 48 hours (172800 seconds) by default.
    function requestOwnershipHandover() public payable virtual {
        unchecked {
            uint256 expires = block.timestamp + _ownershipHandoverValidFor();
            /// @solidity memory-safe-assembly
            assembly {
                // Compute and set the handover slot to `expires`.
                mstore(0x0c, _HANDOVER_SLOT_SEED)
                mstore(0x00, caller())
                sstore(keccak256(0x0c, 0x20), expires)
                // Emit the {OwnershipHandoverRequested} event.
                log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())
            }
        }
    }

    /// @dev Cancels the two-step ownership handover to the caller, if any.
    function cancelOwnershipHandover() public payable virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and set the handover slot to 0.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, caller())
            sstore(keccak256(0x0c, 0x20), 0)
            // Emit the {OwnershipHandoverCanceled} event.
            log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())
        }
    }

    /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`.
    /// Reverts if there is no existing ownership handover requested by `pendingOwner`.
    function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and set the handover slot to 0.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, pendingOwner)
            let handoverSlot := keccak256(0x0c, 0x20)
            // If the handover does not exist, or has expired.
            if gt(timestamp(), sload(handoverSlot)) {
                mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`.
                revert(0x1c, 0x04)
            }
            // Set the handover slot to 0.
            sstore(handoverSlot, 0)
        }
        _setOwner(pendingOwner);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   PUBLIC READ FUNCTIONS                    */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the owner of the contract.
    function owner() public view virtual returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := sload(_OWNER_SLOT)
        }
    }

    /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.
    function ownershipHandoverExpiresAt(address pendingOwner)
        public
        view
        virtual
        returns (uint256 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the handover slot.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, pendingOwner)
            // Load the handover slot.
            result := sload(keccak256(0x0c, 0x20))
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         MODIFIERS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Marks a function as only callable by the owner.
    modifier onlyOwner() virtual {
        _checkOwner();
        _;
    }
}

File 4 of 6 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (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;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

File 5 of 6 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

File 6 of 6 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @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);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @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 `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount) external returns (bool);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 500
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"payable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"AmountExceedsMax","type":"error"},{"inputs":[],"name":"BlacklistedFrom","type":"error"},{"inputs":[],"name":"BlacklistedTo","type":"error"},{"inputs":[],"name":"BuySellFeesTooHigh","type":"error"},{"inputs":[],"name":"CannotBlacklist","type":"error"},{"inputs":[],"name":"CannotBlacklistUni","type":"error"},{"inputs":[],"name":"CannotRemoveFromAMMPair","type":"error"},{"inputs":[],"name":"FeeDistributionTooHigh","type":"error"},{"inputs":[],"name":"MaxSwapTokensTooLow","type":"error"},{"inputs":[],"name":"MaxTradingAmountTooLow","type":"error"},{"inputs":[],"name":"MaxWalletAmountTooLow","type":"error"},{"inputs":[],"name":"MaxWalletReached","type":"error"},{"inputs":[],"name":"MhhAreYouOk","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"RevokedBlacklist","type":"error"},{"inputs":[],"name":"SwapAmountTooLow","type":"error"},{"inputs":[],"name":"TradingNotActive","type":"error"},{"inputs":[],"name":"TransferFromZeroAddr","type":"error"},{"inputs":[],"name":"TransferToZeroAddr","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"ZeroTokenAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Accrued","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"bool","name":"value","type":"bool"}],"name":"AutomatedMarkerPairUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lpAddr","type":"address"},{"indexed":false,"internalType":"bool","name":"value","type":"bool"}],"name":"BlacklistLpUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"bool","name":"value","type":"bool"}],"name":"BlacklistUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"ExcludeFromFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"bool","name":"isEx","type":"bool"}],"name":"ExcludedFromMaxTrading","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"MarketWalletUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"min","type":"uint256"}],"name":"RevMinHoldingUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"RevStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"RevWalletUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"addr","type":"address"}],"name":"TeamWalletUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blacklistRenounced","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"buyFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr_","type":"address"},{"internalType":"bool","name":"excluded_","type":"bool"}],"name":"excludeFromFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr_","type":"address"},{"internalType":"bool","name":"isEx_","type":"bool"}],"name":"excludeFromMaxTrading","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"flags","outputs":[{"internalType":"bool","name":"feeExcluded","type":"bool"},{"internalType":"bool","name":"isAmmp","type":"bool"},{"internalType":"bool","name":"blacklisted","type":"bool"},{"internalType":"bool","name":"flaggedBot","type":"bool"},{"internalType":"bool","name":"maxExcluded","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"init","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"marketFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSwapTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTradingAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"revEpochDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"revFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"revMinHoldings","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"revStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"revWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sellFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair_","type":"address"},{"internalType":"bool","name":"value_","type":"bool"}],"name":"setAutomatedMarketMakerPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startNow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startRev","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapTokensAtAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"teamFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"teamWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradingBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradingStartedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"uniswapV2Pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapV2Router","outputs":[{"internalType":"contract IUniswapV2Router","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr_","type":"address"},{"internalType":"bool","name":"value_","type":"bool"}],"name":"updateBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr_","type":"address"},{"internalType":"bool","name":"value_","type":"bool"}],"name":"updateBlacklistLp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"marketFee_","type":"uint256"},{"internalType":"uint256","name":"revFee_","type":"uint256"}],"name":"updateFeeDistribution","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"buyFees_","type":"uint256"},{"internalType":"uint256","name":"sellFees_","type":"uint256"}],"name":"updateFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet_","type":"address"}],"name":"updateMarketWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"max_","type":"uint256"}],"name":"updateMaxSwapTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"max_","type":"uint256"}],"name":"updateMaxTradingAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"max_","type":"uint256"}],"name":"updateMaxWalletAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"duration_","type":"uint256"}],"name":"updateRevEpochDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"min_","type":"uint256"}],"name":"updateRevMinHoldings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet_","type":"address"}],"name":"updateRevWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"stage1_","type":"uint256"},{"internalType":"uint256","name":"stage2_","type":"uint256"}],"name":"updateStageFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"updateSwapTokensAtAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet_","type":"address"}],"name":"updateTeamWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"address","name":"to_","type":"address"}],"name":"withdrawStuckERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr_","type":"address"}],"name":"withdrawStuckETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60a06040526127106200001f6a084595161401484a000000601962000632565b6200002b919062000652565b600855612710620000496a084595161401484a000000603262000632565b62000055919062000652565b600955612710620000736a084595161401484a000000601962000632565b6200007f919062000652565b600a556127106200009d6a084595161401484a000000601962000632565b620000a9919062000652565b600b55612710620000c76a084595161401484a000000601462000632565b620000d3919062000652565b600c5562093a80600d55601180546001600160a01b031990811673e4742a92147628ea668b35e245088d31e1292a6b179091556012805482167350349e0a700c4aea3420e3628d175107da3ee7bd17905560138054909116735d4453912dc5c932f2de84cd156f84cd8870a1e817905560016014556032601581905560165560c86017819055601855610258601955604080518082018252600b81526a2bb434b936102a37b5b2b760a91b6020808301919091528251808401909352600583526415d212549360da1b90830152906003620001af83826200070f565b506004620001be82826200070f565b505050620001d2336200051a60201b60201c565b61019060065560c8600755737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b03166080816001600160a01b0316815250506001601a5f737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b03166001600160a01b031681526020019081526020015f205f0160046101000a81548160ff0219169083151502179055506001601a5f73ea07ddbbea804e7fe66b958329f8fa5cda95bd556001600160a01b03166001600160a01b031681526020019081526020015f205f0160046101000a81548160ff0219169083151502179055506001601a5f737cc7e125d83a581ff438608490cc0f7bdff791276001600160a01b03166001600160a01b031681526020019081526020015f205f0160046101000a81548160ff0219169083151502179055506040518060a001604052806001151581526020015f151581526020015f151581526020015f1515815260200160011515815250601a5f336001600160a01b03166001600160a01b031681526020019081526020015f205f820151815f015f6101000a81548160ff0219169083151502179055506020820151815f0160016101000a81548160ff0219169083151502179055506040820151815f0160026101000a81548160ff0219169083151502179055506060820151815f0160036101000a81548160ff0219169083151502179055506080820151815f0160046101000a81548160ff0219169083151502179055509050506040518060a001604052806001151581526020015f151581526020015f151581526020015f1515815260200160011515815250601a5f306001600160a01b03166001600160a01b031681526020019081526020015f205f820151815f015f6101000a81548160ff0219169083151502179055506020820151815f0160016101000a81548160ff0219169083151502179055506040820151815f0160026101000a81548160ff0219169083151502179055506060820151815f0160036101000a81548160ff0219169083151502179055506080820151815f0160046101000a81548160ff02191690831515021790555090505062000514336a02acfdea827d4b498940006a084595161401484a0000006200050e9190620007db565b62000555565b62000807565b6001600160a01b0316638b78c6d819819055805f7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a350565b6001600160a01b038216620005b05760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640160405180910390fd5b8060025f828254620005c39190620007f1565b90915550506001600160a01b0382165f81815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b505050565b634e487b7160e01b5f52601160045260245ffd5b80820281158282048414176200064c576200064c6200061e565b92915050565b5f826200066d57634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806200069b57607f821691505b602082108103620006ba57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156200061957805f5260205f20601f840160051c81016020851015620006e75750805b601f840160051c820191505b8181101562000708575f8155600101620006f3565b5050505050565b81516001600160401b038111156200072b576200072b62000672565b62000743816200073c845462000686565b84620006c0565b602080601f83116001811462000779575f8415620007615750858301515b5f19600386901b1c1916600185901b178555620007d3565b5f85815260208120601f198616915b82811015620007a95788860151825594840194600190910190840162000788565b5085821015620007c757878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b818103818111156200064c576200064c6200061e565b808201808211156200064c576200064c6200061e565b608051612ba9620008435f395f818161046e01528181611627015281816116a50152818161205f015281816120b9015261269c0152612ba95ff3fe6080604052600436106103ab575f3560e01c80638da5cb5b116101e9578063cd51e6d411610108578063e2f456051161009d578063f04e283e1161006d578063f04e283e14610ab6578063f2fde38b14610ac9578063f8b45b0514610adc578063fee81cf414610af1575f80fd5b8063e2f4560514610a4e578063e4440a8614610a63578063e4748b9e14610a82578063edecdae614610a97575f80fd5b8063dcdfe2bc116100d8578063dcdfe2bc146109ce578063dd62ed3e146109ed578063e0f3ccf514610a31578063e1c7392a14610a46575f80fd5b8063cd51e6d414610966578063d201b01e1461097b578063d257b34f1461099a578063d7c94efd146109b9575f80fd5b8063a457c2d71161017e578063c02466681161014e578063c0246668146108fe578063c07736ae1461091d578063c18bc19514610932578063c29eadb214610951575f80fd5b8063a457c2d714610882578063a9059cbb146108a1578063adfa29e5146108c0578063b98fcdce146108df575f80fd5b806396ea32da116101b957806396ea32da146107a75780639a7a23d6146107bc5780639b66731b146107db5780639fef0c01146107fa575f80fd5b80638da5cb5b1461073d5780639155e0831461075557806391ddd7ba1461077457806395d89b4114610793575f80fd5b80633b07b894116102d55780635f1893611161026a578063715018a61161023a578063715018a6146106e25780637cb332bb146106ea5780637d2544ab146107095780637db80d0814610728575f80fd5b80635f1893611461065c57806364f99f82146106705780636db794371461068f57806370a08231146106ae575f80fd5b806349bd5a5e116102a557806349bd5a5e146105f75780634d474d421461061657806354d1f13d14610635578063599270441461063d575f80fd5b80633b07b894146105855780633dc599ff14610599578063422b5bf5146105b957806342966c68146105d8575f80fd5b806321d37e391161034b578063313ce5671161031b578063313ce5671461051757806336a1efe41461053257806338377d0a146105475780633950935114610566575f80fd5b806321d37e39146104bc57806323b872dd146104d157806325692962146104f05780633098db4e146104f8575f80fd5b80630ccf2156116103865780630ccf2156146104325780630e3db9f2146104475780631694505e1461045d57806318160ddd146104a8575f80fd5b806306fdde03146103b6578063091f319c146103e0578063095ea7b314610403575f80fd5b366103b257005b5f80fd5b3480156103c1575f80fd5b506103ca610b22565b6040516103d79190612829565b60405180910390f35b3480156103eb575f80fd5b506103f5600c5481565b6040519081526020016103d7565b34801561040e575f80fd5b5061042261041d366004612889565b610bb2565b60405190151581526020016103d7565b34801561043d575f80fd5b506103f560175481565b348015610452575f80fd5b5061045b610bcb565b005b348015610468575f80fd5b506104907f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016103d7565b3480156104b3575f80fd5b506002546103f5565b3480156104c7575f80fd5b506103f560185481565b3480156104dc575f80fd5b506104226104eb3660046128b3565b610bf5565b61045b610c18565b348015610503575f80fd5b5061045b6105123660046128f1565b610c65565b348015610522575f80fd5b50604051601281526020016103d7565b34801561053d575f80fd5b506103f5600b5481565b348015610552575f80fd5b5061045b6105613660046128f1565b610cc9565b348015610571575f80fd5b50610422610580366004612889565b610cf8565b348015610590575f80fd5b5061045b610d36565b3480156105a4575f80fd5b5060135461042290600160a01b900460ff1681565b3480156105c4575f80fd5b5061045b6105d3366004612908565b610d84565b3480156105e3575f80fd5b5061045b6105f23660046128f1565b610dc3565b348015610602575f80fd5b50600554610490906001600160a01b031681565b348015610621575f80fd5b5061045b610630366004612928565b610dd0565b61045b610e26565b348015610648575f80fd5b50601354610490906001600160a01b031681565b348015610667575f80fd5b5061045b610e5f565b34801561067b575f80fd5b5061045b61068a366004612957565b610e7c565b34801561069a575f80fd5b5061045b6106a9366004612908565b610ef5565b3480156106b9575f80fd5b506103f56106c8366004612928565b6001600160a01b03165f9081526020819052604090205490565b61045b610f2c565b3480156106f5575f80fd5b5061045b610704366004612928565b610f3d565b348015610714575f80fd5b5061045b6107233660046128f1565b610f93565b348015610733575f80fd5b506103f5600e5481565b348015610748575f80fd5b50638b78c6d81954610490565b348015610760575f80fd5b5061045b61076f366004612957565b610fd0565b34801561077f575f80fd5b5061045b61078e366004612908565b6110b3565b34801561079e575f80fd5b506103ca611107565b3480156107b2575f80fd5b506103f560085481565b3480156107c7575f80fd5b5061045b6107d6366004612957565b611116565b3480156107e6575f80fd5b5061045b6107f53660046128f1565b6111a7565b348015610805575f80fd5b50610850610814366004612928565b601a6020525f908152604090205460ff808216916101008104821691620100008204811691630100000081048216916401000000009091041685565b60408051951515865293151560208601529115159284019290925290151560608301521515608082015260a0016103d7565b34801561088d575f80fd5b5061042261089c366004612889565b6111d5565b3480156108ac575f80fd5b506104226108bb366004612889565b61126b565b3480156108cb575f80fd5b5061045b6108da366004612928565b611278565b3480156108ea575f80fd5b5061045b6108f936600461298e565b6112ce565b348015610909575f80fd5b5061045b610918366004612957565b6113d6565b348015610928575f80fd5b506103f5600f5481565b34801561093d575f80fd5b5061045b61094c3660046128f1565b611435565b34801561095c575f80fd5b506103f5600d5481565b348015610971575f80fd5b506103f560105481565b348015610986575f80fd5b5061045b610995366004612928565b611464565b3480156109a5575f80fd5b5061045b6109b43660046128f1565b6114cb565b3480156109c4575f80fd5b506103f560195481565b3480156109d9575f80fd5b5061045b6109e8366004612957565b6114f9565b3480156109f8575f80fd5b506103f5610a0736600461298e565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b348015610a3c575f80fd5b506103f560165481565b61045b6115d0565b348015610a59575f80fd5b506103f5600a5481565b348015610a6e575f80fd5b50601154610490906001600160a01b031681565b348015610a8d575f80fd5b506103f560155481565b348015610aa2575f80fd5b50601254610490906001600160a01b031681565b61045b610ac4366004612928565b611899565b61045b610ad7366004612928565b6118d3565b348015610ae7575f80fd5b506103f560095481565b348015610afc575f80fd5b506103f5610b0b366004612928565b63389a75e1600c9081525f91909152602090205490565b606060038054610b31906129ba565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5d906129ba565b8015610ba85780601f10610b7f57610100808354040283529160200191610ba8565b820191905f5260205f20905b815481529060010190602001808311610b8b57829003601f168201915b5050505050905090565b5f33610bbf8185856118f9565b60019150505b92915050565b610bd3611a1d565b600f5415610beb57610beb63774a291b60e01b611a37565b42600f5543601055565b5f33610c02858285611a3f565b610c0d858585611ac9565b506001949350505050565b5f6202a30067ffffffffffffffff164201905063389a75e1600c52335f52806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f80a250565b610c6d611a1d565b6301e13380811115610c8957610c8963774a291b60e01b611a37565b600d81905542600e556040518181527f091649c18145d9eb5f0cf165c4f06d879cd3e0cc9b172daa5914ec79b3a7b7d3906020015b60405180910390a150565b610cd1611a1d565b69021e19e0c9bab2400000811015610cf357610cf3631df070bd60e11b611a37565b600855565b335f8181526001602090815260408083206001600160a01b0387168452909152812054909190610bbf9082908690610d31908790612a1a565b6118f9565b610d3e611a1d565b600e545f03610d825742600e55600d546040519081527f091649c18145d9eb5f0cf165c4f06d879cd3e0cc9b172daa5914ec79b3a7b7d39060200160405180910390a15b565b610d8c611a1d565b6103e8610d998284612a1a565b1115610daf57610daf6395104ca160e01b611a37565b60178290556018819055016103e803601955565b610dcd3382611e37565b50565b610dd8611a1d565b601180546001600160a01b0319166001600160a01b0383169081179091556040519081527f1bb3fb05b048af71bf27de34a5635a4dd622820cd15b6971f24990a68a82884890602001610cbe565b63389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f80a2565b610e67611a1d565b6013805460ff60a01b1916600160a01b179055565b610e84611a1d565b6001600160a01b0382165f818152601a6020908152604091829020805464ff000000001916640100000000861515908102919091179091558251938452908301527f76c7bbc173883950fee8616f9f2000818bbcd0e917eff135c39c95d9d7baaf7691015b60405180910390a15050565b610efd611a1d565b6064821180610f0c5750606481115b15610f2157610f216319b1b9d560e31b611a37565b601591909155601655565b610f34611a1d565b610d825f611f5f565b610f45611a1d565b601380546001600160a01b0319166001600160a01b0383169081179091556040519081527ff6215f245bfd24e51265c56ef650fdd856aa4ece6221ee1ef395bbe0a555801090602001610cbe565b610f9b611a1d565b600c8190556040518181527fe627cfda1518dcda9892dd9d17a3bf7c0b455556833b4dfc2ba0b6d9ae6e294090602001610cbe565b610fd8611a1d565b601354600160a01b900460ff1615610ffa57610ffa63a5b5b95160e01b611a37565b6005546001600160a01b038381169116148061103257506001600160a01b038216737a250d5630b4cf539739df2c5dacb4c659f2488d145b156110475761104763403c6cdb60e01b611a37565b6001600160a01b0382165f818152601a6020526040908190208054841515620100000262ff000019909116179055517f6a12b3df6cba4203bd7fd06b816789f87de8c594299aed5717ae070fac781bac906110a790841515815260200190565b60405180910390a25050565b6110bb611a1d565b5f6110c960026103e8612a2d565b9050808311156110e3576110e363774a291b60e01b611a37565b808211156110fb576110fb63774a291b60e01b611a37565b50600691909155600755565b606060048054610b31906129ba565b61111e611a1d565b6005546001600160a01b03908116908316036111445761114463f42cc60b60e01b611a37565b6001600160a01b0382165f818152601a6020908152604091829020805461ff001916610100861515908102919091179091558251938452908301527f147e6829bf05f216effd968a961382a7a7c844c3674d97e6cba90c75d02b345b9101610ee9565b6111af611a1d565b683635c9adc5dea000008110156111d0576111d0636b61462560e11b611a37565b600b55565b335f8181526001602090815260408083206001600160a01b03871684529091528120549091908381101561125e5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b610c0d82868684036118f9565b5f33610bbf818585611ac9565b611280611a1d565b601280546001600160a01b0319166001600160a01b0383169081179091556040519081527f5debfde3cdb20722cb44b9572a9a13a02d358c03b2a694ed04819f303d1d375f90602001610cbe565b6112d6611a1d565b6001600160a01b0382166112f4576112f4636b093aad60e01b611a37565b6040516370a0823160e01b81523060048201525f906001600160a01b038416906370a0823190602401602060405180830381865afa158015611338573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061135c9190612a4c565b60405163a9059cbb60e01b81526001600160a01b038481166004830152602482018390529192509084169063a9059cbb906044016020604051808303815f875af11580156113ac573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113d09190612a63565b50505050565b6113de611a1d565b6001600160a01b0382165f818152601a6020908152604091829020805460ff191685151590811790915591519182527f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df791016110a7565b61143d611a1d565b69152d02c7e14af680000081101561145f5761145f631266cf8d60e11b611a37565b600955565b61146c611a1d565b5f816001600160a01b0316476040515f6040518083038185875af1925050503d805f81146114b5576040519150601f19603f3d011682016040523d82523d5f602084013e6114ba565b606091505b50509050806114c7575f80fd5b5050565b6114d3611a1d565b68056bc75e2d631000008110156114f4576114f463f570cd7760e01b611a37565b600a55565b611501611a1d565b601354600160a01b900460ff16156115235761152363a5b5b95160e01b611a37565b6005546001600160a01b038381169116148061155b57506001600160a01b038216737a250d5630b4cf539739df2c5dacb4c659f2488d145b156115705761157063403c6cdb60e01b611a37565b6001600160a01b0382165f818152601a6020526040908190208054841515620100000262ff000019909116179055517f1966ca748a5ebecef9311c0af7f5d0641518851f13d364ebb3fb7870a84fe3b6906110a790841515815260200190565b6115d8611a1d565b601354600160a81b900460ff16156115fa576115fa63774a291b60e01b611a37565b6013805460ff60a81b1916600160a81b1790556040805163c45a015560e01b815290516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163c45a01559160048083019260209291908290030181865afa158015611670573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116949190612a7e565b6001600160a01b031663c9c65396307f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116ff573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117239190612a7e565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303815f875af1158015611785573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117a99190612a7e565b600580546001600160a01b0319166001600160a01b039290921691821790556040805160a0810182525f808252600160208084018281528486018481526060860185815260808701948552978552601a9092529490922092518354945192519551915161ffff1990951690151561ff00191617610100921515929092029190911763ffff00001916620100009415159490940263ff0000001916939093176301000000931515939093029290921764ff00000000191664010000000091151591909102179055611884306a02acfdea827d4b49894000611f9c565b610d826a02acfdea827d4b4989400047612059565b6118a1611a1d565b63389a75e1600c52805f526020600c2080544211156118c757636f5e88185f526004601cfd5b5f9055610dcd81611f5f565b6118db611a1d565b8060601b6118f057637448fbae5f526004601cfd5b610dcd81611f5f565b6001600160a01b03831661195b5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401611255565b6001600160a01b0382166119bc5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401611255565b6001600160a01b038381165f8181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b638b78c6d819543314610d82576382b429005f526004601cfd5b805f5260045ffd5b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f1981146113d05781811015611abc5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401611255565b6113d084848484036118f9565b6001600160a01b038316611ae757611ae763730e5fd160e11b611a37565b6001600160a01b038216611b0557611b05635fb0610d60e11b611a37565b5f601a5f856001600160a01b03166001600160a01b031681526020019081526020015f206040518060a00160405290815f82015f9054906101000a900460ff161515151581526020015f820160019054906101000a900460ff161515151581526020015f820160029054906101000a900460ff161515151581526020015f820160039054906101000a900460ff161515151581526020015f820160049054906101000a900460ff16151515158152505090505f601a5f856001600160a01b03166001600160a01b031681526020019081526020015f206040518060a00160405290815f82015f9054906101000a900460ff161515151581526020015f820160019054906101000a900460ff161515151581526020015f820160029054906101000a900460ff161515151581526020015f820160039054906101000a900460ff161515151581526020015f820160049054906101000a900460ff1615151515815250509050816040015115611c8357611c83631aeaf0db60e01b611a37565b806040015115611c9d57611c9d638623ffef60e01b611a37565b825f03611cb657611caf85855f61212e565b5050505050565b600f546014546001145f611ccd638b78c6d8195490565b9050806001600160a01b0316886001600160a01b031614158015611d035750806001600160a01b0316876001600160a01b031614155b8015611d1757506001600160a01b03871615155b8015611d205750815b15611d3257611d32838787878b6122d0565b600a54305f90815260208190526040902054108015908190611d515750825b8015611d5f57508560200151155b8015611d6a57508551155b8015611d7557508451155b15611d8d576002601455611d876123e2565b60016014555b85515f90158015611d9d57508551155b8015611da65750835b90508015611dfc575f6103e8611dc7878d8d8c602001518c60200151612548565b611dd1908b612a99565b611ddb9190612a2d565b9050611de7818a612ab0565b98508015611dfa57611dfa8b308361212e565b505b600e5415611e2057611e128a8860200151612613565b611e20898760200151612613565b611e2b8a8a8a61212e565b50505050505050505050565b6001600160a01b038216611e975760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401611255565b6001600160a01b0382165f9081526020819052604090205481811015611f0a5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401611255565b6001600160a01b0383165f818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101611a10565b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a355565b6001600160a01b038216611ff25760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401611255565b8060025f8282546120039190612a1a565b90915550506001600160a01b0382165f81815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b612084307f0000000000000000000000000000000000000000000000000000000000000000846118f9565b60405163f305d71960e01b8152306004820152602481018390525f6044820181905260648201523360848201524260a48201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f305d71990839060c40160606040518083038185885af1158015612109573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190611caf9190612ac3565b6001600160a01b0383166121925760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401611255565b6001600160a01b0382166121f45760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401611255565b6001600160a01b0383165f908152602081905260409020548181101561226b5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401611255565b6001600160a01b038481165f81815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36113d0565b845f036122fa5782511580156122e557508151155b156122fa576122fa632924508760e21b611a37565b8260200151801561230d57508160800151155b1561236c5760085484111561232c5761232c63070b5a6f60e21b611a37565b6009546001600160a01b0382165f908152602081905260409020546123519086612a1a565b111561236757612367633ce8c2bd60e11b611a37565b611caf565b8160200151801561237f57508260800151155b1561239e576008548411156123675761236763070b5a6f60e21b611a37565b8160800151611caf576009546001600160a01b0382165f908152602081905260409020546123cc9086612a1a565b1115611caf57611caf633ce8c2bd60e11b611a37565b305f90815260208190526040812054908190036123fc5750565b600b548082111561240b578091505b476124158361268b565b5f805f8084470390506103e8601754820281612433576124336129f2565b0493506103e860185482028161244b5761244b6129f2565b6011546040519290910494509185900384900392505f916001600160a01b03169085908381818185875af1925050503d805f81146124a4576040519150601f19603f3d011682016040523d82523d5f602084013e6124a9565b606091505b50506012546040519192506001600160a01b03169084905f81818185875af1925050503d805f81146124f6576040519150601f19603f3d011682016040523d82523d5f602084013e6124fb565b606091505b50506013546040519192506001600160a01b03169083905f81818185875af1925050503d805f8114611e2b576040519150601f19603f3d011682016040523d82523d5f602084013e611e2b565b6001600160a01b0384165f908152601a60205260408120546301000000900460ff1615612578575061019061260a565b61012c86014211156125a9578215612593575060155461260a565b81156125a2575060165461260a565b505f61260a565b8280156125bb57506002601054014311155b156125e9576001600160a01b0384165f908152601a60205260409020805463ff000000191663010000001790555b82806125f25750815b156126075761260086612806565b905061260a565b505f5b95945050505050565b801561261d575050565b6001600160a01b0382165f90815260208190526040902054600c5481101561264457505050565b604080516001600160a01b0385168152602081018390527f603f16706d8facbdadddadc2f84737909caebc5d1f3adf53d69014f2d908611c910160405180910390a1505050565b6040805160028082526060820183527f0000000000000000000000000000000000000000000000000000000000000000925f92919060208301908036833701905050905030815f815181106126e2576126e2612aee565b60200260200101906001600160a01b031690816001600160a01b031681525050816001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801561273e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127629190612a7e565b8160018151811061277557612775612aee565b60200260200101906001600160a01b031690816001600160a01b0316815250506127a03083856118f9565b60405163791ac94760e01b81526001600160a01b0383169063791ac947906127d49086905f90869030904290600401612b02565b5f604051808303815f87803b1580156127eb575f80fd5b505af11580156127fd573d5f803e3d5ffd5b50505050505050565b5f612812602d83612a1a565b42111561282157505060075490565b505060065490565b5f602080835283518060208501525f5b8181101561285557858101830151858201604001528201612839565b505f604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b0381168114610dcd575f80fd5b5f806040838503121561289a575f80fd5b82356128a581612875565b946020939093013593505050565b5f805f606084860312156128c5575f80fd5b83356128d081612875565b925060208401356128e081612875565b929592945050506040919091013590565b5f60208284031215612901575f80fd5b5035919050565b5f8060408385031215612919575f80fd5b50508035926020909101359150565b5f60208284031215612938575f80fd5b813561294381612875565b9392505050565b8015158114610dcd575f80fd5b5f8060408385031215612968575f80fd5b823561297381612875565b915060208301356129838161294a565b809150509250929050565b5f806040838503121561299f575f80fd5b82356129aa81612875565b9150602083013561298381612875565b600181811c908216806129ce57607f821691505b6020821081036129ec57634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b80820180821115610bc557610bc5612a06565b5f82612a4757634e487b7160e01b5f52601260045260245ffd5b500490565b5f60208284031215612a5c575f80fd5b5051919050565b5f60208284031215612a73575f80fd5b81516129438161294a565b5f60208284031215612a8e575f80fd5b815161294381612875565b8082028115828204841417610bc557610bc5612a06565b81810381811115610bc557610bc5612a06565b5f805f60608486031215612ad5575f80fd5b8351925060208401519150604084015190509250925092565b634e487b7160e01b5f52603260045260245ffd5b5f60a08201878352602087602085015260a0604085015281875180845260c0860191506020890193505f5b81811015612b525784516001600160a01b031683529383019391830191600101612b2d565b50506001600160a01b0396909616606085015250505060800152939250505056fea264697066735822122066923d30d4d0cbd43d16edcd59efe5b39b50b0bbd658e4d98c5202528a6815ea64736f6c63430008160033

Deployed Bytecode

0x6080604052600436106103ab575f3560e01c80638da5cb5b116101e9578063cd51e6d411610108578063e2f456051161009d578063f04e283e1161006d578063f04e283e14610ab6578063f2fde38b14610ac9578063f8b45b0514610adc578063fee81cf414610af1575f80fd5b8063e2f4560514610a4e578063e4440a8614610a63578063e4748b9e14610a82578063edecdae614610a97575f80fd5b8063dcdfe2bc116100d8578063dcdfe2bc146109ce578063dd62ed3e146109ed578063e0f3ccf514610a31578063e1c7392a14610a46575f80fd5b8063cd51e6d414610966578063d201b01e1461097b578063d257b34f1461099a578063d7c94efd146109b9575f80fd5b8063a457c2d71161017e578063c02466681161014e578063c0246668146108fe578063c07736ae1461091d578063c18bc19514610932578063c29eadb214610951575f80fd5b8063a457c2d714610882578063a9059cbb146108a1578063adfa29e5146108c0578063b98fcdce146108df575f80fd5b806396ea32da116101b957806396ea32da146107a75780639a7a23d6146107bc5780639b66731b146107db5780639fef0c01146107fa575f80fd5b80638da5cb5b1461073d5780639155e0831461075557806391ddd7ba1461077457806395d89b4114610793575f80fd5b80633b07b894116102d55780635f1893611161026a578063715018a61161023a578063715018a6146106e25780637cb332bb146106ea5780637d2544ab146107095780637db80d0814610728575f80fd5b80635f1893611461065c57806364f99f82146106705780636db794371461068f57806370a08231146106ae575f80fd5b806349bd5a5e116102a557806349bd5a5e146105f75780634d474d421461061657806354d1f13d14610635578063599270441461063d575f80fd5b80633b07b894146105855780633dc599ff14610599578063422b5bf5146105b957806342966c68146105d8575f80fd5b806321d37e391161034b578063313ce5671161031b578063313ce5671461051757806336a1efe41461053257806338377d0a146105475780633950935114610566575f80fd5b806321d37e39146104bc57806323b872dd146104d157806325692962146104f05780633098db4e146104f8575f80fd5b80630ccf2156116103865780630ccf2156146104325780630e3db9f2146104475780631694505e1461045d57806318160ddd146104a8575f80fd5b806306fdde03146103b6578063091f319c146103e0578063095ea7b314610403575f80fd5b366103b257005b5f80fd5b3480156103c1575f80fd5b506103ca610b22565b6040516103d79190612829565b60405180910390f35b3480156103eb575f80fd5b506103f5600c5481565b6040519081526020016103d7565b34801561040e575f80fd5b5061042261041d366004612889565b610bb2565b60405190151581526020016103d7565b34801561043d575f80fd5b506103f560175481565b348015610452575f80fd5b5061045b610bcb565b005b348015610468575f80fd5b506104907f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d81565b6040516001600160a01b0390911681526020016103d7565b3480156104b3575f80fd5b506002546103f5565b3480156104c7575f80fd5b506103f560185481565b3480156104dc575f80fd5b506104226104eb3660046128b3565b610bf5565b61045b610c18565b348015610503575f80fd5b5061045b6105123660046128f1565b610c65565b348015610522575f80fd5b50604051601281526020016103d7565b34801561053d575f80fd5b506103f5600b5481565b348015610552575f80fd5b5061045b6105613660046128f1565b610cc9565b348015610571575f80fd5b50610422610580366004612889565b610cf8565b348015610590575f80fd5b5061045b610d36565b3480156105a4575f80fd5b5060135461042290600160a01b900460ff1681565b3480156105c4575f80fd5b5061045b6105d3366004612908565b610d84565b3480156105e3575f80fd5b5061045b6105f23660046128f1565b610dc3565b348015610602575f80fd5b50600554610490906001600160a01b031681565b348015610621575f80fd5b5061045b610630366004612928565b610dd0565b61045b610e26565b348015610648575f80fd5b50601354610490906001600160a01b031681565b348015610667575f80fd5b5061045b610e5f565b34801561067b575f80fd5b5061045b61068a366004612957565b610e7c565b34801561069a575f80fd5b5061045b6106a9366004612908565b610ef5565b3480156106b9575f80fd5b506103f56106c8366004612928565b6001600160a01b03165f9081526020819052604090205490565b61045b610f2c565b3480156106f5575f80fd5b5061045b610704366004612928565b610f3d565b348015610714575f80fd5b5061045b6107233660046128f1565b610f93565b348015610733575f80fd5b506103f5600e5481565b348015610748575f80fd5b50638b78c6d81954610490565b348015610760575f80fd5b5061045b61076f366004612957565b610fd0565b34801561077f575f80fd5b5061045b61078e366004612908565b6110b3565b34801561079e575f80fd5b506103ca611107565b3480156107b2575f80fd5b506103f560085481565b3480156107c7575f80fd5b5061045b6107d6366004612957565b611116565b3480156107e6575f80fd5b5061045b6107f53660046128f1565b6111a7565b348015610805575f80fd5b50610850610814366004612928565b601a6020525f908152604090205460ff808216916101008104821691620100008204811691630100000081048216916401000000009091041685565b60408051951515865293151560208601529115159284019290925290151560608301521515608082015260a0016103d7565b34801561088d575f80fd5b5061042261089c366004612889565b6111d5565b3480156108ac575f80fd5b506104226108bb366004612889565b61126b565b3480156108cb575f80fd5b5061045b6108da366004612928565b611278565b3480156108ea575f80fd5b5061045b6108f936600461298e565b6112ce565b348015610909575f80fd5b5061045b610918366004612957565b6113d6565b348015610928575f80fd5b506103f5600f5481565b34801561093d575f80fd5b5061045b61094c3660046128f1565b611435565b34801561095c575f80fd5b506103f5600d5481565b348015610971575f80fd5b506103f560105481565b348015610986575f80fd5b5061045b610995366004612928565b611464565b3480156109a5575f80fd5b5061045b6109b43660046128f1565b6114cb565b3480156109c4575f80fd5b506103f560195481565b3480156109d9575f80fd5b5061045b6109e8366004612957565b6114f9565b3480156109f8575f80fd5b506103f5610a0736600461298e565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205490565b348015610a3c575f80fd5b506103f560165481565b61045b6115d0565b348015610a59575f80fd5b506103f5600a5481565b348015610a6e575f80fd5b50601154610490906001600160a01b031681565b348015610a8d575f80fd5b506103f560155481565b348015610aa2575f80fd5b50601254610490906001600160a01b031681565b61045b610ac4366004612928565b611899565b61045b610ad7366004612928565b6118d3565b348015610ae7575f80fd5b506103f560095481565b348015610afc575f80fd5b506103f5610b0b366004612928565b63389a75e1600c9081525f91909152602090205490565b606060038054610b31906129ba565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5d906129ba565b8015610ba85780601f10610b7f57610100808354040283529160200191610ba8565b820191905f5260205f20905b815481529060010190602001808311610b8b57829003601f168201915b5050505050905090565b5f33610bbf8185856118f9565b60019150505b92915050565b610bd3611a1d565b600f5415610beb57610beb63774a291b60e01b611a37565b42600f5543601055565b5f33610c02858285611a3f565b610c0d858585611ac9565b506001949350505050565b5f6202a30067ffffffffffffffff164201905063389a75e1600c52335f52806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f80a250565b610c6d611a1d565b6301e13380811115610c8957610c8963774a291b60e01b611a37565b600d81905542600e556040518181527f091649c18145d9eb5f0cf165c4f06d879cd3e0cc9b172daa5914ec79b3a7b7d3906020015b60405180910390a150565b610cd1611a1d565b69021e19e0c9bab2400000811015610cf357610cf3631df070bd60e11b611a37565b600855565b335f8181526001602090815260408083206001600160a01b0387168452909152812054909190610bbf9082908690610d31908790612a1a565b6118f9565b610d3e611a1d565b600e545f03610d825742600e55600d546040519081527f091649c18145d9eb5f0cf165c4f06d879cd3e0cc9b172daa5914ec79b3a7b7d39060200160405180910390a15b565b610d8c611a1d565b6103e8610d998284612a1a565b1115610daf57610daf6395104ca160e01b611a37565b60178290556018819055016103e803601955565b610dcd3382611e37565b50565b610dd8611a1d565b601180546001600160a01b0319166001600160a01b0383169081179091556040519081527f1bb3fb05b048af71bf27de34a5635a4dd622820cd15b6971f24990a68a82884890602001610cbe565b63389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f80a2565b610e67611a1d565b6013805460ff60a01b1916600160a01b179055565b610e84611a1d565b6001600160a01b0382165f818152601a6020908152604091829020805464ff000000001916640100000000861515908102919091179091558251938452908301527f76c7bbc173883950fee8616f9f2000818bbcd0e917eff135c39c95d9d7baaf7691015b60405180910390a15050565b610efd611a1d565b6064821180610f0c5750606481115b15610f2157610f216319b1b9d560e31b611a37565b601591909155601655565b610f34611a1d565b610d825f611f5f565b610f45611a1d565b601380546001600160a01b0319166001600160a01b0383169081179091556040519081527ff6215f245bfd24e51265c56ef650fdd856aa4ece6221ee1ef395bbe0a555801090602001610cbe565b610f9b611a1d565b600c8190556040518181527fe627cfda1518dcda9892dd9d17a3bf7c0b455556833b4dfc2ba0b6d9ae6e294090602001610cbe565b610fd8611a1d565b601354600160a01b900460ff1615610ffa57610ffa63a5b5b95160e01b611a37565b6005546001600160a01b038381169116148061103257506001600160a01b038216737a250d5630b4cf539739df2c5dacb4c659f2488d145b156110475761104763403c6cdb60e01b611a37565b6001600160a01b0382165f818152601a6020526040908190208054841515620100000262ff000019909116179055517f6a12b3df6cba4203bd7fd06b816789f87de8c594299aed5717ae070fac781bac906110a790841515815260200190565b60405180910390a25050565b6110bb611a1d565b5f6110c960026103e8612a2d565b9050808311156110e3576110e363774a291b60e01b611a37565b808211156110fb576110fb63774a291b60e01b611a37565b50600691909155600755565b606060048054610b31906129ba565b61111e611a1d565b6005546001600160a01b03908116908316036111445761114463f42cc60b60e01b611a37565b6001600160a01b0382165f818152601a6020908152604091829020805461ff001916610100861515908102919091179091558251938452908301527f147e6829bf05f216effd968a961382a7a7c844c3674d97e6cba90c75d02b345b9101610ee9565b6111af611a1d565b683635c9adc5dea000008110156111d0576111d0636b61462560e11b611a37565b600b55565b335f8181526001602090815260408083206001600160a01b03871684529091528120549091908381101561125e5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b610c0d82868684036118f9565b5f33610bbf818585611ac9565b611280611a1d565b601280546001600160a01b0319166001600160a01b0383169081179091556040519081527f5debfde3cdb20722cb44b9572a9a13a02d358c03b2a694ed04819f303d1d375f90602001610cbe565b6112d6611a1d565b6001600160a01b0382166112f4576112f4636b093aad60e01b611a37565b6040516370a0823160e01b81523060048201525f906001600160a01b038416906370a0823190602401602060405180830381865afa158015611338573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061135c9190612a4c565b60405163a9059cbb60e01b81526001600160a01b038481166004830152602482018390529192509084169063a9059cbb906044016020604051808303815f875af11580156113ac573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113d09190612a63565b50505050565b6113de611a1d565b6001600160a01b0382165f818152601a6020908152604091829020805460ff191685151590811790915591519182527f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df791016110a7565b61143d611a1d565b69152d02c7e14af680000081101561145f5761145f631266cf8d60e11b611a37565b600955565b61146c611a1d565b5f816001600160a01b0316476040515f6040518083038185875af1925050503d805f81146114b5576040519150601f19603f3d011682016040523d82523d5f602084013e6114ba565b606091505b50509050806114c7575f80fd5b5050565b6114d3611a1d565b68056bc75e2d631000008110156114f4576114f463f570cd7760e01b611a37565b600a55565b611501611a1d565b601354600160a01b900460ff16156115235761152363a5b5b95160e01b611a37565b6005546001600160a01b038381169116148061155b57506001600160a01b038216737a250d5630b4cf539739df2c5dacb4c659f2488d145b156115705761157063403c6cdb60e01b611a37565b6001600160a01b0382165f818152601a6020526040908190208054841515620100000262ff000019909116179055517f1966ca748a5ebecef9311c0af7f5d0641518851f13d364ebb3fb7870a84fe3b6906110a790841515815260200190565b6115d8611a1d565b601354600160a81b900460ff16156115fa576115fa63774a291b60e01b611a37565b6013805460ff60a81b1916600160a81b1790556040805163c45a015560e01b815290516001600160a01b037f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d169163c45a01559160048083019260209291908290030181865afa158015611670573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116949190612a7e565b6001600160a01b031663c9c65396307f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116ff573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117239190612a7e565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303815f875af1158015611785573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117a99190612a7e565b600580546001600160a01b0319166001600160a01b039290921691821790556040805160a0810182525f808252600160208084018281528486018481526060860185815260808701948552978552601a9092529490922092518354945192519551915161ffff1990951690151561ff00191617610100921515929092029190911763ffff00001916620100009415159490940263ff0000001916939093176301000000931515939093029290921764ff00000000191664010000000091151591909102179055611884306a02acfdea827d4b49894000611f9c565b610d826a02acfdea827d4b4989400047612059565b6118a1611a1d565b63389a75e1600c52805f526020600c2080544211156118c757636f5e88185f526004601cfd5b5f9055610dcd81611f5f565b6118db611a1d565b8060601b6118f057637448fbae5f526004601cfd5b610dcd81611f5f565b6001600160a01b03831661195b5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401611255565b6001600160a01b0382166119bc5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401611255565b6001600160a01b038381165f8181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b638b78c6d819543314610d82576382b429005f526004601cfd5b805f5260045ffd5b6001600160a01b038381165f908152600160209081526040808320938616835292905220545f1981146113d05781811015611abc5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401611255565b6113d084848484036118f9565b6001600160a01b038316611ae757611ae763730e5fd160e11b611a37565b6001600160a01b038216611b0557611b05635fb0610d60e11b611a37565b5f601a5f856001600160a01b03166001600160a01b031681526020019081526020015f206040518060a00160405290815f82015f9054906101000a900460ff161515151581526020015f820160019054906101000a900460ff161515151581526020015f820160029054906101000a900460ff161515151581526020015f820160039054906101000a900460ff161515151581526020015f820160049054906101000a900460ff16151515158152505090505f601a5f856001600160a01b03166001600160a01b031681526020019081526020015f206040518060a00160405290815f82015f9054906101000a900460ff161515151581526020015f820160019054906101000a900460ff161515151581526020015f820160029054906101000a900460ff161515151581526020015f820160039054906101000a900460ff161515151581526020015f820160049054906101000a900460ff1615151515815250509050816040015115611c8357611c83631aeaf0db60e01b611a37565b806040015115611c9d57611c9d638623ffef60e01b611a37565b825f03611cb657611caf85855f61212e565b5050505050565b600f546014546001145f611ccd638b78c6d8195490565b9050806001600160a01b0316886001600160a01b031614158015611d035750806001600160a01b0316876001600160a01b031614155b8015611d1757506001600160a01b03871615155b8015611d205750815b15611d3257611d32838787878b6122d0565b600a54305f90815260208190526040902054108015908190611d515750825b8015611d5f57508560200151155b8015611d6a57508551155b8015611d7557508451155b15611d8d576002601455611d876123e2565b60016014555b85515f90158015611d9d57508551155b8015611da65750835b90508015611dfc575f6103e8611dc7878d8d8c602001518c60200151612548565b611dd1908b612a99565b611ddb9190612a2d565b9050611de7818a612ab0565b98508015611dfa57611dfa8b308361212e565b505b600e5415611e2057611e128a8860200151612613565b611e20898760200151612613565b611e2b8a8a8a61212e565b50505050505050505050565b6001600160a01b038216611e975760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401611255565b6001600160a01b0382165f9081526020819052604090205481811015611f0a5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401611255565b6001600160a01b0383165f818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101611a10565b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a355565b6001600160a01b038216611ff25760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401611255565b8060025f8282546120039190612a1a565b90915550506001600160a01b0382165f81815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b612084307f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d846118f9565b60405163f305d71960e01b8152306004820152602481018390525f6044820181905260648201523360848201524260a48201527f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b03169063f305d71990839060c40160606040518083038185885af1158015612109573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190611caf9190612ac3565b6001600160a01b0383166121925760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401611255565b6001600160a01b0382166121f45760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401611255565b6001600160a01b0383165f908152602081905260409020548181101561226b5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401611255565b6001600160a01b038481165f81815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36113d0565b845f036122fa5782511580156122e557508151155b156122fa576122fa632924508760e21b611a37565b8260200151801561230d57508160800151155b1561236c5760085484111561232c5761232c63070b5a6f60e21b611a37565b6009546001600160a01b0382165f908152602081905260409020546123519086612a1a565b111561236757612367633ce8c2bd60e11b611a37565b611caf565b8160200151801561237f57508260800151155b1561239e576008548411156123675761236763070b5a6f60e21b611a37565b8160800151611caf576009546001600160a01b0382165f908152602081905260409020546123cc9086612a1a565b1115611caf57611caf633ce8c2bd60e11b611a37565b305f90815260208190526040812054908190036123fc5750565b600b548082111561240b578091505b476124158361268b565b5f805f8084470390506103e8601754820281612433576124336129f2565b0493506103e860185482028161244b5761244b6129f2565b6011546040519290910494509185900384900392505f916001600160a01b03169085908381818185875af1925050503d805f81146124a4576040519150601f19603f3d011682016040523d82523d5f602084013e6124a9565b606091505b50506012546040519192506001600160a01b03169084905f81818185875af1925050503d805f81146124f6576040519150601f19603f3d011682016040523d82523d5f602084013e6124fb565b606091505b50506013546040519192506001600160a01b03169083905f81818185875af1925050503d805f8114611e2b576040519150601f19603f3d011682016040523d82523d5f602084013e611e2b565b6001600160a01b0384165f908152601a60205260408120546301000000900460ff1615612578575061019061260a565b61012c86014211156125a9578215612593575060155461260a565b81156125a2575060165461260a565b505f61260a565b8280156125bb57506002601054014311155b156125e9576001600160a01b0384165f908152601a60205260409020805463ff000000191663010000001790555b82806125f25750815b156126075761260086612806565b905061260a565b505f5b95945050505050565b801561261d575050565b6001600160a01b0382165f90815260208190526040902054600c5481101561264457505050565b604080516001600160a01b0385168152602081018390527f603f16706d8facbdadddadc2f84737909caebc5d1f3adf53d69014f2d908611c910160405180910390a1505050565b6040805160028082526060820183527f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d925f92919060208301908036833701905050905030815f815181106126e2576126e2612aee565b60200260200101906001600160a01b031690816001600160a01b031681525050816001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801561273e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127629190612a7e565b8160018151811061277557612775612aee565b60200260200101906001600160a01b031690816001600160a01b0316815250506127a03083856118f9565b60405163791ac94760e01b81526001600160a01b0383169063791ac947906127d49086905f90869030904290600401612b02565b5f604051808303815f87803b1580156127eb575f80fd5b505af11580156127fd573d5f803e3d5ffd5b50505050505050565b5f612812602d83612a1a565b42111561282157505060075490565b505060065490565b5f602080835283518060208501525f5b8181101561285557858101830151858201604001528201612839565b505f604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b0381168114610dcd575f80fd5b5f806040838503121561289a575f80fd5b82356128a581612875565b946020939093013593505050565b5f805f606084860312156128c5575f80fd5b83356128d081612875565b925060208401356128e081612875565b929592945050506040919091013590565b5f60208284031215612901575f80fd5b5035919050565b5f8060408385031215612919575f80fd5b50508035926020909101359150565b5f60208284031215612938575f80fd5b813561294381612875565b9392505050565b8015158114610dcd575f80fd5b5f8060408385031215612968575f80fd5b823561297381612875565b915060208301356129838161294a565b809150509250929050565b5f806040838503121561299f575f80fd5b82356129aa81612875565b9150602083013561298381612875565b600181811c908216806129ce57607f821691505b6020821081036129ec57634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b80820180821115610bc557610bc5612a06565b5f82612a4757634e487b7160e01b5f52601260045260245ffd5b500490565b5f60208284031215612a5c575f80fd5b5051919050565b5f60208284031215612a73575f80fd5b81516129438161294a565b5f60208284031215612a8e575f80fd5b815161294381612875565b8082028115828204841417610bc557610bc5612a06565b81810381811115610bc557610bc5612a06565b5f805f60608486031215612ad5575f80fd5b8351925060208401519150604084015190509250925092565b634e487b7160e01b5f52603260045260245ffd5b5f60a08201878352602087602085015260a0604085015281875180845260c0860191506020890193505f5b81811015612b525784516001600160a01b031683529383019391830191600101612b2d565b50506001600160a01b0396909616606085015250505060800152939250505056fea264697066735822122066923d30d4d0cbd43d16edcd59efe5b39b50b0bbd658e4d98c5202528a6815ea64736f6c63430008160033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

OVERVIEW

The frictionless multichain privacy solution. Swap, Bridge, Disperse, Fund. Privately. All within a single DApp.

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.