Sepolia Testnet

Contract

0xFAC3D81644976e6dea44Ad9D7c9B8558A6cea33d

Overview

ETH Balance

0.000197486995666487 ETH

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Execute72634222024-12-12 11:04:242 hrs ago1734001464IN
0xFAC3D816...8A6cea33d
0 ETH0.000363223.45049719
Execute72632142024-12-12 10:19:363 hrs ago1733998776IN
0xFAC3D816...8A6cea33d
0 ETH0.000484914.43690216
Execute72632142024-12-12 10:19:363 hrs ago1733998776IN
0xFAC3D816...8A6cea33d
0 ETH0.000467064.43690216
Execute72631882024-12-12 10:13:243 hrs ago1733998404IN
0xFAC3D816...8A6cea33d
0 ETH0.000612474.81990051
Execute72631882024-12-12 10:13:243 hrs ago1733998404IN
0xFAC3D816...8A6cea33d
0 ETH0.000612424.81990051
Execute72631312024-12-12 10:01:243 hrs ago1733997684IN
0xFAC3D816...8A6cea33d
0 ETH0.000720565.8937357
Execute72628182024-12-12 8:55:244 hrs ago1733993724IN
0xFAC3D816...8A6cea33d
0 ETH0.0017065716.21352281
Execute72624042024-12-12 7:26:486 hrs ago1733988408IN
0xFAC3D816...8A6cea33d
0 ETH0.000651075.9559248
Execute72617992024-12-12 5:17:488 hrs ago1733980668IN
0xFAC3D816...8A6cea33d
0 ETH0.0082324467.26953349
Execute72616842024-12-12 4:53:488 hrs ago1733979228IN
0xFAC3D816...8A6cea33d
0 ETH0.000247172.01955141
Execute72615912024-12-12 4:34:248 hrs ago1733978064IN
0xFAC3D816...8A6cea33d
0 ETH0.000158191.50308253
Execute72615562024-12-12 4:26:489 hrs ago1733977608IN
0xFAC3D816...8A6cea33d
0 ETH0.000013260.12604046
Execute72615562024-12-12 4:26:489 hrs ago1733977608IN
0xFAC3D816...8A6cea33d
0 ETH0.000013760.12604046
Execute72609642024-12-12 2:19:2411 hrs ago1733969964IN
0xFAC3D816...8A6cea33d
0 ETH0.000158071.50134256
Execute72601672024-12-11 23:32:4813 hrs ago1733959968IN
0xFAC3D816...8A6cea33d
0 ETH0.00016391.50067526
Execute72601402024-12-11 23:26:4814 hrs ago1733959608IN
0xFAC3D816...8A6cea33d
0 ETH0.000183451.50068958
Execute72590552024-12-11 19:36:2417 hrs ago1733945784IN
0xFAC3D816...8A6cea33d
0 ETH0.000706496.71985634
Execute72587322024-12-11 18:26:4819 hrs ago1733941608IN
0xFAC3D816...8A6cea33d
0 ETH0.000877867.17399095
Execute72568332024-12-11 11:41:4825 hrs ago1733917308IN
0xFAC3D816...8A6cea33d
0 ETH0.0091045483.30553335
Execute72558042024-12-11 8:04:2429 hrs ago1733904264IN
0xFAC3D816...8A6cea33d
0 ETH0.0030235824.70654993
Execute72551992024-12-11 5:56:4831 hrs ago1733896608IN
0xFAC3D816...8A6cea33d
0 ETH0.000188781.79356523
Execute72551702024-12-11 5:50:4831 hrs ago1733896248IN
0xFAC3D816...8A6cea33d
0 ETH0.000229031.81300769
Execute72527552024-12-10 21:19:1240 hrs ago1733865552IN
0xFAC3D816...8A6cea33d
0 ETH0.0022676720.76720112
Execute72508122024-12-10 14:29:4846 hrs ago1733840988IN
0xFAC3D816...8A6cea33d
0 ETH0.01953026159.6027141
Execute72503872024-12-10 12:59:482 days ago1733835588IN
0xFAC3D816...8A6cea33d
0 ETH0.0031604625.83007141
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block
From
To
72627302024-12-12 8:36:364 hrs ago1733992596
0xFAC3D816...8A6cea33d
0.00271542 ETH
72627302024-12-12 8:36:364 hrs ago1733992596
0xFAC3D816...8A6cea33d
0.00271542 ETH
72610912024-12-12 2:47:1210 hrs ago1733971632
0xFAC3D816...8A6cea33d
0.00271542 ETH
72610912024-12-12 2:47:1210 hrs ago1733971632
0xFAC3D816...8A6cea33d
0.00271542 ETH
72608472024-12-12 1:55:2411 hrs ago1733968524
0xFAC3D816...8A6cea33d
0.0081719 ETH
72608472024-12-12 1:55:2411 hrs ago1733968524
0xFAC3D816...8A6cea33d
0.04415181 ETH
72608472024-12-12 1:55:2411 hrs ago1733968524
0xFAC3D816...8A6cea33d
0.04415181 ETH
72608452024-12-12 1:54:4811 hrs ago1733968488
0xFAC3D816...8A6cea33d
0.0081719 ETH
72608452024-12-12 1:54:4811 hrs ago1733968488
0xFAC3D816...8A6cea33d
0.04415181 ETH
72608452024-12-12 1:54:4811 hrs ago1733968488
0xFAC3D816...8A6cea33d
0.04415181 ETH
72604242024-12-12 0:26:3613 hrs ago1733963196
0xFAC3D816...8A6cea33d
0.0081719 ETH
72604242024-12-12 0:26:3613 hrs ago1733963196
0xFAC3D816...8A6cea33d
0.01078944 ETH
72604242024-12-12 0:26:3613 hrs ago1733963196
0xFAC3D816...8A6cea33d
0.01078944 ETH
72600642024-12-11 23:10:2414 hrs ago1733958624
0xFAC3D816...8A6cea33d
0.00544793 ETH
72600642024-12-11 23:10:2414 hrs ago1733958624
0xFAC3D816...8A6cea33d
0.00544793 ETH
72600252024-12-11 23:02:0014 hrs ago1733958120
0xFAC3D816...8A6cea33d
0.00544793 ETH
72600252024-12-11 23:02:0014 hrs ago1733958120
0xFAC3D816...8A6cea33d
0.00544793 ETH
72591622024-12-11 19:59:0017 hrs ago1733947140
0xFAC3D816...8A6cea33d
0.00271542 ETH
72591622024-12-11 19:59:0017 hrs ago1733947140
0xFAC3D816...8A6cea33d
0.00271542 ETH
72590412024-12-11 19:33:1217 hrs ago1733945592
0xFAC3D816...8A6cea33d
0.00271542 ETH
72590412024-12-11 19:33:1217 hrs ago1733945592
0xFAC3D816...8A6cea33d
0.00271542 ETH
72583902024-12-11 17:13:3620 hrs ago1733937216
0xFAC3D816...8A6cea33d
0.00549915 ETH
72583902024-12-11 17:13:3620 hrs ago1733937216
0xFAC3D816...8A6cea33d
0.00549915 ETH
72581362024-12-11 16:19:1221 hrs ago1733933952
0xFAC3D816...8A6cea33d
0.00271542 ETH
72581362024-12-11 16:19:1221 hrs ago1733933952
0xFAC3D816...8A6cea33d
0.00271542 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SynthrBridgeLightChainAxelar

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 24 : SynthrBridgeLightChainAxelar.sol
// SPDX-License-Identifier: MIT

pragma solidity =0.8.24;

import "./BaseBridgeAxelar.sol";
import "../../interfaces/ISynthrIssuer.sol";
import "../../interfaces/IExchanger.sol";
import "../../interfaces/IWrappedSynthr.sol";
import "../../libraries/BytesLib.sol";

/**
 * @title SynthrBridgeLightChainAxelar
 * @dev Bridge contract for cross-chain communication using Axelar in the Synthr protocol
 */
contract SynthrBridgeLightChainAxelar is BaseBridgeAxelar {
    using BytesLib for bytes;

    error source_chainID_lookup_not_set();
    error Call_from_invalid_source();
    error Bridging_on_same_chain();
    error Margin_delta_zero();
    error Unknown_packetType(uint16 packetType);

    /**
     * @dev Constructor to initialize the SynthrBridgeLightChainAxelar contract.
     * @param _selfAxelarGateway Address of the Axelar gateway contract
     * @param _selfGasReceiver Address of the gas receiver contract
     */
    constructor(address _selfAxelarGateway, address _selfGasReceiver) BaseBridgeAxelar(_selfAxelarGateway, _selfGasReceiver) {
        lzFeePercentage = 100;
    }

    /**
     * @notice Get the main chain ID
     * @return The main chain ID
     */
    function mainChainId() external view returns (uint16) {
        return _mainChainId;
    }

    /**
     * @notice Initialize the contract with the given parameters
     * @param __synthrAddressResolver The address resolver for Synthr
     * @param __mainChainId The ID of the main chain
     * @param __selfChainId The ID of the current chain
     */
    function initialize(
        address __synthrAddressResolver,
        uint16 __mainChainId,
        uint16 __selfChainId
    ) external onlyOwner {
        _mainChainId = __mainChainId;
        _synthrAddressResolver = __synthrAddressResolver;
        _selfChainId = __selfChainId;
    }

    function _execute(
        string calldata _sourceChain,
        string calldata _sourceAddress,
        bytes calldata _payload
    ) internal override {
        uint16 srcChainID = srcChainIdLookup[_sourceChain];
        if (srcChainID == 0) {
            revert source_chainID_lookup_not_set();
        }
        AxelarChainInfo memory axelarChainInfo = axelarDstChainLookup[srcChainID];

        // destination chain can also be source for mainchain bridge (while call from lightchain -> mainchain bridge)
        if (
            keccak256(abi.encodePacked(_sourceAddress)) != keccak256(abi.encodePacked(axelarChainInfo.dstChainAddress)) &&
            keccak256(abi.encodePacked(_sourceChain)) != keccak256(abi.encodePacked(axelarChainInfo.dstChainName))
        ) {
            revert Call_from_invalid_source();
        }
        _receiveCall(srcChainID, _payload);
    }

    function _receiveCall(uint16 _srcChainId, bytes memory _payload) internal {
        uint16 packetType;
        assembly {
            packetType := mload(add(_payload, 32))
        }

        address account;
        if (packetType == PT_MINT_SYNTH) {
            // receive mint synth message
            // from only the main chain
            (, bytes memory accountBytes, bytes32 synthKey, uint amount) = abi.decode(_payload, (uint16, bytes, bytes32, uint));
            account = accountBytes.toAddress(0);

            ISynthrIssuer(getAddressFromResolver("Issuer")).destIssue(account, synthKey, amount);
        } else if (packetType == PT_WITHDRAW_COLLATERAL) {
            // withdraw collateral message
            // from only the main chain
            (, bytes memory accountBytes, bytes32 collateralKey, uint amount) = abi.decode(_payload, (uint16, bytes, bytes32, uint));

            account = accountBytes.toAddress(0);
            IWrappedSynthr(getAddressFromResolver("WrappedSynthr")).withdrawCollateral(account, account, collateralKey, amount);
        } else if (packetType == PT_EXCHANGE) {
            // exchange syTokens
            // from every chain
            (, bytes memory accountBytes, , , bytes32 destKey, uint destAmount, ) = abi.decode(_payload, (uint16, bytes, bytes32, uint, bytes32, uint, uint));
            account = accountBytes.toAddress(0);
            IExchanger(getAddressFromResolver("Exchanger")).updateDestinationForExchange(account, destKey, destAmount);
        } else if (packetType == PT_LIQUIDATE) {
            // liquidate collateral
            // message from only the main chain
            (, bytes memory accountBytes, bytes32 collateralKey, uint collateralAmount) = abi.decode(_payload, (uint16, bytes, bytes32, uint));
            account = accountBytes.toAddress(0);
            IWrappedSynthr(getAddressFromResolver("WrappedSynthr")).collateralTransfer(account, collateralKey, collateralAmount);
        } else if (packetType == PT_BRIDGE_SYNTH) {
            // bridge syToken
            // message from every chain
            (, bytes memory accountBytes, bytes32 synthKey, uint amount) = abi.decode(_payload, (uint16, bytes, bytes32, uint));
            account = accountBytes.toAddress(0);
            ISynthrIssuer(getAddressFromResolver("Issuer")).destIssue(account, synthKey, amount);
        } else if (packetType == PT_WITHDRAW_MARGIN) {
            (, bytes memory accountBytes, uint amount) = abi.decode(_payload, (uint16, bytes, uint));

            account = accountBytes.toAddress(0);
            // bytes32("sUSD") = 0x7355534400000000000000000000000000000000000000000000000000000000
            ISynthrIssuer(getAddressFromResolver("Issuer")).destIssue(account, 0x7355534400000000000000000000000000000000000000000000000000000000, amount);
        } else if (packetType == PT_CROSS_SWAP_CASE_1) {
            (
                ,
                bytes memory accountBytes,
                bytes32 srcKey,
                uint srcAmount,
                bytes32 dstKey,
                uint dstAmount, // uint16 dstChainId // uint fee
                ,
                ,
                bytes memory dexPayload,
                bytes memory dexAddressBytes
            ) = abi.decode(_payload, (uint16, bytes, bytes32, uint, bytes32, uint, uint16, uint, bytes, bytes));
            account = accountBytes.toAddress(0);
            address dexAddress = dexAddressBytes.toAddress(0);

            ISynthrSwap(getAddressFromResolver("SynthrSwap")).destSwapSynthToNative(account, srcKey, srcAmount, dstKey, dstAmount, dexAddress, dexPayload);
        } else if (packetType == PT_CROSS_SWAP_CASE_2) {
            (
                ,
                bytes memory accountBytes,
                bytes32 srcKey,
                uint srcAmount,
                bytes32 dstKey,
                uint dstAmount, // uint16 dstChainId // uint fee
                ,

            ) = abi.decode(_payload, (uint16, bytes, bytes32, uint, bytes32, uint, uint16, uint));

            account = accountBytes.toAddress(0);

            ISynthrSwap(getAddressFromResolver("SynthrSwap")).destSwapNativeToSynth(account, srcKey, srcAmount, dstKey, dstAmount);
        } else if (packetType == PT_CROSS_SWAP_CASE_3) {
            (
                ,
                bytes memory accountBytes,
                bytes32 srcKey,
                uint srcAmount,
                bytes32 dstKey,
                uint dstAmount, // uint16 dstChainId // uint fee,
                ,
                ,
                bytes memory dexPayload,
                bytes memory dexAddressBytes
            ) = abi.decode(_payload, (uint16, bytes, bytes32, uint, bytes32, uint, uint16, uint, bytes, bytes));

            account = accountBytes.toAddress(0);
            address dexAddress = dexAddressBytes.toAddress(0);

            ISynthrSwap(getAddressFromResolver("SynthrSwap")).destSwapNativeToNative(account, srcKey, srcAmount, dstKey, dstAmount, dexAddress, dexPayload);
        } else if (packetType == PT_CROSS_SWAP_DEX_CASE_1) {
            (
                ,
                bytes memory accountBytes,
                bytes32 srcKey,
                uint srcAmount,
                bytes32 dstKey,
                uint dstAmount, //uint16 dstChainId // uint fee
                ,

            ) = abi.decode(_payload, (uint16, bytes, bytes32, uint, bytes32, uint, uint16, uint));
            account = accountBytes.toAddress(0);

            ISynthrSwapDex(getAddressFromResolver("SynthrSwapWithDex")).destSwapSynthToNative(account, srcKey, srcAmount, dstKey, dstAmount);
        } else if (packetType == PT_CROSS_SWAP_DEX_CASE_3) {
            (
                ,
                bytes memory accountBytes,
                bytes32 srcKey,
                uint srcAmount,
                bytes32 dstKey,
                uint dstAmount, // uint16 dstChainId // uint fee
                ,

            ) = abi.decode(_payload, (uint16, bytes, bytes32, uint, bytes32, uint, uint16, uint));

            account = accountBytes.toAddress(0);

            ISynthrSwapDex(getAddressFromResolver("SynthrSwapWithDex")).destSwapNativeToNative(account, srcKey, srcAmount, dstKey, dstAmount);
        } else {
            revert Unknown_packetType(packetType);
        }

        {
            emit ReceiveMsg(account, packetType, _srcChainId);
        }
    }

    // send a message to only the main chain
    /**
     * @notice Send a deposit collateral message to the main chain
     * @param account The account depositing collateral
     * @param collateralKey The key representing the collateral
     * @param amount The amount of collateral to deposit
     * Boolean indicating if ZRO token payment is used for LayerZero fee
     */
    function sendDepositCollateral(
        address account,
        bytes32 collateralKey,
        uint amount,
        bool // the param to check ZRO token payment -  true: ZRO token payment for LZ fee, false: native token payment for LZ fee
    ) external payable onlySynthr {
        bytes memory lzPayload = abi.encode(PT_DEPOSIT_COLLATERAL, abi.encodePacked(account), collateralKey, amount);

        _broadcast(account, lzPayload, PT_DEPOSIT_COLLATERAL, _mainChainId, msg.value, false);
    }

    /**
     * @notice Send a burn synth message to the main chain
     * @param account The account burning synth tokens
     * @param synthKey The key representing the synth token
     * @param amount The amount of synth tokens to burn
     * Boolean indicating if ZRO token payment is used for LayerZero fee
     */
    function sendBurn(
        address account,
        bytes32 synthKey,
        uint amount,
        bool // the param to check ZRO token payment -  true: ZRO token payment for LZ fee, false: native token payment for LZ fee
    ) external payable onlySynthr {
        bytes memory lzPayload = abi.encode(PT_BURN_SYNTH, abi.encodePacked(account), synthKey, amount);
        _broadcast(account, lzPayload, PT_BURN_SYNTH, _mainChainId, msg.value, false);
    }

    // send a message to the dest chain and main chain
    function sendExchange(
        address account,
        bytes32 srcSynthKey,
        bytes32 dstSynthKey,
        uint srcAmount,
        uint dstAmount,
        uint reclaimed,
        uint refund,
        uint fee,
        uint16 dstChainId,
        bool // the param to check ZRO token payment -  true: ZRO token payment for LZ fee, false: native token payment for LZ fee
    ) external payable onlySynthr {
        srcAmount += reclaimed - refund;
        if (dstChainId == 0) {
            dstChainId = _selfChainId;
        }

        bytes memory lzPayload = abi.encode(PT_EXCHANGE, abi.encodePacked(account), srcSynthKey, srcAmount, dstSynthKey, dstAmount, fee, dstChainId);
        uint value = msg.value;
        if (dstChainId != _selfChainId) {
            uint consumed = _broadcast(account, lzPayload, PT_EXCHANGE, dstChainId, value, false);
            value -= consumed;
        }

        if (dstChainId != _mainChainId) {
            _broadcast(account, lzPayload, PT_EXCHANGE, _mainChainId, value, false);
        }
    }

    /**
     * @notice Send a bridge synth token message to the destination chain
     * @param account The account bridging synth tokens
     * @param synthKey The key representing the synth token
     * @param amount The amount of synth tokens to bridge
     * @param dstChainId The destination chain ID
     * Boolean indicating if ZRO token payment is used for LayerZero fee
     */
    function sendBridgeSyToken(
        address account,
        bytes32 synthKey,
        uint amount,
        uint16 dstChainId,
        bool // the param to check ZRO token payment -  true: ZRO token payment for LZ fee, false: native token payment for LZ fee
    ) external payable onlySynthr {
        if (dstChainId == 0) {
            revert Bridging_on_same_chain();
        }

        bytes memory lzPayload = abi.encode(PT_BRIDGE_SYNTH, abi.encodePacked(account), synthKey, amount, dstChainId);

        uint value = msg.value;
        uint consumed = _broadcast(account, lzPayload, PT_BRIDGE_SYNTH, dstChainId, value, false);
        value -= consumed;

        if (dstChainId != _mainChainId) {
            _broadcast(account, lzPayload, PT_BRIDGE_SYNTH, _mainChainId, value, false);
        }
    }

    // This function is on only the light chain as we don't need to bridge `transfer margin` message to the other chain
    /**
     * @notice Send a transfer margin message to the main chain
     * @param account The account transferring margin
     * @param marginDelta The amount of margin to transfer
     * @param marketKey The key representing the market
     * Boolean indicating if ZRO token payment is used for LayerZero fee
     */
    function sendTransferMargin(
        address account,
        uint marginDelta,
        bytes32 marketKey,
        bool // the param to check ZRO token payment -  true: ZRO token payment for LZ fee, false: native token payment for LZ fee
    ) external payable onlySynthr {
        if (marginDelta == 0) {
            revert Margin_delta_zero();
        }
        bytes memory lzPayload = abi.encode(PT_TRANSFER_MARGIN, abi.encodePacked(account), marginDelta, marketKey);
        _broadcast(account, lzPayload, PT_TRANSFER_MARGIN, _mainChainId, msg.value, false);
    }

    // TODO
    // DO we need to check the hash of the dexPayload?
    /**
     * @notice Send a cross-chain swap from synth to native asset
     * @param account The account performing the swap
     * @param srcKey The key representing the source synth token
     * @param srcAmount The amount of source synth tokens
     * @param dstKey The key representing the destination native asset
     * @param dstAmount The amount of destination native asset
     * @param dstChainId The destination chain ID
     * @param fee The fee for the swap
     * @param dexPayload The payload data for the DEX
     * @param dexAddress The address of the DEX
     * Boolean indicating if ZRO token payment is used for LayerZero fee
     */
    function sendCrossSwapSyAssetToNative(
        address account,
        bytes32 srcKey,
        uint srcAmount,
        bytes32 dstKey,
        uint dstAmount,
        uint16 dstChainId,
        uint fee,
        bytes calldata dexPayload,
        address dexAddress,
        bool // the param to check ZRO token payment -  true: ZRO token payment for LZ fee, false: native token payment for LZ fee
    ) external payable onlySynthr {
        bytes memory lzPayload = abi.encode(
            PT_CROSS_SWAP_CASE_1,
            abi.encodePacked(account),
            srcKey,
            srcAmount,
            dstKey,
            dstAmount,
            dstChainId,
            fee,
            dexPayload,
            abi.encodePacked(dexAddress)
        );

        uint value = msg.value;
        uint consumed = _broadcast(account, lzPayload, PT_CROSS_SWAP_CASE_1, _mainChainId, msg.value, false);
        value -= consumed;

        // to the light chain
        if (dstChainId != _mainChainId) {
            _broadcast(account, lzPayload, PT_CROSS_SWAP_CASE_1, dstChainId, value, false);
        }
    }

    /**
     * @notice Send a cross-chain swap from native asset to synth
     * @param account The account performing the swap
     * @param srcKey The key representing the source native asset
     * @param srcAmount The amount of source native asset
     * @param dstKey The key representing the destination synth token
     * @param dstAmount The amount of destination synth tokens
     * @param dstChainId The destination chain ID
     * @param fee The fee for the swap
     * Boolean indicating if ZRO token payment is used for LayerZero fee
     */
    function sendCrossSwapNativeToSyAsset(
        address account,
        bytes32 srcKey,
        uint srcAmount,
        bytes32 dstKey,
        uint dstAmount,
        uint16 dstChainId,
        uint fee,
        bool // the param to check ZRO token payment -  true: ZRO token payment for LZ fee, false: native token payment for LZ fee
    ) external payable onlySynthr {
        bytes memory lzPayload = abi.encode(PT_CROSS_SWAP_CASE_2, abi.encodePacked(account), srcKey, srcAmount, dstKey, dstAmount, dstChainId, fee);
        uint value = msg.value;
        uint consumed = _broadcast(account, lzPayload, PT_CROSS_SWAP_CASE_2, _mainChainId, msg.value, false);
        value -= consumed;

        if (dstChainId != _mainChainId) {
            _broadcast(account, lzPayload, PT_CROSS_SWAP_CASE_2, dstChainId, value, false);
        }
    }

    /**
     * @notice Send a cross-chain swap from native asset to native asset
     * @param account The account performing the swap
     * @param srcKey The key representing the source native asset
     * @param srcAmount The amount of source native asset
     * @param dstKey The key representing the destination native asset
     * @param dstAmount The amount of destination native asset
     * @param dstChainId The destination chain ID
     * @param fee The fee for the swap
     * @param dexAddress The address of the DEX
     * @param dexPayload The payload data for the DEX
     * Boolean indicating if ZRO token payment is used for LayerZero fee
     */
    function sendCrossSwapNativeToNative(
        address account,
        bytes32 srcKey,
        uint srcAmount,
        bytes32 dstKey,
        uint dstAmount,
        uint16 dstChainId,
        uint fee,
        address dexAddress,
        bytes calldata dexPayload,
        bool // the param to check ZRO token payment -  true: ZRO token payment for LZ fee, false: native token payment for LZ fee
    ) external payable onlySynthr {
        bytes memory lzPayload = abi.encode(
            PT_CROSS_SWAP_CASE_3,
            abi.encodePacked(account),
            srcKey,
            srcAmount,
            dstKey,
            dstAmount,
            dstChainId,
            fee,
            dexPayload,
            abi.encodePacked(dexAddress)
        );

        uint value = msg.value;
        uint consumed = _broadcast(account, lzPayload, PT_CROSS_SWAP_CASE_3, _mainChainId, value, false);
        value -= consumed;

        if (dstChainId != _mainChainId) {
            _broadcast(account, lzPayload, PT_CROSS_SWAP_CASE_3, dstChainId, value, false);
        }
    }

    /**
     * @notice Send a cross-chain swap from synth to native asset using a DEX
     * @param account The account performing the swap
     * @param srcKey The key representing the source synth token
     * @param srcAmount The amount of source synth tokens
     * @param dstKey The key representing the destination native asset
     * @param dstAmount The amount of destination native asset
     * @param dstChainId The destination chain ID
     * @param fee The fee for the swap
     * Boolean indicating if ZRO token payment is used for LayerZero fee
     */
    function sendCrossSwapSyAssetToNativeWithDex(
        address account,
        bytes32 srcKey,
        uint srcAmount,
        bytes32 dstKey,
        uint dstAmount,
        uint16 dstChainId,
        uint fee,
        bool // the param to check ZRO token payment -  true: ZRO token payment for LZ fee, false: native token payment for LZ fee
    ) external payable onlySynthr {
        bytes memory lzPayload = abi.encode(PT_CROSS_SWAP_DEX_CASE_1, abi.encodePacked(account), srcKey, srcAmount, dstKey, dstAmount, dstChainId, fee);

        uint value = msg.value;
        uint consumed = _broadcast(account, lzPayload, PT_CROSS_SWAP_DEX_CASE_1, _mainChainId, msg.value, false);
        value -= consumed;

        // to the light chain
        if (dstChainId != _mainChainId) {
            _broadcast(account, lzPayload, PT_CROSS_SWAP_DEX_CASE_1, dstChainId, value, false);
        }
    }

    /**
     * @notice Send a cross-chain swap from native asset to native asset using a DEX
     * @param account The account performing the swap
     * @param srcKey The key representing the source native asset
     * @param srcAmount The amount of source native asset
     * @param dstKey The key representing the destination native asset
     * @param dstAmount The amount of destination native asset
     * @param dstChainId The destination chain ID
     * @param fee The fee for the swap
     * Boolean indicating if ZRO token payment is used for LayerZero fee
     */
    function sendCrossSwapNativeToNativeWithDex(
        address account,
        bytes32 srcKey,
        uint srcAmount,
        bytes32 dstKey,
        uint dstAmount,
        uint16 dstChainId,
        uint fee,
        bool // the param to check ZRO token payment -  true: ZRO token payment for LZ fee, false: native token payment for LZ fee
    ) external payable onlySynthr {
        bytes memory lzPayload = abi.encode(PT_CROSS_SWAP_DEX_CASE_3, abi.encodePacked(account), srcKey, srcAmount, dstKey, dstAmount, dstChainId, fee);

        uint value = msg.value;
        uint consumed = _broadcast(account, lzPayload, PT_CROSS_SWAP_DEX_CASE_3, _mainChainId, value, false);
        value -= consumed;

        if (dstChainId != _mainChainId) {
            _broadcast(account, lzPayload, PT_CROSS_SWAP_DEX_CASE_3, dstChainId, value, false);
        }
    }
}

