MATIC Price: $0.355177 (-21.25%)
 

Overview

MATIC Balance

Polygon PoS Chain LogoPolygon PoS Chain LogoPolygon PoS Chain Logo1,225.432759621670207222 MATIC

MATIC Value

$435.25 (@ $0.36/MATIC)

Token Holdings

Multichain Info

Transaction Hash
Method
Block
From
To
0xd81918bf1a940c1cd73fd5b01b1c71e98b33c5790a6bb9798284d1c4dd31f9ee -(pending)2024-08-05 11:47:335 secs ago1722858453IN
0x07964f13...d45000000
0 MATIC(Pending)(Pending)
Exact Input V3Sw...602213342024-08-05 11:47:2216 secs ago1722858442IN
0x07964f13...d45000000
0 MATIC0.05758975227.01105275
Exact Input V3Sw...602213052024-08-05 11:46:201 min ago1722858380IN
0x07964f13...d45000000
0 MATIC0.05705227219.65569629
Exact Input V3Sw...602213042024-08-05 11:46:181 min ago1722858378IN
0x07964f13...d45000000
0 MATIC0.05686294229.96948567
Exact Input V3Sw...602212832024-08-05 11:45:342 mins ago1722858334IN
0x07964f13...d45000000
0 MATIC0.05183411209.62558636
Exact Input V3Sw...602212762024-08-05 11:45:182 mins ago1722858318IN
0x07964f13...d45000000
0 MATIC0.04945622219.32878936
Exact Input V3Sw...602212732024-08-05 11:45:122 mins ago1722858312IN
0x07964f13...d45000000
0 MATIC0.05786553228.07118746
Exact Input V3Sw...602212592024-08-05 11:44:343 mins ago1722858274IN
0x07964f13...d45000000
0 MATIC0.06706101331.47486298
Exact Input V3Sw...602212582024-08-05 11:44:303 mins ago1722858270IN
0x07964f13...d45000000
0 MATIC0.03650796208.22428869
Exact Input V3Sw...602212542024-08-05 11:44:143 mins ago1722858254IN
0x07964f13...d45000000
13 MATIC0.05095201215.6717184
Exact Input V2Sw...602212472024-08-05 11:43:443 mins ago1722858224IN
0x07964f13...d45000000
0 MATIC0.04604667188.98618768
Exact Input V3Sw...602212472024-08-05 11:43:443 mins ago1722858224IN
0x07964f13...d45000000
0 MATIC0.05260131205.48109398
Exact Input V3Sw...602212422024-08-05 11:43:344 mins ago1722858214IN
0x07964f13...d45000000
0 MATIC0.05016293202.86377979
Exact Input V3Sw...602212312024-08-05 11:43:104 mins ago1722858190IN
0x07964f13...d45000000
0 MATIC0.05251631226.1119577
Exact Input V3Sw...602212242024-08-05 11:42:564 mins ago1722858176IN
0x07964f13...d45000000
0 MATIC0.05296373209.07342351
Exact Input V3Sw...602212242024-08-05 11:42:564 mins ago1722858176IN
0x07964f13...d45000000
0 MATIC0.06232551233.936194
Exact Input V3Sw...602212112024-08-05 11:42:285 mins ago1722858148IN
0x07964f13...d45000000
0 MATIC0.0752749470.71527551
Exact Input V3Sw...602211552024-08-05 11:40:307 mins ago1722858030IN
0x07964f13...d45000000
0 MATIC0.03664778246.53904696
Aggregate602211512024-08-05 11:40:207 mins ago1722858020IN
0x07964f13...d45000000
0 MATIC0.0818355212.29012254
Exact Input V3Sw...602211482024-08-05 11:40:147 mins ago1722858014IN
0x07964f13...d45000000
0 MATIC0.06227065268.6187435
Exact Input V3Sw...602211442024-08-05 11:40:067 mins ago1722858006IN
0x07964f13...d45000000
0 MATIC0.07255179277.04320374
Exact Input V3Sw...602211392024-08-05 11:39:567 mins ago1722857996IN
0x07964f13...d45000000
0 MATIC0.04561438196.66626976
Exact Input V3Sw...602211352024-08-05 11:39:467 mins ago1722857986IN
0x07964f13...d45000000
0 MATIC0.03229702130.42925349
Exact Input V3Sw...602211282024-08-05 11:39:328 mins ago1722857972IN
0x07964f13...d45000000
0 MATIC0.03700883159.35463566
Exact Input V3Sw...602211252024-08-05 11:39:268 mins ago1722857966IN
0x07964f13...d45000000
0 MATIC0.02753494178.09867243
View all transactions

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To
602213052024-08-05 11:46:201 min ago1722858380
0x07964f13...d45000000
2.83081033 MATIC
602213052024-08-05 11:46:201 min ago1722858380
0x07964f13...d45000000
2.83081033 MATIC
602213042024-08-05 11:46:181 min ago1722858378
0x07964f13...d45000000
5.62770302 MATIC
602213042024-08-05 11:46:181 min ago1722858378
0x07964f13...d45000000
5.62770302 MATIC
602212832024-08-05 11:45:342 mins ago1722858334
0x07964f13...d45000000
28.27338922 MATIC
602212832024-08-05 11:45:342 mins ago1722858334
0x07964f13...d45000000
28.27338922 MATIC
602212732024-08-05 11:45:122 mins ago1722858312
0x07964f13...d45000000
5.67616144 MATIC
602212732024-08-05 11:45:122 mins ago1722858312
0x07964f13...d45000000
5.67616144 MATIC
602212542024-08-05 11:44:143 mins ago1722858254
0x07964f13...d45000000
12.961 MATIC
602212472024-08-05 11:43:443 mins ago1722858224
0x07964f13...d45000000
3.13439686 MATIC
602212472024-08-05 11:43:443 mins ago1722858224
0x07964f13...d45000000
3.13439686 MATIC
602212472024-08-05 11:43:443 mins ago1722858224
0x07964f13...d45000000
56.73939667 MATIC
602212472024-08-05 11:43:443 mins ago1722858224
0x07964f13...d45000000
56.73939667 MATIC
602212422024-08-05 11:43:344 mins ago1722858214
0x07964f13...d45000000
28.23077836 MATIC
602212422024-08-05 11:43:344 mins ago1722858214
0x07964f13...d45000000
28.23077836 MATIC
602212242024-08-05 11:42:564 mins ago1722858176
0x07964f13...d45000000
11.42313802 MATIC
602212242024-08-05 11:42:564 mins ago1722858176
0x07964f13...d45000000
11.42313802 MATIC
602212242024-08-05 11:42:564 mins ago1722858176
0x07964f13...d45000000
1.39768038 MATIC
602212242024-08-05 11:42:564 mins ago1722858176
0x07964f13...d45000000
1.39768038 MATIC
602211352024-08-05 11:39:467 mins ago1722857986
0x07964f13...d45000000
2.85418498 MATIC
602211352024-08-05 11:39:467 mins ago1722857986
0x07964f13...d45000000
2.85418498 MATIC
602211232024-08-05 11:39:228 mins ago1722857962
0x07964f13...d45000000
14.25143221 MATIC
602211232024-08-05 11:39:228 mins ago1722857962
0x07964f13...d45000000
14.25143221 MATIC
602211142024-08-05 11:39:028 mins ago1722857942
0x07964f13...d45000000
216.349 MATIC
602210992024-08-05 11:38:309 mins ago1722857910
0x07964f13...d45000000
284.59920117 MATIC
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TransitSwapRouterV5

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 15 : TransitSwapRouterV5.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.20;

import "./UniswapV2Router.sol";
import "./UniswapV3Router.sol";
import "./AggregateRouter.sol";
import "./CrossRouter.sol";

contract TransitSwapRouterV5 is UniswapV2Router, UniswapV3Router, AggregateRouter, CrossRouter  {

    function withdrawTokens(address[] memory tokens, address recipient) external onlyExecutor {
        for (uint index; index < tokens.length; index++) {
            uint amount;
            if (TransferHelper.isETH(tokens[index])) {
                amount = address(this).balance;
                TransferHelper.safeTransferETH(recipient, amount);
            } else {
                amount = IERC20(tokens[index]).balanceOf(address(this));
                TransferHelper.safeTransferWithoutRequire(tokens[index], recipient, amount);
            }
            emit Withdraw(tokens[index], msg.sender, recipient, amount);
        }
    }
}

File 2 of 15 : CrossRouter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./BaseCore.sol";

contract CrossRouter is BaseCore {

    using SafeMath for uint256;

    constructor() {}

    function cross(CrossDescription calldata desc) external payable nonReentrant whenNotPaused(FunctionFlag.cross) {
        require(desc.calls.length > 0, "data should be not zero");
        require(desc.amount > 0, "amount should be greater than 0");
        require(_cross_caller_allowed[desc.caller], "invalid caller");
        
        uint256 swapAmount = executeFunds(FunctionFlag.cross, desc.srcToken, desc.wrappedToken, desc.caller, desc.amount, desc.fee, desc.signature);

        {
            (bool success, bytes memory result) = desc.caller.call{value:swapAmount}(desc.calls);
            if (!success) {
                revert(RevertReasonParser.parse(result, "TransitCrossV5:"));
            }
            TransferHelper.safeApprove(desc.srcToken, desc.caller, 0);
        }

        _emitTransit(desc.srcToken, desc.dstToken, desc.dstReceiver, desc.amount, 0, desc.toChain, desc.channel);
    } 
}

File 3 of 15 : AggregateRouter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./BaseCore.sol";

contract AggregateRouter is BaseCore {

    using SafeMath for uint256;

    constructor() {

    }

    function aggregateAndGasUsed(TransitSwapDescription calldata desc, CallbytesDescription calldata callbytesDesc) external payable returns (uint256 returnAmount, uint256 gasUsed) {
        uint256 gasLeftBefore = gasleft();
        returnAmount = _executeAggregate(desc, callbytesDesc);
        gasUsed = gasLeftBefore - gasleft();
    }

    function aggregate(TransitSwapDescription calldata desc, CallbytesDescription calldata callbytesDesc) external payable returns (uint256 returnAmount) {
        returnAmount = _executeAggregate(desc, callbytesDesc);
    }

    function _executeAggregate(TransitSwapDescription calldata desc, CallbytesDescription calldata callbytesDesc) internal nonReentrant whenNotPaused(FunctionFlag.executeAggregate) returns (uint256 returnAmount) {
        require(callbytesDesc.calldatas.length > 0, "data should be not zero");
        require(desc.amount > 0, "amount should be greater than 0");
        require(desc.dstReceiver != address(0), "receiver should be not address(0)");
        require(desc.minReturnAmount > 0, "minReturnAmount should be greater than 0");
        require(_wrapped_allowed[desc.wrappedToken], "invalid wrapped address");

        uint256 toBeforeBalance;
        address bridgeAddress = _aggregate_bridge;
        uint256 swapAmount = executeFunds(FunctionFlag.executeAggregate, desc.srcToken, desc.wrappedToken, bridgeAddress, desc.amount, desc.fee, desc.signature);

        if (TransferHelper.isETH(desc.dstToken)) {
            toBeforeBalance = desc.dstReceiver.balance;
        } else {
            toBeforeBalance = IERC20(desc.dstToken).balanceOf(desc.dstReceiver);
        }

        {
            //bytes4(keccak256(bytes('callbytes(CallbytesDescription)')));
            (bool success, bytes memory result) = bridgeAddress.call{value : swapAmount}(abi.encodeWithSelector(0x3f3204d2, callbytesDesc));
            if (!success) {
                revert(RevertReasonParser.parse(result, "TransitSwap:"));
            }
        }

        if (TransferHelper.isETH(desc.dstToken)) {
            returnAmount = desc.dstReceiver.balance.sub(toBeforeBalance);
        } else {
            returnAmount = IERC20(desc.dstToken).balanceOf(desc.dstReceiver).sub(toBeforeBalance);
        }
        require(returnAmount >= desc.minReturnAmount, "Too little received");

        _emitTransit(desc.srcToken, desc.dstToken, desc.dstReceiver, desc.amount, returnAmount, 0, desc.channel);

    }
}

File 4 of 15 : UniswapV3Router.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./BaseCore.sol";

contract UniswapV3Router is BaseCore {

    using SafeMath for uint256;

    uint256 private constant _ZERO_FOR_ONE_MASK = 1 << 255;
    uint160 private constant MIN_SQRT_RATIO = 4295128739;
    uint160 private constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;

    constructor() {}

    fallback() external {
        (int256 amount0Delta, int256 amount1Delta, bytes memory _data) = abi.decode(msg.data[4:], (int256,int256,bytes));
        _executeCallback(amount0Delta, amount1Delta, _data);
    }

    function pancakeV3SwapCallback(
        int256 amount0Delta,
        int256 amount1Delta,
        bytes calldata _data
    ) external {
        _executeCallback(amount0Delta, amount1Delta, _data);
    }

    function uniswapV3SwapCallback(
        int256 amount0Delta,
        int256 amount1Delta,
        bytes calldata _data
    ) external {
        _executeCallback(amount0Delta, amount1Delta, _data);
    }

    function _executeCallback(
        int256 amount0Delta,
        int256 amount1Delta,
        bytes memory _data
    ) internal {
        require(amount0Delta > 0 || amount1Delta > 0, "M0 or M1"); // swaps entirely within 0-liquidity regions are not supported
        (uint256 pool, bytes memory tokenInAndPoolSalt) = abi.decode(_data, (uint256, bytes));
        (address tokenIn, bytes32 poolSalt) = abi.decode(tokenInAndPoolSalt, (address, bytes32));
        _verifyCallback(pool, poolSalt, msg.sender);

        uint256 amountToPay = uint256(amount1Delta);
        if (amount0Delta > 0) {
            amountToPay = uint256(amount0Delta);
        }

        TransferHelper.safeTransfer(tokenIn, msg.sender, amountToPay);
    }

    function exactInputV3SwapAndGasUsed(ExactInputV3SwapParams calldata params) external payable returns (uint256 returnAmount, uint256 gasUsed) {
        uint256 gasLeftBefore = gasleft();
        returnAmount = _executeV3Swap(params);
        gasUsed = gasLeftBefore - gasleft();

    }

    function exactInputV3Swap(ExactInputV3SwapParams calldata params) external payable returns (uint256 returnAmount) {
        returnAmount = _executeV3Swap(params);
    }

    function _executeV3Swap(ExactInputV3SwapParams calldata params) internal nonReentrant whenNotPaused(FunctionFlag.executeV3Swap) returns (uint256 returnAmount) {
        require(params.pools.length > 0, "Empty pools");
        require(params.deadline >= block.timestamp, "Expired");
        require(_wrapped_allowed[params.wrappedToken], "Invalid wrapped address");
        address tokenIn = params.srcToken;
        address tokenOut = params.dstToken;

        uint256 toBeforeBalance;
        bool isToETH;
        if (TransferHelper.isETH(params.srcToken)) {
            tokenIn = params.wrappedToken;
        }
        uint256 actualAmountIn = executeFunds(FunctionFlag.executeV3Swap, params.srcToken, params.wrappedToken, address(0), params.amount, params.fee, params.signature);

        if (TransferHelper.isETH(params.dstToken)) {
            tokenOut = params.wrappedToken;
            toBeforeBalance = IERC20(params.wrappedToken).balanceOf(address(this));
            isToETH = true;
        } else {
            toBeforeBalance = IERC20(params.dstToken).balanceOf(params.dstReceiver);
        }

        {
            uint256 len = params.pools.length;
            address recipient = address(this);
            bytes memory tokenInAndPoolSalt;
            if (len > 1) {
                address thisTokenIn = tokenIn;
                address thisTokenOut = address(0);
                for (uint256 i; i < len; i++) {
                    uint256 thisPool = params.pools[i];
                    (thisTokenIn, tokenInAndPoolSalt) = _verifyPool(thisTokenIn, thisTokenOut, thisPool);
                    if (i == len - 1 && !isToETH) {
                        recipient = params.dstReceiver;
                        thisTokenOut = tokenOut;
                    } 
                    actualAmountIn = _swap(recipient, thisPool, tokenInAndPoolSalt, actualAmountIn);
                }
                returnAmount = actualAmountIn;
            } else {
                (, tokenInAndPoolSalt) = _verifyPool(tokenIn, tokenOut, params.pools[0]);
                if (!isToETH) {
                    recipient = params.dstReceiver;
                }
                returnAmount = _swap(recipient, params.pools[0], tokenInAndPoolSalt, actualAmountIn);
            }
        }

        if (isToETH) {
            returnAmount = IERC20(params.wrappedToken).balanceOf(address(this)).sub(toBeforeBalance);
            require(returnAmount >= params.minReturnAmount, "Too little received");
            TransferHelper.safeWithdraw(params.wrappedToken, returnAmount);
            TransferHelper.safeTransferETH(params.dstReceiver, returnAmount);
        } else {
            returnAmount = IERC20(params.dstToken).balanceOf(params.dstReceiver).sub(toBeforeBalance);
            require(returnAmount >= params.minReturnAmount, "Too little received");
        }
        
        _emitTransit(params.srcToken, params.dstToken, params.dstReceiver, params.amount, returnAmount, 0, params.channel);

    }

    function _swap(address recipient, uint256 pool, bytes memory tokenInAndPoolSalt, uint256 amount) internal returns (uint256 amountOut) {
        bool zeroForOne = pool & _ZERO_FOR_ONE_MASK == 0;
        if (zeroForOne) {
            (, int256 amount1) =
                IUniswapV3Pool(address(uint160(pool))).swap(
                    recipient,
                    zeroForOne,
                    amount.toInt256(),
                    MIN_SQRT_RATIO + 1,
                    abi.encode(pool, tokenInAndPoolSalt)
                );
            amountOut = SafeMath.toUint256(-amount1);
        } else {
            (int256 amount0,) =
                IUniswapV3Pool(address(uint160(pool))).swap(
                    recipient,
                    zeroForOne,
                    amount.toInt256(),
                    MAX_SQRT_RATIO - 1,
                    abi.encode(pool, tokenInAndPoolSalt)
                );
            amountOut = SafeMath.toUint256(-amount0);
        }
    }

    function _verifyPool(address tokenIn, address tokenOut, uint256 pool) internal view returns (address nextTokenIn, bytes memory tokenInAndPoolSalt) {
        IUniswapV3Pool iPool = IUniswapV3Pool(address(uint160(pool)));
        address token0 = iPool.token0();
        address token1 = iPool.token1();
        uint24 fee = iPool.fee();
        bytes32 poolSalt = keccak256(abi.encode(token0, token1, fee));

        bool zeroForOne = pool & _ZERO_FOR_ONE_MASK == 0;
        if (zeroForOne) {
            require(tokenIn == token0, "Bad pool");
            if (tokenOut != address(0)) {
                require(tokenOut == token1, "Bad pool");
            }
            nextTokenIn = token1;
            tokenInAndPoolSalt = abi.encode(token0, poolSalt);
        } else {
            require(tokenIn == token1, "Bad pool");
            if (tokenOut != address(0)) {
                require(tokenOut == token0, "Bad pool");
            }
            nextTokenIn = token0;
            tokenInAndPoolSalt = abi.encode(token1, poolSalt);
        }
        _verifyCallback(pool, poolSalt, address(uint160(pool)));
    }

    function _verifyCallback(uint256 pool, bytes32 poolSalt, address caller) internal view {
        uint poolDigit = pool >> 248 & 0xf;
        UniswapV3Pool memory v3Pool = _uniswapV3_factory_allowed[poolDigit];
        require(v3Pool.factory != address(0), "Callback bad pool indexed");
        address calcPool = address(
            uint160(
                uint256(
                    keccak256(
                        abi.encodePacked(
                            hex'ff',
                            v3Pool.factory,
                            poolSalt,
                            v3Pool.initCodeHash
                        )
                    )
                )
            )
        );
        require(calcPool == caller, "Callback bad pool");
    }

}

File 5 of 15 : UniswapV2Router.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./BaseCore.sol";

