POL Price: $0.22612 (+2.71%)
 

Overview

POL Balance

Polygon PoS Chain LogoPolygon PoS Chain LogoPolygon PoS Chain Logo2.09182561 POL

POL Value

$0.47 (@ $0.23/POL)

Token Holdings

Multichain Info

Transaction Hash
Method
Block
From
To
Transfer546738872024-03-15 4:23:40375 days ago1710476620IN
0xb45A2DDA...E7ab18E39
2.09182561 POL0.005596250
Change Pause479632882023-09-25 10:17:28547 days ago1695637048IN
0xb45A2DDA...E7ab18E39
0 POL0.00448778149.1205555
Swap472866752023-09-08 8:08:08564 days ago1694160488IN
0xb45A2DDA...E7ab18E39
0 POL0.01634111156.15911541
Withdraw Tokens471246362023-09-04 6:35:30568 days ago1693809330IN
0xb45A2DDA...E7ab18E39
0 POL0.02102924119.65973309
Withdraw Tokens471246272023-09-04 6:35:12568 days ago1693809312IN
0xb45A2DDA...E7ab18E39
0 POL0.00384613110.73099396
Swap466193842023-08-22 13:50:53581 days ago1692712253IN
0xb45A2DDA...E7ab18E39
1 POL0.02263596180.37484286
Swap463965932023-08-17 0:46:34586 days ago1692233194IN
0xb45A2DDA...E7ab18E39
0 POL0.03275382313.00239615
Swap463965932023-08-17 0:46:34586 days ago1692233194IN
0xb45A2DDA...E7ab18E39
0 POL0.02772769264.9716893
Cross459412842023-08-05 13:55:22598 days ago1691243722IN
0xb45A2DDA...E7ab18E39
0 POL0.0149041788.86606489
Swap458961852023-08-04 10:57:17599 days ago1691146637IN
0xb45A2DDA...E7ab18E39
0 POL0.0255696297.43631784
Swap458961242023-08-04 10:55:07599 days ago1691146507IN
0xb45A2DDA...E7ab18E39
100 POL0.0283032798.80530552
Swap458960832023-08-04 10:53:41599 days ago1691146421IN
0xb45A2DDA...E7ab18E39
0 POL0.03312643101.97015323
Swap458960552023-08-04 10:52:41599 days ago1691146361IN
0xb45A2DDA...E7ab18E39
0 POL0.0310086697.59068975
Swap458959242023-08-04 10:48:03599 days ago1691146083IN
0xb45A2DDA...E7ab18E39
0 POL0.0276896582.40528297
Swap458958812023-08-04 10:46:31599 days ago1691145991IN
0xb45A2DDA...E7ab18E39
0 POL0.0248206879.87913663
Swap458958572023-08-04 10:45:41599 days ago1691145941IN
0xb45A2DDA...E7ab18E39
0 POL0.06512461102.55780868
Swap458958232023-08-04 10:44:27599 days ago1691145867IN
0xb45A2DDA...E7ab18E39
0 POL0.0644716100.76963321
Swap458957602023-08-04 10:42:15599 days ago1691145735IN
0xb45A2DDA...E7ab18E39
0 POL0.03676801131.05270223
Swap458957102023-08-04 10:40:27599 days ago1691145627IN
0xb45A2DDA...E7ab18E39
0.1 POL0.04552636134.23587387
Swap458956322023-08-04 10:37:34599 days ago1691145454IN
0xb45A2DDA...E7ab18E39
23.01631214 POL0.05946036153.89766731
Cross458955882023-08-04 10:35:24599 days ago1691145324IN
0xb45A2DDA...E7ab18E39
0 POL0.04063138242.32081178
Swap458955352023-08-04 10:33:30599 days ago1691145210IN
0xb45A2DDA...E7ab18E39
425 POL0.03810052133.00468318
Swap458953812023-08-04 10:28:04599 days ago1691144884IN
0xb45A2DDA...E7ab18E39
0 POL0.0206649197.23016844
Swap458953292023-08-04 10:26:14599 days ago1691144774IN
0xb45A2DDA...E7ab18E39
0 POL0.03279511156.78164219
Swap458952142023-08-04 10:22:08599 days ago1691144528IN
0xb45A2DDA...E7ab18E39
0 POL0.04572119157.75994371
View all transactions

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To
471246272023-09-04 6:35:12568 days ago1693809312
0xb45A2DDA...E7ab18E39
41.08503509 POL
466193842023-08-22 13:50:53581 days ago1692712253
0xb45A2DDA...E7ab18E39
0.997 POL
458961242023-08-04 10:55:07599 days ago1691146507
0xb45A2DDA...E7ab18E39
99.7 POL
458957102023-08-04 10:40:27599 days ago1691145627
0xb45A2DDA...E7ab18E39
0.0997 POL
458956322023-08-04 10:37:34599 days ago1691145454
0xb45A2DDA...E7ab18E39
22.9472632 POL
458955352023-08-04 10:33:30599 days ago1691145210
0xb45A2DDA...E7ab18E39
423.725 POL
458952052023-08-04 10:21:50599 days ago1691144510
0xb45A2DDA...E7ab18E39
1.994 POL
458951352023-08-04 10:19:12599 days ago1691144352
0xb45A2DDA...E7ab18E39
106.679 POL
458947802023-08-04 10:06:36599 days ago1691143596
0xb45A2DDA...E7ab18E39
77.844 POL
458938912023-08-04 9:35:06599 days ago1691141706
0xb45A2DDA...E7ab18E39
162.77537567 POL
458938142023-08-04 9:32:14599 days ago1691141534
0xb45A2DDA...E7ab18E39
37.886 POL
458932162023-08-04 9:10:56599 days ago1691140256
0xb45A2DDA...E7ab18E39
233.298 POL
458931042023-08-04 9:06:58599 days ago1691140018
0xb45A2DDA...E7ab18E39
837.48 POL
458930362023-08-04 9:04:32599 days ago1691139872
0xb45A2DDA...E7ab18E39
35.892 POL
458929502023-08-04 9:01:29599 days ago1691139689
0xb45A2DDA...E7ab18E39
151.544 POL
458928942023-08-04 8:59:29599 days ago1691139569
0xb45A2DDA...E7ab18E39
154.535 POL
458925462023-08-04 8:46:59599 days ago1691138819
0xb45A2DDA...E7ab18E39
1.4955 POL
458921102023-08-04 8:31:28599 days ago1691137888
0xb45A2DDA...E7ab18E39
2.991 POL
458917302023-08-04 8:18:01599 days ago1691137081
0xb45A2DDA...E7ab18E39
25.922 POL
458916772023-08-04 8:16:05599 days ago1691136965
0xb45A2DDA...E7ab18E39
9.97 POL
458915052023-08-04 8:09:59599 days ago1691136599
0xb45A2DDA...E7ab18E39
1,297.4 POL
458906902023-08-04 7:41:02599 days ago1691134862
0xb45A2DDA...E7ab18E39
58.0254 POL
458903782023-08-04 7:29:58599 days ago1691134198
0xb45A2DDA...E7ab18E39
5.8823 POL
458903432023-08-04 7:28:44599 days ago1691134124
0xb45A2DDA...E7ab18E39
4.985 POL
458901382023-08-04 7:21:15599 days ago1691133675
0xb45A2DDA...E7ab18E39
301.094 POL
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TransitSwapRouterV4

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 10 : TransitSwapRouterV4.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./libraries/ReentrancyGuard.sol";
import "./libraries/RevertReasonParser.sol";
import "./libraries/TransferHelper.sol";
import "./libraries/TransitStructs.sol";
import "./libraries/Ownable.sol";
import "./libraries/Pausable.sol";
import "./libraries/SafeMath.sol";
import "./interfaces/IERC20.sol";
import "./interfaces/ITransitSwapFees.sol";