File 2 of 24 : AxelarExecutable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IAxelarGateway } from '../interfaces/IAxelarGateway.sol';
import { IAxelarExecutable } from '../interfaces/IAxelarExecutable.sol';

contract AxelarExecutable is IAxelarExecutable {
    IAxelarGateway public immutable gateway;

    constructor(address gateway_) {
        if (gateway_ == address(0)) revert InvalidAddress();

        gateway = IAxelarGateway(gateway_);
    }

    function execute(
        bytes32 commandId,
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload
    ) external {
        bytes32 payloadHash = keccak256(payload);

        if (!gateway.validateContractCall(commandId, sourceChain, sourceAddress, payloadHash))
            revert NotApprovedByGateway();

        _execute(sourceChain, sourceAddress, payload);
    }

    function executeWithToken(
        bytes32 commandId,
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload,
        string calldata tokenSymbol,
        uint256 amount
    ) external {
        bytes32 payloadHash = keccak256(payload);

        if (
            !gateway.validateContractCallAndMint(
                commandId,
                sourceChain,
                sourceAddress,
                payloadHash,
                tokenSymbol,
                amount
            )
        ) revert NotApprovedByGateway();

        _executeWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount);
    }

    function _execute(
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload
    ) internal virtual {}

    function _executeWithToken(
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload,
        string calldata tokenSymbol,
        uint256 amount
    ) internal virtual {}
}

File 3 of 24 : IAxelarExecutable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IAxelarGateway } from './IAxelarGateway.sol';

interface IAxelarExecutable {
    error InvalidAddress();
    error NotApprovedByGateway();

    function gateway() external view returns (IAxelarGateway);

    function execute(
        bytes32 commandId,
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload
    ) external;

    function executeWithToken(
        bytes32 commandId,
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes calldata payload,
        string calldata tokenSymbol,
        uint256 amount
    ) external;
}

File 4 of 24 : IAxelarGasService.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IInterchainGasEstimation } from './IInterchainGasEstimation.sol';
import { IUpgradable } from './IUpgradable.sol';

/**
 * @title IAxelarGasService Interface
 * @notice This is an interface for the AxelarGasService contract which manages gas payments
 * and refunds for cross-chain communication on the Axelar network.
 * @dev This interface inherits IUpgradable
 */
interface IAxelarGasService is IInterchainGasEstimation, IUpgradable {
    error InvalidAddress();
    error NotCollector();
    error InvalidAmounts();
    error InvalidGasUpdates();
    error InsufficientGasPayment(uint256 required, uint256 provided);