contract UniswapV2Router is BaseCore {

    using SafeMath for uint256;

    constructor() {

    }

    function _beforeSwap(ExactInputV2SwapParams calldata exactInput, bool supportingFeeOn) internal returns (bool isToETH, uint256 actualAmountIn, address[] memory paths, uint256 thisAddressBeforeBalance, uint256 toBeforeBalance) {
        require(exactInput.path.length == exactInput.pool.length + 1, "Invalid path");
        require(_wrapped_allowed[exactInput.wrappedToken], "Invalid wrapped address");

        (bool isToVault, uint256 vaultFee) = splitFee(exactInput.fee);
        actualAmountIn = calculateTradeFee(true, exactInput.amount, vaultFee, exactInput.signature);
        address[] memory path = exactInput.path;
        address dstToken = path[exactInput.path.length - 1];
        if (TransferHelper.isETH(exactInput.path[0])) {
            require(msg.value == exactInput.amount, "Invalid msg.value");
            if (isToVault) {
                TransferHelper.safeTransferETH(_vault, vaultFee);
            }
            path[0] = exactInput.wrappedToken;
            TransferHelper.safeDeposit(exactInput.wrappedToken, actualAmountIn);
        } else {
            if (supportingFeeOn) {
                actualAmountIn = IERC20(path[0]).balanceOf(address(this));
                TransferHelper.safeTransferFrom(path[0], msg.sender, address(this), exactInput.amount);
                actualAmountIn = IERC20(path[0]).balanceOf(address(this)).sub(actualAmountIn).sub(exactInput.fee);
            } else {
                TransferHelper.safeTransferFrom(path[0], msg.sender, address(this), exactInput.amount);
            }
            if (isToVault) {
                TransferHelper.safeTransferWithoutRequire(path[0], _vault, vaultFee);
            }
        }
        if (TransferHelper.isETH(dstToken)) {
            path[path.length - 1] = exactInput.wrappedToken;
            isToETH = true;
            thisAddressBeforeBalance = IERC20(exactInput.wrappedToken).balanceOf(address(this));
        } else {
            if (supportingFeeOn) {
                toBeforeBalance = IERC20(dstToken).balanceOf(exactInput.dstReceiver);
            }
        }
        paths = path;
    }

    function exactInputV2SwapAndGasUsed(ExactInputV2SwapParams calldata exactInput, uint256 deadline) external payable returns (uint256 returnAmount, uint256 gasUsed) {
        uint256 gasLeftBefore = gasleft();
        returnAmount = _executeV2Swap(exactInput, deadline);
        gasUsed = gasLeftBefore - gasleft();
    }

    function exactInputV2Swap(ExactInputV2SwapParams calldata exactInput, uint256 deadline) external payable returns (uint256 returnAmount) {
        returnAmount = _executeV2Swap(exactInput, deadline);
    }

    function _executeV2Swap(ExactInputV2SwapParams calldata exactInput, uint256 deadline) internal nonReentrant whenNotPaused(FunctionFlag.executeV2Swap) returns (uint256 returnAmount) {
        require(deadline >= block.timestamp, "Expired");
        
        bool supportingFeeOn = exactInput.router >> 248 & 0xf == 1;
        {
            (bool isToETH, uint256 actualAmountIn, address[] memory paths, uint256 thisAddressBeforeBalance, uint256 toBeforeBalance) = _beforeSwap(exactInput, supportingFeeOn);
            
            TransferHelper.safeTransfer(paths[0], exactInput.pool[0], actualAmountIn);

            if (supportingFeeOn) {
                if(isToETH) {
                    _swapSupportingFeeOnTransferTokens(address(uint160(exactInput.router)), paths, exactInput.pool, address(this));
                    returnAmount = IERC20(exactInput.wrappedToken).balanceOf(address(this)).sub(thisAddressBeforeBalance);
                } else {
                    _swapSupportingFeeOnTransferTokens(address(uint160(exactInput.router)), paths, exactInput.pool, exactInput.dstReceiver);
                    returnAmount = IERC20(paths[paths.length - 1]).balanceOf(exactInput.dstReceiver).sub(toBeforeBalance);
                }
            } else {
                uint[] memory amounts = IUniswapV2(address(uint160(exactInput.router))).getAmountsOut(actualAmountIn, paths);
                if(isToETH) {
                    _swap(amounts, paths, exactInput.pool, address(this));
                    returnAmount = IERC20(exactInput.wrappedToken).balanceOf(address(this)).sub(thisAddressBeforeBalance);
                } else {
                    _swap(amounts, paths, exactInput.pool, exactInput.dstReceiver);
                    returnAmount = amounts[amounts.length - 1];
                }
            }

            require(returnAmount >= exactInput.minReturnAmount, "Too little received");
            if (isToETH) {
                TransferHelper.safeWithdraw(exactInput.wrappedToken, returnAmount);
                TransferHelper.safeTransferETH(exactInput.dstReceiver, returnAmount);
            }
        }
        string memory channel = exactInput.channel;

        _emitTransit(exactInput.path[0], exactInput.path[exactInput.path.length - 1], exactInput.dstReceiver, exactInput.amount, returnAmount, 0, channel);
        
    }

    function _swap(uint[] memory amounts, address[] memory path, address[] memory pool, address _to) internal {
        for (uint i; i < path.length - 1; i++) {
            (address input, address output) = (path[i], path[i + 1]);
            (address token0,) = input < output ? (input, output) : (output, input);
            uint amountOut = amounts[i + 1];
            (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOut) : (amountOut, uint(0));
            address to = i < path.length - 2 ? pool[i + 1] : _to;
            IUniswapV2(pool[i]).swap(
                amount0Out, amount1Out, to, new bytes(0)
            );
        }
    }

    function _swapSupportingFeeOnTransferTokens(address router, address[] memory path, address[] memory pool, address _to) internal virtual {
        for (uint i; i < path.length - 1; i++) {
            (address input, address output) = (path[i], path[i + 1]);
            (address token0,) = input < output ? (input, output) : (output, input);
            IUniswapV2 pair = IUniswapV2(pool[i]);
            uint amountInput;
            uint amountOutput;
            { // scope to avoid stack too deep errors
                (uint reserve0, uint reserve1,) = pair.getReserves();
                (uint reserveInput, uint reserveOutput) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
                amountInput = IERC20(input).balanceOf(address(pair)).sub(reserveInput);
                amountOutput = IUniswapV2(router).getAmountOut(amountInput, reserveInput, reserveOutput);
            }
            (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOutput) : (amountOutput, uint(0));
            address to = i < path.length - 2 ? pool[i + 1] : _to;
            pair.swap(amount0Out, amount1Out, to, new bytes(0));
        }
    }

}

File 6 of 15 : BaseCore.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./libs/Pausable.sol";
import "./libs/ReentrancyGuard.sol";
import "./libs/TransferHelper.sol";
import "./libs/RevertReasonParser.sol";
import "./libs/SafeMath.sol";
import "./libs/Ownable.sol";
import "./interfaces/IERC20.sol";
import "./interfaces/IUniswapV2.sol";
import "./interfaces/IUniswapV3Pool.sol";


contract BaseCore is Ownable, Pausable, ReentrancyGuard {

    using SafeMath for uint256;

    struct ExactInputV2SwapParams {
        address dstReceiver;
        address wrappedToken;
        uint256 router;
        uint256 amount;
        uint256 minReturnAmount;
        uint256 fee;
        address[] path;
        address[] pool;
        bytes signature;
        string channel;
    }

    struct ExactInputV3SwapParams {
        address srcToken;
        address dstToken;
        address dstReceiver;
        address wrappedToken;
        uint256 amount;
        uint256 minReturnAmount;
        uint256 fee;
        uint256 deadline;
        uint256[] pools;
        bytes signature;
        string channel;
    }

    struct TransitSwapDescription {
        address srcToken;
        address dstToken;
        address dstReceiver;
        address wrappedToken;
        uint256 amount;
        uint256 minReturnAmount;
        uint256 fee;
        string channel;
        bytes signature;
    }

    struct CrossDescription {
        address srcToken;
        address dstToken;
        address caller;
        address dstReceiver;
        address wrappedToken;
        uint256 amount;
        uint256 fee;
        uint256 toChain;
        string channel;
        bytes calls;
        bytes signature;
    }

    struct CallbytesDescription {
        address srcToken;
        bytes calldatas;
    }

    struct UniswapV3Pool {
        address factory;
        bytes initCodeHash;
    }

    uint256 internal _aggregate_fee;
    uint256 internal _cross_fee;
    address internal _aggregate_bridge;
    address internal _fee_signer;
    address internal _vault;
    bytes32 public DOMAIN_SEPARATOR;
    //whitelist cross's caller
    mapping(address => bool) internal _cross_caller_allowed;
    //whitelist wrapped
    mapping(address => bool) internal _wrapped_allowed;
    //whitelist uniswap v3 factory
    mapping(uint => UniswapV3Pool) internal _uniswapV3_factory_allowed;
    bytes32 public constant CHECKFEE_TYPEHASH = keccak256("CheckFee(address payer,uint256 amount,uint256 fee)");

    event Receipt(address from, uint256 amount);
    event Withdraw(address indexed token, address indexed executor, address indexed recipient, uint amount);
    event ChangeWrappedAllowed(address[] wrappedTokens, bool[] newAllowed);
    event ChangeV3FactoryAllowed(uint256[] poolIndex, address[] factories, bytes[] initCodeHash);
    event ChangeCrossCallerAllowed(address[] callers);
    event ChangeFeeRate(bool isAggregate, uint256 newRate);
    event ChangeSigner(address preSigner, address newSigner);
    event ChangeAggregateBridge(address newBridge);
    event ChangeVault(address preVault, address newVault);
    event TransitSwapped(address indexed srcToken, address indexed dstToken, address indexed dstReceiver, uint256 amount, uint256 returnAmount, uint256 toChainID, string channel);
    
    constructor() Ownable(msg.sender) {
        DOMAIN_SEPARATOR = keccak256(
            abi.encode(
                keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                keccak256(bytes("TransitSwapV5")),
                keccak256(bytes("5")),
                block.chainid,
                address(this)
            )
        );
    }

    receive() external payable {
        emit Receipt(msg.sender, msg.value);
    }

    function calculateTradeFee(bool isAggregate, uint256 tradeAmount, uint256 fee, bytes calldata signature) internal view returns (uint256) {
        uint256 thisFee;
        if (isAggregate) {
            thisFee = tradeAmount.mul(_aggregate_fee).div(10000);
        } else {
            thisFee = tradeAmount.mul(_cross_fee).div(10000);
        }
        if (fee < thisFee) {
            require(verifySignature(tradeAmount, fee, signature), "Invalid signature fee");
        }
        return tradeAmount.sub(fee);
    }

    function _emitTransit(address srcToken, address dstToken, address dstReceiver, uint256 amount, uint256 returnAmount, uint256 toChainID, string memory channel) internal {
        emit TransitSwapped (
            srcToken, 
            dstToken, 
            dstReceiver,
            amount,
            returnAmount,
            toChainID,
            channel
        );
    }

    function changeFee(bool[] memory isAggregate, uint256[] memory newRate) external onlyExecutor {
        for (uint i; i < isAggregate.length; i++) {
            require(newRate[i] >= 0 && newRate[i] <= 1000, "fee rate is:0-1000");
            if (isAggregate[i]) {
                _aggregate_fee = newRate[i];
            } else {
                _cross_fee = newRate[i];
            }
            emit ChangeFeeRate(isAggregate[i], newRate[i]);
        }
    }

    function changeTransitProxy(address aggregator, address signer, address vault) external onlyExecutor {
        if (aggregator != address(0)) {
            _aggregate_bridge = aggregator;
            emit ChangeAggregateBridge(aggregator);
        }
        if (signer != address(0)) {
            address preSigner = _fee_signer;
            _fee_signer = signer;
            emit ChangeSigner(preSigner, signer);
        }
        if (vault != address(0)) {
            address preVault = _vault;
            _vault = vault;
            emit ChangeVault(preVault, vault);
        }
    }

    function changeAllowed(address[] calldata crossCallers, address[] calldata wrappedTokens) public onlyExecutor {
        if(crossCallers.length != 0){
            for (uint i; i < crossCallers.length; i++) {
                _cross_caller_allowed[crossCallers[i]] = !_cross_caller_allowed[crossCallers[i]];
            }
            emit ChangeCrossCallerAllowed(crossCallers);
        }
        if(wrappedTokens.length != 0) {
            bool[] memory newAllowed = new bool[](wrappedTokens.length);
            for (uint index; index < wrappedTokens.length; index++) {
                _wrapped_allowed[wrappedTokens[index]] = !_wrapped_allowed[wrappedTokens[index]];
                newAllowed[index] = _wrapped_allowed[wrappedTokens[index]];
            }
            emit ChangeWrappedAllowed(wrappedTokens, newAllowed);
        }
    }

    function changeUniswapV3FactoryAllowed(uint[] calldata poolIndex, address[] calldata factories, bytes[] calldata initCodeHash) public onlyExecutor {
        require(poolIndex.length == initCodeHash.length, "invalid data");
        require(factories.length == initCodeHash.length, "invalid data");
        uint len = factories.length;
        for (uint i; i < len; i++) {
            _uniswapV3_factory_allowed[poolIndex[i]] = UniswapV3Pool(factories[i],initCodeHash[i]);
        }
        emit ChangeV3FactoryAllowed(poolIndex, factories, initCodeHash);
    }

    function changePause(bool paused, FunctionFlag[] calldata flags) external onlyExecutor {
        uint len = flags.length;
        for (uint i; i < len; i++) {
            if (paused) {
                _pause(flags[i]);
            } else {
                _unpause(flags[i]);
            }
        }
    }

    function transitProxyAddress() external view returns (address bridgeProxy, address feeSigner) {
        bridgeProxy = _aggregate_bridge;
        feeSigner = _fee_signer;
    }

    function transitFee() external view returns (uint256, uint256, address) {
        return (_aggregate_fee, _cross_fee, _vault);
    }

    function transitAllowedQuery(address crossCaller, address wrappedToken, uint256 poolIndex) external view returns (bool isCrossCallerAllowed, bool isWrappedAllowed, UniswapV3Pool memory pool) {
        isCrossCallerAllowed = _cross_caller_allowed[crossCaller];
        isWrappedAllowed = _wrapped_allowed[wrappedToken];
        pool = _uniswapV3_factory_allowed[poolIndex];
    }

    function verifySignature(uint256 amount, uint256 fee, bytes calldata signature) internal view returns (bool) {
        bytes32 digest = keccak256(
            abi.encodePacked(
                "\x19\x01",
                DOMAIN_SEPARATOR,
                keccak256(abi.encode(CHECKFEE_TYPEHASH, msg.sender, amount, fee))
            )
        );
        (uint8 v, bytes32 r, bytes32 s) = splitSignature(signature);
        address recovered = ecrecover(digest, v, r, s);
        return recovered == _fee_signer;
    }

    function splitSignature(bytes memory _signature) internal pure returns (uint8 v, bytes32 r, bytes32 s) {
        require(bytes(_signature).length == 65, "Invalid signature length");

        assembly {
            r := mload(add(_signature, 0x20))
            s := mload(add(_signature, 0x40))
            v := byte(0, mload(add(_signature, 0x60)))
        }

        return (v, r, s);
    }

    function splitFee(uint256 fee) internal view returns (bool isToVault, uint256 vaultFee) {
        uint vaultFlag = fee % 10;
        vaultFee = (fee.sub(vaultFlag)).div(10);
        if (vaultFlag == 1 && vaultFee > 0 && _vault != address(0)) {
            isToVault = true;
        }
    }

    function executeFunds(FunctionFlag flag, address srcToken, address wrappedToken, address caller, uint256 amount, uint256 fee, bytes calldata signature) internal returns (uint256 swapAmount) {
        (bool isToVault, uint256 vaultFee) = splitFee(fee);
        bool isAggregate = flag == FunctionFlag.cross ? false : true;
        uint256 actualAmountIn = calculateTradeFee(isAggregate, amount, vaultFee, signature);
        if (TransferHelper.isETH(srcToken)) {
            if (flag == FunctionFlag.cross) {
                require(msg.value >= amount, "invalid msg.value");
                swapAmount = msg.value.sub(vaultFee);
            } else {
                require(msg.value == amount, "invalid msg.value");
                swapAmount = actualAmountIn;
            }
            if (wrappedToken != address(0)) {
                require(_wrapped_allowed[wrappedToken], "Invalid wrapped address");
                if (flag == FunctionFlag.cross) {
                    TransferHelper.safeDeposit(wrappedToken, swapAmount);
                    TransferHelper.safeApprove(wrappedToken, caller, swapAmount);
                    swapAmount = 0;
                } else if (flag == FunctionFlag.executeV3Swap) {
                    TransferHelper.safeDeposit(wrappedToken, actualAmountIn);
                }
            }
            if (isToVault) {
                TransferHelper.safeTransferETH(_vault, vaultFee);
            }
        } else {
            TransferHelper.safeTransferFrom(srcToken, msg.sender, address(this), amount);
            if (flag == FunctionFlag.cross) {
                TransferHelper.safeApprove(srcToken, caller, actualAmountIn);
                swapAmount = msg.value;
            } else if (flag == FunctionFlag.executeAggregate) {
                TransferHelper.safeTransfer(srcToken, caller, actualAmountIn);
            } else if (flag == FunctionFlag.executeV3Swap) {
                swapAmount = actualAmountIn;
            }
            if (isToVault) {
                TransferHelper.safeTransferWithoutRequire(srcToken, _vault, vaultFee);
            }
        }
    }

}

File 7 of 15 : IUniswapV3Pool.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0;

interface IUniswapV3Pool {
    function token0() external view returns (address);
    function token1() external view returns (address);
    function fee() external view returns (uint24);
    function swap(
        address recipient,
        bool zeroForOne,
        int256 amountSpecified,
        uint160 sqrtPriceLimitX96,
        bytes calldata data
    ) external returns (int256 amount0, int256 amount1);
}

File 8 of 15 : IUniswapV2.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9;

interface IUniswapV2 {
    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
    function getAmountsOut(uint amountIn, address[] memory path) external view returns (uint[] memory amounts);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
}

File 9 of 15 : IERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9;

interface IERC20 {
    
    function totalSupply() external view returns (uint256);
    function decimals() external view returns (uint8);
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
 
}

File 10 of 15 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
// Add executor extension

pragma solidity ^0.8.0;

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable {

    address private _executor;
    address private _pendingExecutor;
    bool internal _initialized;

    event ExecutorshipTransferStarted(address indexed previousExecutor, address indexed newExecutor);
    event ExecutorshipTransferred(address indexed previousExecutor, address indexed newExecutor);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor(address newExecutor) {
        require(!_initialized, "Ownable: initialized");
        _transferExecutorship(newExecutor);
        _initialized = true;
    }

    /**
     * @dev Throws if called by any account other than the executor.
     */
    modifier onlyExecutor() {
        _checkExecutor();
        _;
    }

    /**
     * @dev Returns the address of the current executor.
     */
    function executor() public view virtual returns (address) {
        return _executor;
    }

    /**
     * @dev Returns the address of the pending executor.
     */
    function pendingExecutor() public view virtual returns (address) {
        return _pendingExecutor;
    }

    /**
     * @dev Throws if the sender is not the executor.
     */
    function _checkExecutor() internal view virtual {
        require(executor() == msg.sender, "Ownable: caller is not the executor");
    }

    /**
     * @dev Transfers executorship of the contract to a new account (`newExecutor`).
     * Can only be called by the current executor.
     */
    function transferExecutorship(address newExecutor) public virtual onlyExecutor {
        _pendingExecutor = newExecutor;
        emit ExecutorshipTransferStarted(executor(), newExecutor);
    }

    function _transferExecutorship(address newExecutor) internal virtual {
        delete _pendingExecutor;
        address oldExecutor = _executor;
        _executor = newExecutor;
        emit ExecutorshipTransferred(oldExecutor, newExecutor);
    }

    function acceptExecutorship() external {
        address sender = msg.sender;
        require(pendingExecutor() == sender, "Ownable: caller is not the new executor");
        _transferExecutorship(sender);
    }
}

File 11 of 15 : SafeMath.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0;

library SafeMath {

    function sub(uint x, uint y) internal pure returns (uint z) {
        require((z = x - y) <= x, 'ds-math-sub-underflow');
    }

    function mul(uint x, uint y) internal pure returns (uint z) {
        require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow');
    }
    
    function div(uint x, uint y) internal pure returns (uint z) {
        require(y != 0 , 'ds-math-div-zero');
        z = x / y;
    }

    function toInt256(uint256 value) internal pure returns (int256) {
        require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
        return int256(value);
    }

    function toUint256(int256 value) internal pure returns (uint256) {
        require(value >= 0, "SafeCast: value must be positive");
        return uint256(value);
    }
}