contract TransitSwapRouterV4 is Ownable, ReentrancyGuard, Pausable {

    using SafeMath for uint256;

    address private _transit_swap;
    address private _transit_cross;
    address private _transit_fees;
    //default: Pre-trade fee model
    mapping(uint8 => bool) private _swap_type_mode;
    //whitelist wrapped
    mapping(address => bool) private _wrapped_allowed;

    event Receipt(address from, uint256 amount);
    event Withdraw(address indexed token, address indexed executor, address indexed recipient, uint amount);
    event ChangeTransitSwap(address indexed previousTransit, address indexed newTransit);
    event ChangeTransitCross(address indexed previousTransit, address indexed newTransit);
    event ChangeTransitFees(address indexed previousTransitFees, address indexed newTransitFees);
    event ChangeSwapTypeMode(uint8[] types, bool[] newModes);
    event ChangeWrappedAllowed(address[] wrappeds, bool[] newAllowed);
    event TransitSwapped(address indexed srcToken, address indexed dstToken, address indexed dstReceiver, address trader, bool feeMode, uint256 amount, uint256 returnAmount, uint256 minReturnAmount, uint256 fee, uint256 toChainID, string channel, uint256 time);


    constructor(address transitSwap_, address transitCross_, address transitFees_, address executor) Ownable (executor) {
        _transit_swap = transitSwap_;
        _transit_cross = transitCross_;
        _transit_fees = transitFees_;
    }

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

    function transitSwap() external view returns (address) {
        return _transit_swap;
    }

    function transitCross() external view returns (address) {
        return _transit_cross;
    }

    function transitFees() external view returns (address) {
        return _transit_fees;
    }

    function swapTypeMode(uint8 swapType) external view returns (bool) {
        return _swap_type_mode[swapType];
    }

    function wrappedAllowed(address wrapped) external view returns (bool) {
        return _wrapped_allowed[wrapped];
    }

    function changeTransitSwap(address newTransit) external onlyExecutor {
        address oldTransit = _transit_swap;
        _transit_swap = newTransit;
        emit ChangeTransitSwap(oldTransit, newTransit);
    }

    function changeTransitCross(address newTransit) external onlyExecutor {
        address oldTransit = _transit_cross;
        _transit_cross = newTransit;
        emit ChangeTransitCross(oldTransit, newTransit);
    }

    function changeTransitFees(address newTransitFees) external onlyExecutor {
        address oldTransitFees = _transit_fees;
        _transit_fees = newTransitFees;
        emit ChangeTransitFees(oldTransitFees, newTransitFees);
    }

    function changeSwapTypeMode(uint8[] memory swapTypes) external onlyExecutor {
        bool[] memory newModes = new bool[](swapTypes.length);
        for (uint index; index < swapTypes.length; index++) {
            _swap_type_mode[swapTypes[index]] = !_swap_type_mode[swapTypes[index]];
            newModes[index] = _swap_type_mode[swapTypes[index]];
        }
        emit ChangeSwapTypeMode(swapTypes, newModes);
    }

    function changeWrappedAllowed(address[] calldata wrappeds) external onlyExecutor {
        bool[] memory newAllowed = new bool[](wrappeds.length);
        for (uint index; index < wrappeds.length; index++) {
            _wrapped_allowed[wrappeds[index]] = !_wrapped_allowed[wrappeds[index]];
            newAllowed[index] = _wrapped_allowed[wrappeds[index]];
        }
        emit ChangeWrappedAllowed(wrappeds, newAllowed);
    }

    function changePause(bool paused) external onlyExecutor {
        if (paused) {
            _pause();
        } else {
            _unpause();
        }
    }

    function _beforeSwap(bool preTradeModel, TransitStructs.TransitSwapDescription calldata desc) private returns (uint256 swapAmount, uint256 fee, uint256 beforeBalance) {
        if (preTradeModel) {
            fee = ITransitSwapFees(_transit_fees).getFeeRate(msg.sender, desc.amount, desc.swapType, desc.channel);
        }
        if (TransferHelper.isETH(desc.srcToken)) {
            require(msg.value == desc.amount, "TransitSwap: invalid msg.value");
            swapAmount = desc.amount.sub(fee);
        } else {
            if (preTradeModel) {
                TransferHelper.safeTransferFrom(desc.srcToken, msg.sender, address(this), desc.amount);
                TransferHelper.safeTransfer(desc.srcToken, desc.srcReceiver, desc.amount.sub(fee));
            } else {
                TransferHelper.safeTransferFrom(desc.srcToken, msg.sender, desc.srcReceiver, desc.amount);
            }
        }
        if (TransferHelper.isETH(desc.dstToken)) {
            if (preTradeModel) {
                beforeBalance = desc.dstReceiver.balance;
            } else {
                if (desc.swapType == uint8(TransitStructs.SwapTypes.swap)) {
                    require(_wrapped_allowed[desc.wrappedNative], "TransitSwap: invalid wrapped address");
                    beforeBalance = IERC20(desc.wrappedNative).balanceOf(address(this));
                } else {
                    beforeBalance = address(this).balance;
                }
            }
        } else {
            if (preTradeModel) {
                beforeBalance = IERC20(desc.dstToken).balanceOf(desc.dstReceiver);
            } else {
                beforeBalance = IERC20(desc.dstToken).balanceOf(address(this));
            }
        }
    }

    function _afterSwap(bool preTradeModel, TransitStructs.TransitSwapDescription calldata desc, uint256 beforeBalance) private returns (uint256 returnAmount, uint256 fee) {
        if (TransferHelper.isETH(desc.dstToken)) {
            if (preTradeModel) {
                returnAmount = desc.dstReceiver.balance.sub(beforeBalance);
                require(returnAmount >= desc.minReturnAmount, "TransitSwap: insufficient return amount");
            } else {
                if (desc.swapType == uint8(TransitStructs.SwapTypes.swap)) {
                    returnAmount = IERC20(desc.wrappedNative).balanceOf(address(this)).sub(beforeBalance);
                    require(_wrapped_allowed[desc.wrappedNative], "TransitSwap: invalid wrapped address");
                    TransferHelper.safeWithdraw(desc.wrappedNative, returnAmount);
                } else {
                    returnAmount = address(this).balance.sub(beforeBalance);
                }
                fee = ITransitSwapFees(_transit_fees).getFeeRate(msg.sender, returnAmount, desc.swapType, desc.channel);
                returnAmount = returnAmount.sub(fee);
                require(returnAmount >= desc.minReturnAmount, "TransitSwap: insufficient return amount");
                TransferHelper.safeTransferETH(desc.dstReceiver, returnAmount);
            }
        } else {
            if (preTradeModel) {
                returnAmount = IERC20(desc.dstToken).balanceOf(desc.dstReceiver).sub(beforeBalance);
                require(returnAmount >= desc.minReturnAmount, "TransitSwap: insufficient return amount");
            } else {
                returnAmount = IERC20(desc.dstToken).balanceOf(address(this)).sub(beforeBalance);
                fee = ITransitSwapFees(_transit_fees).getFeeRate(msg.sender, returnAmount, desc.swapType, desc.channel);
                returnAmount = returnAmount.sub(fee);
                uint256 receiverBeforeBalance = IERC20(desc.dstToken).balanceOf(desc.dstReceiver);
                TransferHelper.safeTransfer(desc.dstToken, desc.dstReceiver, returnAmount);
                returnAmount = IERC20(desc.dstToken).balanceOf(desc.dstReceiver).sub(receiverBeforeBalance);
                require(returnAmount >= desc.minReturnAmount, "TransitSwap: insufficient return amount");
            }
        }        
    }

    function swap(TransitStructs.TransitSwapDescription calldata desc, TransitStructs.CallbytesDescription calldata callbytesDesc) external payable nonReentrant whenNotPaused {
        require(callbytesDesc.calldatas.length > 0, "TransitSwap: data should be not zero");
        require(desc.amount > 0, "TransitSwap: amount should be greater than 0");
        require(desc.dstReceiver != address(0), "TransitSwap: receiver should be not address(0)");
        require(desc.minReturnAmount > 0, "TransitSwap: minReturnAmount should be greater than 0");
        if (callbytesDesc.flag == uint8(TransitStructs.Flag.aggregate)) {
            require(desc.srcToken == callbytesDesc.srcToken, "TransitSwap: invalid callbytesDesc");
        }
        bool preTradeModel = !_swap_type_mode[desc.swapType];
        (uint256 swapAmount, uint256 fee, uint256 beforeBalance) = _beforeSwap(preTradeModel, desc);

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

        (uint256 returnAmount, uint256 postFee) = _afterSwap(preTradeModel, desc, beforeBalance);
        if (postFee > fee) {
            fee = postFee;
        }
        _emitTransit(desc, preTradeModel, fee, returnAmount);
    }

    function _beforeCross(TransitStructs.TransitSwapDescription calldata desc) private returns (uint256 swapAmount, uint256 fee, uint256 beforeBalance) {
        fee = ITransitSwapFees(_transit_fees).getFeeRate(msg.sender, desc.amount, desc.swapType, desc.channel);
        if (TransferHelper.isETH(desc.srcToken)) {
            require(msg.value == desc.amount, "TransitSwap: invalid msg.value");
            swapAmount = desc.amount.sub(fee);
        } else {
            beforeBalance = IERC20(desc.srcToken).balanceOf(_transit_cross);
            if (fee == 0) {
                TransferHelper.safeTransferFrom(desc.srcToken, msg.sender, _transit_cross, desc.amount);
            } else {
                TransferHelper.safeTransferFrom(desc.srcToken, msg.sender, address(this), desc.amount);
                TransferHelper.safeTransfer(desc.srcToken, _transit_cross, desc.amount.sub(fee));
            }
        }
    }

    function cross(TransitStructs.TransitSwapDescription calldata desc, TransitStructs.CallbytesDescription calldata callbytesDesc) external payable nonReentrant whenNotPaused {
        require(callbytesDesc.calldatas.length > 0, "TransitSwap: data should be not zero");
        require(desc.amount > 0, "TransitSwap: amount should be greater than 0");
        require(desc.srcToken == callbytesDesc.srcToken, "TransitSwap: invalid callbytesDesc");
        (uint256 swapAmount, uint256 fee, uint256 beforeBalance) = _beforeCross(desc);
        
        {
            //bytes4(keccak256(bytes('callbytes(TransitStructs.CallbytesDescription)')));
            (bool success, bytes memory result) = _transit_cross.call{value:swapAmount}(abi.encodeWithSelector(0xccbe4007, callbytesDesc));
            if (!success) {
                revert(RevertReasonParser.parse(result,"TransitSwap:"));
            }
        }
        
        if (!TransferHelper.isETH(desc.srcToken)) {
            require(IERC20(desc.srcToken).balanceOf(_transit_cross) >= beforeBalance, "TransitSwap: invalid cross");
        }

        _emitTransit(desc, true, fee, 0);
    }

    function _emitTransit(TransitStructs.TransitSwapDescription calldata desc, bool preTradeModel, uint256 fee, uint256 returnAmount) private {
        emit TransitSwapped(
            desc.srcToken, 
            desc.dstToken, 
            desc.dstReceiver, 
            msg.sender, 
            preTradeModel, 
            desc.amount, 
            returnAmount, 
            desc.minReturnAmount, 
            fee, 
            desc.toChainID, 
            desc.channel,
            block.timestamp
        );
    }

    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 10 : ITransitSwapFees.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.9;

interface ITransitSwapFees {
    
    function getFeeRate(address trader, uint256 tradeAmount, uint8 swapType, string memory channel) external  view returns (uint payFees);

}

File 3 of 10 : 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 4 of 10 : SafeMath.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0;

library SafeMath {
    function add(uint x, uint y) internal pure returns (uint z) {
        require((z = x + y) >= x, 'ds-math-add-overflow');
    }

    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;
    }
}