    event GasPaidForContractCall(
        address indexed sourceAddress,
        string destinationChain,
        string destinationAddress,
        bytes32 indexed payloadHash,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event GasPaidForContractCallWithToken(
        address indexed sourceAddress,
        string destinationChain,
        string destinationAddress,
        bytes32 indexed payloadHash,
        string symbol,
        uint256 amount,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event NativeGasPaidForContractCall(
        address indexed sourceAddress,
        string destinationChain,
        string destinationAddress,
        bytes32 indexed payloadHash,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event NativeGasPaidForContractCallWithToken(
        address indexed sourceAddress,
        string destinationChain,
        string destinationAddress,
        bytes32 indexed payloadHash,
        string symbol,
        uint256 amount,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event GasPaidForExpressCall(
        address indexed sourceAddress,
        string destinationChain,
        string destinationAddress,
        bytes32 indexed payloadHash,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event GasPaidForExpressCallWithToken(
        address indexed sourceAddress,
        string destinationChain,
        string destinationAddress,
        bytes32 indexed payloadHash,
        string symbol,
        uint256 amount,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event NativeGasPaidForExpressCall(
        address indexed sourceAddress,
        string destinationChain,
        string destinationAddress,
        bytes32 indexed payloadHash,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event NativeGasPaidForExpressCallWithToken(
        address indexed sourceAddress,
        string destinationChain,
        string destinationAddress,
        bytes32 indexed payloadHash,
        string symbol,
        uint256 amount,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event GasAdded(
        bytes32 indexed txHash,
        uint256 indexed logIndex,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event NativeGasAdded(bytes32 indexed txHash, uint256 indexed logIndex, uint256 gasFeeAmount, address refundAddress);

    event ExpressGasAdded(
        bytes32 indexed txHash,
        uint256 indexed logIndex,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event NativeExpressGasAdded(
        bytes32 indexed txHash,
        uint256 indexed logIndex,
        uint256 gasFeeAmount,
        address refundAddress
    );

    event Refunded(
        bytes32 indexed txHash,
        uint256 indexed logIndex,
        address payable receiver,
        address token,
        uint256 amount
    );

    /**
     * @notice Pay for gas for any type of contract execution on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @dev If estimateOnChain is true, the function will estimate the gas cost and revert if the payment is insufficient.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call
     * @param executionGasLimit The gas limit for the contract call
     * @param estimateOnChain Flag to enable on-chain gas estimation
     * @param refundAddress The address where refunds, if any, should be sent
     * @param params Additional parameters for gas payment. This can be left empty for normal contract call payments.
     */
    function payGas(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        uint256 executionGasLimit,
        bool estimateOnChain,
        address refundAddress,
        bytes calldata params
    ) external payable;

    /**
     * @notice Pay for gas using ERC20 tokens for a contract call on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call
     * @param gasToken The address of the ERC20 token used to pay for gas
     * @param gasFeeAmount The amount of tokens to pay for gas
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payGasForContractCall(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external;

    /**
     * @notice Pay for gas using ERC20 tokens for a contract call with tokens on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call with tokens will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call with tokens
     * @param symbol The symbol of the token to be sent with the call
     * @param amount The amount of tokens to be sent with the call
     * @param gasToken The address of the ERC20 token used to pay for gas
     * @param gasFeeAmount The amount of tokens to pay for gas
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payGasForContractCallWithToken(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        string calldata symbol,
        uint256 amount,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external;

    /**
     * @notice Pay for gas using native currency for a contract call on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payNativeGasForContractCall(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address refundAddress
    ) external payable;

    /**
     * @notice Pay for gas using native currency for a contract call with tokens on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call with tokens will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call with tokens
     * @param symbol The symbol of the token to be sent with the call
     * @param amount The amount of tokens to be sent with the call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payNativeGasForContractCallWithToken(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        string calldata symbol,
        uint256 amount,
        address refundAddress
    ) external payable;

    /**
     * @notice Pay for gas using ERC20 tokens for an express contract call on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to express execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call
     * @param gasToken The address of the ERC20 token used to pay for gas
     * @param gasFeeAmount The amount of tokens to pay for gas
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payGasForExpressCall(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external;

    /**
     * @notice Pay for gas using ERC20 tokens for an express contract call with tokens on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to express execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call with tokens will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call with tokens
     * @param symbol The symbol of the token to be sent with the call
     * @param amount The amount of tokens to be sent with the call
     * @param gasToken The address of the ERC20 token used to pay for gas
     * @param gasFeeAmount The amount of tokens to pay for gas
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payGasForExpressCallWithToken(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        string calldata symbol,
        uint256 amount,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external;

    /**
     * @notice Pay for gas using native currency for an express contract call on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payNativeGasForExpressCall(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        address refundAddress
    ) external payable;

    /**
     * @notice Pay for gas using native currency for an express contract call with tokens on a destination chain.
     * @dev This function is called on the source chain before calling the gateway to execute a remote contract.
     * @param sender The address making the payment
     * @param destinationChain The target chain where the contract call with tokens will be made
     * @param destinationAddress The target address on the destination chain
     * @param payload Data payload for the contract call with tokens
     * @param symbol The symbol of the token to be sent with the call
     * @param amount The amount of tokens to be sent with the call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function payNativeGasForExpressCallWithToken(
        address sender,
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        string calldata symbol,
        uint256 amount,
        address refundAddress
    ) external payable;

    /**
     * @notice Add additional gas payment using ERC20 tokens after initiating a cross-chain call.
     * @dev This function can be called on the source chain after calling the gateway to execute a remote contract.
     * @param txHash The transaction hash of the cross-chain call
     * @param logIndex The log index for the cross-chain call
     * @param gasToken The ERC20 token address used to add gas
     * @param gasFeeAmount The amount of tokens to add as gas
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function addGas(
        bytes32 txHash,
        uint256 logIndex,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external;

    /**
     * @notice Add additional gas payment using native currency after initiating a cross-chain call.
     * @dev This function can be called on the source chain after calling the gateway to execute a remote contract.
     * @param txHash The transaction hash of the cross-chain call
     * @param logIndex The log index for the cross-chain call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function addNativeGas(
        bytes32 txHash,
        uint256 logIndex,
        address refundAddress
    ) external payable;

    /**
     * @notice Add additional gas payment using ERC20 tokens after initiating an express cross-chain call.
     * @dev This function can be called on the source chain after calling the gateway to express execute a remote contract.
     * @param txHash The transaction hash of the cross-chain call
     * @param logIndex The log index for the cross-chain call
     * @param gasToken The ERC20 token address used to add gas
     * @param gasFeeAmount The amount of tokens to add as gas
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function addExpressGas(
        bytes32 txHash,
        uint256 logIndex,
        address gasToken,
        uint256 gasFeeAmount,
        address refundAddress
    ) external;

    /**
     * @notice Add additional gas payment using native currency after initiating an express cross-chain call.
     * @dev This function can be called on the source chain after calling the gateway to express execute a remote contract.
     * @param txHash The transaction hash of the cross-chain call
     * @param logIndex The log index for the cross-chain call
     * @param refundAddress The address where refunds, if any, should be sent
     */
    function addNativeExpressGas(
        bytes32 txHash,
        uint256 logIndex,
        address refundAddress
    ) external payable;

    /**
     * @notice Updates the gas price for a specific chain.
     * @dev This function is called by the gas oracle to update the gas prices for a specific chains.
     * @param chains Array of chain names
     * @param gasUpdates Array of gas updates
     */
    function updateGasInfo(string[] calldata chains, GasInfo[] calldata gasUpdates) external;

    /**
     * @notice Allows the gasCollector to collect accumulated fees from the contract.
     * @dev Use address(0) as the token address for native currency.
     * @param receiver The address to receive the collected fees
     * @param tokens Array of token addresses to be collected
     * @param amounts Array of amounts to be collected for each respective token address
     */
    function collectFees(
        address payable receiver,
        address[] calldata tokens,
        uint256[] calldata amounts
    ) external;

    /**
     * @notice Refunds gas payment to the receiver in relation to a specific cross-chain transaction.
     * @dev Only callable by the gasCollector.
     * @dev Use address(0) as the token address to refund native currency.
     * @param txHash The transaction hash of the cross-chain call
     * @param logIndex The log index for the cross-chain call
     * @param receiver The address to receive the refund
     * @param token The token address to be refunded
     * @param amount The amount to refund
     */
    function refund(
        bytes32 txHash,
        uint256 logIndex,
        address payable receiver,
        address token,
        uint256 amount
    ) external;

    /**
     * @notice Returns the address of the designated gas collector.
     * @return address of the gas collector
     */
    function gasCollector() external returns (address);
}

File 5 of 24 : IAxelarGateway.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IGovernable } from './IGovernable.sol';
import { IImplementation } from './IImplementation.sol';

interface IAxelarGateway is IImplementation, IGovernable {
    /**********\
    |* Errors *|
    \**********/

    error NotSelf();
    error InvalidCodeHash();
    error SetupFailed();
    error InvalidAuthModule();
    error InvalidTokenDeployer();
    error InvalidAmount();
    error InvalidChainId();
    error InvalidCommands();
    error TokenDoesNotExist(string symbol);
    error TokenAlreadyExists(string symbol);
    error TokenDeployFailed(string symbol);
    error TokenContractDoesNotExist(address token);
    error BurnFailed(string symbol);
    error MintFailed(string symbol);
    error InvalidSetMintLimitsParams();
    error ExceedMintLimit(string symbol);

    /**********\
    |* Events *|
    \**********/

    event TokenSent(
        address indexed sender,
        string destinationChain,
        string destinationAddress,
        string symbol,
        uint256 amount
    );

    event ContractCall(
        address indexed sender,
        string destinationChain,
        string destinationContractAddress,
        bytes32 indexed payloadHash,
        bytes payload
    );

    event ContractCallWithToken(
        address indexed sender,
        string destinationChain,
        string destinationContractAddress,
        bytes32 indexed payloadHash,
        bytes payload,
        string symbol,
        uint256 amount
    );

    event Executed(bytes32 indexed commandId);

    event TokenDeployed(string symbol, address tokenAddresses);

    event ContractCallApproved(
        bytes32 indexed commandId,
        string sourceChain,
        string sourceAddress,
        address indexed contractAddress,
        bytes32 indexed payloadHash,
        bytes32 sourceTxHash,
        uint256 sourceEventIndex
    );

    event ContractCallApprovedWithMint(
        bytes32 indexed commandId,
        string sourceChain,
        string sourceAddress,
        address indexed contractAddress,
        bytes32 indexed payloadHash,
        string symbol,
        uint256 amount,
        bytes32 sourceTxHash,
        uint256 sourceEventIndex
    );

    event ContractCallExecuted(bytes32 indexed commandId);

    event TokenMintLimitUpdated(string symbol, uint256 limit);

    event OperatorshipTransferred(bytes newOperatorsData);

    event Upgraded(address indexed implementation);

    /********************\
    |* Public Functions *|
    \********************/

    function sendToken(
        string calldata destinationChain,
        string calldata destinationAddress,
        string calldata symbol,
        uint256 amount
    ) external;

    function callContract(
        string calldata destinationChain,
        string calldata contractAddress,
        bytes calldata payload
    ) external;

    function callContractWithToken(
        string calldata destinationChain,
        string calldata contractAddress,
        bytes calldata payload,
        string calldata symbol,
        uint256 amount
    ) external;

    function isContractCallApproved(
        bytes32 commandId,
        string calldata sourceChain,
        string calldata sourceAddress,
        address contractAddress,
        bytes32 payloadHash
    ) external view returns (bool);

    function isContractCallAndMintApproved(
        bytes32 commandId,
        string calldata sourceChain,
        string calldata sourceAddress,
        address contractAddress,
        bytes32 payloadHash,
        string calldata symbol,
        uint256 amount
    ) external view returns (bool);

    function validateContractCall(
        bytes32 commandId,
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes32 payloadHash
    ) external returns (bool);

    function validateContractCallAndMint(
        bytes32 commandId,
        string calldata sourceChain,
        string calldata sourceAddress,
        bytes32 payloadHash,
        string calldata symbol,
        uint256 amount
    ) external returns (bool);

    /***********\
    |* Getters *|
    \***********/

    function authModule() external view returns (address);

    function tokenDeployer() external view returns (address);

    function tokenMintLimit(string memory symbol) external view returns (uint256);

    function tokenMintAmount(string memory symbol) external view returns (uint256);

    function allTokensFrozen() external view returns (bool);

    function implementation() external view returns (address);

    function tokenAddresses(string memory symbol) external view returns (address);

    function tokenFrozen(string memory symbol) external view returns (bool);

    function isCommandExecuted(bytes32 commandId) external view returns (bool);

    /************************\
    |* Governance Functions *|
    \************************/

    function setTokenMintLimits(string[] calldata symbols, uint256[] calldata limits) external;

    function upgrade(
        address newImplementation,
        bytes32 newImplementationCodeHash,
        bytes calldata setupParams
    ) external;

    /**********************\
    |* External Functions *|
    \**********************/

    function execute(bytes calldata input) external;
}

File 6 of 24 : IContractIdentifier.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// General interface for upgradable contracts
interface IContractIdentifier {
    /**
     * @notice Returns the contract ID. It can be used as a check during upgrades.
     * @dev Meant to be overridden in derived contracts.
     * @return bytes32 The contract ID
     */
    function contractId() external pure returns (bytes32);
}

File 7 of 24 : IGovernable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title IGovernable Interface
 * @notice This is an interface used by the AxelarGateway contract to manage governance and mint limiter roles.
 */
interface IGovernable {
    error NotGovernance();
    error NotMintLimiter();
    error InvalidGovernance();
    error InvalidMintLimiter();

    event GovernanceTransferred(address indexed previousGovernance, address indexed newGovernance);
    event MintLimiterTransferred(address indexed previousGovernance, address indexed newGovernance);

    /**
     * @notice Returns the governance address.
     * @return address of the governance
     */
    function governance() external view returns (address);

    /**
     * @notice Returns the mint limiter address.
     * @return address of the mint limiter
     */
    function mintLimiter() external view returns (address);

    /**
     * @notice Transfer the governance role to another address.
     * @param newGovernance The new governance address
     */
    function transferGovernance(address newGovernance) external;

    /**
     * @notice Transfer the mint limiter role to another address.
     * @param newGovernance The new mint limiter address
     */
    function transferMintLimiter(address newGovernance) external;
}

File 8 of 24 : IImplementation.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IContractIdentifier } from './IContractIdentifier.sol';

interface IImplementation is IContractIdentifier {
    error NotProxy();

    function setup(bytes calldata data) external;
}

File 9 of 24 : IInterchainGasEstimation.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title IInterchainGasEstimation Interface
 * @notice This is an interface for the InterchainGasEstimation contract
 * which allows for estimating gas fees for cross-chain communication on the Axelar network.
 */
interface IInterchainGasEstimation {
    error UnsupportedEstimationType(GasEstimationType gasEstimationType);

    /**
     * @notice Event emitted when the gas price for a specific chain is updated.
     * @param chain The name of the chain
     * @param info The gas info for the chain
     */
    event GasInfoUpdated(string chain, GasInfo info);

    enum GasEstimationType {
        Default,
        OptimismEcotone
    }

    struct GasInfo {
        GasEstimationType gasEstimationType; // Custom gas pricing rule, such as L1 data fee on L2s
        uint128 axelarBaseFee; // axelar base fee for cross-chain message approval (in terms of src native gas token)
        uint128 expressFee; // axelar express fee for cross-chain message approval and express execution
        uint128 relativeGasPrice; // dest_gas_price * dest_token_market_price / src_token_market_price
        uint128 relativeBlobBaseFee; // dest_blob_base_fee * dest_token_market_price / src_token_market_price
    }

    /**
     * @notice Returns the gas price for a specific chain.
     * @param chain The name of the chain
     * @return gasInfo The gas info for the chain
     */
    function getGasInfo(string calldata chain) external view returns (GasInfo memory);

    /**
     * @notice Estimates the gas fee for a cross-chain contract call.
     * @param destinationChain Axelar registered name of the destination chain
     * @param destinationAddress Destination contract address being called
     * @param executionGasLimit The gas limit to be used for the destination contract execution,
     *        e.g. pass in 200k if your app consumes needs upto 200k for this contract call
     * @param params Additional parameters for the gas estimation
     * @return gasEstimate The cross-chain gas estimate, in terms of source chain's native gas token that should be forwarded to the gas service.
     */
    function estimateGasFee(
        string calldata destinationChain,
        string calldata destinationAddress,
        bytes calldata payload,
        uint256 executionGasLimit,
        bytes calldata params
    ) external view returns (uint256 gasEstimate);
}

File 10 of 24 : IOwnable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @title IOwnable Interface
 * @notice IOwnable is an interface that abstracts the implementation of a
 * contract with ownership control features. It's commonly used in upgradable
 * contracts and includes the functionality to get current owner, transfer
 * ownership, and propose and accept ownership.
 */
interface IOwnable {
    error NotOwner();
    error InvalidOwner();
    error InvalidOwnerAddress();

    event OwnershipTransferStarted(address indexed newOwner);
    event OwnershipTransferred(address indexed newOwner);

    /**
     * @notice Returns the current owner of the contract.
     * @return address The address of the current owner
     */
    function owner() external view returns (address);

    /**
     * @notice Returns the address of the pending owner of the contract.
     * @return address The address of the pending owner
     */
    function pendingOwner() external view returns (address);

    /**
     * @notice Transfers ownership of the contract to a new address
     * @param newOwner The address to transfer ownership to
     */
    function transferOwnership(address newOwner) external;

    /**
     * @notice Proposes to transfer the contract's ownership to a new address.
     * The new owner needs to accept the ownership explicitly.
     * @param newOwner The address to transfer ownership to
     */
    function proposeOwnership(address newOwner) external;

    /**
     * @notice Transfers ownership to the pending owner.
     * @dev Can only be called by the pending owner
     */
    function acceptOwnership() external;
}

File 11 of 24 : IUpgradable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IOwnable } from './IOwnable.sol';
import { IImplementation } from './IImplementation.sol';

// General interface for upgradable contracts
interface IUpgradable is IOwnable, IImplementation {
    error InvalidCodeHash();
    error InvalidImplementation();
    error SetupFailed();

    event Upgraded(address indexed newImplementation);

    function implementation() external view returns (address);

    function upgrade(
        address newImplementation,
        bytes32 newImplementationCodeHash,
        bytes calldata params
    ) external;
}

File 12 of 24 : AddressString.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

library StringToAddress {
    error InvalidAddressString();

    function toAddress(string memory addressString) internal pure returns (address) {
        bytes memory stringBytes = bytes(addressString);
        uint160 addressNumber = 0;
        uint8 stringByte;

        if (stringBytes.length != 42 || stringBytes[0] != '0' || stringBytes[1] != 'x') revert InvalidAddressString();

        for (uint256 i = 2; i < 42; ++i) {
            stringByte = uint8(stringBytes[i]);

            if ((stringByte >= 97) && (stringByte <= 102)) stringByte -= 87;
            else if ((stringByte >= 65) && (stringByte <= 70)) stringByte -= 55;
            else if ((stringByte >= 48) && (stringByte <= 57)) stringByte -= 48;
            else revert InvalidAddressString();

            addressNumber |= uint160(uint256(stringByte) << ((41 - i) << 2));
        }

        return address(addressNumber);
    }
}

library AddressToString {
    function toString(address address_) internal pure returns (string memory) {
        bytes memory addressBytes = abi.encodePacked(address_);
        bytes memory characters = '0123456789abcdef';
        bytes memory stringBytes = new bytes(42);

        stringBytes[0] = '0';
        stringBytes[1] = 'x';

        for (uint256 i; i < 20; ++i) {
            stringBytes[2 + i * 2] = characters[uint8(addressBytes[i] >> 4)];
            stringBytes[3 + i * 2] = characters[uint8(addressBytes[i] & 0x0f)];
        }

        return string(stringBytes);
    }
}

File 13 of 24 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * 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 is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

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

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

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

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

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

File 14 of 24 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 15 of 24 : BaseBridgeAxelar.sol
// SPDX-License-Identifier: MIT

pragma solidity =0.8.24;

import "../BaseBridge.sol";
import {AxelarExecutable} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarExecutable.sol";
import {IAxelarGasService} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol";
import {
    StringToAddress, AddressToString
} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/libs/AddressString.sol";

/**
 * @title BaseBridgeAxelar
 * @dev Base contract for interacting with Axelar Network for cross-chain transactions.
 */
abstract contract BaseBridgeAxelar is BaseBridge, AxelarExecutable {
    error Fee_Percentage_less_than_100();
    error Minimum_Gas_Invalid(uint256 gasAmount);
    error Execution_gas_limit_not_set_for_this_packet_type(uint16 packetType);
    error Insufficient_Value_Attached_For_GasPayment(uint256 attachedValue, uint256 expectedValue);

    struct AxelarChainInfo {
        string dstChainName;
        string dstChainAddress; //  lightchain/mainchain bridge address
    }

    using AddressToString for address;
    using StringToAddress for string;

    uint16 internal _selfChainId; // lz chain-id as LZ-endpoint-ID
    uint16 internal _mainChainId;
    uint16 public lzFeePercentage;

    mapping(uint16 => mapping(uint16 => uint256)) public minDstGasLookup; // lzChainID -> (packetType -> gasAmount)
    mapping(uint16 => AxelarChainInfo) public axelarDstChainLookup; // axelar destination chain info (lzChainId -> AxelarChainInfo)
    mapping(string => uint16) public srcChainIdLookup; // Axelar source chain -> lzChainId (call from remote chain to address(this))

    IAxelarGasService public immutable gasService;

    event SendMessage(address indexed account, uint16 indexed dstChainId, uint16 indexed packetType, bytes payload);
    event ReceiveMsg(address indexed account, uint16 indexed packetType, uint16 indexed srcChainId);
    event SetMinDstGas(uint16 dstChainId, uint16 packetType, uint256 minGas);
    event SetTrustedRemote(uint16 remoteChainId, string remoteChainName, string remoteChainAddress);

    /**
     * @dev Constructor to initialize the contract with AxelarGateway and gas receiver.
     * @param _selfAxelarGateway Address of the AxelarGateway contract.
     * @param _selfGasReceiver Address of the gas receiver contract.
     */
    constructor(address _selfAxelarGateway, address _selfGasReceiver) AxelarExecutable(_selfAxelarGateway) {
        gasService = IAxelarGasService(_selfGasReceiver);
    }

    /**
     * @dev Calculate the fee for executing a cross-chain transaction.
     * @param _payload The payload data for the transaction.
     * @param packetType The type of the transaction packet.
     * @param dstChainId The destination chain ID.
     * @return lzFee The calculated fee in native currency.
     */
    function calcFee(bytes memory _payload, uint16 packetType, uint16 dstChainId)
        public
        view
        override
        returns (uint256 lzFee)
    {
        uint256 _fee = _getEstimatedFees(_payload,dstChainId, packetType);
        if (_checkMultiBroadcast(packetType)) {
            _fee += _getEstimatedFees(_payload, _mainChainId, packetType);
        }
        lzFee = _fee * lzFeePercentage / 100;
    }

    /**
     * @dev Set the LZ fee percentage for transactions.
     * @param _percentage The fee percentage to be set.
     */
    function setLZFeePercentage(uint16 _percentage) public {
        if (_percentage < 100) {
            revert Fee_Percentage_less_than_100();
        }
        lzFeePercentage = _percentage;
    }

    /**
     * @dev Get the self LZ chain ID.
     * @return _selfChainId The current LZ chain ID.
     */
    function selfChainId() external view returns (uint16) {
        return _selfChainId; // lz chain id
    }

    /**
     * @dev Set a trusted remote chain for interaction.
     * @param _remoteChainId The ID of the remote chain.
     * @param _remoteChainName The name of the remote chain.
     * @param _remoteAddress The address of the remote chain bridge.
     * @notice Trusted remote should be address of other bridges on different network
     */
    function setTrustedRemote(uint16 _remoteChainId, string calldata _remoteChainName, string calldata _remoteAddress)
        external
        onlyOwner
    {
        axelarDstChainLookup[_remoteChainId] =
            AxelarChainInfo({dstChainName: _remoteChainName, dstChainAddress: _remoteAddress});
        emit SetTrustedRemote(_remoteChainId, _remoteChainName, _remoteAddress);
    }

    /**
     * @dev Set the source chain ID lookup for Axelar.
     * @param _srcChainName The name of the source chain.
     * @param _srcChainId The ID of the source chain.
     */
    function setSrcChainIdLookup(string calldata _srcChainName, uint16 _srcChainId) external onlyOwner {
        srcChainIdLookup[_srcChainName] = _srcChainId;
    }

    /**
     * @dev Set the minimum gas required for a destination chain and packet type.
     * @param _destinationChainId The ID of the destination chain.
     * @param _packetType The type of the packet.
     * @param _minGasAmount The minimum gas amount required.
     */
    function setMinDestinatinGas(uint16 _destinationChainId, uint16 _packetType, uint256 _minGasAmount)
        external
        onlyOwner
    {
        if (_minGasAmount == 0) {
            revert Minimum_Gas_Invalid(_minGasAmount);
        }
        minDstGasLookup[_destinationChainId][_packetType] = _minGasAmount;

        emit SetMinDstGas(_destinationChainId, _packetType, _minGasAmount);
    }

    function _broadcast(
        address account,
        bytes memory payload,
        uint16 packetType,
        uint16 dstChainId,
        uint256 value,
        bool // the param to check ZRO token payment
    ) internal returns (uint256) {
        uint256 executionGasLimit = minDstGasLookup[dstChainId][packetType];
        if (executionGasLimit == 0) {
            revert Execution_gas_limit_not_set_for_this_packet_type(packetType);
        }
        AxelarChainInfo memory dstChainInfo = axelarDstChainLookup[dstChainId];
        uint256 nativeFee = _validateGasAmount(
            dstChainInfo.dstChainName, dstChainInfo.dstChainAddress, payload, executionGasLimit, value
        );
        gasService.payNativeGasForContractCall{value: value}(
            address(this), dstChainInfo.dstChainName, dstChainInfo.dstChainAddress, payload, payable(address(this))
        );

        gateway.callContract(dstChainInfo.dstChainName, dstChainInfo.dstChainAddress, payload);

        emit SendMessage(account, dstChainId, packetType, payload);
        return nativeFee;
    }

    function _validateGasAmount(
        string memory chainName,
        string memory dstAddress,
        bytes memory payload,
        uint256 executionGasLimit,
        uint256 value
    ) internal view returns (uint256 _fee) {
        _fee = gasService.estimateGasFee(chainName, dstAddress, payload, executionGasLimit, bytes("0"));
        if (value < _fee) {
            revert Insufficient_Value_Attached_For_GasPayment(value, _fee);
        }
    }

    function _getEstimatedFees(bytes memory _payload, uint16 _dstChainId, uint16 _packetType)
        internal
        view
        returns (uint256 fee)
    {
        AxelarChainInfo memory _chainInfo = axelarDstChainLookup[_dstChainId];
        uint256 _minDstGas = minDstGasLookup[_dstChainId][_packetType];
        fee = gasService.estimateGasFee(
            _chainInfo.dstChainName, _chainInfo.dstChainAddress, _payload, _minDstGas, bytes("0")
        );
    }

    // check for different packetTypes to invoke 2-way cross transaction in case of lightchain <> lightchain
    function _checkMultiBroadcast(uint16 _packetType) private view returns (bool isAllowed) {
        if (
            (
                _packetType == PT_EXCHANGE || _packetType == PT_BRIDGE_SYNTH || _packetType == PT_CROSS_SWAP_CASE_1
                    || _packetType == PT_CROSS_SWAP_CASE_2 || _packetType == PT_CROSS_SWAP_CASE_3
                    || _packetType == PT_CROSS_SWAP_DEX_CASE_1 || _packetType == PT_CROSS_SWAP_DEX_CASE_3
            ) && (_selfChainId != _mainChainId)
        ) {
            isAllowed = true;
        }
    }
}

File 16 of 24 : BaseBridge.sol
// SPDX-License-Identifier: MIT

pragma solidity =0.8.24;

import "@openzeppelin/contracts/access/Ownable.sol";
import "../libraries/TransferHelper.sol";
import "../interfaces/ISynthrSwap.sol";
import "../interfaces/ISynthrSwapDex.sol";
import "../interfaces/IFuturesMarketManager.sol";

interface IAddressResolver {
    function getAddress(bytes32 name) external view returns (address);
}

abstract contract BaseBridge is Ownable {
    error Invalid_caller();

    address public _synthrAddressResolver;

    uint16 internal constant PT_DEPOSIT_COLLATERAL = 1;
    uint16 internal constant PT_MINT_SYNTH = 2;
    uint16 internal constant PT_WITHDRAW_COLLATERAL = 3;
    uint16 internal constant PT_BURN_SYNTH = 4;
    uint16 internal constant PT_EXCHANGE = 5;
    uint16 internal constant PT_LIQUIDATE = 6;
    uint16 internal constant PT_BRIDGE_SYNTH = 7;
    uint16 internal constant PT_TRANSFER_MARGIN = 9;
    uint16 internal constant PT_WITHDRAW_MARGIN = 10;
    uint16 internal constant PT_CROSS_SWAP_CASE_1 = 11;
    uint16 internal constant PT_CROSS_SWAP_CASE_2 = 12;
    uint16 internal constant PT_CROSS_SWAP_CASE_3 = 13;
    uint16 internal constant PT_CROSS_SWAP_DEX_CASE_1 = 14;
    uint16 internal constant PT_CROSS_SWAP_DEX_CASE_3 = 15;

    constructor() {}

    modifier onlySynthr() {
        if (isAllowedCaller(msg.sender)) {
            _;
        } else {
            revert Invalid_caller();
        }
    }

    receive() external payable {}

    function isAllowedCaller(address caller) private view returns (bool) {
        return
            caller == getAddressFromResolver("WrappedSynthr") ||
            caller == getAddressFromResolver("Issuer") ||
            caller == getAddressFromResolver("Exchanger") ||
            caller == getAddressFromResolver("SynthrSwap") ||
            caller == getAddressFromResolver("SynthrSwapWithDex") ||
            caller == getAddressFromResolver("OffChainExchanger") ||
            caller == getAddressFromResolver("FuturesMarketManager") ||
            IFuturesMarketManager(getAddressFromResolver("FuturesMarketManager")).isMarketImplementation(caller);
    }

    function getAddressFromResolver(bytes32 name) internal view returns (address) {
        return IAddressResolver(_synthrAddressResolver).getAddress(name);
    }

    /**
     * @notice Calculate the fee for a given payload and packet type
     * @param payload The payload to calculate the fee for
     * @param packetType The packet type
     * @param dstChainId The destination chain ID
     * @return The calculated fee
     */
    function calcFee(
        bytes memory payload,
        uint16 packetType,
        uint16 dstChainId
    ) public view virtual returns (uint);

    /**
     * @notice Withdraw a specified amount of a given token
     * @param token The address of the token to withdraw
     * @param amount The amount to withdraw
     */
    function withdrawAsset(address token, uint amount) public onlyOwner {
        if (token == address(0)) {
            TransferHelper.safeTransferETH(msg.sender, amount);
        } else {
            TransferHelper.safeTransfer(token, msg.sender, amount);
        }
    }
}

File 17 of 24 : IExchanger.sol
// SPDX-License-Identifier: MIT

pragma solidity =0.8.24;

interface IExchanger {
    function updateDestinationForExchange(
        address recipient,
        bytes32 destinationKey,
        uint destinationAmount
    ) external;
}

File 18 of 24 : IFuturesMarketManager.sol
// SPDX-License-Identifier: MIT

pragma solidity =0.8.24;

interface IFuturesMarketManager {
    function marketForKey(bytes32 marketKey) external view returns (address);

    function isMarketImplementation(address _account) external view returns (bool);
}

File 19 of 24 : ISynthrIssuer.sol
// SPDX-License-Identifier: MIT

pragma solidity =0.8.24;

interface ISynthrIssuer {
    function synthsByAddress(address synthAddress) external view returns (bytes32);

    function destIssue(
        address account,
        bytes32 synthKey,
        uint synthAmount
    ) external;
}

File 20 of 24 : ISynthrSwap.sol
// SPDX-License-Identifier: MIT

pragma solidity =0.8.24;

interface ISynthrSwap {
    function destSwapSynthToNative(
        address account,
        bytes32 sourceKey,
        uint sourceAmount,
        bytes32 destKey,
        uint destAmount,
        address target,
        bytes memory data
    ) external returns (bool);

    function destSwapNativeToSynth(
        address account,
        bytes32 sourceKey,
        uint sourceAmount,
        bytes32 destKey,
        uint destAmount
    ) external;

    function destSwapNativeToNative(
        address account,
        bytes32 sourceKey,
        uint sourceAmount,
        bytes32 destKey,
        uint destAmount,
        address target,
        bytes memory data
    ) external returns (bool);
}

File 21 of 24 : ISynthrSwapDex.sol
// SPDX-License-Identifier: MIT

pragma solidity =0.8.24;

interface ISynthrSwapDex {
    function destSwapSynthToNative(
        address account,
        bytes32 sourceKey,
        uint sourceAmount,
        bytes32 destKey,
        uint destAmount
    ) external returns (bool);

    function destSwapNativeToNative(
        address account,
        bytes32 sourceKey,
        uint sourceAmount,
        bytes32 destKey,
        uint destAmount
    ) external returns (bool);
}

File 22 of 24 : IWrappedSynthr.sol
// SPDX-License-Identifier: MIT

pragma solidity =0.8.24;

interface IWrappedSynthr {
    function getAvailableCollaterals() external view returns (bytes32[] memory);

    function withdrawCollateral(
        address from,
        address to,
        bytes32 collateralKey,
        uint collateralAmount
    ) external;

    function collateralTransfer(
        address _from,
        bytes32 _collateralKey,
        uint _collateralAmount
    ) external;

    function destBurn(
        address account,
        bytes32 synthKey,
        uint amount
    ) external returns (bool);

    function destTransferMargin(
        address account,
        uint marginDelta,
        bytes32 marketKey
    ) external returns (bool);
}

File 23 of 24 : BytesLib.sol
// SPDX-License-Identifier: Unlicense
/*
 * @title Solidity Bytes Arrays Utils
 * @author Gonçalo Sá <[email protected]>
 *
 * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.
 *      The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.
 */
pragma solidity =0.8.24;

library BytesLib {
    function concat(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bytes memory) {
        bytes memory tempBytes;

        assembly {
            // Get a location of some free memory and store it in tempBytes as
            // Solidity does for memory variables.
            tempBytes := mload(0x40)

            // Store the length of the first bytes array at the beginning of
            // the memory for tempBytes.
            let length := mload(_preBytes)
            mstore(tempBytes, length)

            // Maintain a memory counter for the current write location in the
            // temp bytes array by adding the 32 bytes for the array length to
            // the starting location.
            let mc := add(tempBytes, 0x20)
            // Stop copying when the memory counter reaches the length of the
            // first bytes array.
            let end := add(mc, length)

            for {
                // Initialize a copy counter to the start of the _preBytes data,
                // 32 bytes into its memory.
                let cc := add(_preBytes, 0x20)
            } lt(mc, end) {
                // Increase both counters by 32 bytes each iteration.
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                // Write the _preBytes data into the tempBytes memory 32 bytes
                // at a time.
                mstore(mc, mload(cc))
            }

            // Add the length of _postBytes to the current length of tempBytes
            // and store it as the new length in the first 32 bytes of the
            // tempBytes memory.
            length := mload(_postBytes)
            mstore(tempBytes, add(length, mload(tempBytes)))

            // Move the memory counter back from a multiple of 0x20 to the
            // actual end of the _preBytes data.
            mc := end
            // Stop copying when the memory counter reaches the new combined
            // length of the arrays.
            end := add(mc, length)

            for { let cc := add(_postBytes, 0x20) } lt(mc, end) {
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } { mstore(mc, mload(cc)) }

            // Update the free-memory pointer by padding our last write location
            // to 32 bytes: add 31 bytes to the end of tempBytes to move to the
            // next 32 byte block, then round down to the nearest multiple of
            // 32. If the sum of the length of the two arrays is zero then add
            // one before rounding down to leave a blank 32 bytes (the length block with 0).
            mstore(
                0x40,
                and(
                    add(add(end, iszero(add(length, mload(_preBytes)))), 31),
                    not(31) // Round down to the nearest 32 bytes.
                )
            )
        }

        return tempBytes;
    }

    function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {
        assembly {
            // Read the first 32 bytes of _preBytes storage, which is the length
            // of the array. (We don't need to use the offset into the slot
            // because arrays use the entire slot.)
            let fslot := sload(_preBytes.slot)
            // Arrays of 31 bytes or less have an even value in their slot,
            // while longer arrays have an odd value. The actual length is
            // the slot divided by two for odd values, and the lowest order
            // byte divided by two for even values.
            // If the slot is even, bitwise and the slot with 255 and divide by
            // two to get the length. If the slot is odd, bitwise and the slot
            // with -1 and divide by two.
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)
            let newlength := add(slength, mlength)
            // slength can contain both the length and contents of the array
            // if length < 32 bytes so let's prepare for that
            // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
            switch add(lt(slength, 32), lt(newlength, 32))
            case 2 {
                // Since the new array still fits in the slot, we just need to
                // update the contents of the slot.
                // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length
                sstore(
                    _preBytes.slot,
                    // all the modifications to the slot are inside this
                    // next block
                    add(
                        // we can just add to the slot contents because the
                        // bytes we want to change are the LSBs
                        fslot,
                        add(
                            mul(
                                div(
                                    // load the bytes from memory
                                    mload(add(_postBytes, 0x20)),
                                    // zero all bytes to the right
                                    exp(0x100, sub(32, mlength))
                                ),
                                // and now shift left the number of bytes to
                                // leave space for the length in the slot
                                exp(0x100, sub(32, newlength))
                            ),
                            // increase length by the double of the memory
                            // bytes length
                            mul(mlength, 2)
                        )
                    )
                )
            }
            case 1 {
                // The stored value fits in the slot, but the combined value
                // will exceed it.
                // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes.slot)
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

                // save new length
                sstore(_preBytes.slot, add(mul(newlength, 2), 1))

                // The contents of the _postBytes array start 32 bytes into
                // the structure. Our first read should obtain the `submod`
                // bytes that can fit into the unused space in the last word
                // of the stored array. To get this, we read 32 bytes starting
                // from `submod`, so the data we read overlaps with the array
                // contents by `submod` bytes. Masking the lowest-order
                // `submod` bytes allows us to add that value directly to the
                // stored value.

                let submod := sub(32, slength)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(
                    sc,
                    add(
                        and(fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00),
                        and(mload(mc), mask)
                    )
                )

                for {
                    mc := add(mc, 0x20)
                    sc := add(sc, 1)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } { sstore(sc, mload(mc)) }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
            default {
                // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes.slot)
                // Start copying to the last used word of the stored array.
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

                // save new length
                sstore(_preBytes.slot, add(mul(newlength, 2), 1))

                // Copy over the first `submod` bytes of the new data as in
                // case 1 above.
                let slengthmod := mod(slength, 32)
                let mlengthmod := mod(mlength, 32)
                let submod := sub(32, slengthmod)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(sc, add(sload(sc), and(mload(mc), mask)))

                for {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } { sstore(sc, mload(mc)) }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
        }
    }

    function slice(bytes memory _bytes, uint256 _start, uint256 _length) internal pure returns (bytes memory) {
        require(_length + 31 >= _length, "slice_overflow");
        require(_bytes.length >= _start + _length, "slice_outOfBounds");

        bytes memory tempBytes;

        assembly {
            switch iszero(_length)
            case 0 {
                // Get a location of some free memory and store it in tempBytes as
                // Solidity does for memory variables.
                tempBytes := mload(0x40)

                // The first word of the slice result is potentially a partial
                // word read from the original array. To read it, we calculate
                // the length of that partial word and start copying that many
                // bytes into the array. The first word we copy will start with
                // data we don't care about, but the last `lengthmod` bytes will
                // land at the beginning of the contents of the new array. When
                // we're done copying, we overwrite the full first word with
                // the actual length of the slice.
                let lengthmod := and(_length, 31)

                // The multiplication in the next line is necessary
                // because when slicing multiples of 32 bytes (lengthmod == 0)
                // the following copy loop was copying the origin's length
                // and then ending prematurely not copying everything it should.
                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
                let end := add(mc, _length)

                for {
                    // The multiplication in the next line has the same exact purpose
                    // as the one above.
                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
                } lt(mc, end) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } { mstore(mc, mload(cc)) }

                mstore(tempBytes, _length)

                //update free-memory pointer
                //allocating the array padded to 32 bytes like the compiler does now
                mstore(0x40, and(add(mc, 31), not(31)))
            }
            //if we want a zero-length slice let's just return a zero-length array
            default {
                tempBytes := mload(0x40)
                //zero out the 32 bytes slice we are about to return
                //we need to do it because Solidity does not garbage collect
                mstore(tempBytes, 0)

                mstore(0x40, add(tempBytes, 0x20))
            }
        }

        return tempBytes;
    }

    function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
        require(_bytes.length >= _start + 20, "toAddress_outOfBounds");
        address tempAddress;

        assembly {
            tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
        }

        return tempAddress;
    }

    function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {
        require(_bytes.length >= _start + 1, "toUint8_outOfBounds");
        uint8 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x1), _start))
        }

        return tempUint;
    }

    function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {
        require(_bytes.length >= _start + 2, "toUint16_outOfBounds");
        uint16 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x2), _start))
        }

        return tempUint;
    }

    function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) {
        require(_bytes.length >= _start + 4, "toUint32_outOfBounds");
        uint32 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x4), _start))
        }

        return tempUint;
    }

    function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {
        require(_bytes.length >= _start + 8, "toUint64_outOfBounds");
        uint64 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x8), _start))
        }

        return tempUint;
    }

    function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) {
        require(_bytes.length >= _start + 12, "toUint96_outOfBounds");
        uint96 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0xc), _start))
        }

        return tempUint;
    }

    function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {
        require(_bytes.length >= _start + 16, "toUint128_outOfBounds");
        uint128 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x10), _start))
        }

        return tempUint;
    }

    function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {
        require(_bytes.length >= _start + 32, "toUint256_outOfBounds");
        uint256 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x20), _start))
        }

        return tempUint;
    }

    function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {
        require(_bytes.length >= _start + 32, "toBytes32_outOfBounds");
        bytes32 tempBytes32;

        assembly {
            tempBytes32 := mload(add(add(_bytes, 0x20), _start))
        }

        return tempBytes32;
    }

    function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {
        bool success = true;

        assembly {
            let length := mload(_preBytes)

            // if lengths don't match the arrays are not equal
            switch eq(length, mload(_postBytes))
            case 1 {
                // cb is a circuit breaker in the for loop since there's
                //  no said feature for inline assembly loops
                // cb = 1 - don't breaker
                // cb = 0 - break
                let cb := 1

                let mc := add(_preBytes, 0x20)
                let end := add(mc, length)

                for { let cc := add(_postBytes, 0x20) }
                // the next line is the loop condition:
                // while(uint256(mc < end) + cb == 2)
                eq(add(lt(mc, end), cb), 2) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    // if any of these checks fails then arrays are not equal
                    if iszero(eq(mload(mc), mload(cc))) {
                        // unsuccess:
                        success := 0
                        cb := 0
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }

    function equal_nonAligned(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {
        bool success = true;

        assembly {
            let length := mload(_preBytes)

            // if lengths don't match the arrays are not equal
            switch eq(length, mload(_postBytes))
            case 1 {
                // cb is a circuit breaker in the for loop since there's
                //  no said feature for inline assembly loops
                // cb = 1 - don't breaker
                // cb = 0 - break
                let cb := 1

                let endMinusWord := add(_preBytes, length)
                let mc := add(_preBytes, 0x20)
                let cc := add(_postBytes, 0x20)

                for {
                    // the next line is the loop condition:
                    // while(uint256(mc < endWord) + cb == 2)
                } eq(add(lt(mc, endMinusWord), cb), 2) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    // if any of these checks fails then arrays are not equal
                    if iszero(eq(mload(mc), mload(cc))) {
                        // unsuccess:
                        success := 0
                        cb := 0
                    }
                }

                // Only if still successful
                // For <1 word tail bytes
                if gt(success, 0) {
                    // Get the remainder of length/32
                    // length % 32 = AND(length, 32 - 1)
                    let numTailBytes := and(length, 0x1f)
                    let mcRem := mload(mc)
                    let ccRem := mload(cc)
                    for { let i := 0 }
                    // the next line is the loop condition:
                    // while(uint256(i < numTailBytes) + cb == 2)
                    eq(add(lt(i, numTailBytes), cb), 2) { i := add(i, 1) } {
                        if iszero(eq(byte(i, mcRem), byte(i, ccRem))) {
                            // unsuccess:
                            success := 0
                            cb := 0
                        }
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }

    function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) {
        bool success = true;

        assembly {
            // we know _preBytes_offset is 0
            let fslot := sload(_preBytes.slot)
            // Decode the length of the stored array like in concatStorage().
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)

            // if lengths don't match the arrays are not equal
            switch eq(slength, mlength)
            case 1 {
                // slength can contain both the length and contents of the array
                // if length < 32 bytes so let's prepare for that
                // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
                if iszero(iszero(slength)) {
                    switch lt(slength, 32)
                    case 1 {
                        // blank the last byte which is the length
                        fslot := mul(div(fslot, 0x100), 0x100)

                        if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {
                            // unsuccess:
                            success := 0
                        }
                    }
                    default {
                        // cb is a circuit breaker in the for loop since there's
                        //  no said feature for inline assembly loops
                        // cb = 1 - don't breaker
                        // cb = 0 - break
                        let cb := 1

                        // get the keccak hash to get the contents of the array
                        mstore(0x0, _preBytes.slot)
                        let sc := keccak256(0x0, 0x20)

                        let mc := add(_postBytes, 0x20)
                        let end := add(mc, mlength)

                        // the next line is the loop condition:
                        // while(uint256(mc < end) + cb == 2)
                        for {} eq(add(lt(mc, end), cb), 2) {
                            sc := add(sc, 1)
                            mc := add(mc, 0x20)
                        } {
                            if iszero(eq(sload(sc), mload(mc))) {
                                // unsuccess:
                                success := 0
                                cb := 0
                            }
                        }
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }
}

File 24 of 24 : TransferHelper.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity =0.8.24;

library TransferHelper {
    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::safeTransfer: transfer failed");
    }

    function safeTransferETH(address to, uint value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, "TransferHelper::safeTransferETH: ETH transfer failed");
    }
}

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

Contract ABI

[{"inputs":[{"internalType":"address","name":"_selfAxelarGateway","type":"address"},{"internalType":"address","name":"_selfGasReceiver","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Bridging_on_same_chain","type":"error"},{"inputs":[],"name":"Call_from_invalid_source","type":"error"},{"inputs":[{"internalType":"uint16","name":"packetType","type":"uint16"}],"name":"Execution_gas_limit_not_set_for_this_packet_type","type":"error"},{"inputs":[],"name":"Fee_Percentage_less_than_100","type":"error"},{"inputs":[{"internalType":"uint256","name":"attachedValue","type":"uint256"},{"internalType":"uint256","name":"expectedValue","type":"uint256"}],"name":"Insufficient_Value_Attached_For_GasPayment","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"Invalid_caller","type":"error"},{"inputs":[],"name":"Margin_delta_zero","type":"error"},{"inputs":[{"internalType":"uint256","name":"gasAmount","type":"uint256"}],"name":"Minimum_Gas_Invalid","type":"error"},{"inputs":[],"name":"NotApprovedByGateway","type":"error"},{"inputs":[{"internalType":"uint16","name":"packetType","type":"uint16"}],"name":"Unknown_packetType","type":"error"},{"inputs":[],"name":"source_chainID_lookup_not_set","type":"error"},{"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":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint16","name":"packetType","type":"uint16"},{"indexed":true,"internalType":"uint16","name":"srcChainId","type":"uint16"}],"name":"ReceiveMsg","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint16","name":"dstChainId","type":"uint16"},{"indexed":true,"internalType":"uint16","name":"packetType","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"payload","type":"bytes"}],"name":"SendMessage","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"dstChainId","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"packetType","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"minGas","type":"uint256"}],"name":"SetMinDstGas","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"remoteChainId","type":"uint16"},{"indexed":false,"internalType":"string","name":"remoteChainName","type":"string"},{"indexed":false,"internalType":"string","name":"remoteChainAddress","type":"string"}],"name":"SetTrustedRemote","type":"event"},{"inputs":[],"name":"_synthrAddressResolver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"axelarDstChainLookup","outputs":[{"internalType":"string","name":"dstChainName","type":"string"},{"internalType":"string","name":"dstChainAddress","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_payload","type":"bytes"},{"internalType":"uint16","name":"packetType","type":"uint16"},{"internalType":"uint16","name":"dstChainId","type":"uint16"}],"name":"calcFee","outputs":[{"internalType":"uint256","name":"lzFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"commandId","type":"bytes32"},{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"commandId","type":"bytes32"},{"internalType":"string","name":"sourceChain","type":"string"},{"internalType":"string","name":"sourceAddress","type":"string"},{"internalType":"bytes","name":"payload","type":"bytes"},{"internalType":"string","name":"tokenSymbol","type":"string"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"executeWithToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gasService","outputs":[{"internalType":"contract IAxelarGasService","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gateway","outputs":[{"internalType":"contract IAxelarGateway","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"__synthrAddressResolver","type":"address"},{"internalType":"uint16","name":"__mainChainId","type":"uint16"},{"internalType":"uint16","name":"__selfChainId","type":"uint16"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lzFeePercentage","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mainChainId","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"minDstGasLookup","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"selfChainId","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"synthKey","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint16","name":"dstChainId","type":"uint16"},{"internalType":"bool","name":"","type":"bool"}],"name":"sendBridgeSyToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"synthKey","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"name":"sendBurn","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"srcKey","type":"bytes32"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"bytes32","name":"dstKey","type":"bytes32"},{"internalType":"uint256","name":"dstAmount","type":"uint256"},{"internalType":"uint16","name":"dstChainId","type":"uint16"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"address","name":"dexAddress","type":"address"},{"internalType":"bytes","name":"dexPayload","type":"bytes"},{"internalType":"bool","name":"","type":"bool"}],"name":"sendCrossSwapNativeToNative","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"srcKey","type":"bytes32"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"bytes32","name":"dstKey","type":"bytes32"},{"internalType":"uint256","name":"dstAmount","type":"uint256"},{"internalType":"uint16","name":"dstChainId","type":"uint16"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"name":"sendCrossSwapNativeToNativeWithDex","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"srcKey","type":"bytes32"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"bytes32","name":"dstKey","type":"bytes32"},{"internalType":"uint256","name":"dstAmount","type":"uint256"},{"internalType":"uint16","name":"dstChainId","type":"uint16"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"name":"sendCrossSwapNativeToSyAsset","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"srcKey","type":"bytes32"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"bytes32","name":"dstKey","type":"bytes32"},{"internalType":"uint256","name":"dstAmount","type":"uint256"},{"internalType":"uint16","name":"dstChainId","type":"uint16"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"bytes","name":"dexPayload","type":"bytes"},{"internalType":"address","name":"dexAddress","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"name":"sendCrossSwapSyAssetToNative","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"srcKey","type":"bytes32"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"bytes32","name":"dstKey","type":"bytes32"},{"internalType":"uint256","name":"dstAmount","type":"uint256"},{"internalType":"uint16","name":"dstChainId","type":"uint16"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"name":"sendCrossSwapSyAssetToNativeWithDex","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"collateralKey","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"name":"sendDepositCollateral","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"srcSynthKey","type":"bytes32"},{"internalType":"bytes32","name":"dstSynthKey","type":"bytes32"},{"internalType":"uint256","name":"srcAmount","type":"uint256"},{"internalType":"uint256","name":"dstAmount","type":"uint256"},{"internalType":"uint256","name":"reclaimed","type":"uint256"},{"internalType":"uint256","name":"refund","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint16","name":"dstChainId","type":"uint16"},{"internalType":"bool","name":"","type":"bool"}],"name":"sendExchange","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"marginDelta","type":"uint256"},{"internalType":"bytes32","name":"marketKey","type":"bytes32"},{"internalType":"bool","name":"","type":"bool"}],"name":"sendTransferMargin","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_percentage","type":"uint16"}],"name":"setLZFeePercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_destinationChainId","type":"uint16"},{"internalType":"uint16","name":"_packetType","type":"uint16"},{"internalType":"uint256","name":"_minGasAmount","type":"uint256"}],"name":"setMinDestinatinGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_srcChainName","type":"string"},{"internalType":"uint16","name":"_srcChainId","type":"uint16"}],"name":"setSrcChainIdLookup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"string","name":"_remoteChainName","type":"string"},{"internalType":"string","name":"_remoteAddress","type":"string"}],"name":"setTrustedRemote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"srcChainIdLookup","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60c034620001a657601f620041fc38819003918201601f19168301916001600160401b03831184841017620001ab578084926040948552833981010312620001a6576200005a60206200005283620001c1565b9201620001c1565b60008054336001600160a01b03198216811783556040516001600160a01b0395909386939192918416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3169081156200019757506080521660a0526001805461ffff60c01b1916601960c21b1790556040516140259081620001d782396080518181816104e501528181610de301528181611b3001528181612135015281816122e90152818161247d01528181612610015281816127a40152818161293801528181612acc01528181612c6001528181612df40152612f88015260a051818181610f5e015281816120d2015281816122860152818161241a015281816125ad01528181612741015281816128d501528181612a6901528181612bfd01528181612d9101528181612f250152818161319301526136830152f35b63e6c4247b60e01b8152600490fd5b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b0382168203620001a65756fe6080604052600436101561001b575b361561001957600080fd5b005b60003560e01c806302de00921461020b5780630cf2abc6146102065780630f45ad4314610201578063116191b6146101fc5780631a98b2e0146101f75780631c4b995a146101f25780632abe893f146101ed5780632bb821bd146101e85780632c957005146101e35780632d89c635146101de57806338e4f064146101d9578063397b2b3a146101d457806349160658146101cf5780634fa34310146101ca5780636a22d8cc146101c55780636fcdef87146101c0578063715018a6146101bb57806380a2eb14146101b6578063863c576f146101b15780638cfd8f5c146101ac5780638da5cb5b146101a7578063af02b429146101a2578063bcc44cb11461019d578063cc9e3e8914610198578063dfb0b30f14610193578063e289c24a1461018e578063e4f84c3f14610189578063f2fde38b14610184578063f3e0893b1461017f578063f4a4229b1461017a5763f7736f3d0361000e576118ae565b6117f1565b611781565b6116ba565b61164f565b611526565b6114a4565b611445565b611354565b6112f8565b6112cf565b611274565b6111c8565b611097565b611039565b610f8d565b610f48565b610e71565b610d15565b610c92565b610b7d565b610998565b61096f565b6107f2565b61066a565b6105a3565b610514565b6104cf565b6104aa565b610405565b610269565b6001600160a01b0381160361022157565b600080fd5b61ffff81160361022157565b9181601f84011215610221578235916001600160401b038311610221576020838186019501011161022157565b8015150361022157565b6101403660031901126102215760043561028281610210565b60a43561028e81610226565b60e4359061029b82610210565b610104356001600160401b038111610221576102bb903690600401610232565b90926102c96101243561025f565b6102d233611e43565b156103c357604051606086901b6001600160601b031916602082015261037492610368906103389061034484603481015b0395610317601f199788810188528761077f565b604051938491602083016014916001600160601b03199060601b1681520190565b0386810184528361077f565b6040519788948860c435916084359060643590604435906024359060208c016119d3565b0390810184528361077f565b61ffff9161039461038e348560015460b01c168488612d19565b34611a7e565b926103b06103a960015461ffff9060b01c1690565b61ffff1690565b908316036103ba57005b61001993612d19565b604051632e79a65160e01b8152600490fd5b6080906003190112610221576004356103ed81610210565b9060243590604435906064356104028161025f565b90565b61040e366103d5565b5061041b92919233611e43565b156103c3576040516001600160601b0319606084901b16602082015260148152610019936104769261048d92601f1992909161045860348461077f565b604051958693600160208601526080604086015260a085019061162a565b91606084015260808301520390810183528261077f565b61ffff60015460b01c16903492612055565b600091031261022157565b3461022157600036600319011261022157602061ffff60015460b01c16604051908152f35b34610221576000366003190112610221576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b346102215760c0366003190112610221576001600160401b0360243581811161022157610545903690600401610232565b6044358381116102215761055d903690600401610232565b60649291923585811161022157610578903690600401610232565b9160843596871161022157610594610019973690600401610232565b95909460a43597600435611aac565b34610221576060366003190112610221576004356105c081610210565b602435906105cd82610226565b6044356105d981610226565b6105e1613041565b600180546001600160a01b039093166001600160c01b031990931660b09490941b61ffff60b01b16939093179190911760a09190911b61ffff60a01b16179055005b6101009060031901126102215760043561063c81610210565b906024359060443590606435906084359060a43561065981610226565b9060c4359060e4356104028161025f565b61067336610623565b509290939161068133611e43565b156103c3576040516001600160601b0319606089901b166020820152601481526106cf94601f19949193610368939192889291906106c060348861077f565b6040519a8b9760208901611ba2565b61ffff916106e760015484349160b01c16838761220e565b340392348411610716576107038160015460b01c1661ffff1690565b9083160361070d57005b6100199361220e565b611a68565b634e487b7160e01b600052604160045260246000fd5b604081019081106001600160401b0382111761074c57604052565b61071b565b6001600160401b03811161074c57604052565b608081019081106001600160401b0382111761074c57604052565b90601f801991011681019081106001600160401b0382111761074c57604052565b6001600160401b03811161074c57601f01601f191660200190565b9291926107c7826107a0565b916107d5604051938461077f565b829481845281830111610221578281602093846000960137010152565b34610221576060366003190112610221576004356001600160401b0381116102215736602382011215610221576108cb6108c461083c6108db9336906024816004013591016107bb565b60243561084881610226565b61085e8160443561085881610226565b84613113565b91600061ffff8084169060058214918215610964575b8215610959575b821561094e575b8215610943575b8215610938575b821561092d575b5081610914575b5061090c575b6108df575b50506001546108be9060c01c61ffff166103a9565b90611c40565b6064900490565b6040519081529081906020820190565b0390f35b61090592916108ff916108f960015461ffff9060b01c1690565b90613113565b90611c33565b38806108a9565b5060016108a4565b905060015490808260b01c169160a01c1614153861089e565b600f14915038610897565b600e81149250610890565b600d81149250610889565b600c81149250610882565b600b8114925061087b565b600781149250610874565b34610221576000366003190112610221576001546040516001600160a01b039091168152602090f35b34610221576060366003190112610221576004356109b581610226565b6001600160401b03602435818111610221576109d5903690600401610232565b92604435838111610221576109ee903690600401610232565b946109f7613041565b604051610a0381610731565b610a0e3683876107bb565b8152610a1b3688856107bb565b6020966020830191825260009761ffff871689526003602052604089209351805192831161074c57610a5783610a51875461154b565b87611c53565b602091601f8411600114610ae05750899a9593610ab884610ac395610acf9a98956001957fe23d07b94549231dae818bc0a03de052bcbc3b986e7861d3c1ab2aed275a92f19f92610ad5575b50508160011b916000199060031b1c19161790565b83555b519101611ca9565b60405195869586611d72565b0390a180f35b015190503880610aa3565b9190601f198416610af687600052602060002090565b938c905b828210610b6557505084610acf9997946001947fe23d07b94549231dae818bc0a03de052bcbc3b986e7861d3c1ab2aed275a92f19e9f9a9894610ac398879510610b4c575b505050811b018355610abb565b015160001960f88460031b161c19169055388080610b3f565b80600186978294978701518155019601940190610afa565b3461022157604036600319011261022157600435610b9a81610210565b602435610ba5613041565b6001600160a01b038216610bbe57610019915033613228565b600091829182604051602081019263a9059cbb60e01b8452336024830152604482015260448152610bee81610764565b51925af1610bfa6131f8565b81610c63575b5015610c0857005b60405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201526c185b9cd9995c8819985a5b1959609a1b6064820152608490fd5b8051801592508215610c78575b505038610c00565b610c8b9250602080918301019101611a8b565b3880610c70565b610c9b366103d5565b50610ca892919233611e43565b156103c3576040516001600160601b0319606084901b166020820152601481526100199361047692610d0392601f19929091610ce560348461077f565b604051958693600460208601526080604086015260a085019061162a565b61ffff60015460b01c169034926123a2565b3461022157600319608036820112610221576004906001600160401b039060243582811161022157610d4a9036908501610232565b909260443581811161022157610d639036908701610232565b92909160643590811161022157610d7d9036908801610232565b9590946020610dd5610d90368a8a6107bb565b805190830120604051635f6970c360e01b81528b358c82015260806024820152938492839291610dc4608485018a8a6119b2565b908482030160448501528a8a6119b2565b6064830191909152038160007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1908115610e6c57600091610e3d575b5015610e2c5761001996506132c5565b604051631403112d60e21b81528790fd5b610e5f915060203d602011610e65575b610e57818361077f565b810190611a8b565b38610e1c565b503d610e4d565b611aa0565b608036600319011261022157600435610e8981610210565b60243590610e9860643561025f565b610ea133611e43565b156103c3578115610f3757610f0b610f256100199360405180610ed986602083016014916001600160601b03199060601b1681520190565b0391610eed601f199384810184528361077f565b604051948592600960208501526080604085015260a084019061162a565b90606083015260443560808301520390810183528261077f565b60015460b01c61ffff16903492612535565b60405162da776760e51b8152600490fd5b34610221576000366003190112610221576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b610f9636610623565b5092909391610fa433611e43565b156103c3576040516001600160601b0319606089901b16602082015260148152610ff294601f1994919361036893919288929190610fe360348861077f565b6040519a8b9760208901611be7565b61ffff9161100a60015484349160b01c1683876126c9565b340392348411610716576110268160015460b01c1661ffff1690565b9083160361103057005b610019936126c9565b346102215760008060031936011261109457611053613041565b80546001600160a01b03198116825581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b80fd5b610140366003190112610221576004356110b081610210565b610104356110bd81610226565b6110c96101243561025f565b6110d233611e43565b156103c357806110f16110e960c43560a435611a7e565b606435611c33565b61ffff809216156111b5575b6040516001600160601b0319606086901b166020820152601481529061115b90601f199061112c60348561077f565b61114f8660405195869360e4359160843591604435916024359060208901611da2565b0390810183528261077f565b34926111716103a960015461ffff9060a01c1690565b9083811691820361119b575b5060015460b01c61ffff169283160361119257005b6100199361285d565b6111ae91945061038e903490848861285d565b923861117d565b60015490925060a01c61ffff16916110fd565b6111d136610623565b50929093916111df33611e43565b156103c3576040516001600160601b0319606089901b1660208201526014815261122d94601f199491936103689391928892919061121e60348861077f565b6040519a8b9760208901611c0d565b61ffff9161124560015484349160b01c1683876129f1565b340392348411610716576112618160015460b01c1661ffff1690565b9083160361126b57005b610019936129f1565b346102215760403660031901126102215760206112c660043561129681610226565b61ffff602435916112a683610226565b166000526002835260406000209061ffff16600052602052604060002090565b54604051908152f35b34610221576000366003190112610221576000546040516001600160a01b039091168152602090f35b346102215760203660031901126102215760043561131581610226565b606461ffff821610611342576001805461ffff60c01b191660c09290921b61ffff60c01b16919091179055005b60405163fccfd58b60e01b8152600490fd5b60a03660031901126102215760043561136c81610210565b60643561137881610226565b61138360843561025f565b61138c33611e43565b156103c35761ffff8082169182156114335761140e61038e82611405604051806113cb8a602083016014916001600160601b03199060601b1681520190565b03906113df601f199283810183528261077f565b6113f9604051978892604435906024359060208601611de8565b0390810186528561077f565b34908488612b85565b9261142060015461ffff9060b01c1690565b9283160361142a57005b61001993612b85565b604051636794524760e01b8152600490fd5b3461022157600036600319011261022157602061ffff60015460a01c16604051908152f35b60005b83811061147d5750506000910152565b818101518382015260200161146d565b906114a06020928281519485920161146a565b0190565b34610221576020366003190112610221576004356001600160401b03811161022157366023820112156102215761ffff61150360206114f06108db9436906024816004013591016107bb565b816040519382858094519384920161146a565b8101600481520301902054166040519182918291909161ffff6020820193169052565b3461022157600036600319011261022157602061ffff60015460c01c16604051908152f35b90600182811c9216801561157b575b602083101461156557565b634e487b7160e01b600052602260045260246000fd5b91607f169161155a565b906040519182600082546115988161154b565b9081845260209460019160018116908160001461160857506001146115c9575b5050506115c79250038361077f565b565b600090815285812095935091905b8183106115f05750506115c793508201013880806115b8565b855488840185015294850194879450918301916115d7565b925050506115c794925060ff191682840152151560051b8201013880806115b8565b906020916116438151809281855285808601910161146a565b601f01601f1916010190565b346102215760203660031901126102215761ffff60043561166f81610226565b1660005260036020526116ac60406000206108db611698600161169184611585565b9301611585565b60405193849360408552604085019061162a565b90838203602085015261162a565b34610221576020366003190112610221576004356116d781610210565b6116df613041565b6001600160a01b03908116801561172d57600080546001600160a01b03198116831782559092167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b34610221576040366003190112610221576004356001600160401b038111610221576117b461ffff913690600401610232565b60243592916020906117c585610226565b6117cd613041565b82604051938492833781016004815203019020911661ffff19825416179055600080f35b346102215760603660031901126102215760043561180e81610226565b6024359061181b82610226565b60443590611827613041565b811561189557916060917f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac09361ffff80911692836000526002602052826118808260406000209061ffff16600052602052604060002090565b556040519384521660208301526040820152a1005b6040516355b56ea760e01b815260048101839052602490fd5b610140366003190112610221576004356118c781610210565b60a4356118d381610226565b60e4356001600160401b038111610221576118f2903690600401610232565b6101049291923561190281610210565b61190e6101243561025f565b61191733611e43565b156103c357604051606086901b6001600160601b031916602082015261197092610368906103389061194c8460348101610303565b6040519788948860c435916084359060643590604435906024359060208c01611a3c565b61ffff9161198a61038e348560015460b01c168488612ead565b9261199f6103a960015461ffff9060b01c1690565b908316036119a957005b61001993612ead565b908060209392818452848401376000828201840152601f01601f1916010190565b98946104029a9894611a2d98946119ff61ffff9599948d61014090600d8152816020820152019061162a565b9860408d015260608c015260808b015260a08a01521660c088015260e08701528583036101008701526119b2565b9161012081840391015261162a565b98946104029a9894611a2d98946119ff61ffff9599948d61014090600b8152816020820152019061162a565b634e487b7160e01b600052601160045260246000fd5b9190820391821161071657565b9081602091031261022157516104028161025f565b6040513d6000823e3d90fd5b9592611b0e611ac860209a9499939b97611b22979636916107bb565b8a815191012094611afa6040519c8d9b8c9b631876eed960e01b8d5260048d015260c060248d015260c48c01916119b2565b9060031993848b84030160448c01526119b2565b9360648801528684030160848701526119b2565b60a4830191909152038160007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1908115610e6c57600091611b83575b5015611b7157565b604051631403112d60e21b8152600490fd5b611b9c915060203d602011610e6557610e57818361077f565b38611b69565b9361ffff93611bc860e097939a9998949a610100600c89528060208a015288019061162a565b9960408701526060860152608085015260a08401521660c08201520152565b9361ffff93611bc860e097939a9998949a610100600f89528060208a015288019061162a565b9361ffff93611bc860e097939a9998949a610100600e89528060208a015288019061162a565b9190820180921161071657565b8181029291811591840414171561071657565b90601f8111611c6157505050565b6000916000526020600020906020601f850160051c83019410611c9f575b601f0160051c01915b828110611c9457505050565b818155600101611c88565b9092508290611c7f565b91909182516001600160401b03811161074c57611cd081611cca845461154b565b84611c53565b602080601f8311600114611d0757508190611d03939495600092610ad55750508160011b916000199060031b1c19161790565b9055565b90601f19831695611d1d85600052602060002090565b926000905b888210611d5a57505083600195969710611d41575b505050811b019055565b015160001960f88460031b161c19169055388080611d37565b80600185968294968601518155019501930190611d22565b9391610402959361ffff611d94931686526060602087015260608601916119b2565b9260408185039101526119b2565b95919796929361ffff94611dc860e0979361010060058b528060208c01528a019061162a565b9960408901526060880152608087015260a086015260c085015216910152565b92936080929594611e0b61ffff936007875260a0602088015260a087019061162a565b966040860152606085015216910152565b908092918237016000815290565b6020908260405193849283378101600481520301902090565b611e5a611e4e6133fa565b6001600160a01b031690565b6001600160a01b03821690811491908215611f7a575b8215611f65575b8215611f50575b8215611f3b575b8215611f26575b8215611f10575b508115611e9e575090565b611ee19150602090611eb4611e4e611e4e6135fd565b6040516308651a8360e31b81526001600160a01b0390921660048301529092839190829081906024820190565b03915afa908115610e6c57600091611ef7575090565b610402915060203d602011610e6557610e57818361077f565b909150611f1e611e4e6135fd565b149038611e93565b9150611f33611e4e6135ab565b821491611e8c565b9150611f48611e4e613559565b821491611e85565b9150611f5d611e4e61350e565b821491611e7e565b9150611f72611e4e6134c4565b821491611e77565b9150611f87611e4e61347d565b821491611e70565b90604051611f9c81610731565b6020611fb660018395611fae81611585565b855201611585565b910152565b93611ff8608094611fea612006949599989960018060a01b03809716895260a060208a015260a089019061162a565b90878203604089015261162a565b90858203606087015261162a565b9416910152565b9161203690612028610402959360608652606086019061162a565b90848203602086015261162a565b91604081840391015261162a565b90602061040292818152019061162a565b906120816120718461ffff166000526002602052604060002090565b6001600052602052604060002090565b549384156121f5576120a96120a48561ffff166000526003602052604060002090565b611f8f565b6120be828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f00000000000000000000000000000000000000000000000000000000000000008616803b1561022157876000936121229560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c576121e2575b50827f0000000000000000000000000000000000000000000000000000000000000000169151905190823b15610221576121889260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff936001986121c9575b506040519384931696169482612044565b0390a490565b806121d66121dc92610751565b8061049f565b386121b2565b806121d66121ef92610751565b38612131565b60405163056a947960e11b815260016004820152602490fd5b9061223a61222a8461ffff166000526002602052604060002090565b600c600052602052604060002090565b549384156123895761225d6120a48561ffff166000526003602052604060002090565b612272828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f00000000000000000000000000000000000000000000000000000000000000008616803b1561022157876000936122d69560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c57612376575b50827f0000000000000000000000000000000000000000000000000000000000000000169151905190823b156102215761233c9260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff93600c986121c957506040519384931696169482612044565b806121d661238392610751565b386122e5565b60405163056a947960e11b8152600c6004820152602490fd5b906123ce6123be8461ffff166000526002602052604060002090565b6004600052602052604060002090565b5493841561251d576123f16120a48561ffff166000526003602052604060002090565b612406828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f00000000000000000000000000000000000000000000000000000000000000008616803b15610221578760009361246a9560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c5761250a575b50827f0000000000000000000000000000000000000000000000000000000000000000169151905190823b15610221576124d09260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff936004986121c957506040519384931696169482612044565b806121d661251792610751565b38612479565b60405163056a947960e11b8152600480820152602490fd5b906125616125518461ffff166000526002602052604060002090565b6009600052602052604060002090565b549384156126b0576125846120a48561ffff166000526003602052604060002090565b612599828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f00000000000000000000000000000000000000000000000000000000000000008616803b1561022157876000936125fd9560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c5761269d575b50827f0000000000000000000000000000000000000000000000000000000000000000169151905190823b15610221576126639260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff936009986121c957506040519384931696169482612044565b806121d66126aa92610751565b3861260c565b60405163056a947960e11b815260096004820152602490fd5b906126f56126e58461ffff166000526002602052604060002090565b600f600052602052604060002090565b54938415612844576127186120a48561ffff166000526003602052604060002090565b61272d828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f00000000000000000000000000000000000000000000000000000000000000008616803b1561022157876000936127919560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c57612831575b50827f0000000000000000000000000000000000000000000000000000000000000000169151905190823b15610221576127f79260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff93600f986121c957506040519384931696169482612044565b806121d661283e92610751565b386127a0565b60405163056a947960e11b8152600f6004820152602490fd5b906128896128798461ffff166000526002602052604060002090565b6005600052602052604060002090565b549384156129d8576128ac6120a48561ffff166000526003602052604060002090565b6128c1828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f00000000000000000000000000000000000000000000000000000000000000008616803b1561022157876000936129259560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c576129c5575b50827f0000000000000000000000000000000000000000000000000000000000000000169151905190823b156102215761298b9260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff936005986121c957506040519384931696169482612044565b806121d66129d292610751565b38612934565b60405163056a947960e11b815260056004820152602490fd5b90612a1d612a0d8461ffff166000526002602052604060002090565b600e600052602052604060002090565b54938415612b6c57612a406120a48561ffff166000526003602052604060002090565b612a55828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f00000000000000000000000000000000000000000000000000000000000000008616803b156102215787600093612ab99560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c57612b59575b50827f0000000000000000000000000000000000000000000000000000000000000000169151905190823b1561022157612b1f9260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff93600e986121c957506040519384931696169482612044565b806121d6612b6692610751565b38612ac8565b60405163056a947960e11b8152600e6004820152602490fd5b90612bb1612ba18461ffff166000526002602052604060002090565b6007600052602052604060002090565b54938415612d0057612bd46120a48561ffff166000526003602052604060002090565b612be9828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f00000000000000000000000000000000000000000000000000000000000000008616803b156102215787600093612c4d9560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c57612ced575b50827f0000000000000000000000000000000000000000000000000000000000000000169151905190823b1561022157612cb39260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff936007986121c957506040519384931696169482612044565b806121d6612cfa92610751565b38612c5c565b60405163056a947960e11b815260076004820152602490fd5b90612d45612d358461ffff166000526002602052604060002090565b600d600052602052604060002090565b54938415612e9457612d686120a48561ffff166000526003602052604060002090565b612d7d828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f00000000000000000000000000000000000000000000000000000000000000008616803b156102215787600093612de19560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c57612e81575b50827f0000000000000000000000000000000000000000000000000000000000000000169151905190823b1561022157612e479260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff93600d986121c957506040519384931696169482612044565b806121d6612e8e92610751565b38612df0565b60405163056a947960e11b8152600d6004820152602490fd5b90612ed9612ec98461ffff166000526002602052604060002090565b600b600052602052604060002090565b5493841561302857612efc6120a48561ffff166000526003602052604060002090565b612f11828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f00000000000000000000000000000000000000000000000000000000000000008616803b156102215787600093612f759560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c57613015575b50827f0000000000000000000000000000000000000000000000000000000000000000169151905190823b1561022157612fdb9260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff93600b986121c957506040519384931696169482612044565b806121d661302292610751565b38612f84565b60405163056a947960e11b8152600b6004820152602490fd5b6000546001600160a01b0316330361305557565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b604051906130a682610731565b60018252600360fc1b6020830152565b90816020910312610221575190565b91926130f261040296946130e46131009460a0875260a087019061162a565b90858203602087015261162a565b90838203604085015261162a565b926060820152608081840391015261162a565b919061315f60209261ffff83166000526003845261314c6131376040600020611f8f565b9361ffff166000526002602052604060002090565b9061ffff16600052602052604060002090565b549061318f83825192015192613173613099565b906040519687958695630135eaa760e41b8752600487016130c5565b03817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610e6c576000916131cf575090565b610402915060203d6020116131f1575b6131e9818361077f565b8101906130b6565b503d6131df565b3d15613223573d90613209826107a0565b91613217604051938461077f565b82523d6000602084013e565b606090565b60405160208101908082106001600160401b0383111761074c576000938493848094938194604052525af161325b6131f8565b501561326357565b60405162461bcd60e51b815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527308115512081d1c985b9cd9995c8819985a5b195960621b6064820152608490fd5b91909394926132df6132d78685611e2a565b5461ffff1690565b9461ffff8616156133e85761331c916133096120a48861ffff166000526003602052604060002090565b9360405193849160208301938491611e1c565b0392613330601f199485810183528261077f565b51902060208401516040516133598161334d60208201809561148d565b0386810183528261077f565b51902014159384613394575b50505050613382576115c79261337c9136916107bb565b90613968565b604051635bb95f3d60e11b8152600490fd5b6133b291929394506133be9060405192839160208301958691611e1c565b0384810183528261077f565b5190209151906133da604051918261114f60208201809661148d565b519020141538808080613365565b6040516378ccabe760e01b8152600490fd5b6001546040516321f8a72160e01b81526c2bb930b83832b229bcb73a343960991b600482015290602090829060249082906001600160a01b03165afa908115610e6c57600091613448575090565b90506020813d602011613475575b816134636020938361077f565b81010312610221575161040281610210565b3d9150613456565b6001546040516321f8a72160e01b81526524b9b9bab2b960d11b600482015290602090829060249082906001600160a01b03165afa908115610e6c57600091613448575090565b6001546040516321f8a72160e01b81526822bc31b430b733b2b960b91b600482015290602090829060249082906001600160a01b03165afa908115610e6c57600091613448575090565b6001546040516321f8a72160e01b815269053796e746872537761760b41b600482015290602090829060249082906001600160a01b03165afa908115610e6c57600091613448575090565b6001546040516321f8a72160e01b8152700a6f2dce8d0e4a6eec2e0aed2e8d088caf607b1b600482015290602090829060249082906001600160a01b03165afa908115610e6c57600091613448575090565b6001546040516321f8a72160e01b81527027b33321b430b4b722bc31b430b733b2b960791b600482015290602090829060249082906001600160a01b03165afa908115610e6c57600091613448575090565b6001546040516321f8a72160e01b815273233aba3ab932b9a6b0b935b2ba26b0b730b3b2b960611b600482015290602090829060249082906001600160a01b03165afa908115610e6c57600091613448575090565b61367f602093969594613663613099565b906040519889958695630135eaa760e41b8752600487016130c5565b03817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa928315610e6c576000936136e7575b50828082106136c9575050565b6044925060405191631cf7a67960e11b835260048301526024820152fd5b61370191935060203d6020116131f1576131e9818361077f565b91386136bc565b51906115c782610226565b81601f82011215610221578051613729816107a0565b92613737604051948561077f565b8184526020828401011161022157610402916020808501910161146a565b9190916101008184031261022157805161376e81610226565b926020820151906001600160401b0382116102215761378e918301613713565b9160408201519160608101519160808201519160a08101519160e060c08301516137b781610226565b92015190565b91909161014081840312610221576137d481613708565b9260208201516001600160401b039081811161022157826137f6918501613713565b9360408401519360608101519360808201519360a08301519361381b60c08501613708565b9360e081015193610100820151848111610221578161383b918401613713565b93610120830151908111610221576104029201613713565b9360e095919361040298979360018060a01b03809616875260208701526040860152606085015260808401521660a08201528160c0820152019061162a565b90916060828403126102215781516138a981610226565b9260208301516001600160401b038111610221576040916137b7918501613713565b9190916080818403126102215780516138e381610226565b926020820151906001600160401b03821161022157613903918301613713565b916060604083015192015190565b909160e08284031261022157815161392881610226565b926020830151906001600160401b03821161022157613948918401613713565b9160408101519160608201519160808101519160c060a083015192015190565b906020908181019283519261ffff928385169460028614600014613a4457509461399a91866139a397510101906138cb565b92509590613f7f565b946139b2611e4e611e4e61347d565b91823b1561022157604051631a4ac9bf60e21b81526001600160a01b038816600482015260248101929092526044820152906000908290606490829084905af18015610e6c57613a31575b505b16916001600160a01b03167fa3a26805904503468e23304f9bd1cdaddc39bac907d3ce175f35a1d1771d9f93600080a4565b806121d6613a3e92610751565b386139fd565b60038603613add57509461399a9186613a6097510101906138cb565b94613a6f611e4e611e4e6133fa565b91823b15610221576040516358ff317f60e11b81526001600160a01b03881660048201819052602482015260448101929092526064820152906000908290818381608481015b03925af18015610e6c57613aca575b506139ff565b806121d6613ad792610751565b38613ac4565b60058603613b58575094613af99186613b069751010190613911565b5094509792915050613f7f565b94613b15611e4e611e4e6134c4565b91823b1561022157604051630a77839d60e11b81526001600160a01b03881660048201526024810192909252604482015290600090829081838160648101613ab5565b60068603613bd357509461399a9186613b7497510101906138cb565b94613b83611e4e611e4e6133fa565b91823b1561022157604051630533242960e31b81526001600160a01b038816600482015260248101929092526044820152906000908290606490829084905af18015610e6c57613aca57506139ff565b60078603613c4157509461399a9186613bef97510101906138cb565b94613bfe611e4e611e4e61347d565b91823b1561022157604051631a4ac9bf60e21b81526001600160a01b03881660048201526024810192909252604482015290600090829081838160648101613ab5565b600a8603613cca575094613c5d9186613c659751010190613892565b959150613f7f565b93613c74611e4e611e4e61347d565b803b1561022157604051631a4ac9bf60e21b81526001600160a01b0387166004820152631cd554d160e21b602482015260448101929092526000908290606490829084905af18015610e6c57613aca57506139ff565b600b8603613d6b575081613d37613d03613cef613d0b998486600097510101906137bd565b969850939b96915050979297969096613f7f565b9d8e93613f7f565b613d19611e4e611e4e61350e565b966040519a8b998a9889976314cf934360e11b895260048901613853565b03925af18015610e6c57613d4d575b50506139ff565b81613d6392903d10610e6557610e57818361077f565b503880613d46565b600c8603613e08575094613d879186613d969751010190613755565b50509390945097909197613f7f565b96613da5611e4e611e4e61350e565b90813b15610221576040516315491d7d60e21b81526001600160a01b038a166004820152602481019190915260448101929092526064820193909352608481019190915290600090829060a490829084905af18015610e6c57613aca57506139ff565b909590600d8603613e5c575081613d37613d03613cef600094848b613e309c510101906137bd565b613e3e611e4e611e4e61350e565b966040519a8b998a988997631077bc3b60e01b895260048901613853565b958296600e8714600014613ee65750613e8c918382613e7e9351010190613755565b5050929a9450949092613f7f565b9860008a613d37613ea1611e4e611e4e613559565b946040519889978896879563b4c4dff960e01b8752600487019192608093969594919660a084019760018060a01b031684526020840152604083015260608201520152565b91925090600f8603613f615750613e7e86928383613f079451010190613755565b9860008a613d37613f1c611e4e611e4e613559565b946040519889978896879563b9eacb7560e01b8752600487019192608093969594919660a084019760018060a01b031684526020840152604083015260608201520152565b604051634f18ccbb60e11b815261ffff919091166004820152602490fd5b6014815110613f92576020015160601c90565b60405162461bcd60e51b8152602060048201526015602482015274746f416464726573735f6f75744f66426f756e647360581b6044820152606490fdfef34f07c5b9fc3912963edcdd4888dd8a9a13cd778c9451ca3f0335c2a32278fea26469706673582212206f366ecb69fa148e7327cfa4d94ab211d54c4c571a9b35f8c84d7216172e956064736f6c63430008180033000000000000000000000000e432150cce91c13a887f7d836923d5597add8e31000000000000000000000000be406f0189a0b4cf3a05c286473d23791dd44cc6