File 12 of 15 : RevertReasonParser.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0;

library RevertReasonParser {
        function parse(bytes memory data, string memory prefix) internal pure returns (string memory) {
        // https://solidity.readthedocs.io/en/latest/control-structures.html#revert
        // We assume that revert reason is abi-encoded as Error(string)

        // 68 = 4-byte selector 0x08c379a0 + 32 bytes offset + 32 bytes length
        if (data.length >= 68 && data[0] == "\x08" && data[1] == "\xc3" && data[2] == "\x79" && data[3] == "\xa0") {
            string memory reason;
            // solhint-disable no-inline-assembly
            assembly {
                // 68 = 32 bytes data length + 4-byte selector + 32 bytes offset
                reason := add(data, 68)
            }
            /*
                revert reason is padded up to 32 bytes with ABI encoder: Error(string)
                also sometimes there is extra 32 bytes of zeros padded in the end:
                https://github.com/ethereum/solidity/issues/10170
                because of that we can't check for equality and instead check
                that string length + extra 68 bytes is less than overall data length
            */
            require(data.length >= 68 + bytes(reason).length, "Invalid revert reason");
            return string(abi.encodePacked(prefix, "Error(", reason, ")"));
        }
        // 36 = 4-byte selector 0x4e487b71 + 32 bytes integer
        else if (data.length == 36 && data[0] == "\x4e" && data[1] == "\x48" && data[2] == "\x7b" && data[3] == "\x71") {
            uint256 code;
            // solhint-disable no-inline-assembly
            assembly {
                // 36 = 32 bytes data length + 4-byte selector
                code := mload(add(data, 36))
            }
            return string(abi.encodePacked(prefix, "Panic(", _toHex(code), ")"));
        }

        return string(abi.encodePacked(prefix, "Unknown(", _toHex(data), ")"));
    }
    
    function _toHex(uint256 value) private pure returns(string memory) {
        return _toHex(abi.encodePacked(value));
    }

    function _toHex(bytes memory data) private pure returns(string memory) {
        bytes16 alphabet = 0x30313233343536373839616263646566;
        bytes memory str = new bytes(2 + data.length * 2);
        str[0] = "0";
        str[1] = "x";
        for (uint256 i = 0; i < data.length; i++) {
            str[2 * i + 2] = alphabet[uint8(data[i] >> 4)];
            str[2 * i + 3] = alphabet[uint8(data[i] & 0x0f)];
        }
        return string(str);
    }
}

File 13 of 15 : TransferHelper.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0;