File 5 of 10 : 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);

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

    bool private _paused;

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

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

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

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

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

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

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

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

File 6 of 10 : 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 _owner;
    address private _pendingOwner;
    address private _executor;
    address private _pendingExecutor;
    bool internal _initialized;

    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    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");
        _transferOwnership(msg.sender);
        _transferExecutorship(newExecutor);
        _initialized = true;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

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

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

    /**
     * @dev Returns the address of the pending owner.
     */
    function pendingOwner() public view virtual returns (address) {
        return _pendingOwner;
    }

    /**
     * @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 owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == msg.sender, "Ownable: caller is not the owner");
    }

    /**
     * @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 Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        _pendingOwner = newOwner;
        emit OwnershipTransferStarted(owner(), newOwner);
    }

    /**
     * @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);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        delete _pendingOwner;
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }

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

    function acceptOwnership() external {
        address sender = msg.sender;
        require(pendingOwner() == sender, "Ownable: caller is not the new owner");
        _transferOwnership(sender);
    }

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

File 7 of 10 : TransitStructs.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

library TransitStructs {

    enum SwapTypes {aggregatePreMode, aggregatePostMode, swap, cross}
    enum Flag {aggregate, swap, cross}

    struct TransitSwapDescription {
        uint8 swapType;
        address srcToken;
        address dstToken;
        address srcReceiver;
        address dstReceiver;
        uint256 amount;
        uint256 minReturnAmount;
        string channel;
        uint256 toChainID;
        address wrappedNative;
    }

    struct CallbytesDescription {
        uint8 flag;
        address srcToken;
        bytes calldatas;
    }

    struct AggregateDescription {
        address dstToken;
        address receiver;
        uint[] amounts;
        uint[] needTransfer;
        address[] callers;
        address[] approveProxy;
        bytes[] calls;
    }

    struct SwapDescription {
        address[][] paths;
        address[][] pairs;
        uint[] fees;
        address receiver;
        uint deadline;
    }

    struct CrossDescription {
        address caller;
        uint256 amount;
        bool needWrapped;
        bytes calls;
    }

    function decodeAggregateDesc(bytes calldata calldatas) internal pure returns (AggregateDescription memory desc) {
        desc = abi.decode(calldatas, (AggregateDescription));
    }

    function decodeSwapDesc(bytes calldata calldatas) internal pure returns (SwapDescription memory desc) {
        desc = abi.decode(calldatas, (SwapDescription));
    }

    function decodeCrossDesc(bytes calldata calldatas) internal pure returns (CrossDescription memory desc) {
        desc = abi.decode(calldatas, (CrossDescription));
    }
}

File 8 of 10 : 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 9 of 10 : 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 10 of 10 : 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() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    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;
    }
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"transitSwap_","type":"address"},{"internalType":"address","name":"transitCross_","type":"address"},{"internalType":"address","name":"transitFees_","type":"address"},{"internalType":"address","name":"executor","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8[]","name":"types","type":"uint8[]"},{"indexed":false,"internalType":"bool[]","name":"newModes","type":"bool[]"}],"name":"ChangeSwapTypeMode","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTransit","type":"address"},{"indexed":true,"internalType":"address","name":"newTransit","type":"address"}],"name":"ChangeTransitCross","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTransitFees","type":"address"},{"indexed":true,"internalType":"address","name":"newTransitFees","type":"address"}],"name":"ChangeTransitFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTransit","type":"address"},{"indexed":true,"internalType":"address","name":"newTransit","type":"address"}],"name":"ChangeTransitSwap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"wrappeds","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":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"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":"address","name":"trader","type":"address"},{"indexed":false,"internalType":"bool","name":"feeMode","type":"bool"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"returnAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toChainID","type":"uint256"},{"indexed":false,"internalType":"string","name":"channel","type":"string"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"TransitSwapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"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"},{"inputs":[],"name":"acceptExecutorship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"paused","type":"bool"}],"name":"changePause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8[]","name":"swapTypes","type":"uint8[]"}],"name":"changeSwapTypeMode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTransit","type":"address"}],"name":"changeTransitCross","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTransitFees","type":"address"}],"name":"changeTransitFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTransit","type":"address"}],"name":"changeTransitSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"wrappeds","type":"address[]"}],"name":"changeWrappedAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"swapType","type":"uint8"},{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"address","name":"dstToken","type":"address"},{"internalType":"address","name":"srcReceiver","type":"address"},{"internalType":"address","name":"dstReceiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"internalType":"string","name":"channel","type":"string"},{"internalType":"uint256","name":"toChainID","type":"uint256"},{"internalType":"address","name":"wrappedNative","type":"address"}],"internalType":"struct TransitStructs.TransitSwapDescription","name":"desc","type":"tuple"},{"components":[{"internalType":"uint8","name":"flag","type":"uint8"},{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"bytes","name":"calldatas","type":"bytes"}],"internalType":"struct TransitStructs.CallbytesDescription","name":"callbytesDesc","type":"tuple"}],"name":"cross","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"executor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingExecutor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"swapType","type":"uint8"},{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"address","name":"dstToken","type":"address"},{"internalType":"address","name":"srcReceiver","type":"address"},{"internalType":"address","name":"dstReceiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"internalType":"string","name":"channel","type":"string"},{"internalType":"uint256","name":"toChainID","type":"uint256"},{"internalType":"address","name":"wrappedNative","type":"address"}],"internalType":"struct TransitStructs.TransitSwapDescription","name":"desc","type":"tuple"},{"components":[{"internalType":"uint8","name":"flag","type":"uint8"},{"internalType":"address","name":"srcToken","type":"address"},{"internalType":"bytes","name":"calldatas","type":"bytes"}],"internalType":"struct TransitStructs.CallbytesDescription","name":"callbytesDesc","type":"tuple"}],"name":"swap","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint8","name":"swapType","type":"uint8"}],"name":"swapTypeMode","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newExecutor","type":"address"}],"name":"transferExecutorship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transitCross","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"transitFees","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"transitSwap","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"address","name":"recipient","type":"address"}],"name":"withdrawTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wrapped","type":"address"}],"name":"wrappedAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040523480156200001157600080fd5b5060405162003697380380620036978339810160408190526200003491620001e4565b6003548190600160a01b900460ff1615620000955760405162461bcd60e51b815260206004820152601460248201527f4f776e61626c653a20696e697469616c697a6564000000000000000000000000604482015260640160405180910390fd5b620000a03362000110565b620000ab816200016a565b50506003805460ff60a01b1916600160a01b1790556001600455600580546001600160a01b03948516610100026001600160a81b0319909116179055600680549284166001600160a01b03199384161790556007805491909316911617905562000241565b600180546001600160a01b0319908116909155600080546001600160a01b03848116938216841783556040519116929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600380546001600160a01b0319908116909155600280546001600160a01b0384811693821684179092556040519116919082907f88436636ea40d5bb1bcc55ff9cd54788af71da886f4147a87f199adcca733d4d90600090a35050565b80516001600160a01b0381168114620001df57600080fd5b919050565b60008060008060808587031215620001fb57600080fd5b6200020685620001c7565b93506200021660208601620001c7565b92506200022660408601620001c7565b91506200023660608601620001c7565b905092959194509250565b61344680620002516000396000f3fe60806040526004361061014f5760003560e01c8063afed2d0e116100b6578063d63234e01161006f578063d63234e0146103e2578063dc69bbad14610400578063e30c397814610420578063e8e1bc5d1461043e578063f2fde38b1461045e578063f8c79f731461047e57600080fd5b8063afed2d0e1461031e578063c10bea5c1461033e578063c34c08e514610351578063c3dc51fe1461036f578063c58dff5c1461038f578063c6c46552146103c257600080fd5b8063715018a611610108578063715018a61461028057806379ba509714610295578063845b1f77146102aa5780638da5cb5b146102cd57806394752e82146102eb57806394d3d7931461030957600080fd5b8063017efb28146101935780630e8cc705146101a85780633932a93c146101c857806351205349146102165780635c975abb146102485780635d4fead31461026057600080fd5b3661018e57604080513381523460208201527f7784f8d436dc514f0690e472c7e2d7f660a73e504c69b2350f6be5a5f02432ef910160405180910390a1005b600080fd5b6101a66101a1366004612b08565b61049e565b005b3480156101b457600080fd5b506101a66101c3366004612c03565b61076f565b3480156101d457600080fd5b506102016101e3366004612cb2565b6001600160a01b031660009081526009602052604090205460ff1690565b60405190151581526020015b60405180910390f35b34801561022257600080fd5b506007546001600160a01b03165b6040516001600160a01b03909116815260200161020d565b34801561025457600080fd5b5060055460ff16610201565b34801561026c57600080fd5b506101a661027b366004612ce2565b6108f3565b34801561028c57600080fd5b506101a6610914565b3480156102a157600080fd5b506101a6610928565b3480156102b657600080fd5b5060055461010090046001600160a01b0316610230565b3480156102d957600080fd5b506000546001600160a01b0316610230565b3480156102f757600080fd5b506006546001600160a01b0316610230565b34801561031557600080fd5b506101a66109a7565b34801561032a57600080fd5b506101a6610339366004612cb2565b610a2a565b6101a661034c366004612b08565b610a9b565b34801561035d57600080fd5b506002546001600160a01b0316610230565b34801561037b57600080fd5b506101a661038a366004612d10565b610dbe565b34801561039b57600080fd5b506102016103aa366004612da8565b60ff9081166000908152600860205260409020541690565b3480156103ce57600080fd5b506101a66103dd366004612cb2565b610f56565b3480156103ee57600080fd5b506003546001600160a01b0316610230565b34801561040c57600080fd5b506101a661041b366004612cb2565b610fb0565b34801561042c57600080fd5b506001546001600160a01b0316610230565b34801561044a57600080fd5b506101a6610459366004612cb2565b611012565b34801561046a57600080fd5b506101a6610479366004612cb2565b61106c565b34801561048a57600080fd5b506101a6610499366004612dc3565b6110dd565b6104a6611299565b6104ae6112f2565b60006104bd6040830183612e38565b9050116104e55760405162461bcd60e51b81526004016104dc90612e86565b60405180910390fd5b60008260a00135116105095760405162461bcd60e51b81526004016104dc90612eca565b6105196040820160208301612cb2565b6001600160a01b03166105326040840160208501612cb2565b6001600160a01b0316146105585760405162461bcd60e51b81526004016104dc90612f16565b600080600061056685611338565b600654604051939650919450925060009182916001600160a01b031690869063ccbe400790610599908a90602401612f81565b6040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516105d29190613035565b60006040518083038185875af1925050503d806000811461060f576040519150601f19603f3d011682016040523d82523d6000602084013e610614565b606091505b5091509150816106655761064c816040518060400160405280600c81526020016b2a3930b739b4ba29bbb0b81d60a11b815250611562565b60405162461bcd60e51b81526004016104dc9190613051565b50610680905061067b6040870160208801612cb2565b6117d9565b61075057806106956040870160208801612cb2565b6006546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa1580156106de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107029190613084565b10156107505760405162461bcd60e51b815260206004820152601a60248201527f5472616e736974537761703a20696e76616c69642063726f737300000000000060448201526064016104dc565b61075e856001846000611812565b50505061076b6001600455565b5050565b6107776118c7565b60005b82518110156108ee5760006107a784838151811061079a5761079a61309d565b60200260200101516117d9565b156107bd5750476107b8838261193c565b61086b565b8382815181106107cf576107cf61309d565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561081f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108439190613084565b905061086984838151811061085a5761085a61309d565b602002602001015184836119f9565b505b826001600160a01b0316336001600160a01b03168584815181106108915761089161309d565b60200260200101516001600160a01b03167f3115d1449a7b732c986cba18244e897a450f61e1bb8d589cd2e69e6c8924f9f7846040516108d391815260200190565b60405180910390a450806108e6816130c9565b91505061077a565b505050565b6108fb6118c7565b801561090c57610909611ae3565b50565b610909611b2e565b61091c611b70565b6109266000611bd9565b565b338061093c6001546001600160a01b031690565b6001600160a01b03161461099e5760405162461bcd60e51b8152602060048201526024808201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206e6577206f6044820152633bb732b960e11b60648201526084016104dc565b61090981611bd9565b33806109bb6003546001600160a01b031690565b6001600160a01b031614610a215760405162461bcd60e51b815260206004820152602760248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206e657720656044820152663c32b1baba37b960c91b60648201526084016104dc565b61090981611c33565b610a326118c7565b600380546001600160a01b0383166001600160a01b03199091168117909155610a636002546001600160a01b031690565b6001600160a01b03167fdd01547fc40682edc3cd8d164d53f5a1ae6b46138a83f045658ed760823ddba860405160405180910390a350565b610aa3611299565b610aab6112f2565b6000610aba6040830183612e38565b905011610ad95760405162461bcd60e51b81526004016104dc90612e86565b60008260a0013511610afd5760405162461bcd60e51b81526004016104dc90612eca565b6000610b0f60a0840160808501612cb2565b6001600160a01b031603610b7c5760405162461bcd60e51b815260206004820152602e60248201527f5472616e736974537761703a2072656365697665722073686f756c642062652060448201526d6e6f74206164647265737328302960901b60648201526084016104dc565b60008260c0013511610bee5760405162461bcd60e51b815260206004820152603560248201527f5472616e736974537761703a206d696e52657475726e416d6f756e742073686f6044820152740756c642062652067726561746572207468616e203605c1b60648201526084016104dc565b6000610bfd6020830183612da8565b60ff1603610c5457610c156040820160208301612cb2565b6001600160a01b0316610c2e6040840160208501612cb2565b6001600160a01b031614610c545760405162461bcd60e51b81526004016104dc90612f16565b6000600881610c666020860186612da8565b60ff908116825260208201929092526040016000908120549091161591508080610c908487611c90565b925092509250600080600560019054906101000a90046001600160a01b03166001600160a01b03168563ccbe400789604051602401610ccf9190612f81565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051610d089190613035565b60006040518083038185875af1925050503d8060008114610d45576040519150601f19603f3d011682016040523d82523d6000602084013e610d4a565b606091505b509150915081610d825761064c816040518060400160405280600c81526020016b2a3930b739b4ba29bbb0b81d60a11b815250611562565b5050600080610d92868985612041565b9150915083811115610da2578093505b610dae88878685611812565b50505050505061076b6001600455565b610dc66118c7565b6000815167ffffffffffffffff811115610de257610de2612b7c565b604051908082528060200260200182016040528015610e0b578160200160208202803683370190505b50905060005b8251811015610f185760086000848381518110610e3057610e3061309d565b602002602001015160ff1660ff16815260200190815260200160002060009054906101000a900460ff161560086000858481518110610e7157610e7161309d565b602002602001015160ff1660ff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060086000848381518110610eba57610eba61309d565b602002602001015160ff1660ff16815260200190815260200160002060009054906101000a900460ff16828281518110610ef657610ef661309d565b9115156020928302919091019091015280610f10816130c9565b915050610e11565b507f5e69b8fb6404283a560ee2205dc0f225019578c56e3a6c52137e0aa995235b668282604051610f4a92919061311f565b60405180910390a15050565b610f5e6118c7565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907faf855a7e4074e8930caf657b3505942d4ba0e69b6b6e63553c653d7b1ffcc06190600090a35050565b610fb86118c7565b600580546001600160a01b03838116610100818102610100600160a81b031985161790945560405193909204169182907fbc071769e275808816d09db519c1888c355f7557cb63095ce21e26a97a5f0e9c90600090a35050565b61101a6118c7565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907ff2ef974bc2aedf0c322b1a97e8627e85114a789cadf8d172b5efb5d6c1d94f8d90600090a35050565b611074611b70565b600180546001600160a01b0383166001600160a01b031990911681179091556110a56000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6110e56118c7565b60008167ffffffffffffffff81111561110057611100612b7c565b604051908082528060200260200182016040528015611129578160200160208202803683370190505b50905060005b82811015611258576009600085858481811061114d5761114d61309d565b90506020020160208101906111629190612cb2565b6001600160a01b03168152602081019190915260400160009081205460ff1615906009908686858181106111985761119861309d565b90506020020160208101906111ad9190612cb2565b6001600160a01b0316815260208101919091526040016000908120805460ff1916921515929092179091556009908585848181106111ed576111ed61309d565b90506020020160208101906112029190612cb2565b6001600160a01b03168152602081019190915260400160002054825160ff909116908390839081106112365761123661309d565b9115156020928302919091019091015280611250816130c9565b91505061112f565b507f4a28b173d9bc739be3886d172e07fef80392184787fc6b92406ce0f0c05b7e6383838360405161128c9392919061316f565b60405180910390a1505050565b6002600454036112eb5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104dc565b6002600455565b60055460ff16156109265760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016104dc565b600754600090819081906001600160a01b03166319fa763a3360a08701356113636020890189612da8565b61137060e08a018a612e38565b6040518663ffffffff1660e01b81526004016113909594939291906131c3565b602060405180830381865afa1580156113ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d19190613084565b91506113e661067b6040860160208701612cb2565b15611453578360a00135341461143e5760405162461bcd60e51b815260206004820152601e60248201527f5472616e736974537761703a20696e76616c6964206d73672e76616c7565000060448201526064016104dc565b61144c60a0850135836124e2565b925061155b565b6114636040850160208601612cb2565b6006546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa1580156114ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d09190613084565b90508160000361150a576115056114ed6040860160208701612cb2565b60065433906001600160a01b031660a0880135612538565b61155b565b61152961151d6040860160208701612cb2565b33308760a00135612538565b61155b61153c6040860160208701612cb2565b6006546001600160a01b031661155660a0880135866124e2565b612668565b9193909250565b6060604483511015801561159b5750826000815181106115845761158461309d565b6020910101516001600160f81b031916600160fb1b145b80156115cc5750826001815181106115b5576115b561309d565b6020910101516001600160f81b03191660c360f81b145b80156115fd5750826002815181106115e6576115e661309d565b6020910101516001600160f81b031916607960f81b145b801561162e5750826003815181106116175761161761309d565b6020910101516001600160f81b031916600560fd1b145b156116b85760448381018051909161164691906131f4565b8451101561168e5760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103932bb32b93a103932b0b9b7b760591b60448201526064016104dc565b82816040516020016116a1929190613207565b6040516020818303038152906040529150506117d3565b825160241480156116ee5750826000815181106116d7576116d761309d565b6020910101516001600160f81b031916602760f91b145b801561171f5750826001815181106117085761170861309d565b6020910101516001600160f81b031916600960fb1b145b80156117505750826002815181106117395761173961309d565b6020910101516001600160f81b031916607b60f81b145b801561178157508260038151811061176a5761176a61309d565b6020910101516001600160f81b031916607160f81b145b156117a65760248301518261179582612791565b6040516020016116a1929190613256565b816117b0846127b9565b6040516020016117c192919061328b565b60405160208183030381529060405290505b92915050565b60006001600160a01b03821615806117d357506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1492915050565b61182260a0850160808601612cb2565b6001600160a01b031661183b6060860160408701612cb2565b6001600160a01b03166118546040870160208801612cb2565b6001600160a01b03167f7055e3d08e2c20429c6b162f3e3bee3f426d59896e66084c3580dc353e54129d33878960a00135878b60c001358a8d61010001358e8060e001906118a29190612e38565b426040516118b99a999897969594939291906132dc565b60405180910390a450505050565b336118da6002546001600160a01b031690565b6001600160a01b0316146109265760405162461bcd60e51b815260206004820152602360248201527f4f776e61626c653a2063616c6c6572206973206e6f74207468652065786563756044820152623a37b960e91b60648201526084016104dc565b604080516000808252602082019092526001600160a01b0384169083906040516119669190613035565b60006040518083038185875af1925050503d80600081146119a3576040519150601f19603f3d011682016040523d82523d6000602084013e6119a8565b606091505b50509050806108ee5760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c45440060448201526064016104dc565b6000806000856001600160a01b031663a9059cbb8686604051602401611a349291906001600160a01b03929092168252602082015260400190565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051611a6d9190613035565b6000604051808303816000865af19150503d8060008114611aaa576040519150601f19603f3d011682016040523d82523d6000602084013e611aaf565b606091505b5091509150818015611ad9575080511580611ad9575080806020019051810190611ad9919061333e565b9695505050505050565b611aeb6112f2565b6005805460ff191660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906020015b60405180910390a1565b611b366129a1565b6005805460ff191690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90602001611b24565b33611b836000546001600160a01b031690565b6001600160a01b0316146109265760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104dc565b600180546001600160a01b0319908116909155600080546001600160a01b03848116938216841783556040519116929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600380546001600160a01b0319908116909155600280546001600160a01b0384811693821684179092556040519116919082907f88436636ea40d5bb1bcc55ff9cd54788af71da886f4147a87f199adcca733d4d90600090a35050565b60008060008415611d30576007546001600160a01b03166319fa763a3360a0870135611cbf6020890189612da8565b611ccc60e08a018a612e38565b6040518663ffffffff1660e01b8152600401611cec9594939291906131c3565b602060405180830381865afa158015611d09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2d9190613084565b91505b611d4361067b6040860160208701612cb2565b15611db0578360a001353414611d9b5760405162461bcd60e51b815260206004820152601e60248201527f5472616e736974537761703a20696e76616c6964206d73672e76616c7565000060448201526064016104dc565b611da960a0850135836124e2565b9250611e2d565b8415611dff57611dc961151d6040860160208701612cb2565b611dfa611ddc6040860160208701612cb2565b611dec6080870160608801612cb2565b61155660a0880135866124e2565b611e2d565b611e2d611e126040860160208701612cb2565b33611e236080880160608901612cb2565b8760a00135612538565b611e4061067b6060860160408701612cb2565b15611f5d578415611e6c57611e5b60a0850160808601612cb2565b6001600160a01b031631905061203a565b6002611e7b6020860186612da8565b60ff1603611f565760096000611e9961014087016101208801612cb2565b6001600160a01b0316815260208101919091526040016000205460ff16611ed25760405162461bcd60e51b81526004016104dc9061335b565b611ee461014085016101208601612cb2565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a08231906024015b602060405180830381865afa158015611f2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f4f9190613084565b905061203a565b504761203a565b8415611fbd57611f736060850160408601612cb2565b6001600160a01b03166370a08231611f9160a0870160808801612cb2565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401611f0e565b611fcd6060850160408601612cb2565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015612013573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120379190613084565b90505b9250925092565b60008061205761067b6060860160408701612cb2565b156122a65784156120b1576120868361207660a0870160808801612cb2565b6001600160a01b031631906124e2565b91508360c001358210156120ac5760405162461bcd60e51b81526004016104dc9061339f565b6124da565b60026120c06020860186612da8565b60ff16036121c05761214f836120de61014087016101208801612cb2565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a08231906024015b602060405180830381865afa158015612125573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121499190613084565b906124e2565b91506009600061216761014087016101208801612cb2565b6001600160a01b0316815260208101919091526040016000205460ff166121a05760405162461bcd60e51b81526004016104dc9061335b565b6121bb6121b561014086016101208701612cb2565b836129ea565b6121cd565b6121ca47846124e2565b91505b6007546001600160a01b03166319fa763a33846121ed6020890189612da8565b6121fa60e08a018a612e38565b6040518663ffffffff1660e01b815260040161221a9594939291906131c3565b602060405180830381865afa158015612237573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225b9190613084565b905061226782826124e2565b91508360c0013582101561228d5760405162461bcd60e51b81526004016104dc9061339f565b6120ac6122a060a0860160808701612cb2565b8361193c565b841561230a57612086836122c06060870160408801612cb2565b6001600160a01b03166370a082316122de60a0890160808a01612cb2565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401612108565b61231e836120de6060870160408801612cb2565b6007549092506001600160a01b03166319fa763a33846123416020890189612da8565b61234e60e08a018a612e38565b6040518663ffffffff1660e01b815260040161236e9594939291906131c3565b602060405180830381865afa15801561238b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123af9190613084565b90506123bb82826124e2565b915060006123cf6060860160408701612cb2565b6001600160a01b03166370a082316123ed60a0880160808901612cb2565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612431573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124559190613084565b905061248061246a6060870160408801612cb2565b61247a60a0880160808901612cb2565b85612668565b6124b2816124946060880160408901612cb2565b6001600160a01b03166370a082316122de60a08a0160808b01612cb2565b92508460c001358310156124d85760405162461bcd60e51b81526004016104dc9061339f565b505b935093915050565b6000826124ef83826133e6565b91508111156117d35760405162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b60448201526064016104dc565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b179052915160009283929088169161259c9190613035565b6000604051808303816000865af19150503d80600081146125d9576040519150601f19603f3d011682016040523d82523d6000602084013e6125de565b606091505b5091509150818015612608575080511580612608575080806020019051810190612608919061333e565b6126605760405162461bcd60e51b8152602060048201526024808201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f46416044820152631253115160e21b60648201526084016104dc565b505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291516000928392908716916126c49190613035565b6000604051808303816000865af19150503d8060008114612701576040519150601f19603f3d011682016040523d82523d6000602084013e612706565b606091505b5091509150818015612730575080511580612730575080806020019051810190612730919061333e565b61278a5760405162461bcd60e51b815260206004820152602560248201527f5472616e7366657248656c7065723a205452414e534645525f544f4b454e5f46604482015264105253115160da1b60648201526084016104dc565b5050505050565b60606117d3826040516020016127a991815260200190565b6040516020818303038152906040525b80516060906f181899199a1a9b1b9c1cb0b131b232b360811b906000906127e19060026133f9565b6127ec9060026131f4565b67ffffffffffffffff81111561280457612804612b7c565b6040519080825280601f01601f19166020018201604052801561282e576020820181803683370190505b509050600360fc1b816000815181106128495761284961309d565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106128785761287861309d565b60200101906001600160f81b031916908160001a90535060005b8451811015612999578260048683815181106128b0576128b061309d565b01602001516001600160f81b031916901c60f81c601081106128d4576128d461309d565b1a60f81b826128e48360026133f9565b6128ef9060026131f4565b815181106128ff576128ff61309d565b60200101906001600160f81b031916908160001a905350828582815181106129295761292961309d565b60209101015160f81c600f16601081106129455761294561309d565b1a60f81b826129558360026133f9565b6129609060036131f4565b815181106129705761297061309d565b60200101906001600160f81b031916908160001a90535080612991816130c9565b915050612892565b509392505050565b60055460ff166109265760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016104dc565b600080836001600160a01b03166000632e1a7d4d85604051602401612a1191815260200190565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051612a4a9190613035565b60006040518083038185875af1925050503d8060008114612a87576040519150601f19603f3d011682016040523d82523d6000602084013e612a8c565b606091505b5091509150818015612ab6575080511580612ab6575080806020019051810190612ab6919061333e565b612b025760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a2057495448445241575f4641494c45440060448201526064016104dc565b50505050565b60008060408385031215612b1b57600080fd5b823567ffffffffffffffff80821115612b3357600080fd5b908401906101408287031215612b4857600080fd5b90925060208401359080821115612b5e57600080fd5b50830160608186031215612b7157600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612bbb57612bbb612b7c565b604052919050565b600067ffffffffffffffff821115612bdd57612bdd612b7c565b5060051b60200190565b80356001600160a01b0381168114612bfe57600080fd5b919050565b60008060408385031215612c1657600080fd5b823567ffffffffffffffff811115612c2d57600080fd5b8301601f81018513612c3e57600080fd5b80356020612c53612c4e83612bc3565b612b92565b82815260059290921b83018101918181019088841115612c7257600080fd5b938201935b83851015612c9757612c8885612be7565b82529382019390820190612c77565b9550612ca69050868201612be7565b93505050509250929050565b600060208284031215612cc457600080fd5b612ccd82612be7565b9392505050565b801515811461090957600080fd5b600060208284031215612cf457600080fd5b8135612ccd81612cd4565b803560ff81168114612bfe57600080fd5b60006020808385031215612d2357600080fd5b823567ffffffffffffffff811115612d3a57600080fd5b8301601f81018513612d4b57600080fd5b8035612d59612c4e82612bc3565b81815260059190911b82018301908381019087831115612d7857600080fd5b928401925b82841015612d9d57612d8e84612cff565b82529284019290840190612d7d565b979650505050505050565b600060208284031215612dba57600080fd5b612ccd82612cff565b60008060208385031215612dd657600080fd5b823567ffffffffffffffff80821115612dee57600080fd5b818501915085601f830112612e0257600080fd5b813581811115612e1157600080fd5b8660208260051b8501011115612e2657600080fd5b60209290920196919550909350505050565b6000808335601e19843603018112612e4f57600080fd5b83018035915067ffffffffffffffff821115612e6a57600080fd5b602001915036819003821315612e7f57600080fd5b9250929050565b60208082526024908201527f5472616e736974537761703a20646174612073686f756c64206265206e6f74206040820152637a65726f60e01b606082015260800190565b6020808252602c908201527f5472616e736974537761703a20616d6f756e742073686f756c6420626520677260408201526b06561746572207468616e20360a41b606082015260800190565b60208082526022908201527f5472616e736974537761703a20696e76616c69642063616c6c62797465734465604082015261736360f01b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6020815260ff612f9083612cff565b16602082015260018060a01b03612fa960208401612be7565b16604082015260006040830135601e19843603018112612fc857600080fd5b830160208101903567ffffffffffffffff811115612fe557600080fd5b803603821315612ff457600080fd5b606080850152613008608085018284612f58565b95945050505050565b60005b8381101561302c578181015183820152602001613014565b50506000910152565b60008251613047818460208701613011565b9190910192915050565b6020815260008251806020840152613070816040850160208701613011565b601f01601f19169190910160400192915050565b60006020828403121561309657600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016130db576130db6130b3565b5060010190565b600081518084526020808501945080840160005b838110156131145781511515875295820195908201906001016130f6565b509495945050505050565b604080825283519082018190526000906020906060840190828701845b8281101561315b57815160ff168452928401929084019060010161313c565b50505083810382850152611ad981866130e2565b6040808252810183905260008460608301825b868110156131b0576001600160a01b0361319b84612be7565b16825260209283019290910190600101613182565b508381036020850152612d9d81866130e2565b60018060a01b038616815284602082015260ff84166040820152608060608201526000612d9d608083018486612f58565b808201808211156117d3576117d36130b3565b60008351613219818460208801613011565b6508ae4e4dee4560d31b908301908152835161323c816006840160208801613011565b602960f81b60069290910191820152600701949350505050565b60008351613268818460208801613011565b650a0c2dcd2c6560d31b908301908152835161323c816006840160208801613011565b6000835161329d818460208801613011565b670aadcd6dcdeeedc560c31b90830190815283516132c2816008840160208801613011565b602960f81b60089290910191820152600901949350505050565b600061012060018060a01b038d1683528b151560208401528a60408401528960608401528860808401528760a08401528660c08401528060e08401526133258184018688612f58565b915050826101008301529b9a5050505050505050505050565b60006020828403121561335057600080fd5b8151612ccd81612cd4565b60208082526024908201527f5472616e736974537761703a20696e76616c69642077726170706564206164646040820152637265737360e01b606082015260800190565b60208082526027908201527f5472616e736974537761703a20696e73756666696369656e742072657475726e60408201526608185b5bdd5b9d60ca1b606082015260800190565b818103818111156117d3576117d36130b3565b80820281158282048414176117d3576117d36130b356fea2646970667358221220e17c9f74d89f6274faaf48b4224f03f82f32783ebfdadf5d8ffbf445abc1ded064736f6c63430008110033000000000000000000000000f7a2f863299c17dfa11cd8a14e7c7dca92f315b90000000000000000000000008755773dc777b9f9b2e2c86402a03f099f8236910000000000000000000000001f6e41c47349634fe261403a18f8515546f58826000000000000000000000000280333c41a9302448ebc070ed0300ad2ed4b8244

Deployed Bytecode

0x60806040526004361061014f5760003560e01c8063afed2d0e116100b6578063d63234e01161006f578063d63234e0146103e2578063dc69bbad14610400578063e30c397814610420578063e8e1bc5d1461043e578063f2fde38b1461045e578063f8c79f731461047e57600080fd5b8063afed2d0e1461031e578063c10bea5c1461033e578063c34c08e514610351578063c3dc51fe1461036f578063c58dff5c1461038f578063c6c46552146103c257600080fd5b8063715018a611610108578063715018a61461028057806379ba509714610295578063845b1f77146102aa5780638da5cb5b146102cd57806394752e82146102eb57806394d3d7931461030957600080fd5b8063017efb28146101935780630e8cc705146101a85780633932a93c146101c857806351205349146102165780635c975abb146102485780635d4fead31461026057600080fd5b3661018e57604080513381523460208201527f7784f8d436dc514f0690e472c7e2d7f660a73e504c69b2350f6be5a5f02432ef910160405180910390a1005b600080fd5b6101a66101a1366004612b08565b61049e565b005b3480156101b457600080fd5b506101a66101c3366004612c03565b61076f565b3480156101d457600080fd5b506102016101e3366004612cb2565b6001600160a01b031660009081526009602052604090205460ff1690565b60405190151581526020015b60405180910390f35b34801561022257600080fd5b506007546001600160a01b03165b6040516001600160a01b03909116815260200161020d565b34801561025457600080fd5b5060055460ff16610201565b34801561026c57600080fd5b506101a661027b366004612ce2565b6108f3565b34801561028c57600080fd5b506101a6610914565b3480156102a157600080fd5b506101a6610928565b3480156102b657600080fd5b5060055461010090046001600160a01b0316610230565b3480156102d957600080fd5b506000546001600160a01b0316610230565b3480156102f757600080fd5b506006546001600160a01b0316610230565b34801561031557600080fd5b506101a66109a7565b34801561032a57600080fd5b506101a6610339366004612cb2565b610a2a565b6101a661034c366004612b08565b610a9b565b34801561035d57600080fd5b506002546001600160a01b0316610230565b34801561037b57600080fd5b506101a661038a366004612d10565b610dbe565b34801561039b57600080fd5b506102016103aa366004612da8565b60ff9081166000908152600860205260409020541690565b3480156103ce57600080fd5b506101a66103dd366004612cb2565b610f56565b3480156103ee57600080fd5b506003546001600160a01b0316610230565b34801561040c57600080fd5b506101a661041b366004612cb2565b610fb0565b34801561042c57600080fd5b506001546001600160a01b0316610230565b34801561044a57600080fd5b506101a6610459366004612cb2565b611012565b34801561046a57600080fd5b506101a6610479366004612cb2565b61106c565b34801561048a57600080fd5b506101a6610499366004612dc3565b6110dd565b6104a6611299565b6104ae6112f2565b60006104bd6040830183612e38565b9050116104e55760405162461bcd60e51b81526004016104dc90612e86565b60405180910390fd5b60008260a00135116105095760405162461bcd60e51b81526004016104dc90612eca565b6105196040820160208301612cb2565b6001600160a01b03166105326040840160208501612cb2565b6001600160a01b0316146105585760405162461bcd60e51b81526004016104dc90612f16565b600080600061056685611338565b600654604051939650919450925060009182916001600160a01b031690869063ccbe400790610599908a90602401612f81565b6040516020818303038152906040529060e01b6020820180516001600160e01b0383818316178352505050506040516105d29190613035565b60006040518083038185875af1925050503d806000811461060f576040519150601f19603f3d011682016040523d82523d6000602084013e610614565b606091505b5091509150816106655761064c816040518060400160405280600c81526020016b2a3930b739b4ba29bbb0b81d60a11b815250611562565b60405162461bcd60e51b81526004016104dc9190613051565b50610680905061067b6040870160208801612cb2565b6117d9565b61075057806106956040870160208801612cb2565b6006546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa1580156106de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107029190613084565b10156107505760405162461bcd60e51b815260206004820152601a60248201527f5472616e736974537761703a20696e76616c69642063726f737300000000000060448201526064016104dc565b61075e856001846000611812565b50505061076b6001600455565b5050565b6107776118c7565b60005b82518110156108ee5760006107a784838151811061079a5761079a61309d565b60200260200101516117d9565b156107bd5750476107b8838261193c565b61086b565b8382815181106107cf576107cf61309d565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561081f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108439190613084565b905061086984838151811061085a5761085a61309d565b602002602001015184836119f9565b505b826001600160a01b0316336001600160a01b03168584815181106108915761089161309d565b60200260200101516001600160a01b03167f3115d1449a7b732c986cba18244e897a450f61e1bb8d589cd2e69e6c8924f9f7846040516108d391815260200190565b60405180910390a450806108e6816130c9565b91505061077a565b505050565b6108fb6118c7565b801561090c57610909611ae3565b50565b610909611b2e565b61091c611b70565b6109266000611bd9565b565b338061093c6001546001600160a01b031690565b6001600160a01b03161461099e5760405162461bcd60e51b8152602060048201526024808201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206e6577206f6044820152633bb732b960e11b60648201526084016104dc565b61090981611bd9565b33806109bb6003546001600160a01b031690565b6001600160a01b031614610a215760405162461bcd60e51b815260206004820152602760248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206e657720656044820152663c32b1baba37b960c91b60648201526084016104dc565b61090981611c33565b610a326118c7565b600380546001600160a01b0383166001600160a01b03199091168117909155610a636002546001600160a01b031690565b6001600160a01b03167fdd01547fc40682edc3cd8d164d53f5a1ae6b46138a83f045658ed760823ddba860405160405180910390a350565b610aa3611299565b610aab6112f2565b6000610aba6040830183612e38565b905011610ad95760405162461bcd60e51b81526004016104dc90612e86565b60008260a0013511610afd5760405162461bcd60e51b81526004016104dc90612eca565b6000610b0f60a0840160808501612cb2565b6001600160a01b031603610b7c5760405162461bcd60e51b815260206004820152602e60248201527f5472616e736974537761703a2072656365697665722073686f756c642062652060448201526d6e6f74206164647265737328302960901b60648201526084016104dc565b60008260c0013511610bee5760405162461bcd60e51b815260206004820152603560248201527f5472616e736974537761703a206d696e52657475726e416d6f756e742073686f6044820152740756c642062652067726561746572207468616e203605c1b60648201526084016104dc565b6000610bfd6020830183612da8565b60ff1603610c5457610c156040820160208301612cb2565b6001600160a01b0316610c2e6040840160208501612cb2565b6001600160a01b031614610c545760405162461bcd60e51b81526004016104dc90612f16565b6000600881610c666020860186612da8565b60ff908116825260208201929092526040016000908120549091161591508080610c908487611c90565b925092509250600080600560019054906101000a90046001600160a01b03166001600160a01b03168563ccbe400789604051602401610ccf9190612f81565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051610d089190613035565b60006040518083038185875af1925050503d8060008114610d45576040519150601f19603f3d011682016040523d82523d6000602084013e610d4a565b606091505b509150915081610d825761064c816040518060400160405280600c81526020016b2a3930b739b4ba29bbb0b81d60a11b815250611562565b5050600080610d92868985612041565b9150915083811115610da2578093505b610dae88878685611812565b50505050505061076b6001600455565b610dc66118c7565b6000815167ffffffffffffffff811115610de257610de2612b7c565b604051908082528060200260200182016040528015610e0b578160200160208202803683370190505b50905060005b8251811015610f185760086000848381518110610e3057610e3061309d565b602002602001015160ff1660ff16815260200190815260200160002060009054906101000a900460ff161560086000858481518110610e7157610e7161309d565b602002602001015160ff1660ff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060086000848381518110610eba57610eba61309d565b602002602001015160ff1660ff16815260200190815260200160002060009054906101000a900460ff16828281518110610ef657610ef661309d565b9115156020928302919091019091015280610f10816130c9565b915050610e11565b507f5e69b8fb6404283a560ee2205dc0f225019578c56e3a6c52137e0aa995235b668282604051610f4a92919061311f565b60405180910390a15050565b610f5e6118c7565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907faf855a7e4074e8930caf657b3505942d4ba0e69b6b6e63553c653d7b1ffcc06190600090a35050565b610fb86118c7565b600580546001600160a01b03838116610100818102610100600160a81b031985161790945560405193909204169182907fbc071769e275808816d09db519c1888c355f7557cb63095ce21e26a97a5f0e9c90600090a35050565b61101a6118c7565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907ff2ef974bc2aedf0c322b1a97e8627e85114a789cadf8d172b5efb5d6c1d94f8d90600090a35050565b611074611b70565b600180546001600160a01b0383166001600160a01b031990911681179091556110a56000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6110e56118c7565b60008167ffffffffffffffff81111561110057611100612b7c565b604051908082528060200260200182016040528015611129578160200160208202803683370190505b50905060005b82811015611258576009600085858481811061114d5761114d61309d565b90506020020160208101906111629190612cb2565b6001600160a01b03168152602081019190915260400160009081205460ff1615906009908686858181106111985761119861309d565b90506020020160208101906111ad9190612cb2565b6001600160a01b0316815260208101919091526040016000908120805460ff1916921515929092179091556009908585848181106111ed576111ed61309d565b90506020020160208101906112029190612cb2565b6001600160a01b03168152602081019190915260400160002054825160ff909116908390839081106112365761123661309d565b9115156020928302919091019091015280611250816130c9565b91505061112f565b507f4a28b173d9bc739be3886d172e07fef80392184787fc6b92406ce0f0c05b7e6383838360405161128c9392919061316f565b60405180910390a1505050565b6002600454036112eb5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016104dc565b6002600455565b60055460ff16156109265760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016104dc565b600754600090819081906001600160a01b03166319fa763a3360a08701356113636020890189612da8565b61137060e08a018a612e38565b6040518663ffffffff1660e01b81526004016113909594939291906131c3565b602060405180830381865afa1580156113ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d19190613084565b91506113e661067b6040860160208701612cb2565b15611453578360a00135341461143e5760405162461bcd60e51b815260206004820152601e60248201527f5472616e736974537761703a20696e76616c6964206d73672e76616c7565000060448201526064016104dc565b61144c60a0850135836124e2565b925061155b565b6114636040850160208601612cb2565b6006546040516370a0823160e01b81526001600160a01b0391821660048201529116906370a0823190602401602060405180830381865afa1580156114ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d09190613084565b90508160000361150a576115056114ed6040860160208701612cb2565b60065433906001600160a01b031660a0880135612538565b61155b565b61152961151d6040860160208701612cb2565b33308760a00135612538565b61155b61153c6040860160208701612cb2565b6006546001600160a01b031661155660a0880135866124e2565b612668565b9193909250565b6060604483511015801561159b5750826000815181106115845761158461309d565b6020910101516001600160f81b031916600160fb1b145b80156115cc5750826001815181106115b5576115b561309d565b6020910101516001600160f81b03191660c360f81b145b80156115fd5750826002815181106115e6576115e661309d565b6020910101516001600160f81b031916607960f81b145b801561162e5750826003815181106116175761161761309d565b6020910101516001600160f81b031916600560fd1b145b156116b85760448381018051909161164691906131f4565b8451101561168e5760405162461bcd60e51b815260206004820152601560248201527424b73b30b634b2103932bb32b93a103932b0b9b7b760591b60448201526064016104dc565b82816040516020016116a1929190613207565b6040516020818303038152906040529150506117d3565b825160241480156116ee5750826000815181106116d7576116d761309d565b6020910101516001600160f81b031916602760f91b145b801561171f5750826001815181106117085761170861309d565b6020910101516001600160f81b031916600960fb1b145b80156117505750826002815181106117395761173961309d565b6020910101516001600160f81b031916607b60f81b145b801561178157508260038151811061176a5761176a61309d565b6020910101516001600160f81b031916607160f81b145b156117a65760248301518261179582612791565b6040516020016116a1929190613256565b816117b0846127b9565b6040516020016117c192919061328b565b60405160208183030381529060405290505b92915050565b60006001600160a01b03821615806117d357506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1492915050565b61182260a0850160808601612cb2565b6001600160a01b031661183b6060860160408701612cb2565b6001600160a01b03166118546040870160208801612cb2565b6001600160a01b03167f7055e3d08e2c20429c6b162f3e3bee3f426d59896e66084c3580dc353e54129d33878960a00135878b60c001358a8d61010001358e8060e001906118a29190612e38565b426040516118b99a999897969594939291906132dc565b60405180910390a450505050565b336118da6002546001600160a01b031690565b6001600160a01b0316146109265760405162461bcd60e51b815260206004820152602360248201527f4f776e61626c653a2063616c6c6572206973206e6f74207468652065786563756044820152623a37b960e91b60648201526084016104dc565b604080516000808252602082019092526001600160a01b0384169083906040516119669190613035565b60006040518083038185875af1925050503d80600081146119a3576040519150601f19603f3d011682016040523d82523d6000602084013e6119a8565b606091505b50509050806108ee5760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c45440060448201526064016104dc565b6000806000856001600160a01b031663a9059cbb8686604051602401611a349291906001600160a01b03929092168252602082015260400190565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051611a6d9190613035565b6000604051808303816000865af19150503d8060008114611aaa576040519150601f19603f3d011682016040523d82523d6000602084013e611aaf565b606091505b5091509150818015611ad9575080511580611ad9575080806020019051810190611ad9919061333e565b9695505050505050565b611aeb6112f2565b6005805460ff191660011790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906020015b60405180910390a1565b611b366129a1565b6005805460ff191690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa90602001611b24565b33611b836000546001600160a01b031690565b6001600160a01b0316146109265760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104dc565b600180546001600160a01b0319908116909155600080546001600160a01b03848116938216841783556040519116929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600380546001600160a01b0319908116909155600280546001600160a01b0384811693821684179092556040519116919082907f88436636ea40d5bb1bcc55ff9cd54788af71da886f4147a87f199adcca733d4d90600090a35050565b60008060008415611d30576007546001600160a01b03166319fa763a3360a0870135611cbf6020890189612da8565b611ccc60e08a018a612e38565b6040518663ffffffff1660e01b8152600401611cec9594939291906131c3565b602060405180830381865afa158015611d09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2d9190613084565b91505b611d4361067b6040860160208701612cb2565b15611db0578360a001353414611d9b5760405162461bcd60e51b815260206004820152601e60248201527f5472616e736974537761703a20696e76616c6964206d73672e76616c7565000060448201526064016104dc565b611da960a0850135836124e2565b9250611e2d565b8415611dff57611dc961151d6040860160208701612cb2565b611dfa611ddc6040860160208701612cb2565b611dec6080870160608801612cb2565b61155660a0880135866124e2565b611e2d565b611e2d611e126040860160208701612cb2565b33611e236080880160608901612cb2565b8760a00135612538565b611e4061067b6060860160408701612cb2565b15611f5d578415611e6c57611e5b60a0850160808601612cb2565b6001600160a01b031631905061203a565b6002611e7b6020860186612da8565b60ff1603611f565760096000611e9961014087016101208801612cb2565b6001600160a01b0316815260208101919091526040016000205460ff16611ed25760405162461bcd60e51b81526004016104dc9061335b565b611ee461014085016101208601612cb2565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a08231906024015b602060405180830381865afa158015611f2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f4f9190613084565b905061203a565b504761203a565b8415611fbd57611f736060850160408601612cb2565b6001600160a01b03166370a08231611f9160a0870160808801612cb2565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401611f0e565b611fcd6060850160408601612cb2565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a0823190602401602060405180830381865afa158015612013573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120379190613084565b90505b9250925092565b60008061205761067b6060860160408701612cb2565b156122a65784156120b1576120868361207660a0870160808801612cb2565b6001600160a01b031631906124e2565b91508360c001358210156120ac5760405162461bcd60e51b81526004016104dc9061339f565b6124da565b60026120c06020860186612da8565b60ff16036121c05761214f836120de61014087016101208801612cb2565b6040516370a0823160e01b81523060048201526001600160a01b0391909116906370a08231906024015b602060405180830381865afa158015612125573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121499190613084565b906124e2565b91506009600061216761014087016101208801612cb2565b6001600160a01b0316815260208101919091526040016000205460ff166121a05760405162461bcd60e51b81526004016104dc9061335b565b6121bb6121b561014086016101208701612cb2565b836129ea565b6121cd565b6121ca47846124e2565b91505b6007546001600160a01b03166319fa763a33846121ed6020890189612da8565b6121fa60e08a018a612e38565b6040518663ffffffff1660e01b815260040161221a9594939291906131c3565b602060405180830381865afa158015612237573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225b9190613084565b905061226782826124e2565b91508360c0013582101561228d5760405162461bcd60e51b81526004016104dc9061339f565b6120ac6122a060a0860160808701612cb2565b8361193c565b841561230a57612086836122c06060870160408801612cb2565b6001600160a01b03166370a082316122de60a0890160808a01612cb2565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401612108565b61231e836120de6060870160408801612cb2565b6007549092506001600160a01b03166319fa763a33846123416020890189612da8565b61234e60e08a018a612e38565b6040518663ffffffff1660e01b815260040161236e9594939291906131c3565b602060405180830381865afa15801561238b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123af9190613084565b90506123bb82826124e2565b915060006123cf6060860160408701612cb2565b6001600160a01b03166370a082316123ed60a0880160808901612cb2565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612431573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124559190613084565b905061248061246a6060870160408801612cb2565b61247a60a0880160808901612cb2565b85612668565b6124b2816124946060880160408901612cb2565b6001600160a01b03166370a082316122de60a08a0160808b01612cb2565b92508460c001358310156124d85760405162461bcd60e51b81526004016104dc9061339f565b505b935093915050565b6000826124ef83826133e6565b91508111156117d35760405162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b60448201526064016104dc565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b179052915160009283929088169161259c9190613035565b6000604051808303816000865af19150503d80600081146125d9576040519150601f19603f3d011682016040523d82523d6000602084013e6125de565b606091505b5091509150818015612608575080511580612608575080806020019051810190612608919061333e565b6126605760405162461bcd60e51b8152602060048201526024808201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f46416044820152631253115160e21b60648201526084016104dc565b505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291516000928392908716916126c49190613035565b6000604051808303816000865af19150503d8060008114612701576040519150601f19603f3d011682016040523d82523d6000602084013e612706565b606091505b5091509150818015612730575080511580612730575080806020019051810190612730919061333e565b61278a5760405162461bcd60e51b815260206004820152602560248201527f5472616e7366657248656c7065723a205452414e534645525f544f4b454e5f46604482015264105253115160da1b60648201526084016104dc565b5050505050565b60606117d3826040516020016127a991815260200190565b6040516020818303038152906040525b80516060906f181899199a1a9b1b9c1cb0b131b232b360811b906000906127e19060026133f9565b6127ec9060026131f4565b67ffffffffffffffff81111561280457612804612b7c565b6040519080825280601f01601f19166020018201604052801561282e576020820181803683370190505b509050600360fc1b816000815181106128495761284961309d565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106128785761287861309d565b60200101906001600160f81b031916908160001a90535060005b8451811015612999578260048683815181106128b0576128b061309d565b01602001516001600160f81b031916901c60f81c601081106128d4576128d461309d565b1a60f81b826128e48360026133f9565b6128ef9060026131f4565b815181106128ff576128ff61309d565b60200101906001600160f81b031916908160001a905350828582815181106129295761292961309d565b60209101015160f81c600f16601081106129455761294561309d565b1a60f81b826129558360026133f9565b6129609060036131f4565b815181106129705761297061309d565b60200101906001600160f81b031916908160001a90535080612991816130c9565b915050612892565b509392505050565b60055460ff166109265760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016104dc565b600080836001600160a01b03166000632e1a7d4d85604051602401612a1191815260200190565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051612a4a9190613035565b60006040518083038185875af1925050503d8060008114612a87576040519150601f19603f3d011682016040523d82523d6000602084013e612a8c565b606091505b5091509150818015612ab6575080511580612ab6575080806020019051810190612ab6919061333e565b612b025760405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a2057495448445241575f4641494c45440060448201526064016104dc565b50505050565b60008060408385031215612b1b57600080fd5b823567ffffffffffffffff80821115612b3357600080fd5b908401906101408287031215612b4857600080fd5b90925060208401359080821115612b5e57600080fd5b50830160608186031215612b7157600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612bbb57612bbb612b7c565b604052919050565b600067ffffffffffffffff821115612bdd57612bdd612b7c565b5060051b60200190565b80356001600160a01b0381168114612bfe57600080fd5b919050565b60008060408385031215612c1657600080fd5b823567ffffffffffffffff811115612c2d57600080fd5b8301601f81018513612c3e57600080fd5b80356020612c53612c4e83612bc3565b612b92565b82815260059290921b83018101918181019088841115612c7257600080fd5b938201935b83851015612c9757612c8885612be7565b82529382019390820190612c77565b9550612ca69050868201612be7565b93505050509250929050565b600060208284031215612cc457600080fd5b612ccd82612be7565b9392505050565b801515811461090957600080fd5b600060208284031215612cf457600080fd5b8135612ccd81612cd4565b803560ff81168114612bfe57600080fd5b60006020808385031215612d2357600080fd5b823567ffffffffffffffff811115612d3a57600080fd5b8301601f81018513612d4b57600080fd5b8035612d59612c4e82612bc3565b81815260059190911b82018301908381019087831115612d7857600080fd5b928401925b82841015612d9d57612d8e84612cff565b82529284019290840190612d7d565b979650505050505050565b600060208284031215612dba57600080fd5b612ccd82612cff565b60008060208385031215612dd657600080fd5b823567ffffffffffffffff80821115612dee57600080fd5b818501915085601f830112612e0257600080fd5b813581811115612e1157600080fd5b8660208260051b8501011115612e2657600080fd5b60209290920196919550909350505050565b6000808335601e19843603018112612e4f57600080fd5b83018035915067ffffffffffffffff821115612e6a57600080fd5b602001915036819003821315612e7f57600080fd5b9250929050565b60208082526024908201527f5472616e736974537761703a20646174612073686f756c64206265206e6f74206040820152637a65726f60e01b606082015260800190565b6020808252602c908201527f5472616e736974537761703a20616d6f756e742073686f756c6420626520677260408201526b06561746572207468616e20360a41b606082015260800190565b60208082526022908201527f5472616e736974537761703a20696e76616c69642063616c6c62797465734465604082015261736360f01b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6020815260ff612f9083612cff565b16602082015260018060a01b03612fa960208401612be7565b16604082015260006040830135601e19843603018112612fc857600080fd5b830160208101903567ffffffffffffffff811115612fe557600080fd5b803603821315612ff457600080fd5b606080850152613008608085018284612f58565b95945050505050565b60005b8381101561302c578181015183820152602001613014565b50506000910152565b60008251613047818460208701613011565b9190910192915050565b6020815260008251806020840152613070816040850160208701613011565b601f01601f19169190910160400192915050565b60006020828403121561309657600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016130db576130db6130b3565b5060010190565b600081518084526020808501945080840160005b838110156131145781511515875295820195908201906001016130f6565b509495945050505050565b604080825283519082018190526000906020906060840190828701845b8281101561315b57815160ff168452928401929084019060010161313c565b50505083810382850152611ad981866130e2565b6040808252810183905260008460608301825b868110156131b0576001600160a01b0361319b84612be7565b16825260209283019290910190600101613182565b508381036020850152612d9d81866130e2565b60018060a01b038616815284602082015260ff84166040820152608060608201526000612d9d608083018486612f58565b808201808211156117d3576117d36130b3565b60008351613219818460208801613011565b6508ae4e4dee4560d31b908301908152835161323c816006840160208801613011565b602960f81b60069290910191820152600701949350505050565b60008351613268818460208801613011565b650a0c2dcd2c6560d31b908301908152835161323c816006840160208801613011565b6000835161329d818460208801613011565b670aadcd6dcdeeedc560c31b90830190815283516132c2816008840160208801613011565b602960f81b60089290910191820152600901949350505050565b600061012060018060a01b038d1683528b151560208401528a60408401528960608401528860808401528760a08401528660c08401528060e08401526133258184018688612f58565b915050826101008301529b9a5050505050505050505050565b60006020828403121561335057600080fd5b8151612ccd81612cd4565b60208082526024908201527f5472616e736974537761703a20696e76616c69642077726170706564206164646040820152637265737360e01b606082015260800190565b60208082526027908201527f5472616e736974537761703a20696e73756666696369656e742072657475726e60408201526608185b5bdd5b9d60ca1b606082015260800190565b818103818111156117d3576117d36130b3565b80820281158282048414176117d3576117d36130b356fea2646970667358221220e17c9f74d89f6274faaf48b4224f03f82f32783ebfdadf5d8ffbf445abc1ded064736f6c63430008110033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000f7a2f863299c17dfa11cd8a14e7c7dca92f315b90000000000000000000000008755773dc777b9f9b2e2c86402a03f099f8236910000000000000000000000001f6e41c47349634fe261403a18f8515546f58826000000000000000000000000280333c41a9302448ebc070ed0300ad2ed4b8244

-----Decoded View---------------
Arg [0] : transitSwap_ (address): 0xf7A2f863299C17dfA11CD8a14e7c7DCA92f315B9
Arg [1] : transitCross_ (address): 0x8755773dc777B9F9B2E2c86402A03F099F823691
Arg [2] : transitFees_ (address): 0x1F6E41c47349634Fe261403A18F8515546f58826
Arg [3] : executor (address): 0x280333C41A9302448EbC070eD0300ad2Ed4B8244

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000f7a2f863299c17dfa11cd8a14e7c7dca92f315b9
Arg [1] : 0000000000000000000000008755773dc777b9f9b2e2c86402a03f099f823691
Arg [2] : 0000000000000000000000001f6e41c47349634fe261403a18f8515546f58826
Arg [3] : 000000000000000000000000280333c41a9302448ebc070ed0300ad2ed4b8244


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
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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