Deployed Bytecode

0x6080604052600436101561001b575b361561001957600080fd5b005b60003560e01c806302de00921461020b5780630cf2abc6146102065780630f45ad4314610201578063116191b6146101fc5780631a98b2e0146101f75780631c4b995a146101f25780632abe893f146101ed5780632bb821bd146101e85780632c957005146101e35780632d89c635146101de57806338e4f064146101d9578063397b2b3a146101d457806349160658146101cf5780634fa34310146101ca5780636a22d8cc146101c55780636fcdef87146101c0578063715018a6146101bb57806380a2eb14146101b6578063863c576f146101b15780638cfd8f5c146101ac5780638da5cb5b146101a7578063af02b429146101a2578063bcc44cb11461019d578063cc9e3e8914610198578063dfb0b30f14610193578063e289c24a1461018e578063e4f84c3f14610189578063f2fde38b14610184578063f3e0893b1461017f578063f4a4229b1461017a5763f7736f3d0361000e576118ae565b6117f1565b611781565b6116ba565b61164f565b611526565b6114a4565b611445565b611354565b6112f8565b6112cf565b611274565b6111c8565b611097565b611039565b610f8d565b610f48565b610e71565b610d15565b610c92565b610b7d565b610998565b61096f565b6107f2565b61066a565b6105a3565b610514565b6104cf565b6104aa565b610405565b610269565b6001600160a01b0381160361022157565b600080fd5b61ffff81160361022157565b9181601f84011215610221578235916001600160401b038311610221576020838186019501011161022157565b8015150361022157565b6101403660031901126102215760043561028281610210565b60a43561028e81610226565b60e4359061029b82610210565b610104356001600160401b038111610221576102bb903690600401610232565b90926102c96101243561025f565b6102d233611e43565b156103c357604051606086901b6001600160601b031916602082015261037492610368906103389061034484603481015b0395610317601f199788810188528761077f565b604051938491602083016014916001600160601b03199060601b1681520190565b0386810184528361077f565b6040519788948860c435916084359060643590604435906024359060208c016119d3565b0390810184528361077f565b61ffff9161039461038e348560015460b01c168488612d19565b34611a7e565b926103b06103a960015461ffff9060b01c1690565b61ffff1690565b908316036103ba57005b61001993612d19565b604051632e79a65160e01b8152600490fd5b6080906003190112610221576004356103ed81610210565b9060243590604435906064356104028161025f565b90565b61040e366103d5565b5061041b92919233611e43565b156103c3576040516001600160601b0319606084901b16602082015260148152610019936104769261048d92601f1992909161045860348461077f565b604051958693600160208601526080604086015260a085019061162a565b91606084015260808301520390810183528261077f565b61ffff60015460b01c16903492612055565b600091031261022157565b3461022157600036600319011261022157602061ffff60015460b01c16604051908152f35b34610221576000366003190112610221576040517f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e316001600160a01b03168152602090f35b346102215760c0366003190112610221576001600160401b0360243581811161022157610545903690600401610232565b6044358381116102215761055d903690600401610232565b60649291923585811161022157610578903690600401610232565b9160843596871161022157610594610019973690600401610232565b95909460a43597600435611aac565b34610221576060366003190112610221576004356105c081610210565b602435906105cd82610226565b6044356105d981610226565b6105e1613041565b600180546001600160a01b039093166001600160c01b031990931660b09490941b61ffff60b01b16939093179190911760a09190911b61ffff60a01b16179055005b6101009060031901126102215760043561063c81610210565b906024359060443590606435906084359060a43561065981610226565b9060c4359060e4356104028161025f565b61067336610623565b509290939161068133611e43565b156103c3576040516001600160601b0319606089901b166020820152601481526106cf94601f19949193610368939192889291906106c060348861077f565b6040519a8b9760208901611ba2565b61ffff916106e760015484349160b01c16838761220e565b340392348411610716576107038160015460b01c1661ffff1690565b9083160361070d57005b6100199361220e565b611a68565b634e487b7160e01b600052604160045260246000fd5b604081019081106001600160401b0382111761074c57604052565b61071b565b6001600160401b03811161074c57604052565b608081019081106001600160401b0382111761074c57604052565b90601f801991011681019081106001600160401b0382111761074c57604052565b6001600160401b03811161074c57601f01601f191660200190565b9291926107c7826107a0565b916107d5604051938461077f565b829481845281830111610221578281602093846000960137010152565b34610221576060366003190112610221576004356001600160401b0381116102215736602382011215610221576108cb6108c461083c6108db9336906024816004013591016107bb565b60243561084881610226565b61085e8160443561085881610226565b84613113565b91600061ffff8084169060058214918215610964575b8215610959575b821561094e575b8215610943575b8215610938575b821561092d575b5081610914575b5061090c575b6108df575b50506001546108be9060c01c61ffff166103a9565b90611c40565b6064900490565b6040519081529081906020820190565b0390f35b61090592916108ff916108f960015461ffff9060b01c1690565b90613113565b90611c33565b38806108a9565b5060016108a4565b905060015490808260b01c169160a01c1614153861089e565b600f14915038610897565b600e81149250610890565b600d81149250610889565b600c81149250610882565b600b8114925061087b565b600781149250610874565b34610221576000366003190112610221576001546040516001600160a01b039091168152602090f35b34610221576060366003190112610221576004356109b581610226565b6001600160401b03602435818111610221576109d5903690600401610232565b92604435838111610221576109ee903690600401610232565b946109f7613041565b604051610a0381610731565b610a0e3683876107bb565b8152610a1b3688856107bb565b6020966020830191825260009761ffff871689526003602052604089209351805192831161074c57610a5783610a51875461154b565b87611c53565b602091601f8411600114610ae05750899a9593610ab884610ac395610acf9a98956001957fe23d07b94549231dae818bc0a03de052bcbc3b986e7861d3c1ab2aed275a92f19f92610ad5575b50508160011b916000199060031b1c19161790565b83555b519101611ca9565b60405195869586611d72565b0390a180f35b015190503880610aa3565b9190601f198416610af687600052602060002090565b938c905b828210610b6557505084610acf9997946001947fe23d07b94549231dae818bc0a03de052bcbc3b986e7861d3c1ab2aed275a92f19e9f9a9894610ac398879510610b4c575b505050811b018355610abb565b015160001960f88460031b161c19169055388080610b3f565b80600186978294978701518155019601940190610afa565b3461022157604036600319011261022157600435610b9a81610210565b602435610ba5613041565b6001600160a01b038216610bbe57610019915033613228565b600091829182604051602081019263a9059cbb60e01b8452336024830152604482015260448152610bee81610764565b51925af1610bfa6131f8565b81610c63575b5015610c0857005b60405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201526c185b9cd9995c8819985a5b1959609a1b6064820152608490fd5b8051801592508215610c78575b505038610c00565b610c8b9250602080918301019101611a8b565b3880610c70565b610c9b366103d5565b50610ca892919233611e43565b156103c3576040516001600160601b0319606084901b166020820152601481526100199361047692610d0392601f19929091610ce560348461077f565b604051958693600460208601526080604086015260a085019061162a565b61ffff60015460b01c169034926123a2565b3461022157600319608036820112610221576004906001600160401b039060243582811161022157610d4a9036908501610232565b909260443581811161022157610d639036908701610232565b92909160643590811161022157610d7d9036908801610232565b9590946020610dd5610d90368a8a6107bb565b805190830120604051635f6970c360e01b81528b358c82015260806024820152938492839291610dc4608485018a8a6119b2565b908482030160448501528a8a6119b2565b6064830191909152038160007f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e316001600160a01b03165af1908115610e6c57600091610e3d575b5015610e2c5761001996506132c5565b604051631403112d60e21b81528790fd5b610e5f915060203d602011610e65575b610e57818361077f565b810190611a8b565b38610e1c565b503d610e4d565b611aa0565b608036600319011261022157600435610e8981610210565b60243590610e9860643561025f565b610ea133611e43565b156103c3578115610f3757610f0b610f256100199360405180610ed986602083016014916001600160601b03199060601b1681520190565b0391610eed601f199384810184528361077f565b604051948592600960208501526080604085015260a084019061162a565b90606083015260443560808301520390810183528261077f565b60015460b01c61ffff16903492612535565b60405162da776760e51b8152600490fd5b34610221576000366003190112610221576040517f000000000000000000000000be406f0189a0b4cf3a05c286473d23791dd44cc66001600160a01b03168152602090f35b610f9636610623565b5092909391610fa433611e43565b156103c3576040516001600160601b0319606089901b16602082015260148152610ff294601f1994919361036893919288929190610fe360348861077f565b6040519a8b9760208901611be7565b61ffff9161100a60015484349160b01c1683876126c9565b340392348411610716576110268160015460b01c1661ffff1690565b9083160361103057005b610019936126c9565b346102215760008060031936011261109457611053613041565b80546001600160a01b03198116825581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b80fd5b610140366003190112610221576004356110b081610210565b610104356110bd81610226565b6110c96101243561025f565b6110d233611e43565b156103c357806110f16110e960c43560a435611a7e565b606435611c33565b61ffff809216156111b5575b6040516001600160601b0319606086901b166020820152601481529061115b90601f199061112c60348561077f565b61114f8660405195869360e4359160843591604435916024359060208901611da2565b0390810183528261077f565b34926111716103a960015461ffff9060a01c1690565b9083811691820361119b575b5060015460b01c61ffff169283160361119257005b6100199361285d565b6111ae91945061038e903490848861285d565b923861117d565b60015490925060a01c61ffff16916110fd565b6111d136610623565b50929093916111df33611e43565b156103c3576040516001600160601b0319606089901b1660208201526014815261122d94601f199491936103689391928892919061121e60348861077f565b6040519a8b9760208901611c0d565b61ffff9161124560015484349160b01c1683876129f1565b340392348411610716576112618160015460b01c1661ffff1690565b9083160361126b57005b610019936129f1565b346102215760403660031901126102215760206112c660043561129681610226565b61ffff602435916112a683610226565b166000526002835260406000209061ffff16600052602052604060002090565b54604051908152f35b34610221576000366003190112610221576000546040516001600160a01b039091168152602090f35b346102215760203660031901126102215760043561131581610226565b606461ffff821610611342576001805461ffff60c01b191660c09290921b61ffff60c01b16919091179055005b60405163fccfd58b60e01b8152600490fd5b60a03660031901126102215760043561136c81610210565b60643561137881610226565b61138360843561025f565b61138c33611e43565b156103c35761ffff8082169182156114335761140e61038e82611405604051806113cb8a602083016014916001600160601b03199060601b1681520190565b03906113df601f199283810183528261077f565b6113f9604051978892604435906024359060208601611de8565b0390810186528561077f565b34908488612b85565b9261142060015461ffff9060b01c1690565b9283160361142a57005b61001993612b85565b604051636794524760e01b8152600490fd5b3461022157600036600319011261022157602061ffff60015460a01c16604051908152f35b60005b83811061147d5750506000910152565b818101518382015260200161146d565b906114a06020928281519485920161146a565b0190565b34610221576020366003190112610221576004356001600160401b03811161022157366023820112156102215761ffff61150360206114f06108db9436906024816004013591016107bb565b816040519382858094519384920161146a565b8101600481520301902054166040519182918291909161ffff6020820193169052565b3461022157600036600319011261022157602061ffff60015460c01c16604051908152f35b90600182811c9216801561157b575b602083101461156557565b634e487b7160e01b600052602260045260246000fd5b91607f169161155a565b906040519182600082546115988161154b565b9081845260209460019160018116908160001461160857506001146115c9575b5050506115c79250038361077f565b565b600090815285812095935091905b8183106115f05750506115c793508201013880806115b8565b855488840185015294850194879450918301916115d7565b925050506115c794925060ff191682840152151560051b8201013880806115b8565b906020916116438151809281855285808601910161146a565b601f01601f1916010190565b346102215760203660031901126102215761ffff60043561166f81610226565b1660005260036020526116ac60406000206108db611698600161169184611585565b9301611585565b60405193849360408552604085019061162a565b90838203602085015261162a565b34610221576020366003190112610221576004356116d781610210565b6116df613041565b6001600160a01b03908116801561172d57600080546001600160a01b03198116831782559092167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b34610221576040366003190112610221576004356001600160401b038111610221576117b461ffff913690600401610232565b60243592916020906117c585610226565b6117cd613041565b82604051938492833781016004815203019020911661ffff19825416179055600080f35b346102215760603660031901126102215760043561180e81610226565b6024359061181b82610226565b60443590611827613041565b811561189557916060917f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac09361ffff80911692836000526002602052826118808260406000209061ffff16600052602052604060002090565b556040519384521660208301526040820152a1005b6040516355b56ea760e01b815260048101839052602490fd5b610140366003190112610221576004356118c781610210565b60a4356118d381610226565b60e4356001600160401b038111610221576118f2903690600401610232565b6101049291923561190281610210565b61190e6101243561025f565b61191733611e43565b156103c357604051606086901b6001600160601b031916602082015261197092610368906103389061194c8460348101610303565b6040519788948860c435916084359060643590604435906024359060208c01611a3c565b61ffff9161198a61038e348560015460b01c168488612ead565b9261199f6103a960015461ffff9060b01c1690565b908316036119a957005b61001993612ead565b908060209392818452848401376000828201840152601f01601f1916010190565b98946104029a9894611a2d98946119ff61ffff9599948d61014090600d8152816020820152019061162a565b9860408d015260608c015260808b015260a08a01521660c088015260e08701528583036101008701526119b2565b9161012081840391015261162a565b98946104029a9894611a2d98946119ff61ffff9599948d61014090600b8152816020820152019061162a565b634e487b7160e01b600052601160045260246000fd5b9190820391821161071657565b9081602091031261022157516104028161025f565b6040513d6000823e3d90fd5b9592611b0e611ac860209a9499939b97611b22979636916107bb565b8a815191012094611afa6040519c8d9b8c9b631876eed960e01b8d5260048d015260c060248d015260c48c01916119b2565b9060031993848b84030160448c01526119b2565b9360648801528684030160848701526119b2565b60a4830191909152038160007f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e316001600160a01b03165af1908115610e6c57600091611b83575b5015611b7157565b604051631403112d60e21b8152600490fd5b611b9c915060203d602011610e6557610e57818361077f565b38611b69565b9361ffff93611bc860e097939a9998949a610100600c89528060208a015288019061162a565b9960408701526060860152608085015260a08401521660c08201520152565b9361ffff93611bc860e097939a9998949a610100600f89528060208a015288019061162a565b9361ffff93611bc860e097939a9998949a610100600e89528060208a015288019061162a565b9190820180921161071657565b8181029291811591840414171561071657565b90601f8111611c6157505050565b6000916000526020600020906020601f850160051c83019410611c9f575b601f0160051c01915b828110611c9457505050565b818155600101611c88565b9092508290611c7f565b91909182516001600160401b03811161074c57611cd081611cca845461154b565b84611c53565b602080601f8311600114611d0757508190611d03939495600092610ad55750508160011b916000199060031b1c19161790565b9055565b90601f19831695611d1d85600052602060002090565b926000905b888210611d5a57505083600195969710611d41575b505050811b019055565b015160001960f88460031b161c19169055388080611d37565b80600185968294968601518155019501930190611d22565b9391610402959361ffff611d94931686526060602087015260608601916119b2565b9260408185039101526119b2565b95919796929361ffff94611dc860e0979361010060058b528060208c01528a019061162a565b9960408901526060880152608087015260a086015260c085015216910152565b92936080929594611e0b61ffff936007875260a0602088015260a087019061162a565b966040860152606085015216910152565b908092918237016000815290565b6020908260405193849283378101600481520301902090565b611e5a611e4e6133fa565b6001600160a01b031690565b6001600160a01b03821690811491908215611f7a575b8215611f65575b8215611f50575b8215611f3b575b8215611f26575b8215611f10575b508115611e9e575090565b611ee19150602090611eb4611e4e611e4e6135fd565b6040516308651a8360e31b81526001600160a01b0390921660048301529092839190829081906024820190565b03915afa908115610e6c57600091611ef7575090565b610402915060203d602011610e6557610e57818361077f565b909150611f1e611e4e6135fd565b149038611e93565b9150611f33611e4e6135ab565b821491611e8c565b9150611f48611e4e613559565b821491611e85565b9150611f5d611e4e61350e565b821491611e7e565b9150611f72611e4e6134c4565b821491611e77565b9150611f87611e4e61347d565b821491611e70565b90604051611f9c81610731565b6020611fb660018395611fae81611585565b855201611585565b910152565b93611ff8608094611fea612006949599989960018060a01b03809716895260a060208a015260a089019061162a565b90878203604089015261162a565b90858203606087015261162a565b9416910152565b9161203690612028610402959360608652606086019061162a565b90848203602086015261162a565b91604081840391015261162a565b90602061040292818152019061162a565b906120816120718461ffff166000526002602052604060002090565b6001600052602052604060002090565b549384156121f5576120a96120a48561ffff166000526003602052604060002090565b611f8f565b6120be828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f000000000000000000000000be406f0189a0b4cf3a05c286473d23791dd44cc68616803b1561022157876000936121229560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c576121e2575b50827f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e31169151905190823b15610221576121889260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff936001986121c9575b506040519384931696169482612044565b0390a490565b806121d66121dc92610751565b8061049f565b386121b2565b806121d66121ef92610751565b38612131565b60405163056a947960e11b815260016004820152602490fd5b9061223a61222a8461ffff166000526002602052604060002090565b600c600052602052604060002090565b549384156123895761225d6120a48561ffff166000526003602052604060002090565b612272828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f000000000000000000000000be406f0189a0b4cf3a05c286473d23791dd44cc68616803b1561022157876000936122d69560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c57612376575b50827f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e31169151905190823b156102215761233c9260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff93600c986121c957506040519384931696169482612044565b806121d661238392610751565b386122e5565b60405163056a947960e11b8152600c6004820152602490fd5b906123ce6123be8461ffff166000526002602052604060002090565b6004600052602052604060002090565b5493841561251d576123f16120a48561ffff166000526003602052604060002090565b612406828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f000000000000000000000000be406f0189a0b4cf3a05c286473d23791dd44cc68616803b15610221578760009361246a9560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c5761250a575b50827f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e31169151905190823b15610221576124d09260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff936004986121c957506040519384931696169482612044565b806121d661251792610751565b38612479565b60405163056a947960e11b8152600480820152602490fd5b906125616125518461ffff166000526002602052604060002090565b6009600052602052604060002090565b549384156126b0576125846120a48561ffff166000526003602052604060002090565b612599828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f000000000000000000000000be406f0189a0b4cf3a05c286473d23791dd44cc68616803b1561022157876000936125fd9560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c5761269d575b50827f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e31169151905190823b15610221576126639260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff936009986121c957506040519384931696169482612044565b806121d66126aa92610751565b3861260c565b60405163056a947960e11b815260096004820152602490fd5b906126f56126e58461ffff166000526002602052604060002090565b600f600052602052604060002090565b54938415612844576127186120a48561ffff166000526003602052604060002090565b61272d828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f000000000000000000000000be406f0189a0b4cf3a05c286473d23791dd44cc68616803b1561022157876000936127919560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c57612831575b50827f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e31169151905190823b15610221576127f79260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff93600f986121c957506040519384931696169482612044565b806121d661283e92610751565b386127a0565b60405163056a947960e11b8152600f6004820152602490fd5b906128896128798461ffff166000526002602052604060002090565b6005600052602052604060002090565b549384156129d8576128ac6120a48561ffff166000526003602052604060002090565b6128c1828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f000000000000000000000000be406f0189a0b4cf3a05c286473d23791dd44cc68616803b1561022157876000936129259560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c576129c5575b50827f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e31169151905190823b156102215761298b9260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff936005986121c957506040519384931696169482612044565b806121d66129d292610751565b38612934565b60405163056a947960e11b815260056004820152602490fd5b90612a1d612a0d8461ffff166000526002602052604060002090565b600e600052602052604060002090565b54938415612b6c57612a406120a48561ffff166000526003602052604060002090565b612a55828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f000000000000000000000000be406f0189a0b4cf3a05c286473d23791dd44cc68616803b156102215787600093612ab99560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c57612b59575b50827f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e31169151905190823b1561022157612b1f9260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff93600e986121c957506040519384931696169482612044565b806121d6612b6692610751565b38612ac8565b60405163056a947960e11b8152600e6004820152602490fd5b90612bb1612ba18461ffff166000526002602052604060002090565b6007600052602052604060002090565b54938415612d0057612bd46120a48561ffff166000526003602052604060002090565b612be9828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f000000000000000000000000be406f0189a0b4cf3a05c286473d23791dd44cc68616803b156102215787600093612c4d9560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c57612ced575b50827f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e31169151905190823b1561022157612cb39260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff936007986121c957506040519384931696169482612044565b806121d6612cfa92610751565b38612c5c565b60405163056a947960e11b815260076004820152602490fd5b90612d45612d358461ffff166000526002602052604060002090565b600d600052602052604060002090565b54938415612e9457612d686120a48561ffff166000526003602052604060002090565b612d7d828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f000000000000000000000000be406f0189a0b4cf3a05c286473d23791dd44cc68616803b156102215787600093612de19560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c57612e81575b50827f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e31169151905190823b1561022157612e479260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff93600d986121c957506040519384931696169482612044565b806121d6612e8e92610751565b38612df0565b60405163056a947960e11b8152600d6004820152602490fd5b90612ed9612ec98461ffff166000526002602052604060002090565b600b600052602052604060002090565b5493841561302857612efc6120a48561ffff166000526003602052604060002090565b612f11828251978560208501998a5190613652565b8151875191976001600160a01b03949092917f000000000000000000000000be406f0189a0b4cf3a05c286473d23791dd44cc68616803b156102215787600093612f759560405196879586948593630c93e3bb60e01b855230923060048701611fbb565b03925af18015610e6c57613015575b50827f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e31169151905190823b1561022157612fdb9260009283879360405196879586948593631c92115f60e01b85526004850161200d565b03925af1948515610e6c576121c3600080516020613fd08339815191529361ffff93600b986121c957506040519384931696169482612044565b806121d661302292610751565b38612f84565b60405163056a947960e11b8152600b6004820152602490fd5b6000546001600160a01b0316330361305557565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b604051906130a682610731565b60018252600360fc1b6020830152565b90816020910312610221575190565b91926130f261040296946130e46131009460a0875260a087019061162a565b90858203602087015261162a565b90838203604085015261162a565b926060820152608081840391015261162a565b919061315f60209261ffff83166000526003845261314c6131376040600020611f8f565b9361ffff166000526002602052604060002090565b9061ffff16600052602052604060002090565b549061318f83825192015192613173613099565b906040519687958695630135eaa760e41b8752600487016130c5565b03817f000000000000000000000000be406f0189a0b4cf3a05c286473d23791dd44cc66001600160a01b03165afa908115610e6c576000916131cf575090565b610402915060203d6020116131f1575b6131e9818361077f565b8101906130b6565b503d6131df565b3d15613223573d90613209826107a0565b91613217604051938461077f565b82523d6000602084013e565b606090565b60405160208101908082106001600160401b0383111761074c576000938493848094938194604052525af161325b6131f8565b501561326357565b60405162461bcd60e51b815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527308115512081d1c985b9cd9995c8819985a5b195960621b6064820152608490fd5b91909394926132df6132d78685611e2a565b5461ffff1690565b9461ffff8616156133e85761331c916133096120a48861ffff166000526003602052604060002090565b9360405193849160208301938491611e1c565b0392613330601f199485810183528261077f565b51902060208401516040516133598161334d60208201809561148d565b0386810183528261077f565b51902014159384613394575b50505050613382576115c79261337c9136916107bb565b90613968565b604051635bb95f3d60e11b8152600490fd5b6133b291929394506133be9060405192839160208301958691611e1c565b0384810183528261077f565b5190209151906133da604051918261114f60208201809661148d565b519020141538808080613365565b6040516378ccabe760e01b8152600490fd5b6001546040516321f8a72160e01b81526c2bb930b83832b229bcb73a343960991b600482015290602090829060249082906001600160a01b03165afa908115610e6c57600091613448575090565b90506020813d602011613475575b816134636020938361077f565b81010312610221575161040281610210565b3d9150613456565b6001546040516321f8a72160e01b81526524b9b9bab2b960d11b600482015290602090829060249082906001600160a01b03165afa908115610e6c57600091613448575090565b6001546040516321f8a72160e01b81526822bc31b430b733b2b960b91b600482015290602090829060249082906001600160a01b03165afa908115610e6c57600091613448575090565b6001546040516321f8a72160e01b815269053796e746872537761760b41b600482015290602090829060249082906001600160a01b03165afa908115610e6c57600091613448575090565b6001546040516321f8a72160e01b8152700a6f2dce8d0e4a6eec2e0aed2e8d088caf607b1b600482015290602090829060249082906001600160a01b03165afa908115610e6c57600091613448575090565b6001546040516321f8a72160e01b81527027b33321b430b4b722bc31b430b733b2b960791b600482015290602090829060249082906001600160a01b03165afa908115610e6c57600091613448575090565b6001546040516321f8a72160e01b815273233aba3ab932b9a6b0b935b2ba26b0b730b3b2b960611b600482015290602090829060249082906001600160a01b03165afa908115610e6c57600091613448575090565b61367f602093969594613663613099565b906040519889958695630135eaa760e41b8752600487016130c5565b03817f000000000000000000000000be406f0189a0b4cf3a05c286473d23791dd44cc66001600160a01b03165afa928315610e6c576000936136e7575b50828082106136c9575050565b6044925060405191631cf7a67960e11b835260048301526024820152fd5b61370191935060203d6020116131f1576131e9818361077f565b91386136bc565b51906115c782610226565b81601f82011215610221578051613729816107a0565b92613737604051948561077f565b8184526020828401011161022157610402916020808501910161146a565b9190916101008184031261022157805161376e81610226565b926020820151906001600160401b0382116102215761378e918301613713565b9160408201519160608101519160808201519160a08101519160e060c08301516137b781610226565b92015190565b91909161014081840312610221576137d481613708565b9260208201516001600160401b039081811161022157826137f6918501613713565b9360408401519360608101519360808201519360a08301519361381b60c08501613708565b9360e081015193610100820151848111610221578161383b918401613713565b93610120830151908111610221576104029201613713565b9360e095919361040298979360018060a01b03809616875260208701526040860152606085015260808401521660a08201528160c0820152019061162a565b90916060828403126102215781516138a981610226565b9260208301516001600160401b038111610221576040916137b7918501613713565b9190916080818403126102215780516138e381610226565b926020820151906001600160401b03821161022157613903918301613713565b916060604083015192015190565b909160e08284031261022157815161392881610226565b926020830151906001600160401b03821161022157613948918401613713565b9160408101519160608201519160808101519160c060a083015192015190565b906020908181019283519261ffff928385169460028614600014613a4457509461399a91866139a397510101906138cb565b92509590613f7f565b946139b2611e4e611e4e61347d565b91823b1561022157604051631a4ac9bf60e21b81526001600160a01b038816600482015260248101929092526044820152906000908290606490829084905af18015610e6c57613a31575b505b16916001600160a01b03167fa3a26805904503468e23304f9bd1cdaddc39bac907d3ce175f35a1d1771d9f93600080a4565b806121d6613a3e92610751565b386139fd565b60038603613add57509461399a9186613a6097510101906138cb565b94613a6f611e4e611e4e6133fa565b91823b15610221576040516358ff317f60e11b81526001600160a01b03881660048201819052602482015260448101929092526064820152906000908290818381608481015b03925af18015610e6c57613aca575b506139ff565b806121d6613ad792610751565b38613ac4565b60058603613b58575094613af99186613b069751010190613911565b5094509792915050613f7f565b94613b15611e4e611e4e6134c4565b91823b1561022157604051630a77839d60e11b81526001600160a01b03881660048201526024810192909252604482015290600090829081838160648101613ab5565b60068603613bd357509461399a9186613b7497510101906138cb565b94613b83611e4e611e4e6133fa565b91823b1561022157604051630533242960e31b81526001600160a01b038816600482015260248101929092526044820152906000908290606490829084905af18015610e6c57613aca57506139ff565b60078603613c4157509461399a9186613bef97510101906138cb565b94613bfe611e4e611e4e61347d565b91823b1561022157604051631a4ac9bf60e21b81526001600160a01b03881660048201526024810192909252604482015290600090829081838160648101613ab5565b600a8603613cca575094613c5d9186613c659751010190613892565b959150613f7f565b93613c74611e4e611e4e61347d565b803b1561022157604051631a4ac9bf60e21b81526001600160a01b0387166004820152631cd554d160e21b602482015260448101929092526000908290606490829084905af18015610e6c57613aca57506139ff565b600b8603613d6b575081613d37613d03613cef613d0b998486600097510101906137bd565b969850939b96915050979297969096613f7f565b9d8e93613f7f565b613d19611e4e611e4e61350e565b966040519a8b998a9889976314cf934360e11b895260048901613853565b03925af18015610e6c57613d4d575b50506139ff565b81613d6392903d10610e6557610e57818361077f565b503880613d46565b600c8603613e08575094613d879186613d969751010190613755565b50509390945097909197613f7f565b96613da5611e4e611e4e61350e565b90813b15610221576040516315491d7d60e21b81526001600160a01b038a166004820152602481019190915260448101929092526064820193909352608481019190915290600090829060a490829084905af18015610e6c57613aca57506139ff565b909590600d8603613e5c575081613d37613d03613cef600094848b613e309c510101906137bd565b613e3e611e4e611e4e61350e565b966040519a8b998a988997631077bc3b60e01b895260048901613853565b958296600e8714600014613ee65750613e8c918382613e7e9351010190613755565b5050929a9450949092613f7f565b9860008a613d37613ea1611e4e611e4e613559565b946040519889978896879563b4c4dff960e01b8752600487019192608093969594919660a084019760018060a01b031684526020840152604083015260608201520152565b91925090600f8603613f615750613e7e86928383613f079451010190613755565b9860008a613d37613f1c611e4e611e4e613559565b946040519889978896879563b9eacb7560e01b8752600487019192608093969594919660a084019760018060a01b031684526020840152604083015260608201520152565b604051634f18ccbb60e11b815261ffff919091166004820152602490fd5b6014815110613f92576020015160601c90565b60405162461bcd60e51b8152602060048201526015602482015274746f416464726573735f6f75744f66426f756e647360581b6044820152606490fdfef34f07c5b9fc3912963edcdd4888dd8a9a13cd778c9451ca3f0335c2a32278fea26469706673582212206f366ecb69fa148e7327cfa4d94ab211d54c4c571a9b35f8c84d7216172e956064736f6c63430008180033

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

000000000000000000000000e432150cce91c13a887f7d836923d5597add8e31000000000000000000000000be406f0189a0b4cf3a05c286473d23791dd44cc6

-----Decoded View---------------
Arg [0] : _selfAxelarGateway (address): 0xe432150cce91c13a887f7D836923d5597adD8E31
Arg [1] : _selfGasReceiver (address): 0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000e432150cce91c13a887f7d836923d5597add8e31
Arg [1] : 000000000000000000000000be406f0189a0b4cf3a05c286473d23791dd44cc6


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ 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.