library TransferHelper {
    
    address private constant _ETH_ADDRESS = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
    address private constant _ZERO_ADDRESS = address(0);
    
    function isETH(address token) internal pure returns (bool) {
        return (token == _ZERO_ADDRESS || token == _ETH_ADDRESS);
    }
    
    function safeApprove(address token, address to, uint value) internal {
        // bytes4(keccak256(bytes('approve(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED');
    }

    function safeTransfer(address token, address to, uint value) internal {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_TOKEN_FAILED');
    }

    function safeTransferWithoutRequire(address token, address to, uint256 value) internal returns (bool) {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
        return (success && (data.length == 0 || abi.decode(data, (bool))));
    }

    function safeTransferFrom(address token, address from, address to, uint value) internal {
        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED');
    }

    function safeTransferETH(address to, uint value) internal {
        // solium-disable-next-line
        (bool success,) = to.call{value:value}(new bytes(0));
        require(success, 'TransferHelper: TRANSFER_FAILED');
    }

    function safeDeposit(address wrapped, uint value) internal {
        // bytes4(keccak256(bytes('deposit()')));
        (bool success, bytes memory data) = wrapped.call{value:value}(abi.encodeWithSelector(0xd0e30db0));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: DEPOSIT_FAILED');
    }

    function safeWithdraw(address wrapped, uint value) internal {
        // bytes4(keccak256(bytes('withdraw(uint256 wad)')));
        (bool success, bytes memory data) = wrapped.call{value:0}(abi.encodeWithSelector(0x2e1a7d4d, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: WITHDRAW_FAILED');
    }
}

File 14 of 15 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
        assembly {
            sstore(_status.slot, _ENTERED)
        }
        _;
        assembly {
            sstore(_status.slot, _NOT_ENTERED)
        }
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 15 of 15 : Pausable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account, FunctionFlag flag);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account, FunctionFlag flag);

    mapping(FunctionFlag => bool) private _paused;

    enum FunctionFlag {executeAggregate, executeV2Swap, executeV3Swap, cross}

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused(FunctionFlag flag) {
        _requireNotPaused(flag);
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused(FunctionFlag flag) {
        _requirePaused(flag);
        _;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused(FunctionFlag flag) public view virtual returns (bool) {
        return _paused[flag];
    }

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused(FunctionFlag flag) internal view virtual {
        require(!paused(flag), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused(FunctionFlag flag) internal view virtual {
        require(paused(flag), "Pausable: not paused");
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause(FunctionFlag flag) internal virtual whenNotPaused(flag) {
        _paused[flag] = true;
        emit Paused(msg.sender, flag);
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause(FunctionFlag flag) internal virtual whenPaused(flag) {
        _paused[flag] = false;
        emit Unpaused(msg.sender, flag);
    }

    function pausedOverAll() public view virtual returns (bool executeAggregate, bool executeV2Swap, bool executeV3Swap, bool cross) {
        executeAggregate = _paused[FunctionFlag.executeAggregate];
        executeV2Swap = _paused[FunctionFlag.executeV2Swap];
        executeV3Swap = _paused[FunctionFlag.executeV3Swap];
        cross = _paused[FunctionFlag.cross];
    }
}

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

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newBridge","type":"address"}],"name":"ChangeAggregateBridge","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"callers","type":"address[]"}],"name":"ChangeCrossCallerAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isAggregate","type":"bool"},{"indexed":false,"internalType":"uint256","name":"newRate","type":"uint256"}],"name":"ChangeFeeRate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"preSigner","type":"address"},{"indexed":false,"internalType":"address","name":"newSigner","type":"address"}],"name":"ChangeSigner","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"poolIndex","type":"uint256[]"},{"indexed":false,"internalType":"address[]","name":"factories","type":"address[]"},{"indexed":false,"internalType":"bytes[]","name":"initCodeHash","type":"bytes[]"}],"name":"ChangeV3FactoryAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"preVault","type":"address"},{"indexed":false,"internalType":"address","name":"newVault","type":"address"}],"name":"ChangeVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"wrappedTokens","type":"address[]"},{"indexed":false,"internalType":"bool[]","name":"newAllowed","type":"bool[]"}],"name":"ChangeWrappedAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousExecutor","type":"address"},{"indexed":true,"internalType":"address","name":"newExecutor","type":"address"}],"name":"ExecutorshipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousExecutor","type":"address"},{"indexed":true,"internalType":"address","name":"newExecutor","type":"address"}],"name":"ExecutorshipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"enum Pausable.FunctionFlag","name":"flag","type":"uint8"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Receipt","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"srcToken","type":"address"},{"indexed":true,"internalType":"address","name":"dstToken","type":"address"},{"indexed":true,"internalType":"address","name":"dstReceiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"returnAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toChainID","type":"uint256"},{"indexed":false,"internalType":"string","name":"channel","type":"string"}],"name":"TransitSwapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"enum Pausable.FunctionFlag","name":"flag","type":"uint8"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"executor","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[],"name":"CHECKFEE_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptExecutorship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"address","name":"dstToken","type":"address"},{"internalType":"address","name":"dstReceiver","type":"address"},{"internalType":"address","name":"wrappedToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"string","name":"channel","type":"string"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct BaseCore.TransitSwapDescription","name":"desc","type":"tuple"},{"components":[{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"bytes","name":"calldatas","type":"bytes"}],"internalType":"struct BaseCore.CallbytesDescription","name":"callbytesDesc","type":"tuple"}],"name":"aggregate","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"address","name":"dstToken","type":"address"},{"internalType":"address","name":"dstReceiver","type":"address"},{"internalType":"address","name":"wrappedToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"string","name":"channel","type":"string"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct BaseCore.TransitSwapDescription","name":"desc","type":"tuple"},{"components":[{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"bytes","name":"calldatas","type":"bytes"}],"internalType":"struct BaseCore.CallbytesDescription","name":"callbytesDesc","type":"tuple"}],"name":"aggregateAndGasUsed","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"crossCallers","type":"address[]"},{"internalType":"address[]","name":"wrappedTokens","type":"address[]"}],"name":"changeAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool[]","name":"isAggregate","type":"bool[]"},{"internalType":"uint256[]","name":"newRate","type":"uint256[]"}],"name":"changeFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"enum Pausable.FunctionFlag[]","name":"flags","type":"uint8[]"}],"name":"changePause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"aggregator","type":"address"},{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"vault","type":"address"}],"name":"changeTransitProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"poolIndex","type":"uint256[]"},{"internalType":"address[]","name":"factories","type":"address[]"},{"internalType":"bytes[]","name":"initCodeHash","type":"bytes[]"}],"name":"changeUniswapV3FactoryAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"address","name":"dstToken","type":"address"},{"internalType":"address","name":"caller","type":"address"},{"internalType":"address","name":"dstReceiver","type":"address"},{"internalType":"address","name":"wrappedToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"toChain","type":"uint256"},{"internalType":"string","name":"channel","type":"string"},{"internalType":"bytes","name":"calls","type":"bytes"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct BaseCore.CrossDescription","name":"desc","type":"tuple"}],"name":"cross","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"dstReceiver","type":"address"},{"internalType":"address","name":"wrappedToken","type":"address"},{"internalType":"uint256","name":"router","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address[]","name":"pool","type":"address[]"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"string","name":"channel","type":"string"}],"internalType":"struct BaseCore.ExactInputV2SwapParams","name":"exactInput","type":"tuple"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"exactInputV2Swap","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"dstReceiver","type":"address"},{"internalType":"address","name":"wrappedToken","type":"address"},{"internalType":"uint256","name":"router","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address[]","name":"pool","type":"address[]"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"string","name":"channel","type":"string"}],"internalType":"struct BaseCore.ExactInputV2SwapParams","name":"exactInput","type":"tuple"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"exactInputV2SwapAndGasUsed","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"address","name":"dstToken","type":"address"},{"internalType":"address","name":"dstReceiver","type":"address"},{"internalType":"address","name":"wrappedToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256[]","name":"pools","type":"uint256[]"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"string","name":"channel","type":"string"}],"internalType":"struct BaseCore.ExactInputV3SwapParams","name":"params","type":"tuple"}],"name":"exactInputV3Swap","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"address","name":"dstToken","type":"address"},{"internalType":"address","name":"dstReceiver","type":"address"},{"internalType":"address","name":"wrappedToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256[]","name":"pools","type":"uint256[]"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"string","name":"channel","type":"string"}],"internalType":"struct BaseCore.ExactInputV3SwapParams","name":"params","type":"tuple"}],"name":"exactInputV3SwapAndGasUsed","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"executor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"amount0Delta","type":"int256"},{"internalType":"int256","name":"amount1Delta","type":"int256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"pancakeV3SwapCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum Pausable.FunctionFlag","name":"flag","type":"uint8"}],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pausedOverAll","outputs":[{"internalType":"bool","name":"executeAggregate","type":"bool"},{"internalType":"bool","name":"executeV2Swap","type":"bool"},{"internalType":"bool","name":"executeV3Swap","type":"bool"},{"internalType":"bool","name":"cross","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingExecutor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newExecutor","type":"address"}],"name":"transferExecutorship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"crossCaller","type":"address"},{"internalType":"address","name":"wrappedToken","type":"address"},{"internalType":"uint256","name":"poolIndex","type":"uint256"}],"name":"transitAllowedQuery","outputs":[{"internalType":"bool","name":"isCrossCallerAllowed","type":"bool"},{"internalType":"bool","name":"isWrappedAllowed","type":"bool"},{"components":[{"internalType":"address","name":"factory","type":"address"},{"internalType":"bytes","name":"initCodeHash","type":"bytes"}],"internalType":"struct BaseCore.UniswapV3Pool","name":"pool","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"transitFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"transitProxyAddress","outputs":[{"internalType":"address","name":"bridgeProxy","type":"address"},{"internalType":"address","name":"feeSigner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"amount0Delta","type":"int256"},{"internalType":"int256","name":"amount1Delta","type":"int256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"uniswapV3SwapCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"address","name":"recipient","type":"address"}],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

608060405234801562000010575f80fd5b506001543390600160a01b900460ff1615620000725760405162461bcd60e51b815260206004820152601460248201527f4f776e61626c653a20696e697469616c697a6564000000000000000000000000604482015260640160405180910390fd5b6200007d8162000175565b506001805460ff60a01b1916600160a01b1781556003819055604080518082018252600d81526c5472616e73697453776170563560981b60209182015281518083018352928352603560f81b9281019290925280517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f928101929092527f20b7d1a4a088b240a0e093c572f43e31015ce187a55e6f343e049dcb744e5341908201527fceebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c160608201524660808201523060a082015260c00160408051601f198184030181529190528051602090910120600955620001ce565b600180546001600160a01b03199081169091555f80546001600160a01b03848116938216841783556040519116929183917f88436636ea40d5bb1bcc55ff9cd54788af71da886f4147a87f199adcca733d4d9190a35050565b615e1680620001dc5f395ff3fe608060405260043610610184575f3560e01c80637ec753fe116100d0578063b9b5149b11610089578063d63234e011610063578063d63234e0146105a8578063d808d889146105c5578063fa461e33146102a4578063fa9ec7af146105d8576101c3565b8063b9b5149b14610546578063bf5c55a214610559578063c34c08e514610578576101c3565b80637ec753fe1461049757806392bcc8be146104b657806394d3d793146104d5578063afed2d0e146104e9578063b93c0beb14610508578063b946fd3b14610527576101c3565b80633644e5151161013d5780635ac86ab7116101175780635ac86ab7146103e95780636b3ec416146104185780636fbf72f91461042b5780637e467ecf14610464576101c3565b80633644e515146102eb5780633c481d57146103005780634c42342f146103d6576101c3565b80630ced9fb9146101ff5780630dc4bdae146102365780630e8cc705146102575780631975b0961461027657806323a69e75146102a45780632adb806f146102c3576101c3565b366101c357604080513381523460208201527f7784f8d436dc514f0690e472c7e2d7f660a73e504c69b2350f6be5a5f02432ef910160405180910390a1005b3480156101ce575f80fd5b505f80806101df3660048184614c14565b8101906101ec9190614ca5565b9250925092506101fd8383836105eb565b005b34801561020a575f80fd5b50600654600754604080516001600160a01b039384168152929091166020830152015b60405180910390f35b610249610244366004614d30565b610694565b60405190815260200161022d565b348015610262575f80fd5b506101fd610271366004614dbc565b6106a6565b348015610281575f80fd5b50610295610290366004614e62565b610826565b60405161022d93929190614eed565b3480156102af575f80fd5b506101fd6102be366004614f2a565b610925565b6102d66102d1366004614fa2565b61096b565b6040805192835260208301919091520161022d565b3480156102f6575f80fd5b5061024960095481565b34801561030b575f80fd5b5060026020527fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b547fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0547f679795a0195a1b76cdebb7c51d74e058aee92919b8c3389af86ef24535e8a28c5460035f527f88601476d11616a71c5be67555bd1dff4b1cbf21533d2669b768b61518cfe1c35460ff938416939283169291821691166040805194151585529215156020850152901515918301919091521515606082015260800161022d565b6102d66103e4366004615026565b610992565b3480156103f4575f80fd5b5061040861040336600461505f565b6109b6565b604051901515815260200161022d565b6101fd610426366004615026565b6109f6565b348015610436575f80fd5b506004546005546008546040805193845260208401929092526001600160a01b03169082015260600161022d565b34801561046f575f80fd5b506102497f048f880a603b1aab0e626a287e33d603417b3d53a36f7527b7c86365bf7def4f81565b3480156104a2575f80fd5b506101fd6104b13660046150ed565b610d11565b3480156104c1575f80fd5b506101fd6104d03660046151e5565b610e96565b3480156104e0575f80fd5b506101fd61107f565b3480156104f4575f80fd5b506101fd610503366004615277565b611105565b348015610513575f80fd5b506101fd610522366004615292565b611175565b348015610532575f80fd5b506101fd6105413660046152f8565b61142a565b610249610554366004615026565b611573565b348015610564575f80fd5b506101fd610573366004615340565b611583565b348015610583575f80fd5b505f546001600160a01b03165b6040516001600160a01b03909116815260200161022d565b3480156105b3575f80fd5b506001546001600160a01b0316610590565b6102496105d3366004614fa2565b611618565b6102d66105e6366004614d30565b611623565b5f8313806105f857505f82135b6106345760405162461bcd60e51b81526020600482015260086024820152674d30206f72204d3160c01b60448201526064015b60405180910390fd5b5f808280602001905181019061064a9190615390565b915091505f8082806020019051810190610664919061540d565b91509150610673848233611633565b855f88131561067f5750865b61068a8333836117e6565b5050505050505050565b5f61069f8383611903565b9392505050565b6106ae611e7b565b5f5b8251811015610821575f6106dc8483815181106106cf576106cf615439565b6020026020010151611ef1565b156106f25750476106ed8382611f29565b61079e565b83828151811061070457610704615439565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610752573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610776919061544d565b905061079c84838151811061078d5761078d615439565b60200260200101518483611fe2565b505b826001600160a01b0316336001600160a01b03168584815181106107c4576107c4615439565b60200260200101516001600160a01b03167f3115d1449a7b732c986cba18244e897a450f61e1bb8d589cd2e69e6c8924f9f78460405161080691815260200190565b60405180910390a4508061081981615478565b9150506106b0565b505050565b6040805180820182525f80825260606020808401919091526001600160a01b038781168352600a8252848320548782168452600b835285842054878552600c84529386902086518088019097528054909216865260018201805460ff92831697929095169594919384019161089a90615490565b80601f01602080910402602001604051908101604052809291908181526020018280546108c690615490565b80156109115780601f106108e857610100808354040283529160200191610911565b820191905f5260205f20905b8154815290600101906020018083116108f457829003601f168201915b505050505081525050905093509350939050565b610965848484848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506105eb92505050565b50505050565b5f805f5a905061097b85856120c6565b92505a61098890826154c2565b9150509250929050565b5f805f5a90506109a1846125d7565b92505a6109ae90826154c2565b915050915091565b5f60025f8360038111156109cc576109cc6154d5565b60038111156109dd576109dd6154d5565b815260208101919091526040015f205460ff1692915050565b600260035403610a185760405162461bcd60e51b815260040161062b906154e9565b60026003556003610a2881612b20565b5f610a37610120840184615520565b905011610a805760405162461bcd60e51b8152602060048201526017602482015276646174612073686f756c64206265206e6f74207a65726f60481b604482015260640161062b565b5f8260a0013511610ad35760405162461bcd60e51b815260206004820152601f60248201527f616d6f756e742073686f756c642062652067726561746572207468616e203000604482015260640161062b565b600a5f610ae66060850160408601615277565b6001600160a01b0316815260208101919091526040015f205460ff16610b3f5760405162461bcd60e51b815260206004820152600e60248201526d34b73b30b634b21031b0b63632b960911b604482015260640161062b565b5f610b8f6003610b526020860186615277565b610b6260a0870160808801615277565b610b726060880160408901615277565b60a088013560c0890135610b8a6101408b018b615520565b612b69565b90505f80610ba36060860160408701615277565b6001600160a01b031683610bbb610120880188615520565b604051610bc9929190615562565b5f6040518083038185875af1925050503d805f8114610c03576040519150601f19603f3d011682016040523d82523d5f602084013e610c08565b606091505b509150915081610c5c57610c43816040518060400160405280600f81526020016e2a3930b739b4ba21b937b9b9ab1a9d60891b815250612ddf565b60405162461bcd60e51b815260040161062b9190615571565b610c82610c6c6020870187615277565b610c7c6060880160408901615277565b5f613053565b50610d079050610c956020850185615277565b610ca56040860160208701615277565b610cb56080870160608801615277565b60a08701355f60e0890135610cce6101008b018b615520565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061316292505050565b5050600160035550565b610d19611e7b565b5f5b8251811015610821575f828281518110610d3757610d37615439565b602002602001015110158015610d6857506103e8828281518110610d5d57610d5d615439565b602002602001015111155b610da95760405162461bcd60e51b8152602060048201526012602482015271066656520726174652069733a302d313030360741b604482015260640161062b565b828181518110610dbb57610dbb615439565b602002602001015115610ded57818181518110610dda57610dda615439565b6020026020010151600481905550610e0e565b818181518110610dff57610dff615439565b60200260200101516005819055505b7f5fa95345cbe35dad70f67a9ca1430c22453a695590cb4fca05d58f637e85af4f838281518110610e4157610e41615439565b6020026020010151838381518110610e5b57610e5b615439565b6020026020010151604051610e7c9291909115158252602082015260400190565b60405180910390a180610e8e81615478565b915050610d1b565b610e9e611e7b565b848114610edc5760405162461bcd60e51b815260206004820152600c60248201526b696e76616c6964206461746160a01b604482015260640161062b565b828114610f1a5760405162461bcd60e51b815260206004820152600c60248201526b696e76616c6964206461746160a01b604482015260640161062b565b825f5b81811015611034576040518060400160405280878784818110610f4257610f42615439565b9050602002016020810190610f579190615277565b6001600160a01b03168152602001858584818110610f7757610f77615439565b9050602002810190610f899190615520565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201829052509390945250600c92508b90508a85818110610fd557610fd5615439565b60209081029290920135835250818101929092526040015f20825181546001600160a01b0319166001600160a01b0390911617815590820151600182019061101d90826155c8565b50905050808061102c90615478565b915050610f1d565b507f652c1af850dcc0b28fcb71cd9473023f56a89edd81bbe7b51056a04caa94002487878787878760405161106e96959493929190615733565b60405180910390a150505050505050565b33806110936001546001600160a01b031690565b6001600160a01b0316146110f95760405162461bcd60e51b815260206004820152602760248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206e657720656044820152663c32b1baba37b960c91b606482015260840161062b565b611102816131c6565b50565b61110d611e7b565b600180546001600160a01b0383166001600160a01b0319909116811790915561113d5f546001600160a01b031690565b6001600160a01b03167fdd01547fc40682edc3cd8d164d53f5a1ae6b46138a83f045658ed760823ddba860405160405180910390a350565b61117d611e7b565b8215611275575f5b8381101561123a57600a5f8686848181106111a2576111a2615439565b90506020020160208101906111b79190615277565b6001600160a01b0316815260208101919091526040015f9081205460ff161590600a908787858181106111ec576111ec615439565b90506020020160208101906112019190615277565b6001600160a01b0316815260208101919091526040015f20805460ff19169115159190911790558061123281615478565b915050611185565b507fb05655746bd43b7fe3ccd9d28b7685b4c67ddc51e70890062b0f7f85dd692695848460405161126c9291906157e3565b60405180910390a15b8015610965575f816001600160401b0381111561129457611294614c3b565b6040519080825280602002602001820160405280156112bd578160200160208202803683370190505b5090505f5b828110156113e757600b5f8585848181106112df576112df615439565b90506020020160208101906112f49190615277565b6001600160a01b0316815260208101919091526040015f9081205460ff161590600b9086868581811061132957611329615439565b905060200201602081019061133e9190615277565b6001600160a01b0316815260208101919091526040015f908120805460ff191692151592909217909155600b9085858481811061137d5761137d615439565b90506020020160208101906113929190615277565b6001600160a01b0316815260208101919091526040015f2054825160ff909116908390839081106113c5576113c5615439565b91151560209283029190910190910152806113df81615478565b9150506112c2565b507f4a28b173d9bc739be3886d172e07fef80392184787fc6b92406ce0f0c05b7e6383838360405161141b939291906157f6565b60405180910390a15050505050565b611432611e7b565b6001600160a01b0383161561149357600680546001600160a01b0319166001600160a01b0385169081179091556040519081527f347fade115440908839b750620f0add8f417b77a392657edd70b950373eda9c39060200160405180910390a15b6001600160a01b0382161561150157600780546001600160a01b038481166001600160a01b031983168117909355604080519190921680825260208201939093527ff9c6fa562c9d8326f8518a29a53ef18ab03cd6b9eead73ac667c5e289354c73e910160405180910390a1505b6001600160a01b0381161561082157600880546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527fb3911b5760f95a64aaa8d7f1775f57a7b6ed0bcf1ebb3fbfcc045e2f04eaad11910160405180910390a150505050565b5f61157d826125d7565b92915050565b61158b611e7b565b805f5b818110156116115784156115d0576115cb8484838181106115b1576115b1615439565b90506020020160208101906115c6919061505f565b61321f565b6115ff565b6115ff8484838181106115e5576115e5615439565b90506020020160208101906115fa919061505f565b6132b1565b8061160981615478565b91505061158e565b5050505050565b5f61069f83836120c6565b5f805f5a905061097b8585611903565b600f60f884901c165f818152600c60209081526040808320815180830190925280546001600160a01b03168252600181018054929391929184019161167790615490565b80601f01602080910402602001604051908101604052809291908181526020018280546116a390615490565b80156116ee5780601f106116c5576101008083540402835291602001916116ee565b820191905f5260205f20905b8154815290600101906020018083116116d157829003601f168201915b5050509190925250508151919250506001600160a01b03166117525760405162461bcd60e51b815260206004820152601960248201527f43616c6c6261636b2062616420706f6f6c20696e646578656400000000000000604482015260640161062b565b5f815f015185836020015160405160200161176f9392919061584f565b604051602081830303815290604052805190602001205f1c9050836001600160a01b0316816001600160a01b0316146117de5760405162461bcd60e51b815260206004820152601160248201527010d85b1b189858dac8189859081c1bdbdb607a1b604482015260640161062b565b505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291515f928392908716916118419190615897565b5f604051808303815f865af19150503d805f811461187a576040519150601f19603f3d011682016040523d82523d5f602084013e61187f565b606091505b50915091508180156118a95750805115806118a95750808060200190518101906118a991906158b2565b6116115760405162461bcd60e51b815260206004820152602560248201527f5472616e7366657248656c7065723a205452414e534645525f544f4b454e5f46604482015264105253115160da1b606482015260840161062b565b5f6002600354036119265760405162461bcd60e51b815260040161062b906154e9565b6002600355600161193681612b20565b428310156119705760405162461bcd60e51b8152602060048201526007602482015266115e1c1a5c995960ca1b604482015260640161062b565b6001600f604086013560f81c16145f8080808061198d8a87613336565b945094509450945094506119ef835f815181106119ac576119ac615439565b60200260200101518b8060e001906119c491906158cd565b5f8181106119d4576119d4615439565b90506020020160208101906119e99190615277565b866117e6565b8515611bb6578415611ad357611a4960408b013584611a1160e08e018e6158cd565b808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250309250613863915050565b611acc82611a5d60408d0160208e01615277565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a08231906024015b602060405180830381865afa158015611aa2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ac6919061544d565b90613b5a565b9750611d2b565b611b3f60408b013584611ae960e08e018e6158cd565b808060200260200160405190810160405280939291908181526020018383602002808284375f81840152601f19601f820116905080830192505050505050508d5f016020810190611b3a9190615277565b613863565b611acc818460018651611b5291906154c2565b81518110611b6257611b62615439565b60200260200101516001600160a01b03166370a082318d5f016020810190611b8a9190615277565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401611a87565b5f8a604001356001600160a01b031663d06ca61f86866040518363ffffffff1660e01b8152600401611be9929190615912565b5f60405180830381865afa158015611c03573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611c2a9190810190615967565b90508515611c9757611c7c8185611c4460e08f018f6158cd565b808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250309250613baf915050565b611c9083611a5d60408e0160208f01615277565b9850611d29565b611cff8185611ca960e08f018f6158cd565b808060200260200160405190810160405280939291908181526020018383602002808284375f81840152601f19601f820116905080830192505050505050508e5f016020810190611cfa9190615277565b613baf565b8060018251611d0e91906154c2565b81518110611d1e57611d1e615439565b602002602001015198505b505b8960800135881015611d4f5760405162461bcd60e51b815260040161062b906159e7565b8415611d8457611d6e611d6860408c0160208d01615277565b89613d99565b611d84611d7e60208c018c615277565b89611f29565b50505050505f85806101200190611d9b9190615520565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250929350611e6d9250611de391505060c08801886158cd565b5f818110611df357611df3615439565b9050602002016020810190611e089190615277565b611e1560c08901896158cd565b6001611e2460c08c018c6158cd565b611e2f9291506154c2565b818110611e3e57611e3e615439565b9050602002016020810190611e539190615277565b611e6060208a018a615277565b8960600135885f87613162565b505050600160035592915050565b33611e8d5f546001600160a01b031690565b6001600160a01b031614611eef5760405162461bcd60e51b815260206004820152602360248201527f4f776e61626c653a2063616c6c6572206973206e6f74207468652065786563756044820152623a37b960e91b606482015260840161062b565b565b5f6001600160a01b038216158061157d57506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1492915050565b604080515f808252602082019092526001600160a01b038416908390604051611f529190615897565b5f6040518083038185875af1925050503d805f8114611f8c576040519150601f19603f3d011682016040523d82523d5f602084013e611f91565b606091505b50509050806108215760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604482015260640161062b565b5f805f856001600160a01b031663a9059cbb868660405160240161201b9291906001600160a01b03929092168252602082015260400190565b6040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516120549190615897565b5f604051808303815f865af19150503d805f811461208d576040519150601f19603f3d011682016040523d82523d5f602084013e612092565b606091505b50915091508180156120bc5750805115806120bc5750808060200190518101906120bc91906158b2565b9695505050505050565b5f6002600354036120e95760405162461bcd60e51b815260040161062b906154e9565b60026003555f6120f881612b20565b5f6121066020850185615520565b90501161214f5760405162461bcd60e51b8152602060048201526017602482015276646174612073686f756c64206265206e6f74207a65726f60481b604482015260640161062b565b5f8460800135116121a25760405162461bcd60e51b815260206004820152601f60248201527f616d6f756e742073686f756c642062652067726561746572207468616e203000604482015260640161062b565b5f6121b36060860160408701615277565b6001600160a01b0316036122135760405162461bcd60e51b815260206004820152602160248201527f72656365697665722073686f756c64206265206e6f74206164647265737328306044820152602960f81b606482015260840161062b565b5f8460a00135116122775760405162461bcd60e51b815260206004820152602860248201527f6d696e52657475726e416d6f756e742073686f756c6420626520677265617465604482015267072207468616e20360c41b606482015260840161062b565b600b5f61228a6080870160608801615277565b6001600160a01b0316815260208101919091526040015f205460ff166122f25760405162461bcd60e51b815260206004820152601760248201527f696e76616c696420777261707065642061646472657373000000000000000000604482015260640161062b565b6006545f906001600160a01b03168161233b8161231260208a018a615277565b61232260808b0160608c01615277565b8560808c013560c08d0135610b8a6101008f018f615520565b90506123556123506040890160208a01615277565b611ef1565b1561237b5761236a6060880160408901615277565b6001600160a01b0316319250612412565b61238b6040880160208901615277565b6001600160a01b03166370a082316123a960608a0160408b01615277565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa1580156123eb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061240f919061544d565b92505b5f80836001600160a01b031683633f3204d28a6040516024016124359190615a14565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161246e9190615897565b5f6040518083038185875af1925050503d805f81146124a8576040519150601f19603f3d011682016040523d82523d5f602084013e6124ad565b606091505b5091509150816124e557610c43816040518060400160405280600c81526020016b2a3930b739b4ba29bbb0b81d60a11b815250612ddf565b506124fb90506123506040890160208a01615277565b1561252b576125248361251460608a0160408b01615277565b6001600160a01b03163190613b5a565b9450612560565b61255d8361253f60408a0160208b01615277565b6001600160a01b03166370a08231611b8a60608c0160408d01615277565b94505b8660a001358510156125845760405162461bcd60e51b815260040161062b906159e7565b6125c86125946020890189615277565b6125a460408a0160208b01615277565b6125b460608b0160408c01615277565b60808b0135895f610cce60e08f018f615520565b50505050600160035592915050565b5f6002600354036125fa5760405162461bcd60e51b815260040161062b906154e9565b6002600355600261260a81612b20565b5f6126196101008501856158cd565b9050116126565760405162461bcd60e51b815260206004820152600b60248201526a456d70747920706f6f6c7360a81b604482015260640161062b565b428360e0013510156126945760405162461bcd60e51b8152602060048201526007602482015266115e1c1a5c995960ca1b604482015260640161062b565b600b5f6126a76080860160608701615277565b6001600160a01b0316815260208101919091526040015f205460ff166126df5760405162461bcd60e51b815260040161062b90615a5f565b5f6126ed6020850185615277565b90505f6127006040860160208701615277565b90505f806127146123506020890189615277565b1561272c576127296080880160608901615277565b93505b5f61276b600261273f60208b018b615277565b61274f60808c0160608d01615277565b5f8c608001358d60c001358e806101200190610b8a9190615520565b905061278061235060408a0160208b01615277565b1561281a576127956080890160608a01615277565b93506127a76080890160608a01615277565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa1580156127eb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061280f919061544d565b9250600191506128b1565b61282a6040890160208a01615277565b6001600160a01b03166370a0823161284860608b0160408c01615277565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561288a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128ae919061544d565b92505b5f6128c06101008a018a6158cd565b91503090506060600183111561297857875f805b8581101561296d575f8e8061010001906128ee91906158cd565b838181106128fe576128fe615439565b905060200201359050612912848483613eac565b955093506129216001886154c2565b8214801561292d575088155b1561294b578e60400160208101906129459190615277565b95508a92505b6129578682878b614197565b975050808061296590615478565b9150506128d4565b50859b5050506129f6565b6129a7888861298b6101008f018f6158cd565b5f81811061299b5761299b615439565b90506020020135613eac565b91508590506129c3576129c060608c0160408d01615277565b91505b6129f3826129d56101008e018e6158cd565b5f8181106129e5576129e5615439565b905060200201358387614197565b99505b5050508115612a7057612a1383611a5d60808b0160608c01615277565b96508760a00135871015612a395760405162461bcd60e51b815260040161062b906159e7565b612a52612a4c60808a0160608b01615277565b88613d99565b612a6b612a6560608a0160408b01615277565b88611f29565b612ac8565b612aa283612a8460408b0160208c01615277565b6001600160a01b03166370a08231611b8a60608d0160408e01615277565b96508760a00135871015612ac85760405162461bcd60e51b815260040161062b906159e7565b612b10612ad860208a018a615277565b612ae860408b0160208c01615277565b612af860608c0160408d01615277565b8b608001358b5f8e806101400190610cce9190615520565b5050505050506001600355919050565b612b29816109b6565b156111025760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161062b565b5f805f612b7586614346565b90925090505f60038c6003811115612b8f57612b8f6154d5565b14612b9b576001612b9d565b5f5b90505f612bad828a858a8a6143a2565b9050612bb88c611ef1565b15612d325760038d6003811115612bd157612bd16154d5565b03612c2b5788341015612c1a5760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964206d73672e76616c756560781b604482015260640161062b565b612c243484613b5a565b9450612c72565b883414612c6e5760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964206d73672e76616c756560781b604482015260640161062b565b8094505b6001600160a01b038b1615612d11576001600160a01b038b165f908152600b602052604090205460ff16612cb85760405162461bcd60e51b815260040161062b90615a5f565b60038d6003811115612ccc57612ccc6154d5565b03612cee57612cdb8b86614457565b612ce68b8b87613053565b5f9450612d11565b60028d6003811115612d0257612d026154d5565b03612d1157612d118b82614457565b8315612d2d57600854612d2d906001600160a01b031684611f29565b612dcf565b612d3e8c33308c614551565b60038d6003811115612d5257612d526154d5565b03612d6a57612d628c8b83613053565b349450612daf565b5f8d6003811115612d7d57612d7d6154d5565b03612d9257612d8d8c8b836117e6565b612daf565b60028d6003811115612da657612da66154d5565b03612daf578094505b8315612dcf57600854612dcd908d906001600160a01b031685611fe2565b505b5050505098975050505050505050565b60606044835110158015612e175750825f81518110612e0057612e00615439565b6020910101516001600160f81b031916600160fb1b145b8015612e48575082600181518110612e3157612e31615439565b6020910101516001600160f81b03191660c360f81b145b8015612e79575082600281518110612e6257612e62615439565b6020910101516001600160f81b031916607960f81b145b8015612eaa575082600381518110612e9357612e93615439565b6020910101516001600160f81b031916600560fd1b145b15612f3457604483810180519091612ec29190615a96565b84511015612f0a5760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103932bb32b93a103932b0b9b7b760591b604482015260640161062b565b8281604051602001612f1d929190615aa9565b60405160208183030381529060405291505061157d565b82516024148015612f695750825f81518110612f5257612f52615439565b6020910101516001600160f81b031916602760f91b145b8015612f9a575082600181518110612f8357612f83615439565b6020910101516001600160f81b031916600960fb1b145b8015612fcb575082600281518110612fb457612fb4615439565b6020910101516001600160f81b031916607b60f81b145b8015612ffc575082600381518110612fe557612fe5615439565b6020910101516001600160f81b031916607160f81b145b156130215760248301518261301082614674565b604051602001612f1d929190615af7565b8161302b8461469c565b60405160200161303c929190615b2b565b604051602081830303815290604052905092915050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b17905291515f928392908716916130ae9190615897565b5f604051808303815f865af19150503d805f81146130e7576040519150601f19603f3d011682016040523d82523d5f602084013e6130ec565b606091505b509150915081801561311657508051158061311657508080602001905181019061311691906158b2565b6116115760405162461bcd60e51b815260206004820152601e60248201527f5472616e7366657248656c7065723a20415050524f56455f4641494c45440000604482015260640161062b565b846001600160a01b0316866001600160a01b0316886001600160a01b03167f2251435bd151cd72851a82be055bf6d1c3d7f34d08d56493dddf874229b8e897878787876040516131b59493929190615b7b565b60405180910390a450505050505050565b600180546001600160a01b03199081169091555f80546001600160a01b03848116938216841783556040519116929183917f88436636ea40d5bb1bcc55ff9cd54788af71da886f4147a87f199adcca733d4d9190a35050565b8061322981612b20565b600160025f846003811115613240576132406154d5565b6003811115613251576132516154d5565b81526020019081526020015f205f6101000a81548160ff0219169083151502179055507f534f879afd40abb4e39f8e1b77a316be4c8e3521d9cf5a3a3db8959d574d455933836040516132a5929190615b9f565b60405180910390a15050565b806132bb8161487c565b5f60025f8460038111156132d1576132d16154d5565b60038111156132e2576132e26154d5565b81526020019081526020015f205f6101000a81548160ff0219169083151502179055507f4cd3e1443d03aba343c5d882744f8f172c07b495e955ac3defb325cbd73c855033836040516132a5929190615b9f565b5f806060818061334960e08801886158cd565b61335591506001615a96565b61336260c08901896158cd565b9050146133a05760405162461bcd60e51b815260206004820152600c60248201526b092dcecc2d8d2c840e0c2e8d60a31b604482015260640161062b565b600b5f6133b360408a0160208b01615277565b6001600160a01b0316815260208101919091526040015f205460ff166133eb5760405162461bcd60e51b815260040161062b90615a5f565b5f806133fa8960a00135614346565b909250905061341d600160608b0135836134186101008e018e615520565b6143a2565b95505f61342d60c08b018b6158cd565b808060200260200160405190810160405280939291908181526020018383602002808284375f92018290525093945084925060019150613472905060c08e018e6158cd565b61347d9291506154c2565b8151811061348d5761348d615439565b602002602001015190506134cf8b8060c001906134aa91906158cd565b5f8181106134ba576134ba615439565b90506020020160208101906123509190615277565b1561358f578a60600135341461351b5760405162461bcd60e51b8152602060048201526011602482015270496e76616c6964206d73672e76616c756560781b604482015260640161062b565b831561353757600854613537906001600160a01b031684611f29565b61354760408c0160208d01615277565b825f8151811061355957613559615439565b6001600160a01b0390921660209283029190910182015261358a906135849060408e01908e01615277565b89614457565b6136f0565b89156136a157815f815181106135a7576135a7615439565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156135f5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613619919061544d565b9750613644825f8151811061363057613630615439565b602002602001015133308e60600135614551565b61369a8b60a00135611ac68a855f8151811061366257613662615439565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401611a87565b97506136b6565b6136b6825f8151811061363057613630615439565b83156136f0576136ee825f815181106136d1576136d1615439565b60209081029190910101516008546001600160a01b031685611fe2565b505b6136f981611ef1565b156137c75761370e60408c0160208d01615277565b826001845161371d91906154c2565b8151811061372d5761372d615439565b6001600160a01b03909216602092830291909101820152600199506137589060408d01908d01615277565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa15801561379c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906137c0919061544d565b9550613852565b8915613852576001600160a01b0381166370a082316137e960208e018e615277565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561382b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061384f919061544d565b94505b819650505050509295509295909350565b5f5b6001845161387391906154c2565b811015611611575f8085838151811061388e5761388e615439565b6020026020010151868460016138a49190615a96565b815181106138b4576138b4615439565b6020026020010151915091505f816001600160a01b0316836001600160a01b0316106138e15781836138e4565b82825b5090505f8685815181106138fa576138fa615439565b602002602001015190505f805f80846001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613944573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906139689190615bee565b506001600160701b031691506001600160701b031691505f80876001600160a01b03168a6001600160a01b0316146139a15782846139a4565b83835b6040516370a0823160e01b81526001600160a01b038a811660048301529294509092506139df918491908d16906370a0823190602401611a87565b95508e6001600160a01b031663054d50d48784846040518463ffffffff1660e01b8152600401613a22939291909283526020830191909152604082015260600190565b602060405180830381865afa158015613a3d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613a61919061544d565b9450505050505f80856001600160a01b0316886001600160a01b031614613a8957825f613a8c565b5f835b915091505f60028d51613a9f91906154c2565b8a10613aab578a613ad0565b8b613ab78b6001615a96565b81518110613ac757613ac7615439565b60200260200101515b604080515f8152602081019182905263022c0d9f60e01b9091529091506001600160a01b0387169063022c0d9f90613b119086908690869060248101615c2f565b5f604051808303815f87803b158015613b28575f80fd5b505af1158015613b3a573d5f803e3d5ffd5b505050505050505050505050508080613b5290615478565b915050613865565b5f82613b6683826154c2565b915081111561157d5760405162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b604482015260640161062b565b5f5b60018451613bbf91906154c2565b811015611611575f80858381518110613bda57613bda615439565b602002602001015186846001613bf09190615a96565b81518110613c0057613c00615439565b6020026020010151915091505f816001600160a01b0316836001600160a01b031610613c2d578183613c30565b82825b5090505f88613c40866001615a96565b81518110613c5057613c50615439565b602002602001015190505f80836001600160a01b0316866001600160a01b031614613c7c57825f613c7f565b5f835b915091505f60028b51613c9291906154c2565b8810613c9e5788613cc3565b89613caa896001615a96565b81518110613cba57613cba615439565b60200260200101515b9050898881518110613cd757613cd7615439565b60200260200101516001600160a01b031663022c0d9f8484845f6001600160401b03811115613d0857613d08614c3b565b6040519080825280601f01601f191660200182016040528015613d32576020820181803683370190505b506040518563ffffffff1660e01b8152600401613d529493929190615c2f565b5f604051808303815f87803b158015613d69575f80fd5b505af1158015613d7b573d5f803e3d5ffd5b50505050505050505050508080613d9190615478565b915050613bb1565b5f80836001600160a01b03165f632e1a7d4d85604051602401613dbe91815260200190565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051613df79190615897565b5f6040518083038185875af1925050503d805f8114613e31576040519150601f19603f3d011682016040523d82523d5f602084013e613e36565b606091505b5091509150818015613e60575080511580613e60575080806020019051810190613e6091906158b2565b6109655760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a2057495448445241575f4641494c454400604482015260640161062b565b5f60605f8390505f816001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ef0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613f149190615c5b565b90505f826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f53573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613f779190615c5b565b90505f836001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa158015613fb6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613fda9190615c76565b604080516001600160a01b03808716602083015285169181019190915262ffffff821660608201529091505f9060800160408051601f1981840301815291905280516020909101209050600160ff1b88161580156140da57846001600160a01b03168b6001600160a01b0316146140635760405162461bcd60e51b815260040161062b90615c98565b6001600160a01b038a16156140a357836001600160a01b03168a6001600160a01b0316146140a35760405162461bcd60e51b815260040161062b90615c98565b604080516001600160a01b03871660208201529081018390529397508793606001604051602081830303815290604052965061417e565b836001600160a01b03168b6001600160a01b03161461410b5760405162461bcd60e51b815260040161062b90615c98565b6001600160a01b038a161561414b57846001600160a01b03168a6001600160a01b03161461414b5760405162461bcd60e51b815260040161062b90615c98565b604080516001600160a01b0386166020820152908101839052949750879460600160405160208183030381529060405296505b61418989838b611633565b505050505050935093915050565b5f600160ff1b841615801561426f575f856001600160a01b031663128acb0888846141c1886148c8565b6141d16401000276a36001615cba565b8b8b6040516020016141e4929190615ce1565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401614213959493929190615cf9565b60408051808303815f875af115801561422e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906142529190615d33565b9150506142678161426290615d55565b614935565b92505061433d565b5f856001600160a01b031663128acb08888461428a886148c8565b6142a9600173fffd8963efd1fc6a506488495d951d5263988d26615d6f565b8b8b6040516020016142bc929190615ce1565b6040516020818303038152906040526040518663ffffffff1660e01b81526004016142eb959493929190615cf9565b60408051808303815f875af1158015614306573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061432a9190615d33565b50905061433961426282615d55565b9250505b50949350505050565b5f8080614354600a85615da3565b905061436b600a6143658684613b5a565b90614986565b915080600114801561437c57505f82115b801561439257506008546001600160a01b031615155b1561439c57600192505b50915091565b5f8086156143cc576143c5612710614365600454896149d390919063ffffffff16565b90506143ea565b6143e7612710614365600554896149d390919063ffffffff16565b90505b80851015614442576143fe86868686614a39565b6144425760405162461bcd60e51b8152602060048201526015602482015274496e76616c6964207369676e61747572652066656560581b604482015260640161062b565b61444c8686613b5a565b979650505050505050565b60408051600481526024810182526020810180516001600160e01b0316630d0e30db60e41b17905290515f9182916001600160a01b03861691859161449c9190615897565b5f6040518083038185875af1925050503d805f81146144d6576040519150601f19603f3d011682016040523d82523d5f602084013e6144db565b606091505b509150915081801561450557508051158061450557508080602001905181019061450591906158b2565b6109655760405162461bcd60e51b815260206004820152601e60248201527f5472616e7366657248656c7065723a204445504f5349545f4641494c45440000604482015260640161062b565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17905291515f928392908816916145b49190615897565b5f604051808303815f865af19150503d805f81146145ed576040519150601f19603f3d011682016040523d82523d5f602084013e6145f2565b606091505b509150915081801561461c57508051158061461c57508080602001905181019061461c91906158b2565b6117de5760405162461bcd60e51b8152602060048201526024808201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f46416044820152631253115160e21b606482015260840161062b565b606061157d8260405160200161468c91815260200190565b6040516020818303038152906040525b80516060906f181899199a1a9b1b9c1cb0b131b232b360811b905f906146c3906002615db6565b6146ce906002615a96565b6001600160401b038111156146e5576146e5614c3b565b6040519080825280601f01601f19166020018201604052801561470f576020820181803683370190505b509050600360fc1b815f8151811061472957614729615439565b60200101906001600160f81b03191690815f1a905350600f60fb1b8160018151811061475757614757615439565b60200101906001600160f81b03191690815f1a9053505f5b84518110156148745782600486838151811061478d5761478d615439565b01602001516001600160f81b031916901c60f81c601081106147b1576147b1615439565b1a60f81b826147c1836002615db6565b6147cc906002615a96565b815181106147dc576147dc615439565b60200101906001600160f81b03191690815f1a9053508285828151811061480557614805615439565b60209101015160f81c600f166010811061482157614821615439565b1a60f81b82614831836002615db6565b61483c906003615a96565b8151811061484c5761484c615439565b60200101906001600160f81b03191690815f1a9053508061486c81615478565b91505061476f565b509392505050565b614885816109b6565b6111025760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161062b565b5f6001600160ff1b038211156149315760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e2061604482015267371034b73a191a9b60c11b606482015260840161062b565b5090565b5f808212156149315760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f736974697665604482015260640161062b565b5f815f036149c95760405162461bcd60e51b815260206004820152601060248201526f64732d6d6174682d6469762d7a65726f60801b604482015260640161062b565b61069f8284615dcd565b5f8115806149f6575082826149e88183615db6565b92506149f49083615dcd565b145b61157d5760405162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b604482015260640161062b565b600954604080517f048f880a603b1aab0e626a287e33d603417b3d53a36f7527b7c86365bf7def4f6020820152339181019190915260608101869052608081018590525f91829160a00160405160208183030381529060405280519060200120604051602001614ac092919061190160f01b81526002810192909252602282015260420190565b6040516020818303038152906040528051906020012090505f805f614b1987878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250614ba592505050565b9250925092505f6001858585856040515f8152602001604052604051614b5b949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015614b7b573d5f803e3d5ffd5b5050604051601f1901516007546001600160a01b039081169116149b9a5050505050505050505050565b5f805f8351604114614bf95760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964207369676e6174757265206c656e6774680000000000000000604482015260640161062b565b505050602081015160408201516060909201515f1a92909190565b5f8085851115614c22575f80fd5b83861115614c2e575f80fd5b5050820193919092039150565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715614c7757614c77614c3b565b604052919050565b5f6001600160401b03821115614c9757614c97614c3b565b50601f01601f191660200190565b5f805f60608486031215614cb7575f80fd5b833592506020840135915060408401356001600160401b03811115614cda575f80fd5b8401601f81018613614cea575f80fd5b8035614cfd614cf882614c7f565b614c4f565b818152876020838501011115614d11575f80fd5b816020840160208301375f602083830101528093505050509250925092565b5f8060408385031215614d41575f80fd5b82356001600160401b03811115614d56575f80fd5b83016101408186031215614d68575f80fd5b946020939093013593505050565b5f6001600160401b03821115614d8e57614d8e614c3b565b5060051b60200190565b6001600160a01b0381168114611102575f80fd5b8035614db781614d98565b919050565b5f8060408385031215614dcd575f80fd5b82356001600160401b03811115614de2575f80fd5b8301601f81018513614df2575f80fd5b80356020614e02614cf883614d76565b82815260059290921b83018101918181019088841115614e20575f80fd5b938201935b83851015614e47578435614e3881614d98565b82529382019390820190614e25565b9550614e569050868201614dac565b93505050509250929050565b5f805f60608486031215614e74575f80fd5b8335614e7f81614d98565b92506020840135614e8f81614d98565b929592945050506040919091013590565b5f5b83811015614eba578181015183820152602001614ea2565b50505f910152565b5f8151808452614ed9816020860160208601614ea0565b601f01601f19169290920160200192915050565b831515815282151560208201526060604082015260018060a01b0382511660608201525f6020830151604060808401526120bc60a0840182614ec2565b5f805f8060608587031215614f3d575f80fd5b843593506020850135925060408501356001600160401b0380821115614f61575f80fd5b818701915087601f830112614f74575f80fd5b813581811115614f82575f80fd5b886020828501011115614f93575f80fd5b95989497505060200194505050565b5f8060408385031215614fb3575f80fd5b82356001600160401b0380821115614fc9575f80fd5b908401906101208287031215614fdd575f80fd5b90925060208401359080821115614ff2575f80fd5b50830160408186031215615004575f80fd5b809150509250929050565b5f6101608284031215615020575f80fd5b50919050565b5f60208284031215615036575f80fd5b81356001600160401b0381111561504b575f80fd5b6150578482850161500f565b949350505050565b5f6020828403121561506f575f80fd5b81356004811061069f575f80fd5b8015158114611102575f80fd5b5f82601f830112615099575f80fd5b813560206150a9614cf883614d76565b82815260059290921b840181019181810190868411156150c7575f80fd5b8286015b848110156150e257803583529183019183016150cb565b509695505050505050565b5f80604083850312156150fe575f80fd5b82356001600160401b0380821115615114575f80fd5b818501915085601f830112615127575f80fd5b81356020615137614cf883614d76565b82815260059290921b84018101918181019089841115615155575f80fd5b948201945b8386101561517c57853561516d8161507d565b8252948201949082019061515a565b96505086013592505080821115615191575f80fd5b506109888582860161508a565b5f8083601f8401126151ae575f80fd5b5081356001600160401b038111156151c4575f80fd5b6020830191508360208260051b85010111156151de575f80fd5b9250929050565b5f805f805f80606087890312156151fa575f80fd5b86356001600160401b0380821115615210575f80fd5b61521c8a838b0161519e565b90985096506020890135915080821115615234575f80fd5b6152408a838b0161519e565b90965094506040890135915080821115615258575f80fd5b5061526589828a0161519e565b979a9699509497509295939492505050565b5f60208284031215615287575f80fd5b813561069f81614d98565b5f805f80604085870312156152a5575f80fd5b84356001600160401b03808211156152bb575f80fd5b6152c78883890161519e565b909650945060208701359150808211156152df575f80fd5b506152ec8782880161519e565b95989497509550505050565b5f805f6060848603121561530a575f80fd5b833561531581614d98565b9250602084013561532581614d98565b9150604084013561533581614d98565b809150509250925092565b5f805f60408486031215615352575f80fd5b833561535d8161507d565b925060208401356001600160401b03811115615377575f80fd5b6153838682870161519e565b9497909650939450505050565b5f80604083850312156153a1575f80fd5b8251915060208301516001600160401b038111156153bd575f80fd5b8301601f810185136153cd575f80fd5b80516153db614cf882614c7f565b8181528660208385010111156153ef575f80fd5b615400826020830160208601614ea0565b8093505050509250929050565b5f806040838503121561541e575f80fd5b825161542981614d98565b6020939093015192949293505050565b634e487b7160e01b5f52603260045260245ffd5b5f6020828403121561545d575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b5f6001820161548957615489615464565b5060010190565b600181811c908216806154a457607f821691505b60208210810361502057634e487b7160e01b5f52602260045260245ffd5b8181038181111561157d5761157d615464565b634e487b7160e01b5f52602160045260245ffd5b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b5f808335601e19843603018112615535575f80fd5b8301803591506001600160401b0382111561554e575f80fd5b6020019150368190038213156151de575f80fd5b818382375f9101908152919050565b602081525f61069f6020830184614ec2565b601f821115610821575f81815260208120601f850160051c810160208610156155a95750805b601f850160051c820191505b818110156117de578281556001016155b5565b81516001600160401b038111156155e1576155e1614c3b565b6155f5816155ef8454615490565b84615583565b602080601f831160018114615628575f84156156115750858301515b5f19600386901b1c1916600185901b1785556117de565b5f85815260208120601f198616915b8281101561565657888601518255948401946001909101908401615637565b508582101561567357878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b8183525f60208085019450825f5b858110156156bf5781356156a481614d98565b6001600160a01b031687529582019590820190600101615691565b509495945050505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b5f808335601e19843603018112615707575f80fd5b83016020810192503590506001600160401b03811115615725575f80fd5b8036038213156151de575f80fd5b606080825281018690525f6001600160fb1b03871115615751575f80fd5b8660051b80896080850137808301905060206080848303018185015261577b60808301888a615683565b84810360408601528581529150808201600586901b83018201875f5b888110156157d157858303601f190184526157b2828b6156f2565b6157bd8582846156ca565b958701959450505090840190600101615797565b50909c9b505050505050505050505050565b602081525f615057602083018486615683565b604081525f615809604083018587615683565b8281036020848101919091528451808352858201928201905f5b81811015615841578451151583529383019391830191600101615823565b509098975050505050505050565b60ff60f81b81526bffffffffffffffffffffffff198460601b1660018201528260158201525f8251615888816035850160208701614ea0565b91909101603501949350505050565b5f82516158a8818460208701614ea0565b9190910192915050565b5f602082840312156158c2575f80fd5b815161069f8161507d565b5f808335601e198436030181126158e2575f80fd5b8301803591506001600160401b038211156158fb575f80fd5b6020019150600581901b36038213156151de575f80fd5b5f60408201848352602060408185015281855180845260608601915082870193505f5b8181101561595a5784516001600160a01b031683529383019391830191600101615935565b5090979650505050505050565b5f6020808385031215615978575f80fd5b82516001600160401b0381111561598d575f80fd5b8301601f8101851361599d575f80fd5b80516159ab614cf882614d76565b81815260059190911b820183019083810190878311156159c9575f80fd5b928401925b8284101561444c578351825292840192908401906159ce565b602080825260139082015272151bdbc81b1a5d1d1b19481c9958d95a5d9959606a1b604082015260600190565b602081525f8235615a2481614d98565b6001600160a01b0316602083810191909152615a42908401846156f2565b604080850152615a566060850182846156ca565b95945050505050565b60208082526017908201527f496e76616c696420777261707065642061646472657373000000000000000000604082015260600190565b8082018082111561157d5761157d615464565b5f8351615aba818460208801614ea0565b6508ae4e4dee4560d31b9083019081528351615add816006840160208801614ea0565b602960f81b60069290910191820152600701949350505050565b5f8351615b08818460208801614ea0565b650a0c2dcd2c6560d31b9083019081528351615add816006840160208801614ea0565b5f8351615b3c818460208801614ea0565b670aadcd6dcdeeedc560c31b9083019081528351615b61816008840160208801614ea0565b602960f81b60089290910191820152600901949350505050565b848152836020820152826040820152608060608201525f6120bc6080830184614ec2565b6001600160a01b03831681526040810160048310615bcb57634e487b7160e01b5f52602160045260245ffd5b8260208301529392505050565b80516001600160701b0381168114614db7575f80fd5b5f805f60608486031215615c00575f80fd5b615c0984615bd8565b9250615c1760208501615bd8565b9150604084015163ffffffff81168114615335575f80fd5b84815283602082015260018060a01b0383166040820152608060608201525f6120bc6080830184614ec2565b5f60208284031215615c6b575f80fd5b815161069f81614d98565b5f60208284031215615c86575f80fd5b815162ffffff8116811461069f575f80fd5b602080825260089082015267109859081c1bdbdb60c21b604082015260600190565b6001600160a01b03818116838216019080821115615cda57615cda615464565b5092915050565b828152604060208201525f6150576040830184614ec2565b6001600160a01b0386811682528515156020830152604082018590528316606082015260a0608082018190525f9061444c90830184614ec2565b5f8060408385031215615d44575f80fd5b505080516020909101519092909150565b5f600160ff1b8201615d6957615d69615464565b505f0390565b6001600160a01b03828116828216039080821115615cda57615cda615464565b634e487b7160e01b5f52601260045260245ffd5b5f82615db157615db1615d8f565b500690565b808202811582820484141761157d5761157d615464565b5f82615ddb57615ddb615d8f565b50049056fea2646970667358221220d82901ab41ad4a880be21280b78ed1e0f46bd9051cce7a4af24a0d40325ddb4d64736f6c63430008140033

Deployed Bytecode

0x608060405260043610610184575f3560e01c80637ec753fe116100d0578063b9b5149b11610089578063d63234e011610063578063d63234e0146105a8578063d808d889146105c5578063fa461e33146102a4578063fa9ec7af146105d8576101c3565b8063b9b5149b14610546578063bf5c55a214610559578063c34c08e514610578576101c3565b80637ec753fe1461049757806392bcc8be146104b657806394d3d793146104d5578063afed2d0e146104e9578063b93c0beb14610508578063b946fd3b14610527576101c3565b80633644e5151161013d5780635ac86ab7116101175780635ac86ab7146103e95780636b3ec416146104185780636fbf72f91461042b5780637e467ecf14610464576101c3565b80633644e515146102eb5780633c481d57146103005780634c42342f146103d6576101c3565b80630ced9fb9146101ff5780630dc4bdae146102365780630e8cc705146102575780631975b0961461027657806323a69e75146102a45780632adb806f146102c3576101c3565b366101c357604080513381523460208201527f7784f8d436dc514f0690e472c7e2d7f660a73e504c69b2350f6be5a5f02432ef910160405180910390a1005b3480156101ce575f80fd5b505f80806101df3660048184614c14565b8101906101ec9190614ca5565b9250925092506101fd8383836105eb565b005b34801561020a575f80fd5b50600654600754604080516001600160a01b039384168152929091166020830152015b60405180910390f35b610249610244366004614d30565b610694565b60405190815260200161022d565b348015610262575f80fd5b506101fd610271366004614dbc565b6106a6565b348015610281575f80fd5b50610295610290366004614e62565b610826565b60405161022d93929190614eed565b3480156102af575f80fd5b506101fd6102be366004614f2a565b610925565b6102d66102d1366004614fa2565b61096b565b6040805192835260208301919091520161022d565b3480156102f6575f80fd5b5061024960095481565b34801561030b575f80fd5b5060026020527fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b547fe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0547f679795a0195a1b76cdebb7c51d74e058aee92919b8c3389af86ef24535e8a28c5460035f527f88601476d11616a71c5be67555bd1dff4b1cbf21533d2669b768b61518cfe1c35460ff938416939283169291821691166040805194151585529215156020850152901515918301919091521515606082015260800161022d565b6102d66103e4366004615026565b610992565b3480156103f4575f80fd5b5061040861040336600461505f565b6109b6565b604051901515815260200161022d565b6101fd610426366004615026565b6109f6565b348015610436575f80fd5b506004546005546008546040805193845260208401929092526001600160a01b03169082015260600161022d565b34801561046f575f80fd5b506102497f048f880a603b1aab0e626a287e33d603417b3d53a36f7527b7c86365bf7def4f81565b3480156104a2575f80fd5b506101fd6104b13660046150ed565b610d11565b3480156104c1575f80fd5b506101fd6104d03660046151e5565b610e96565b3480156104e0575f80fd5b506101fd61107f565b3480156104f4575f80fd5b506101fd610503366004615277565b611105565b348015610513575f80fd5b506101fd610522366004615292565b611175565b348015610532575f80fd5b506101fd6105413660046152f8565b61142a565b610249610554366004615026565b611573565b348015610564575f80fd5b506101fd610573366004615340565b611583565b348015610583575f80fd5b505f546001600160a01b03165b6040516001600160a01b03909116815260200161022d565b3480156105b3575f80fd5b506001546001600160a01b0316610590565b6102496105d3366004614fa2565b611618565b6102d66105e6366004614d30565b611623565b5f8313806105f857505f82135b6106345760405162461bcd60e51b81526020600482015260086024820152674d30206f72204d3160c01b60448201526064015b60405180910390fd5b5f808280602001905181019061064a9190615390565b915091505f8082806020019051810190610664919061540d565b91509150610673848233611633565b855f88131561067f5750865b61068a8333836117e6565b5050505050505050565b5f61069f8383611903565b9392505050565b6106ae611e7b565b5f5b8251811015610821575f6106dc8483815181106106cf576106cf615439565b6020026020010151611ef1565b156106f25750476106ed8382611f29565b61079e565b83828151811061070457610704615439565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610752573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610776919061544d565b905061079c84838151811061078d5761078d615439565b60200260200101518483611fe2565b505b826001600160a01b0316336001600160a01b03168584815181106107c4576107c4615439565b60200260200101516001600160a01b03167f3115d1449a7b732c986cba18244e897a450f61e1bb8d589cd2e69e6c8924f9f78460405161080691815260200190565b60405180910390a4508061081981615478565b9150506106b0565b505050565b6040805180820182525f80825260606020808401919091526001600160a01b038781168352600a8252848320548782168452600b835285842054878552600c84529386902086518088019097528054909216865260018201805460ff92831697929095169594919384019161089a90615490565b80601f01602080910402602001604051908101604052809291908181526020018280546108c690615490565b80156109115780601f106108e857610100808354040283529160200191610911565b820191905f5260205f20905b8154815290600101906020018083116108f457829003601f168201915b505050505081525050905093509350939050565b610965848484848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506105eb92505050565b50505050565b5f805f5a905061097b85856120c6565b92505a61098890826154c2565b9150509250929050565b5f805f5a90506109a1846125d7565b92505a6109ae90826154c2565b915050915091565b5f60025f8360038111156109cc576109cc6154d5565b60038111156109dd576109dd6154d5565b815260208101919091526040015f205460ff1692915050565b600260035403610a185760405162461bcd60e51b815260040161062b906154e9565b60026003556003610a2881612b20565b5f610a37610120840184615520565b905011610a805760405162461bcd60e51b8152602060048201526017602482015276646174612073686f756c64206265206e6f74207a65726f60481b604482015260640161062b565b5f8260a0013511610ad35760405162461bcd60e51b815260206004820152601f60248201527f616d6f756e742073686f756c642062652067726561746572207468616e203000604482015260640161062b565b600a5f610ae66060850160408601615277565b6001600160a01b0316815260208101919091526040015f205460ff16610b3f5760405162461bcd60e51b815260206004820152600e60248201526d34b73b30b634b21031b0b63632b960911b604482015260640161062b565b5f610b8f6003610b526020860186615277565b610b6260a0870160808801615277565b610b726060880160408901615277565b60a088013560c0890135610b8a6101408b018b615520565b612b69565b90505f80610ba36060860160408701615277565b6001600160a01b031683610bbb610120880188615520565b604051610bc9929190615562565b5f6040518083038185875af1925050503d805f8114610c03576040519150601f19603f3d011682016040523d82523d5f602084013e610c08565b606091505b509150915081610c5c57610c43816040518060400160405280600f81526020016e2a3930b739b4ba21b937b9b9ab1a9d60891b815250612ddf565b60405162461bcd60e51b815260040161062b9190615571565b610c82610c6c6020870187615277565b610c7c6060880160408901615277565b5f613053565b50610d079050610c956020850185615277565b610ca56040860160208701615277565b610cb56080870160608801615277565b60a08701355f60e0890135610cce6101008b018b615520565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061316292505050565b5050600160035550565b610d19611e7b565b5f5b8251811015610821575f828281518110610d3757610d37615439565b602002602001015110158015610d6857506103e8828281518110610d5d57610d5d615439565b602002602001015111155b610da95760405162461bcd60e51b8152602060048201526012602482015271066656520726174652069733a302d313030360741b604482015260640161062b565b828181518110610dbb57610dbb615439565b602002602001015115610ded57818181518110610dda57610dda615439565b6020026020010151600481905550610e0e565b818181518110610dff57610dff615439565b60200260200101516005819055505b7f5fa95345cbe35dad70f67a9ca1430c22453a695590cb4fca05d58f637e85af4f838281518110610e4157610e41615439565b6020026020010151838381518110610e5b57610e5b615439565b6020026020010151604051610e7c9291909115158252602082015260400190565b60405180910390a180610e8e81615478565b915050610d1b565b610e9e611e7b565b848114610edc5760405162461bcd60e51b815260206004820152600c60248201526b696e76616c6964206461746160a01b604482015260640161062b565b828114610f1a5760405162461bcd60e51b815260206004820152600c60248201526b696e76616c6964206461746160a01b604482015260640161062b565b825f5b81811015611034576040518060400160405280878784818110610f4257610f42615439565b9050602002016020810190610f579190615277565b6001600160a01b03168152602001858584818110610f7757610f77615439565b9050602002810190610f899190615520565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201829052509390945250600c92508b90508a85818110610fd557610fd5615439565b60209081029290920135835250818101929092526040015f20825181546001600160a01b0319166001600160a01b0390911617815590820151600182019061101d90826155c8565b50905050808061102c90615478565b915050610f1d565b507f652c1af850dcc0b28fcb71cd9473023f56a89edd81bbe7b51056a04caa94002487878787878760405161106e96959493929190615733565b60405180910390a150505050505050565b33806110936001546001600160a01b031690565b6001600160a01b0316146110f95760405162461bcd60e51b815260206004820152602760248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206e657720656044820152663c32b1baba37b960c91b606482015260840161062b565b611102816131c6565b50565b61110d611e7b565b600180546001600160a01b0383166001600160a01b0319909116811790915561113d5f546001600160a01b031690565b6001600160a01b03167fdd01547fc40682edc3cd8d164d53f5a1ae6b46138a83f045658ed760823ddba860405160405180910390a350565b61117d611e7b565b8215611275575f5b8381101561123a57600a5f8686848181106111a2576111a2615439565b90506020020160208101906111b79190615277565b6001600160a01b0316815260208101919091526040015f9081205460ff161590600a908787858181106111ec576111ec615439565b90506020020160208101906112019190615277565b6001600160a01b0316815260208101919091526040015f20805460ff19169115159190911790558061123281615478565b915050611185565b507fb05655746bd43b7fe3ccd9d28b7685b4c67ddc51e70890062b0f7f85dd692695848460405161126c9291906157e3565b60405180910390a15b8015610965575f816001600160401b0381111561129457611294614c3b565b6040519080825280602002602001820160405280156112bd578160200160208202803683370190505b5090505f5b828110156113e757600b5f8585848181106112df576112df615439565b90506020020160208101906112f49190615277565b6001600160a01b0316815260208101919091526040015f9081205460ff161590600b9086868581811061132957611329615439565b905060200201602081019061133e9190615277565b6001600160a01b0316815260208101919091526040015f908120805460ff191692151592909217909155600b9085858481811061137d5761137d615439565b90506020020160208101906113929190615277565b6001600160a01b0316815260208101919091526040015f2054825160ff909116908390839081106113c5576113c5615439565b91151560209283029190910190910152806113df81615478565b9150506112c2565b507f4a28b173d9bc739be3886d172e07fef80392184787fc6b92406ce0f0c05b7e6383838360405161141b939291906157f6565b60405180910390a15050505050565b611432611e7b565b6001600160a01b0383161561149357600680546001600160a01b0319166001600160a01b0385169081179091556040519081527f347fade115440908839b750620f0add8f417b77a392657edd70b950373eda9c39060200160405180910390a15b6001600160a01b0382161561150157600780546001600160a01b038481166001600160a01b031983168117909355604080519190921680825260208201939093527ff9c6fa562c9d8326f8518a29a53ef18ab03cd6b9eead73ac667c5e289354c73e910160405180910390a1505b6001600160a01b0381161561082157600880546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527fb3911b5760f95a64aaa8d7f1775f57a7b6ed0bcf1ebb3fbfcc045e2f04eaad11910160405180910390a150505050565b5f61157d826125d7565b92915050565b61158b611e7b565b805f5b818110156116115784156115d0576115cb8484838181106115b1576115b1615439565b90506020020160208101906115c6919061505f565b61321f565b6115ff565b6115ff8484838181106115e5576115e5615439565b90506020020160208101906115fa919061505f565b6132b1565b8061160981615478565b91505061158e565b5050505050565b5f61069f83836120c6565b5f805f5a905061097b8585611903565b600f60f884901c165f818152600c60209081526040808320815180830190925280546001600160a01b03168252600181018054929391929184019161167790615490565b80601f01602080910402602001604051908101604052809291908181526020018280546116a390615490565b80156116ee5780601f106116c5576101008083540402835291602001916116ee565b820191905f5260205f20905b8154815290600101906020018083116116d157829003601f168201915b5050509190925250508151919250506001600160a01b03166117525760405162461bcd60e51b815260206004820152601960248201527f43616c6c6261636b2062616420706f6f6c20696e646578656400000000000000604482015260640161062b565b5f815f015185836020015160405160200161176f9392919061584f565b604051602081830303815290604052805190602001205f1c9050836001600160a01b0316816001600160a01b0316146117de5760405162461bcd60e51b815260206004820152601160248201527010d85b1b189858dac8189859081c1bdbdb607a1b604482015260640161062b565b505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291515f928392908716916118419190615897565b5f604051808303815f865af19150503d805f811461187a576040519150601f19603f3d011682016040523d82523d5f602084013e61187f565b606091505b50915091508180156118a95750805115806118a95750808060200190518101906118a991906158b2565b6116115760405162461bcd60e51b815260206004820152602560248201527f5472616e7366657248656c7065723a205452414e534645525f544f4b454e5f46604482015264105253115160da1b606482015260840161062b565b5f6002600354036119265760405162461bcd60e51b815260040161062b906154e9565b6002600355600161193681612b20565b428310156119705760405162461bcd60e51b8152602060048201526007602482015266115e1c1a5c995960ca1b604482015260640161062b565b6001600f604086013560f81c16145f8080808061198d8a87613336565b945094509450945094506119ef835f815181106119ac576119ac615439565b60200260200101518b8060e001906119c491906158cd565b5f8181106119d4576119d4615439565b90506020020160208101906119e99190615277565b866117e6565b8515611bb6578415611ad357611a4960408b013584611a1160e08e018e6158cd565b808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250309250613863915050565b611acc82611a5d60408d0160208e01615277565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a08231906024015b602060405180830381865afa158015611aa2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ac6919061544d565b90613b5a565b9750611d2b565b611b3f60408b013584611ae960e08e018e6158cd565b808060200260200160405190810160405280939291908181526020018383602002808284375f81840152601f19601f820116905080830192505050505050508d5f016020810190611b3a9190615277565b613863565b611acc818460018651611b5291906154c2565b81518110611b6257611b62615439565b60200260200101516001600160a01b03166370a082318d5f016020810190611b8a9190615277565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401611a87565b5f8a604001356001600160a01b031663d06ca61f86866040518363ffffffff1660e01b8152600401611be9929190615912565b5f60405180830381865afa158015611c03573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611c2a9190810190615967565b90508515611c9757611c7c8185611c4460e08f018f6158cd565b808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250309250613baf915050565b611c9083611a5d60408e0160208f01615277565b9850611d29565b611cff8185611ca960e08f018f6158cd565b808060200260200160405190810160405280939291908181526020018383602002808284375f81840152601f19601f820116905080830192505050505050508e5f016020810190611cfa9190615277565b613baf565b8060018251611d0e91906154c2565b81518110611d1e57611d1e615439565b602002602001015198505b505b8960800135881015611d4f5760405162461bcd60e51b815260040161062b906159e7565b8415611d8457611d6e611d6860408c0160208d01615277565b89613d99565b611d84611d7e60208c018c615277565b89611f29565b50505050505f85806101200190611d9b9190615520565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250929350611e6d9250611de391505060c08801886158cd565b5f818110611df357611df3615439565b9050602002016020810190611e089190615277565b611e1560c08901896158cd565b6001611e2460c08c018c6158cd565b611e2f9291506154c2565b818110611e3e57611e3e615439565b9050602002016020810190611e539190615277565b611e6060208a018a615277565b8960600135885f87613162565b505050600160035592915050565b33611e8d5f546001600160a01b031690565b6001600160a01b031614611eef5760405162461bcd60e51b815260206004820152602360248201527f4f776e61626c653a2063616c6c6572206973206e6f74207468652065786563756044820152623a37b960e91b606482015260840161062b565b565b5f6001600160a01b038216158061157d57506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1492915050565b604080515f808252602082019092526001600160a01b038416908390604051611f529190615897565b5f6040518083038185875af1925050503d805f8114611f8c576040519150601f19603f3d011682016040523d82523d5f602084013e611f91565b606091505b50509050806108215760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604482015260640161062b565b5f805f856001600160a01b031663a9059cbb868660405160240161201b9291906001600160a01b03929092168252602082015260400190565b6040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516120549190615897565b5f604051808303815f865af19150503d805f811461208d576040519150601f19603f3d011682016040523d82523d5f602084013e612092565b606091505b50915091508180156120bc5750805115806120bc5750808060200190518101906120bc91906158b2565b9695505050505050565b5f6002600354036120e95760405162461bcd60e51b815260040161062b906154e9565b60026003555f6120f881612b20565b5f6121066020850185615520565b90501161214f5760405162461bcd60e51b8152602060048201526017602482015276646174612073686f756c64206265206e6f74207a65726f60481b604482015260640161062b565b5f8460800135116121a25760405162461bcd60e51b815260206004820152601f60248201527f616d6f756e742073686f756c642062652067726561746572207468616e203000604482015260640161062b565b5f6121b36060860160408701615277565b6001600160a01b0316036122135760405162461bcd60e51b815260206004820152602160248201527f72656365697665722073686f756c64206265206e6f74206164647265737328306044820152602960f81b606482015260840161062b565b5f8460a00135116122775760405162461bcd60e51b815260206004820152602860248201527f6d696e52657475726e416d6f756e742073686f756c6420626520677265617465604482015267072207468616e20360c41b606482015260840161062b565b600b5f61228a6080870160608801615277565b6001600160a01b0316815260208101919091526040015f205460ff166122f25760405162461bcd60e51b815260206004820152601760248201527f696e76616c696420777261707065642061646472657373000000000000000000604482015260640161062b565b6006545f906001600160a01b03168161233b8161231260208a018a615277565b61232260808b0160608c01615277565b8560808c013560c08d0135610b8a6101008f018f615520565b90506123556123506040890160208a01615277565b611ef1565b1561237b5761236a6060880160408901615277565b6001600160a01b0316319250612412565b61238b6040880160208901615277565b6001600160a01b03166370a082316123a960608a0160408b01615277565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa1580156123eb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061240f919061544d565b92505b5f80836001600160a01b031683633f3204d28a6040516024016124359190615a14565b6040516020818303038152906040529060e01b6020820180516001600160e01b03838183161783525050505060405161246e9190615897565b5f6040518083038185875af1925050503d805f81146124a8576040519150601f19603f3d011682016040523d82523d5f602084013e6124ad565b606091505b5091509150816124e557610c43816040518060400160405280600c81526020016b2a3930b739b4ba29bbb0b81d60a11b815250612ddf565b506124fb90506123506040890160208a01615277565b1561252b576125248361251460608a0160408b01615277565b6001600160a01b03163190613b5a565b9450612560565b61255d8361253f60408a0160208b01615277565b6001600160a01b03166370a08231611b8a60608c0160408d01615277565b94505b8660a001358510156125845760405162461bcd60e51b815260040161062b906159e7565b6125c86125946020890189615277565b6125a460408a0160208b01615277565b6125b460608b0160408c01615277565b60808b0135895f610cce60e08f018f615520565b50505050600160035592915050565b5f6002600354036125fa5760405162461bcd60e51b815260040161062b906154e9565b6002600355600261260a81612b20565b5f6126196101008501856158cd565b9050116126565760405162461bcd60e51b815260206004820152600b60248201526a456d70747920706f6f6c7360a81b604482015260640161062b565b428360e0013510156126945760405162461bcd60e51b8152602060048201526007602482015266115e1c1a5c995960ca1b604482015260640161062b565b600b5f6126a76080860160608701615277565b6001600160a01b0316815260208101919091526040015f205460ff166126df5760405162461bcd60e51b815260040161062b90615a5f565b5f6126ed6020850185615277565b90505f6127006040860160208701615277565b90505f806127146123506020890189615277565b1561272c576127296080880160608901615277565b93505b5f61276b600261273f60208b018b615277565b61274f60808c0160608d01615277565b5f8c608001358d60c001358e806101200190610b8a9190615520565b905061278061235060408a0160208b01615277565b1561281a576127956080890160608a01615277565b93506127a76080890160608a01615277565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa1580156127eb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061280f919061544d565b9250600191506128b1565b61282a6040890160208a01615277565b6001600160a01b03166370a0823161284860608b0160408c01615277565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561288a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128ae919061544d565b92505b5f6128c06101008a018a6158cd565b91503090506060600183111561297857875f805b8581101561296d575f8e8061010001906128ee91906158cd565b838181106128fe576128fe615439565b905060200201359050612912848483613eac565b955093506129216001886154c2565b8214801561292d575088155b1561294b578e60400160208101906129459190615277565b95508a92505b6129578682878b614197565b975050808061296590615478565b9150506128d4565b50859b5050506129f6565b6129a7888861298b6101008f018f6158cd565b5f81811061299b5761299b615439565b90506020020135613eac565b91508590506129c3576129c060608c0160408d01615277565b91505b6129f3826129d56101008e018e6158cd565b5f8181106129e5576129e5615439565b905060200201358387614197565b99505b5050508115612a7057612a1383611a5d60808b0160608c01615277565b96508760a00135871015612a395760405162461bcd60e51b815260040161062b906159e7565b612a52612a4c60808a0160608b01615277565b88613d99565b612a6b612a6560608a0160408b01615277565b88611f29565b612ac8565b612aa283612a8460408b0160208c01615277565b6001600160a01b03166370a08231611b8a60608d0160408e01615277565b96508760a00135871015612ac85760405162461bcd60e51b815260040161062b906159e7565b612b10612ad860208a018a615277565b612ae860408b0160208c01615277565b612af860608c0160408d01615277565b8b608001358b5f8e806101400190610cce9190615520565b5050505050506001600355919050565b612b29816109b6565b156111025760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161062b565b5f805f612b7586614346565b90925090505f60038c6003811115612b8f57612b8f6154d5565b14612b9b576001612b9d565b5f5b90505f612bad828a858a8a6143a2565b9050612bb88c611ef1565b15612d325760038d6003811115612bd157612bd16154d5565b03612c2b5788341015612c1a5760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964206d73672e76616c756560781b604482015260640161062b565b612c243484613b5a565b9450612c72565b883414612c6e5760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964206d73672e76616c756560781b604482015260640161062b565b8094505b6001600160a01b038b1615612d11576001600160a01b038b165f908152600b602052604090205460ff16612cb85760405162461bcd60e51b815260040161062b90615a5f565b60038d6003811115612ccc57612ccc6154d5565b03612cee57612cdb8b86614457565b612ce68b8b87613053565b5f9450612d11565b60028d6003811115612d0257612d026154d5565b03612d1157612d118b82614457565b8315612d2d57600854612d2d906001600160a01b031684611f29565b612dcf565b612d3e8c33308c614551565b60038d6003811115612d5257612d526154d5565b03612d6a57612d628c8b83613053565b349450612daf565b5f8d6003811115612d7d57612d7d6154d5565b03612d9257612d8d8c8b836117e6565b612daf565b60028d6003811115612da657612da66154d5565b03612daf578094505b8315612dcf57600854612dcd908d906001600160a01b031685611fe2565b505b5050505098975050505050505050565b60606044835110158015612e175750825f81518110612e0057612e00615439565b6020910101516001600160f81b031916600160fb1b145b8015612e48575082600181518110612e3157612e31615439565b6020910101516001600160f81b03191660c360f81b145b8015612e79575082600281518110612e6257612e62615439565b6020910101516001600160f81b031916607960f81b145b8015612eaa575082600381518110612e9357612e93615439565b6020910101516001600160f81b031916600560fd1b145b15612f3457604483810180519091612ec29190615a96565b84511015612f0a5760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103932bb32b93a103932b0b9b7b760591b604482015260640161062b565b8281604051602001612f1d929190615aa9565b60405160208183030381529060405291505061157d565b82516024148015612f695750825f81518110612f5257612f52615439565b6020910101516001600160f81b031916602760f91b145b8015612f9a575082600181518110612f8357612f83615439565b6020910101516001600160f81b031916600960fb1b145b8015612fcb575082600281518110612fb457612fb4615439565b6020910101516001600160f81b031916607b60f81b145b8015612ffc575082600381518110612fe557612fe5615439565b6020910101516001600160f81b031916607160f81b145b156130215760248301518261301082614674565b604051602001612f1d929190615af7565b8161302b8461469c565b60405160200161303c929190615b2b565b604051602081830303815290604052905092915050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b17905291515f928392908716916130ae9190615897565b5f604051808303815f865af19150503d805f81146130e7576040519150601f19603f3d011682016040523d82523d5f602084013e6130ec565b606091505b509150915081801561311657508051158061311657508080602001905181019061311691906158b2565b6116115760405162461bcd60e51b815260206004820152601e60248201527f5472616e7366657248656c7065723a20415050524f56455f4641494c45440000604482015260640161062b565b846001600160a01b0316866001600160a01b0316886001600160a01b03167f2251435bd151cd72851a82be055bf6d1c3d7f34d08d56493dddf874229b8e897878787876040516131b59493929190615b7b565b60405180910390a450505050505050565b600180546001600160a01b03199081169091555f80546001600160a01b03848116938216841783556040519116929183917f88436636ea40d5bb1bcc55ff9cd54788af71da886f4147a87f199adcca733d4d9190a35050565b8061322981612b20565b600160025f846003811115613240576132406154d5565b6003811115613251576132516154d5565b81526020019081526020015f205f6101000a81548160ff0219169083151502179055507f534f879afd40abb4e39f8e1b77a316be4c8e3521d9cf5a3a3db8959d574d455933836040516132a5929190615b9f565b60405180910390a15050565b806132bb8161487c565b5f60025f8460038111156132d1576132d16154d5565b60038111156132e2576132e26154d5565b81526020019081526020015f205f6101000a81548160ff0219169083151502179055507f4cd3e1443d03aba343c5d882744f8f172c07b495e955ac3defb325cbd73c855033836040516132a5929190615b9f565b5f806060818061334960e08801886158cd565b61335591506001615a96565b61336260c08901896158cd565b9050146133a05760405162461bcd60e51b815260206004820152600c60248201526b092dcecc2d8d2c840e0c2e8d60a31b604482015260640161062b565b600b5f6133b360408a0160208b01615277565b6001600160a01b0316815260208101919091526040015f205460ff166133eb5760405162461bcd60e51b815260040161062b90615a5f565b5f806133fa8960a00135614346565b909250905061341d600160608b0135836134186101008e018e615520565b6143a2565b95505f61342d60c08b018b6158cd565b808060200260200160405190810160405280939291908181526020018383602002808284375f92018290525093945084925060019150613472905060c08e018e6158cd565b61347d9291506154c2565b8151811061348d5761348d615439565b602002602001015190506134cf8b8060c001906134aa91906158cd565b5f8181106134ba576134ba615439565b90506020020160208101906123509190615277565b1561358f578a60600135341461351b5760405162461bcd60e51b8152602060048201526011602482015270496e76616c6964206d73672e76616c756560781b604482015260640161062b565b831561353757600854613537906001600160a01b031684611f29565b61354760408c0160208d01615277565b825f8151811061355957613559615439565b6001600160a01b0390921660209283029190910182015261358a906135849060408e01908e01615277565b89614457565b6136f0565b89156136a157815f815181106135a7576135a7615439565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156135f5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613619919061544d565b9750613644825f8151811061363057613630615439565b602002602001015133308e60600135614551565b61369a8b60a00135611ac68a855f8151811061366257613662615439565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401611a87565b97506136b6565b6136b6825f8151811061363057613630615439565b83156136f0576136ee825f815181106136d1576136d1615439565b60209081029190910101516008546001600160a01b031685611fe2565b505b6136f981611ef1565b156137c75761370e60408c0160208d01615277565b826001845161371d91906154c2565b8151811061372d5761372d615439565b6001600160a01b03909216602092830291909101820152600199506137589060408d01908d01615277565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa15801561379c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906137c0919061544d565b9550613852565b8915613852576001600160a01b0381166370a082316137e960208e018e615277565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561382b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061384f919061544d565b94505b819650505050509295509295909350565b5f5b6001845161387391906154c2565b811015611611575f8085838151811061388e5761388e615439565b6020026020010151868460016138a49190615a96565b815181106138b4576138b4615439565b6020026020010151915091505f816001600160a01b0316836001600160a01b0316106138e15781836138e4565b82825b5090505f8685815181106138fa576138fa615439565b602002602001015190505f805f80846001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613944573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906139689190615bee565b506001600160701b031691506001600160701b031691505f80876001600160a01b03168a6001600160a01b0316146139a15782846139a4565b83835b6040516370a0823160e01b81526001600160a01b038a811660048301529294509092506139df918491908d16906370a0823190602401611a87565b95508e6001600160a01b031663054d50d48784846040518463ffffffff1660e01b8152600401613a22939291909283526020830191909152604082015260600190565b602060405180830381865afa158015613a3d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613a61919061544d565b9450505050505f80856001600160a01b0316886001600160a01b031614613a8957825f613a8c565b5f835b915091505f60028d51613a9f91906154c2565b8a10613aab578a613ad0565b8b613ab78b6001615a96565b81518110613ac757613ac7615439565b60200260200101515b604080515f8152602081019182905263022c0d9f60e01b9091529091506001600160a01b0387169063022c0d9f90613b119086908690869060248101615c2f565b5f604051808303815f87803b158015613b28575f80fd5b505af1158015613b3a573d5f803e3d5ffd5b505050505050505050505050508080613b5290615478565b915050613865565b5f82613b6683826154c2565b915081111561157d5760405162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b604482015260640161062b565b5f5b60018451613bbf91906154c2565b811015611611575f80858381518110613bda57613bda615439565b602002602001015186846001613bf09190615a96565b81518110613c0057613c00615439565b6020026020010151915091505f816001600160a01b0316836001600160a01b031610613c2d578183613c30565b82825b5090505f88613c40866001615a96565b81518110613c5057613c50615439565b602002602001015190505f80836001600160a01b0316866001600160a01b031614613c7c57825f613c7f565b5f835b915091505f60028b51613c9291906154c2565b8810613c9e5788613cc3565b89613caa896001615a96565b81518110613cba57613cba615439565b60200260200101515b9050898881518110613cd757613cd7615439565b60200260200101516001600160a01b031663022c0d9f8484845f6001600160401b03811115613d0857613d08614c3b565b6040519080825280601f01601f191660200182016040528015613d32576020820181803683370190505b506040518563ffffffff1660e01b8152600401613d529493929190615c2f565b5f604051808303815f87803b158015613d69575f80fd5b505af1158015613d7b573d5f803e3d5ffd5b50505050505050505050508080613d9190615478565b915050613bb1565b5f80836001600160a01b03165f632e1a7d4d85604051602401613dbe91815260200190565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051613df79190615897565b5f6040518083038185875af1925050503d805f8114613e31576040519150601f19603f3d011682016040523d82523d5f602084013e613e36565b606091505b5091509150818015613e60575080511580613e60575080806020019051810190613e6091906158b2565b6109655760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a2057495448445241575f4641494c454400604482015260640161062b565b5f60605f8390505f816001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ef0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613f149190615c5b565b90505f826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015613f53573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613f779190615c5b565b90505f836001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa158015613fb6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613fda9190615c76565b604080516001600160a01b03808716602083015285169181019190915262ffffff821660608201529091505f9060800160408051601f1981840301815291905280516020909101209050600160ff1b88161580156140da57846001600160a01b03168b6001600160a01b0316146140635760405162461bcd60e51b815260040161062b90615c98565b6001600160a01b038a16156140a357836001600160a01b03168a6001600160a01b0316146140a35760405162461bcd60e51b815260040161062b90615c98565b604080516001600160a01b03871660208201529081018390529397508793606001604051602081830303815290604052965061417e565b836001600160a01b03168b6001600160a01b03161461410b5760405162461bcd60e51b815260040161062b90615c98565b6001600160a01b038a161561414b57846001600160a01b03168a6001600160a01b03161461414b5760405162461bcd60e51b815260040161062b90615c98565b604080516001600160a01b0386166020820152908101839052949750879460600160405160208183030381529060405296505b61418989838b611633565b505050505050935093915050565b5f600160ff1b841615801561426f575f856001600160a01b031663128acb0888846141c1886148c8565b6141d16401000276a36001615cba565b8b8b6040516020016141e4929190615ce1565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401614213959493929190615cf9565b60408051808303815f875af115801561422e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906142529190615d33565b9150506142678161426290615d55565b614935565b92505061433d565b5f856001600160a01b031663128acb08888461428a886148c8565b6142a9600173fffd8963efd1fc6a506488495d951d5263988d26615d6f565b8b8b6040516020016142bc929190615ce1565b6040516020818303038152906040526040518663ffffffff1660e01b81526004016142eb959493929190615cf9565b60408051808303815f875af1158015614306573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061432a9190615d33565b50905061433961426282615d55565b9250505b50949350505050565b5f8080614354600a85615da3565b905061436b600a6143658684613b5a565b90614986565b915080600114801561437c57505f82115b801561439257506008546001600160a01b031615155b1561439c57600192505b50915091565b5f8086156143cc576143c5612710614365600454896149d390919063ffffffff16565b90506143ea565b6143e7612710614365600554896149d390919063ffffffff16565b90505b80851015614442576143fe86868686614a39565b6144425760405162461bcd60e51b8152602060048201526015602482015274496e76616c6964207369676e61747572652066656560581b604482015260640161062b565b61444c8686613b5a565b979650505050505050565b60408051600481526024810182526020810180516001600160e01b0316630d0e30db60e41b17905290515f9182916001600160a01b03861691859161449c9190615897565b5f6040518083038185875af1925050503d805f81146144d6576040519150601f19603f3d011682016040523d82523d5f602084013e6144db565b606091505b509150915081801561450557508051158061450557508080602001905181019061450591906158b2565b6109655760405162461bcd60e51b815260206004820152601e60248201527f5472616e7366657248656c7065723a204445504f5349545f4641494c45440000604482015260640161062b565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17905291515f928392908816916145b49190615897565b5f604051808303815f865af19150503d805f81146145ed576040519150601f19603f3d011682016040523d82523d5f602084013e6145f2565b606091505b509150915081801561461c57508051158061461c57508080602001905181019061461c91906158b2565b6117de5760405162461bcd60e51b8152602060048201526024808201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f46416044820152631253115160e21b606482015260840161062b565b606061157d8260405160200161468c91815260200190565b6040516020818303038152906040525b80516060906f181899199a1a9b1b9c1cb0b131b232b360811b905f906146c3906002615db6565b6146ce906002615a96565b6001600160401b038111156146e5576146e5614c3b565b6040519080825280601f01601f19166020018201604052801561470f576020820181803683370190505b509050600360fc1b815f8151811061472957614729615439565b60200101906001600160f81b03191690815f1a905350600f60fb1b8160018151811061475757614757615439565b60200101906001600160f81b03191690815f1a9053505f5b84518110156148745782600486838151811061478d5761478d615439565b01602001516001600160f81b031916901c60f81c601081106147b1576147b1615439565b1a60f81b826147c1836002615db6565b6147cc906002615a96565b815181106147dc576147dc615439565b60200101906001600160f81b03191690815f1a9053508285828151811061480557614805615439565b60209101015160f81c600f166010811061482157614821615439565b1a60f81b82614831836002615db6565b61483c906003615a96565b8151811061484c5761484c615439565b60200101906001600160f81b03191690815f1a9053508061486c81615478565b91505061476f565b509392505050565b614885816109b6565b6111025760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161062b565b5f6001600160ff1b038211156149315760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e2061604482015267371034b73a191a9b60c11b606482015260840161062b565b5090565b5f808212156149315760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f736974697665604482015260640161062b565b5f815f036149c95760405162461bcd60e51b815260206004820152601060248201526f64732d6d6174682d6469762d7a65726f60801b604482015260640161062b565b61069f8284615dcd565b5f8115806149f6575082826149e88183615db6565b92506149f49083615dcd565b145b61157d5760405162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b604482015260640161062b565b600954604080517f048f880a603b1aab0e626a287e33d603417b3d53a36f7527b7c86365bf7def4f6020820152339181019190915260608101869052608081018590525f91829160a00160405160208183030381529060405280519060200120604051602001614ac092919061190160f01b81526002810192909252602282015260420190565b6040516020818303038152906040528051906020012090505f805f614b1987878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250614ba592505050565b9250925092505f6001858585856040515f8152602001604052604051614b5b949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015614b7b573d5f803e3d5ffd5b5050604051601f1901516007546001600160a01b039081169116149b9a5050505050505050505050565b5f805f8351604114614bf95760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964207369676e6174757265206c656e6774680000000000000000604482015260640161062b565b505050602081015160408201516060909201515f1a92909190565b5f8085851115614c22575f80fd5b83861115614c2e575f80fd5b5050820193919092039150565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715614c7757614c77614c3b565b604052919050565b5f6001600160401b03821115614c9757614c97614c3b565b50601f01601f191660200190565b5f805f60608486031215614cb7575f80fd5b833592506020840135915060408401356001600160401b03811115614cda575f80fd5b8401601f81018613614cea575f80fd5b8035614cfd614cf882614c7f565b614c4f565b818152876020838501011115614d11575f80fd5b816020840160208301375f602083830101528093505050509250925092565b5f8060408385031215614d41575f80fd5b82356001600160401b03811115614d56575f80fd5b83016101408186031215614d68575f80fd5b946020939093013593505050565b5f6001600160401b03821115614d8e57614d8e614c3b565b5060051b60200190565b6001600160a01b0381168114611102575f80fd5b8035614db781614d98565b919050565b5f8060408385031215614dcd575f80fd5b82356001600160401b03811115614de2575f80fd5b8301601f81018513614df2575f80fd5b80356020614e02614cf883614d76565b82815260059290921b83018101918181019088841115614e20575f80fd5b938201935b83851015614e47578435614e3881614d98565b82529382019390820190614e25565b9550614e569050868201614dac565b93505050509250929050565b5f805f60608486031215614e74575f80fd5b8335614e7f81614d98565b92506020840135614e8f81614d98565b929592945050506040919091013590565b5f5b83811015614eba578181015183820152602001614ea2565b50505f910152565b5f8151808452614ed9816020860160208601614ea0565b601f01601f19169290920160200192915050565b831515815282151560208201526060604082015260018060a01b0382511660608201525f6020830151604060808401526120bc60a0840182614ec2565b5f805f8060608587031215614f3d575f80fd5b843593506020850135925060408501356001600160401b0380821115614f61575f80fd5b818701915087601f830112614f74575f80fd5b813581811115614f82575f80fd5b886020828501011115614f93575f80fd5b95989497505060200194505050565b5f8060408385031215614fb3575f80fd5b82356001600160401b0380821115614fc9575f80fd5b908401906101208287031215614fdd575f80fd5b90925060208401359080821115614ff2575f80fd5b50830160408186031215615004575f80fd5b809150509250929050565b5f6101608284031215615020575f80fd5b50919050565b5f60208284031215615036575f80fd5b81356001600160401b0381111561504b575f80fd5b6150578482850161500f565b949350505050565b5f6020828403121561506f575f80fd5b81356004811061069f575f80fd5b8015158114611102575f80fd5b5f82601f830112615099575f80fd5b813560206150a9614cf883614d76565b82815260059290921b840181019181810190868411156150c7575f80fd5b8286015b848110156150e257803583529183019183016150cb565b509695505050505050565b5f80604083850312156150fe575f80fd5b82356001600160401b0380821115615114575f80fd5b818501915085601f830112615127575f80fd5b81356020615137614cf883614d76565b82815260059290921b84018101918181019089841115615155575f80fd5b948201945b8386101561517c57853561516d8161507d565b8252948201949082019061515a565b96505086013592505080821115615191575f80fd5b506109888582860161508a565b5f8083601f8401126151ae575f80fd5b5081356001600160401b038111156151c4575f80fd5b6020830191508360208260051b85010111156151de575f80fd5b9250929050565b5f805f805f80606087890312156151fa575f80fd5b86356001600160401b0380821115615210575f80fd5b61521c8a838b0161519e565b90985096506020890135915080821115615234575f80fd5b6152408a838b0161519e565b90965094506040890135915080821115615258575f80fd5b5061526589828a0161519e565b979a9699509497509295939492505050565b5f60208284031215615287575f80fd5b813561069f81614d98565b5f805f80604085870312156152a5575f80fd5b84356001600160401b03808211156152bb575f80fd5b6152c78883890161519e565b909650945060208701359150808211156152df575f80fd5b506152ec8782880161519e565b95989497509550505050565b5f805f6060848603121561530a575f80fd5b833561531581614d98565b9250602084013561532581614d98565b9150604084013561533581614d98565b809150509250925092565b5f805f60408486031215615352575f80fd5b833561535d8161507d565b925060208401356001600160401b03811115615377575f80fd5b6153838682870161519e565b9497909650939450505050565b5f80604083850312156153a1575f80fd5b8251915060208301516001600160401b038111156153bd575f80fd5b8301601f810185136153cd575f80fd5b80516153db614cf882614c7f565b8181528660208385010111156153ef575f80fd5b615400826020830160208601614ea0565b8093505050509250929050565b5f806040838503121561541e575f80fd5b825161542981614d98565b6020939093015192949293505050565b634e487b7160e01b5f52603260045260245ffd5b5f6020828403121561545d575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b5f6001820161548957615489615464565b5060010190565b600181811c908216806154a457607f821691505b60208210810361502057634e487b7160e01b5f52602260045260245ffd5b8181038181111561157d5761157d615464565b634e487b7160e01b5f52602160045260245ffd5b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b5f808335601e19843603018112615535575f80fd5b8301803591506001600160401b0382111561554e575f80fd5b6020019150368190038213156151de575f80fd5b818382375f9101908152919050565b602081525f61069f6020830184614ec2565b601f821115610821575f81815260208120601f850160051c810160208610156155a95750805b601f850160051c820191505b818110156117de578281556001016155b5565b81516001600160401b038111156155e1576155e1614c3b565b6155f5816155ef8454615490565b84615583565b602080601f831160018114615628575f84156156115750858301515b5f19600386901b1c1916600185901b1785556117de565b5f85815260208120601f198616915b8281101561565657888601518255948401946001909101908401615637565b508582101561567357878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b8183525f60208085019450825f5b858110156156bf5781356156a481614d98565b6001600160a01b031687529582019590820190600101615691565b509495945050505050565b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b5f808335601e19843603018112615707575f80fd5b83016020810192503590506001600160401b03811115615725575f80fd5b8036038213156151de575f80fd5b606080825281018690525f6001600160fb1b03871115615751575f80fd5b8660051b80896080850137808301905060206080848303018185015261577b60808301888a615683565b84810360408601528581529150808201600586901b83018201875f5b888110156157d157858303601f190184526157b2828b6156f2565b6157bd8582846156ca565b958701959450505090840190600101615797565b50909c9b505050505050505050505050565b602081525f615057602083018486615683565b604081525f615809604083018587615683565b8281036020848101919091528451808352858201928201905f5b81811015615841578451151583529383019391830191600101615823565b509098975050505050505050565b60ff60f81b81526bffffffffffffffffffffffff198460601b1660018201528260158201525f8251615888816035850160208701614ea0565b91909101603501949350505050565b5f82516158a8818460208701614ea0565b9190910192915050565b5f602082840312156158c2575f80fd5b815161069f8161507d565b5f808335601e198436030181126158e2575f80fd5b8301803591506001600160401b038211156158fb575f80fd5b6020019150600581901b36038213156151de575f80fd5b5f60408201848352602060408185015281855180845260608601915082870193505f5b8181101561595a5784516001600160a01b031683529383019391830191600101615935565b5090979650505050505050565b5f6020808385031215615978575f80fd5b82516001600160401b0381111561598d575f80fd5b8301601f8101851361599d575f80fd5b80516159ab614cf882614d76565b81815260059190911b820183019083810190878311156159c9575f80fd5b928401925b8284101561444c578351825292840192908401906159ce565b602080825260139082015272151bdbc81b1a5d1d1b19481c9958d95a5d9959606a1b604082015260600190565b602081525f8235615a2481614d98565b6001600160a01b0316602083810191909152615a42908401846156f2565b604080850152615a566060850182846156ca565b95945050505050565b60208082526017908201527f496e76616c696420777261707065642061646472657373000000000000000000604082015260600190565b8082018082111561157d5761157d615464565b5f8351615aba818460208801614ea0565b6508ae4e4dee4560d31b9083019081528351615add816006840160208801614ea0565b602960f81b60069290910191820152600701949350505050565b5f8351615b08818460208801614ea0565b650a0c2dcd2c6560d31b9083019081528351615add816006840160208801614ea0565b5f8351615b3c818460208801614ea0565b670aadcd6dcdeeedc560c31b9083019081528351615b61816008840160208801614ea0565b602960f81b60089290910191820152600901949350505050565b848152836020820152826040820152608060608201525f6120bc6080830184614ec2565b6001600160a01b03831681526040810160048310615bcb57634e487b7160e01b5f52602160045260245ffd5b8260208301529392505050565b80516001600160701b0381168114614db7575f80fd5b5f805f60608486031215615c00575f80fd5b615c0984615bd8565b9250615c1760208501615bd8565b9150604084015163ffffffff81168114615335575f80fd5b84815283602082015260018060a01b0383166040820152608060608201525f6120bc6080830184614ec2565b5f60208284031215615c6b575f80fd5b815161069f81614d98565b5f60208284031215615c86575f80fd5b815162ffffff8116811461069f575f80fd5b602080825260089082015267109859081c1bdbdb60c21b604082015260600190565b6001600160a01b03818116838216019080821115615cda57615cda615464565b5092915050565b828152604060208201525f6150576040830184614ec2565b6001600160a01b0386811682528515156020830152604082018590528316606082015260a0608082018190525f9061444c90830184614ec2565b5f8060408385031215615d44575f80fd5b505080516020909101519092909150565b5f600160ff1b8201615d6957615d69615464565b505f0390565b6001600160a01b03828116828216039080821115615cda57615cda615464565b634e487b7160e01b5f52601260045260245ffd5b5f82615db157615db1615d8f565b500690565b808202811582820484141761157d5761157d615464565b5f82615ddb57615ddb615d8f565b50049056fea2646970667358221220d82901ab41ad4a880be21280b78ed1e0f46bd9051cce7a4af24a0d40325ddb4d64736f6c63430008140033

Block Transaction Gas Used Reward
view all blocks produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Chain Token Portfolio % Price Amount Value
BLAST23.11%$2,263.190.8445$1,911.21
BLAST5.78%$0.982937486.4075$478.11
BLAST2.05%$0.01415911,943.1304$169.11
BLAST1.41%$0.00783714,831.6515$116.24
BLAST0.23%$0.00123115,448.4481$19.02
BLAST0.12%$0.01557614.0102$9.56
BLAST0.10%$0.0059961,419.4119$8.51
BLAST0.06%$0.07659567.7255$5.19
BLAST0.04%$0.000021144,204.513$3.09
BLAST0.03%<$0.00000110,893,779,514.4255$2.18
BLAST0.02%$0.010896135.7399$1.48
BLAST0.02%<$0.000001461,009,239.4256$1.34
BLAST0.02%$0.0008561,475.6728$1.26
BLAST<0.01%<$0.0000015,962,555.8153$0.3887
BLAST<0.01%$2,240.990.00012295$0.2755
BLAST<0.01%$0.002101117.1757$0.2462
MATIC20.27%$11,674.4479$1,676.12
MATIC
Polygon (MATIC)
5.26%$0.3551771,225.4328$435.25
MATIC1.28%$27.823.8169$106.19
MATIC0.96%$2,241.70.0355$79.53
MATIC0.55%$1.3832.65$45.2
MATIC0.21%$0.99954417.5773$17.57
MATIC0.18%$0.99954414.9443$14.94
MATIC0.12%$0.0014346,812.8$9.77
MATIC0.11%$7.431.1679$8.68
MATIC0.10%$0.1521956.0414$8.53
MATIC0.09%$0.0018094,084.5208$7.39
MATIC0.08%$0.0000041,671,826.6151$6.87
MATIC0.08%$0.09148869.6048$6.37
MATIC0.07%$0.0040381,529.4772$6.18
MATIC0.07%$0.014791400.0908$5.92
MATIC0.07%$0.012394448.9484$5.56
MATIC0.07%$0.014098389.5775$5.49
MATIC0.06%$0.37760413.1519$4.97
MATIC0.06%$0.000011453,865.2042$4.96
MATIC0.06%$0.0041431,197.209$4.96
MATIC0.06%$0.0011654,256.1606$4.96
MATIC0.05%$1,819.930.00245521$4.47
MATIC0.05%$0.12514732.5687$4.08
MATIC0.05%$0.022475175.9816$3.96
MATIC0.04%$0.3499129.7426$3.41
MATIC0.04%<$0.000001185,657,460.3337$3.36
MATIC0.04%$0.029879108.146$3.23
MATIC0.04%$0.04770867.231$3.21
MATIC0.04%$0.6694994.5328$3.03
MATIC0.04%$0.0020391,462.537$2.98
MATIC0.03%$0.3650217.5138$2.74
MATIC0.03%$51,0380.00005225$2.67
MATIC0.03%$0.8705352.7491$2.39
MATIC0.03%$0.02390499.3383$2.37
MATIC0.03%$0.009356253.5627$2.37
MATIC0.03%$0.010443211.8626$2.21
MATIC0.03%$8.170.2693$2.2
MATIC0.03%$0.21377210.1676$2.17
MATIC0.03%$0.004573474.433$2.17
MATIC0.03%$4.770.4519$2.16
MATIC0.03%$0.05215241.3114$2.15
MATIC0.03%$0.02952771.4734$2.11
MATIC0.03%$0.0013581,552.3947$2.11
MATIC0.02%$0.03002263.4733$1.91
MATIC0.02%$0.18139910.4958$1.9
MATIC0.02%$0.0010231,761.5906$1.8
MATIC0.02%<$0.0000013,590,701.637$1.77
MATIC0.02%$2.120.7383$1.57
MATIC0.02%$0.4570683.353$1.53
MATIC0.02%$0.0007911,867.0156$1.48
MATIC0.02%$0.0010761,353.2687$1.46
MATIC0.02%<$0.00000111,144,401.951$1.3
MATIC0.01%$0.01842165.973$1.22
MATIC0.01%$0.01248496.3059$1.2
MATIC0.01%<$0.0000012,294,424,803.3778$1.15
MATIC0.01%$0.00005122,351.7404$1.15
MATIC0.01%$2.80.3977$1.11
MATIC0.01%$0.2254474.9017$1.11
MATIC0.01%$67.990.0158$1.08
MATIC0.01%$0.2605234.0826$1.06
MATIC0.01%$0.004779220.1254$1.05
MATIC0.01%$0.03662427.0113$0.9892
MATIC0.01%$0.007582130.311$0.988
MATIC0.01%$0.0002833,388.0625$0.9573
MATIC0.01%$0.001113849.135$0.9451
MATIC0.01%$2.110.4443$0.9374
MATIC0.01%$0.01548859.9022$0.9277
MATIC0.01%$0.7383021.2497$0.9226
MATIC0.01%$0.06346814.2592$0.905
MATIC0.01%$0.01537656.4733$0.8683
MATIC<0.01%$0.3348652.3551$0.7886
MATIC<0.01%$0.3714742.1209$0.7878
MATIC<0.01%$0.02370530.2584$0.7172
MATIC<0.01%$0.116996.1123$0.715
MATIC<0.01%$0.05528312.6299$0.6982
MATIC<0.01%$0.02527326.0626$0.6586
MATIC<0.01%$0.001185551.2581$0.6532
MATIC<0.01%$4,447.480.00014616$0.65
MATIC<0.01%$34.610.0181$0.6255
MATIC<0.01%$0.01087156.9009$0.6185
MATIC<0.01%$0.1313994.5$0.5912
MATIC<0.01%$49,636.350.00001133$0.5623
MATIC<0.01%$51,191.960.00001081$0.5533
MATIC<0.01%$142.230.00382787$0.5444
MATIC<0.01%$0.0001713,060$0.5219
MATIC<0.01%$0.000912533.8904$0.4866
MATIC<0.01%$0.0773516.2631$0.4844
MATIC<0.01%$0.00003712,664.151$0.4713
MATIC<0.01%$0.000621744.6391$0.4625
MATIC<0.01%$0.01238836.614$0.4535
MATIC<0.01%$0.00001628,108.8436$0.4403
MATIC<0.01%$0.04333810.0701$0.4364
MATIC<0.01%$0.1993862.1654$0.4317
MATIC<0.01%$0.04125210.3815$0.4282
MATIC<0.01%$10.4222$0.4222
MATIC<0.01%$6.490.0628$0.4078
MATIC<0.01%$0.02803413.971$0.3916
MATIC<0.01%$0.001001389.0935$0.3896
MATIC<0.01%$0.00252154.2521$0.3886
MATIC<0.01%$0.9403650.4008$0.3769
MATIC<0.01%$0.3543641.0616$0.3762
MATIC<0.01%$0.01529224.5653$0.3756
MATIC<0.01%$0.001006319.6318$0.3216
MATIC<0.01%$0.0378058.4$0.3175
MATIC<0.01%$78.930.00396878$0.3132
MATIC<0.01%$0.000002147,900$0.3064
MATIC<0.01%$0.2635711.1397$0.3003
MATIC<0.01%$0.00360681$0.292
MATIC<0.01%$0.001795161.1939$0.2894
MATIC<0.01%$0.7370730.3445$0.2539
MATIC<0.01%$0.01450716.6918$0.2421
MATIC<0.01%$0.0977242.4754$0.2419
MATIC<0.01%$0.001225196.7091$0.2408
MATIC<0.01%$0.00810427.4428$0.2223
MATIC<0.01%$0.00496143.1355$0.214
MATIC<0.01%$1.610.1328$0.2137
MATIC<0.01%$0.00350659.2127$0.2075
MATIC<0.01%$0.00675729.3317$0.1982
MATIC<0.01%$0.00443643.7716$0.1941
MATIC<0.01%$0.1421831.3146$0.1869
MATIC<0.01%$0.000382472.58$0.1803
MATIC<0.01%$0.3903920.4585$0.1789
MATIC<0.01%$0.9230640.1822$0.1681
MATIC<0.01%$0.00444137.8156$0.1679
MATIC<0.01%$0.00459436.4873$0.1676
MATIC<0.01%$0.0001591,044.0131$0.1656
MATIC<0.01%$0.2556470.6466$0.1653
MATIC<0.01%$1.720.0944$0.1623
MATIC<0.01%$0.1793230.8818$0.1581
MATIC<0.01%$0.000001141,165.1047$0.1577
MATIC<0.01%$0.0000532,906.594$0.1532
MATIC<0.01%$0.00171985.4094$0.1468
MATIC<0.01%$0.0001291,127.4849$0.1457
MATIC<0.01%$0.0285644.776$0.1364
MATIC<0.01%$111.640.00122227$0.1364
MATIC<0.01%$0.00646920.7698$0.1343
MATIC<0.01%$0.1576450.8354$0.1316
MATIC<0.01%$0.195290.6549$0.1278
MATIC<0.01%$17.750.0071357$0.1266
MATIC<0.01%$0.0384793.2541$0.1252
MATIC<0.01%$0.00421128.162$0.1185
MATIC<0.01%$0.00974512.12$0.1181
MATIC<0.01%$0.7574610.1407$0.1065
ARB10.43%$1860.0271$862.61
ARB1.88%$2,267.460.0686$155.48
ARB1.26%$51,0890.00204722$104.59
ARB0.21%$0.39545344.865$17.74
ARB0.11%$0.0014856,082.6219$9.03
ARB0.10%$2.822.8924$8.16
ARB0.06%$2,2450.00230858$5.18
ARB0.06%$1.722.9897$5.14
ARB0.06%$0.43575311.2915$4.92
ARB0.04%$13.646$3.66
ARB0.04%$1.123.0036$3.36
ARB0.04%$13.0527$3.06
ARB0.04%$180.169$3.04
ARB0.04%$0.027591109.5439$3.02
ARB0.03%$0.05996344.8671$2.69
ARB0.03%$2.231.1984$2.67
ARB0.02%$0.010041204.6597$2.05
ARB0.01%$0.2862993.6525$1.05
ARB<0.01%<$0.0000013,811,427,845.5974$0.7622
ARB<0.01%$1.210.5992$0.725
ARB<0.01%$0.0000149,058.5048$0.491
ARB<0.01%$0.2130551.6534$0.3522
ARB<0.01%$0.01749619.5184$0.3415
ARB<0.01%$0.0704344.5114$0.3177
ARB<0.01%$0.4604370.6536$0.3009
ARB<0.01%$0.1691.5508$0.262
ARB<0.01%<$0.000001622,814,672.6419$0.2491
ARB<0.01%$0.00001812,345.0099$0.2261
ARB<0.01%$1.540.1345$0.2071
ARB<0.01%$1.50.12$0.1799
ARB<0.01%$2,266.50.00004887$0.1107
BASE4.39%$2,265.870.1603$363.21
BASE0.73%$0.99957360.5775$60.55
BASE0.67%$0.00082467,021.7505$55.22
BASE0.43%$0.00062756,441.3226$35.38
BASE0.19%$0.0147741,050.9284$15.53
BASE0.12%$0.00026137,499.8125$9.8
BASE0.12%$0.0013387,309.9724$9.78
BASE0.11%$0.00039723,208.4917$9.22
BASE0.11%$0.53639516.9779$9.11
BASE0.10%$0.00008596,741.9632$8.23
BASE0.09%<$0.0000011,254,054,650.3361$7.78
BASE0.09%$0.0000015,402,495.362$7.51
BASE0.08%$0.060643113.2799$6.87
BASE0.07%$0.015105390.8799$5.9
BASE0.07%$0.0029931,910.8115$5.72
BASE0.06%$0.0005689,111.1464$5.17
BASE0.06%$0.00026718,591.4175$4.97
BASE0.05%$0.0007166,221.4683$4.46
BASE0.05%<$0.000001384,329,743.4972$4.38
BASE0.05%$0.00034811,978.8821$4.17
BASE0.05%$0.00038810,519.8698$4.08
BASE0.04%$0.0024411,363.2649$3.33
BASE0.03%$0.0002439,614.0136$2.34
BASE0.03%$0.004294543.6608$2.33
BASE0.03%$0.011753177.1391$2.08
BASE0.02%$0.0020071,008.1564$2.02
BASE0.02%$0.01758997.2643$1.71
BASE0.02%$0.0003933,714.3606$1.46
BASE0.02%$0.01505496.5467$1.45
BASE0.02%$0.00003338,232.4893$1.26
BASE0.02%$0.00008514,728.4441$1.25
BASE0.01%$0.000157,008.4858$1.05
BASE0.01%$4.560.2269$1.03
BASE0.01%$0.0671215.178$1.02
BASE0.01%$2.770.3388$0.9383
BASE0.01%$0.0005431,657.2673$0.8991
BASE0.01%<$0.0000014,323,006,764.2335$0.8646
BASE<0.01%$0.00972783.6079$0.8132
BASE<0.01%$0.00005613,949.4351$0.7778
BASE<0.01%$0.01436440.004$0.5746
BASE<0.01%$0.0005041,110$0.5593
BASE<0.01%$10.54$0.54
BASE<0.01%$0.00001533,361.2496$0.5105
BASE<0.01%$0.002354207.4971$0.4885
BASE<0.01%$0.00159270.348$0.4297
BASE<0.01%<$0.00000194,278,522.9179$0.4242
BASE<0.01%$0.0001143,013.6643$0.3446
BASE<0.01%$0.000001379,819.9706$0.3399
BASE<0.01%$0.0001212,658.1826$0.3215
BASE<0.01%$0.9989140.2846$0.2843
BASE<0.01%$0.0000247,347.3303$0.1764
BASE<0.01%$0.0000335,231.1623$0.1735
BASE<0.01%$0.0000971,684$0.1636
BASE<0.01%$0.00594425.2958$0.1503
BASE<0.01%$0.00459830.8153$0.1416
BASE<0.01%$0.0005251.0851$0.1254
BASE<0.01%$0.0050321.3062$0.1071
BASE<0.01%$0.0009111.715$0.1004
FTM3.43%$60,5190.00468551$283.56
FTM0.78%$2,899.150.0221$64.17
FTM0.17%$0.36478838.6001$14.08
FTM0.09%$5,289.210.00138096$7.3
FTM<0.01%$6.990.0702$0.4905
FTM<0.01%$0.4539041.0394$0.4717
FTM<0.01%$0.00345579.1473$0.2734
LINEA3.43%$2,263.190.1252$283.32
LINEA0.11%$0.9995739.416$9.41
LINEA0.08%$0.9766946.6943$6.54
LINEA0.08%$16.3864$6.39
LINEA0.02%$2,277.790.00083868$1.91
LINEA0.02%$2,265.120.00077416$1.75
LINEA<0.01%$0.0001681,273.9988$0.2137
LINEA<0.01%$0.0599992.4958$0.1497
SCROLL1.58%$2,263.190.0577$130.54
SCROLL0.84%$0.99886869.1442$69.07
SCROLL0.23%$119.005$19.01
SCROLL0.02%$51,035.670.0000261$1.33
OPBNB1.04%$428.440.2013$86.25
OPBNB0.11%$1.028.7377$8.92
KROMA0.34%$2,269.540.0125$28.29
KROMA0.27%$122.4834$22.48
AVAX0.19%$18.040.8759$15.8
AVAX0.09%$17.6894$7.7
AVAX0.07%$0.07346177.0226$5.66
AVAX0.02%$0.0000011,525,739.2199$1.59
AVAX<0.01%$10.7219$0.7224
AVAX<0.01%<$0.00000110,572,711.3943$0.1744
AVAX<0.01%$0.00418934.17$0.1431
AVAX<0.01%$10.1353$0.1354
AVAX<0.01%$0.3300490.3253$0.1073
BSC0.07%$429.550.013$5.58
MANTLE0.01%$0.9981121.0651$1.06
MANTLE<0.01%$0.5394750.375$0.202303
MANTLE<0.01%$0.997560.1148$0.1145
[ 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.