Sepolia Testnet

Contract

0xD63F8e2FfE633945Bc107E35c391006Bf212D1c1

Overview

ETH Balance

0 ETH

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Burn Synths72349272024-12-08 6:05:123 mins ago1733637912IN
0xD63F8e2F...Bf212D1c1
0.0004069 ETH0.000546891.60904718
Burn Synths72349232024-12-08 6:04:244 mins ago1733637864IN
0xD63F8e2F...Bf212D1c1
0 ETH0.000373281.62422919
Exchange Atomica...72348912024-12-08 5:57:3611 mins ago1733637456IN
0xD63F8e2F...Bf212D1c1
0.00081429 ETH0.001010541.78125409
Exchange Atomica...72345062024-12-08 4:35:481 hr ago1733632548IN
0xD63F8e2F...Bf212D1c1
0.00081429 ETH0.000737281.62871275
Exchange Atomica...72343062024-12-08 3:52:482 hrs ago1733629968IN
0xD63F8e2F...Bf212D1c1
0.00081429 ETH0.000679751.50171242
Exchange Atomica...72342342024-12-08 3:38:002 hrs ago1733629080IN
0xD63F8e2F...Bf212D1c1
0 ETH0.000367341.50031344
Exchange Atomica...72341842024-12-08 3:27:122 hrs ago1733628432IN
0xD63F8e2F...Bf212D1c1
0.00131005 ETH0.000923481.50008175
Stake Collateral72340012024-12-08 2:48:483 hrs ago1733626128IN
0xD63F8e2F...Bf212D1c1
0.0004069 ETH0.000000350.00101285
Stake Collateral72339422024-12-08 2:36:123 hrs ago1733625372IN
0xD63F8e2F...Bf212D1c1
0.0004069 ETH0.000000340.00101462
Burn Synths72339252024-12-08 2:32:363 hrs ago1733625156IN
0xD63F8e2F...Bf212D1c1
0.0004069 ETH0.000000340.00101996
Stake Collateral72337372024-12-08 1:52:484 hrs ago1733622768IN
0xD63F8e2F...Bf212D1c1
0.0004069 ETH0.000539591.50000006
Exchange Atomica...72335492024-12-08 1:13:124 hrs ago1733620392IN
0xD63F8e2F...Bf212D1c1
0.00081429 ETH0.000000640.00100008
Exchange Atomica...72335452024-12-08 1:12:244 hrs ago1733620344IN
0xD63F8e2F...Bf212D1c1
0.00081429 ETH0.000000560.00100007
Exchange Atomica...72334072024-12-08 0:44:125 hrs ago1733618652IN
0xD63F8e2F...Bf212D1c1
0.00264063 ETH0.000000620.00101001
Stake Collateral72332912024-12-08 0:19:245 hrs ago1733617164IN
0xD63F8e2F...Bf212D1c1
0.0004069 ETH0.000513921.50000001
Stake Collateral72332512024-12-08 0:11:125 hrs ago1733616672IN
0xD63F8e2F...Bf212D1c1
0.0004069 ETH0.000539591.50000001
Stake Collateral72332212024-12-08 0:05:006 hrs ago1733616300IN
0xD63F8e2F...Bf212D1c1
0.0004069 ETH0.000532411.50000001
Burn Synths72331482024-12-07 23:49:126 hrs ago1733615352IN
0xD63F8e2F...Bf212D1c1
0.0004069 ETH0.00000040.00120001
Stake Collateral72330092024-12-07 23:19:366 hrs ago1733613576IN
0xD63F8e2F...Bf212D1c1
0.00271542 ETH0.000282041.50000001
Exchange Atomica...72329422024-12-07 23:05:127 hrs ago1733612712IN
0xD63F8e2F...Bf212D1c1
0.00081429 ETH0.000000530.00100001
Burn Synths72329392024-12-07 23:04:367 hrs ago1733612676IN
0xD63F8e2F...Bf212D1c1
0.0004069 ETH0.000000330.00100001
Exchange Atomica...72329172024-12-07 22:59:247 hrs ago1733612364IN
0xD63F8e2F...Bf212D1c1
0.00081429 ETH0.000678981.50000001
Exchange Atomica...72329092024-12-07 22:57:367 hrs ago1733612256IN
0xD63F8e2F...Bf212D1c1
0.00081429 ETH0.000829281.50000001
Stake Collateral72329072024-12-07 22:57:127 hrs ago1733612232IN
0xD63F8e2F...Bf212D1c1
0.0004069 ETH0.000506741.50000001
Stake Collateral72328802024-12-07 22:51:127 hrs ago1733611872IN
0xD63F8e2F...Bf212D1c1
0.0004069 ETH0.000506761.50000001
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
72349272024-12-08 6:05:123 mins ago1733637912
0xD63F8e2F...Bf212D1c1
0.0004069 ETH
72348912024-12-08 5:57:3611 mins ago1733637456
0xD63F8e2F...Bf212D1c1
0.00081429 ETH
72345062024-12-08 4:35:481 hr ago1733632548
0xD63F8e2F...Bf212D1c1
0.00081429 ETH
72343062024-12-08 3:52:482 hrs ago1733629968
0xD63F8e2F...Bf212D1c1
0.00081429 ETH
72341842024-12-08 3:27:122 hrs ago1733628432
0xD63F8e2F...Bf212D1c1
0.00131005 ETH
72340012024-12-08 2:48:483 hrs ago1733626128
0xD63F8e2F...Bf212D1c1
0.0004069 ETH
72339422024-12-08 2:36:123 hrs ago1733625372
0xD63F8e2F...Bf212D1c1
0.0004069 ETH
72339252024-12-08 2:32:363 hrs ago1733625156
0xD63F8e2F...Bf212D1c1
0.0004069 ETH
72337372024-12-08 1:52:484 hrs ago1733622768
0xD63F8e2F...Bf212D1c1
0.0004069 ETH
72335492024-12-08 1:13:124 hrs ago1733620392
0xD63F8e2F...Bf212D1c1
0.00081429 ETH
72335452024-12-08 1:12:244 hrs ago1733620344
0xD63F8e2F...Bf212D1c1
0.00081429 ETH
72334072024-12-08 0:44:125 hrs ago1733618652
0xD63F8e2F...Bf212D1c1
0.00264063 ETH
72332912024-12-08 0:19:245 hrs ago1733617164
0xD63F8e2F...Bf212D1c1
0.0004069 ETH
72332512024-12-08 0:11:125 hrs ago1733616672
0xD63F8e2F...Bf212D1c1
0.0004069 ETH
72332212024-12-08 0:05:006 hrs ago1733616300
0xD63F8e2F...Bf212D1c1
0.0004069 ETH
72331482024-12-07 23:49:126 hrs ago1733615352
0xD63F8e2F...Bf212D1c1
0.0004069 ETH
72330092024-12-07 23:19:366 hrs ago1733613576
0xD63F8e2F...Bf212D1c1
0.00271542 ETH
72329422024-12-07 23:05:127 hrs ago1733612712
0xD63F8e2F...Bf212D1c1
0.00081429 ETH
72329392024-12-07 23:04:367 hrs ago1733612676
0xD63F8e2F...Bf212D1c1
0.0004069 ETH
72329172024-12-07 22:59:247 hrs ago1733612364
0xD63F8e2F...Bf212D1c1
0.00081429 ETH
72329092024-12-07 22:57:367 hrs ago1733612256
0xD63F8e2F...Bf212D1c1
0.00081429 ETH
72329072024-12-07 22:57:127 hrs ago1733612232
0xD63F8e2F...Bf212D1c1
0.0004069 ETH
72328802024-12-07 22:51:127 hrs ago1733611872
0xD63F8e2F...Bf212D1c1
0.0004069 ETH
72328712024-12-07 22:49:247 hrs ago1733611764
0xD63F8e2F...Bf212D1c1
0.0004069 ETH
72328522024-12-07 22:45:367 hrs ago1733611536
0xD63F8e2F...Bf212D1c1
0.0004069 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
WrappedSynthrLightChain

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 20 : WrappedSynthrLightChain.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

// Inheritance
import "./BaseWrappedSynthr.sol";
import "./ExternWrappedStateTokenLightChain.sol";
import "./SafeDecimalMath.sol";
import "../interfaces/IExchanger.sol";

// Internal references
import "../libraries/TransferHelper.sol";

contract WrappedSynthrLightChain is BaseWrappedSynthr {
    using SafeMath for uint256;
    using SafeDecimalMath for uint256;

    bytes32 public constant CONTRACT_NAME = "Wrapped Synthr";
    uint16 private constant PT_DEPOSIT_COLLATERAL = 1; // staking collateral
    uint16 internal constant PT_BURN_SYNTH = 4;
    uint16 internal constant PT_TRANSFER_MARGIN_SYNTH = 9;

    // ========== CONSTRUCTOR ==========
    constructor(
        ExternWrappedStateTokenLightChain _extTokenState,
        address _owner,
        address _resolver
    ) BaseWrappedSynthr(_extTokenState, _owner, _resolver) {}

    // ========== VIEWS ==========

    function balanceOf(address account) external view returns (uint256) {
        uint256 synthrBalance;
        bytes32[] memory availableCollateralCurrencies = extTokenState.getAvailableCollaterals();
        for (uint256 ii = 0; ii < availableCollateralCurrencies.length; ii++) {
            bytes32 _collateralCurrencyKey = availableCollateralCurrencies[ii];
            if (extTokenState.collateralByIssuer(_collateralCurrencyKey, account) > 0) {
                (uint256 collateralRate, ) = exchangeRates().rateAndInvalid(_collateralCurrencyKey);
                synthrBalance = synthrBalance.add(
                    extTokenState
                        .collateralByIssuer(_collateralCurrencyKey, account)
                        .multiplyDecimal(collateralRate)
                );
            }
        }
        return synthrBalance;
    }

    function balanceOfPerKey(
        address _account,
        bytes32 _collateralKey
    ) external view returns (uint256) {
        (uint256 collateralRate, ) = exchangeRates().rateAndInvalid(_collateralKey);
        return
            extTokenState.collateralByIssuer(_collateralKey, _account).multiplyDecimal(
                collateralRate
            );
    }

    /**
     * @dev Calculates the gas fee for withdrawing collateral.
     * @param _account The address of the account.
     * @param _collateralKey The key of the collateral.
     * @param _collateralAmount The amount of collateral.
     * @param _bridgeName The name of the bridge.
     * @param _destChainId The ID of the destination chain.
     * @return The gas fee for withdrawing collateral.
     */
    function getSendStakingGasFee(
        address _account,
        bytes32 _collateralKey,
        uint256 _collateralAmount,
        bytes32 _bridgeName,
        uint16 _destChainId
    ) external view returns (uint256) {
        bytes memory lzPayload = abi.encode(
            PT_DEPOSIT_COLLATERAL,
            abi.encodePacked(_account),
            _collateralKey,
            _collateralAmount
        );
        return synthrBridge(_bridgeName).calcFee(lzPayload, PT_DEPOSIT_COLLATERAL, _destChainId);
    }

    /**
     * @dev Returns the gas fee for sending and burning a specific amount of a synthetic asset on a different chain.
     * @param _account The address of the account initiating the transaction.
     * @param _synthKey The key of the synthetic asset.
     * @param _synthAmount The amount of the synthetic asset to be burned.
     * @param _bridgeName The name of the bridge contract.
     * @param _destChainId The ID of the destination chain.
     * @return The gas fee for the transaction.
     */
    function getSendBurnGasFee(
        address _account,
        bytes32 _synthKey,
        uint256 _synthAmount,
        bytes32 _bridgeName,
        uint16 _destChainId
    ) external view returns (uint256) {
        bytes memory lzPayload = abi.encode(
            PT_BURN_SYNTH,
            abi.encodePacked(_account),
            _synthKey,
            _synthAmount
        );
        return synthrBridge(_bridgeName).calcFee(lzPayload, PT_BURN_SYNTH, _destChainId);
    }

    /**
     * @dev Returns the gas fee for sending a margin transfer on a different chain.
     * @param _account The address of the account initiating the transaction.
     * @param _marginDelta The change in margin value.
     * @param _marketKey The key of the market.
     * @param _bridgeName The name of the bridge contract.
     * @param _destChainId The ID of the destination chain.
     * @return The gas fee for the transaction.
     */
    function getSendTransferMargin(
        address _account,
        uint256 _marginDelta,
        bytes32 _marketKey,
        bytes32 _bridgeName,
        uint16 _destChainId
    ) external view returns (uint256) {
        bytes memory lzPayload = abi.encode(
            PT_TRANSFER_MARGIN_SYNTH,
            abi.encodePacked(_account),
            _marginDelta,
            _marketKey
        );
        return synthrBridge(_bridgeName).calcFee(lzPayload, PT_TRANSFER_MARGIN_SYNTH, _destChainId);
    }

    /* ========== MUTATIVE FUNCTIONS ========== */

    /**
     * @dev Function to exchange Synth tokens atomically.
     * @param sourceCurrencyKey The source currency key.
     * @param sourceAmount The source amount.
     * @param destinationCurrencyKey The destination currency key.
     * @param minAmount The minimum amount.
     * @param bridgeName The name of the bridge.
     * @param destChainId The ID of the destination chain.
     * @param erc20Payment The ERC20 payment flag.
     */
    function exchangeAtomically(
        bytes32 sourceCurrencyKey,
        uint256 sourceAmount,
        bytes32 destinationCurrencyKey,
        uint256 minAmount,
        bytes32 bridgeName,
        uint16 destChainId,
        bool erc20Payment
    )
        external
        payable
        exchangeActive(sourceCurrencyKey, destinationCurrencyKey)
        systemActive
        returns (uint256 amountReceived)
    {
        IExchanger.ExchangeArgs memory args = IExchanger.ExchangeArgs({
            fromAccount: msg.sender,
            destAccount: msg.sender,
            sourceCurrencyKey: sourceCurrencyKey,
            destCurrencyKey: destinationCurrencyKey,
            sourceAmount: sourceAmount,
            destAmount: 0,
            fee: 0,
            reclaimed: 0,
            refunded: 0,
            destChainId: destChainId,
            erc20Payment: erc20Payment
        });
        return exchanger().exchangeAtomically{value: msg.value}(minAmount, args, bridgeName);
    }

    /**
     * @dev Performs an off-chain exchange between two currencies.
     * @param sourceCurrencyKey The currency key of the source currency.
     * @param sourceAmount The amount of the source currency to exchange.
     * @param destinationCurrencyKey The currency key of the destination currency.
     * @param bridgeName The name of the bridge to use for the exchange.
     * @param priceUpdateData Additional data required for the price update.
     * @param destChainId The chain ID of the destination chain.
     * @param erc20Payment Flag indicating if the payment is in ERC20 tokens.
     * @return amountReceived The amount of the destination currency received after the exchange.
     */
    function offChainExchange(
        bytes32 sourceCurrencyKey,
        uint256 sourceAmount,
        bytes32 destinationCurrencyKey,
        bytes32 bridgeName,
        bytes[] calldata priceUpdateData,
        uint16 destChainId,
        bool erc20Payment
    )
        external
        payable
        exchangeActive(sourceCurrencyKey, destinationCurrencyKey)
        systemActive
        returns (uint256 amountReceived)
    {
        IExchanger.ExchangeArgs memory args = IExchanger.ExchangeArgs({
            fromAccount: msg.sender,
            destAccount: msg.sender,
            sourceCurrencyKey: sourceCurrencyKey,
            destCurrencyKey: destinationCurrencyKey,
            sourceAmount: sourceAmount,
            destAmount: 0,
            fee: 0,
            reclaimed: 0,
            refunded: 0,
            destChainId: destChainId,
            erc20Payment: erc20Payment
        });
        return offChainExchanger().exchange{value: msg.value}(args, bridgeName, priceUpdateData);
    }

    /**
     * @dev Settle the outstanding entries for a specific currency key.
     * @param currencyKey The currency key for which the entries will be settled.
     * @return reclaimed The amount of tokens reclaimed from the entries.
     * @return refunded The amount of tokens refunded from the entries.
     * @return numEntriesSettled The number of entries settled.
     */
    function settle(
        bytes32 currencyKey
    ) external returns (uint256 reclaimed, uint256 refunded, uint256 numEntriesSettled) {
        return exchanger().settle(msg.sender, currencyKey);
    }

    /**
     * @dev Transfer margin from the sender's account to the issuer's account and send the transfer details to the specified bridge.
     * @param marginDelta The change in margin amount.
     * @param marketKey The key of the market.
     * @param bridgeName The name of the bridge.
     * @param erc20Payment Flag indicating if the payment is in ERC20 tokens.
     */
    function transferMargin(
        uint256 marginDelta,
        bytes32 marketKey,
        bytes32 bridgeName,
        bool erc20Payment
    ) external payable issuanceActive systemActive {
        uint256 transferAmount = issuer().transferMargin(msg.sender, marginDelta);
        synthrBridge(bridgeName).sendTransferMargin{value: msg.value}(
            msg.sender,
            transferAmount,
            marketKey,
            erc20Payment
        );
        emit TransferMargin(msg.sender, transferAmount);
    }

    /**
     * @dev Burn synths from the sender's account and send the burn details to the specified bridge.
     * @param _amount The amount of synths to burn.
     * @param _synthKey The key of the synth.
     * @param _bridgeName The name of the bridge.
     * @param _erc20Payment Flag indicating if the payment is in ERC20 tokens.
     */
    function burnSynths(
        uint256 _amount,
        bytes32 _synthKey,
        bytes32 _bridgeName,
        bool _erc20Payment
    ) external payable issuanceActive systemActive {
        (uint256 synthAmount, , , ) = issuer().burnSynths(msg.sender, _synthKey, _amount);
        synthrBridge(_bridgeName).sendBurn{value: msg.value}(
            msg.sender,
            _synthKey,
            synthAmount,
            _erc20Payment
        );
        emit BurnSynth(msg.sender, _synthKey, synthAmount);
    }

    /**
     * @dev Stake collateral from the sender's account and send the staking details to the specified bridge.
     * @param _collateralKey The key of the collateral.
     * @param _collateralAmount The amount of collateral to stake.
     * @param _bridgeName The name of the bridge.
     * @param _erc20Payment Flag indicating if the payment is in ERC20 tokens.
     */
    function stakeCollateral(
        bytes32 _collateralKey,
        uint256 _collateralAmount,
        bytes32 _bridgeName,
        bool _erc20Payment
    ) external payable issuanceActive systemActive {
        require(_collateralAmount > 0, "Collateral amount must be larger than zero.");
        uint256 msgValueForGas = msg.value;
        _stakingCollateral(msg.sender, msg.sender, _collateralKey, _collateralAmount);
        if (extTokenState.collateralCurrency(_collateralKey) == NULL_ADDRESS) {
            require(msg.value > _collateralAmount, "Insufficient ETH amount.");
            msgValueForGas = msg.value - _collateralAmount;
        }

        synthrBridge(_bridgeName).sendDepositCollateral{value: msgValueForGas}(
            msg.sender,
            _collateralKey,
            _collateralAmount,
            _erc20Payment
        );
        return;
    }

    function _stakingCollateral(
        address from,
        address to,
        bytes32 _collateralKey,
        uint256 _collateralAmount
    ) internal {
        require(
            extTokenState.collateralCurrency(_collateralKey) != address(0),
            "No Collateral Currency exists."
        );
        if (extTokenState.collateralCurrency(_collateralKey) != NULL_ADDRESS) {
            TransferHelper.safeTransferFrom(
                extTokenState.collateralCurrency(_collateralKey),
                from,
                address(extTokenState),
                _collateralAmount
            );
        } else {
            TransferHelper.safeTransferETH(address(extTokenState), _collateralAmount);
        }

        bool isSucceed = _mint(to, _collateralAmount, _collateralKey);
        require(isSucceed, "Mint Synthr failed.");
        emit StakeCollateral(from, to, _collateralKey, _collateralAmount);
    }

    /**
     * @dev Allows a user to withdraw collateral from the WrappedSynthrLightChain contract.
     * @param _from The address of the user who wants to withdraw collateral.
     * @param _to The address where the withdrawn collateral will be transferred.
     * @param _collateralKey The key representing the type of collateral.
     * @param _collateralAmount The amount of collateral to be withdrawn.
     */
    function withdrawCollateral(
        address _from,
        address _to,
        bytes32 _collateralKey,
        uint256 _collateralAmount
    ) external issuanceActive systemActive onlySynthrBridge {
        require(_collateralAmount > 0, "Collateral amount must not be zero");
        require(
            extTokenState.collateralCurrency(_collateralKey) != address(0),
            "No Collateral Currency exists."
        );
        require(
            extTokenState.collateralByIssuer(_collateralKey, _from) >= _collateralAmount,
            "Insufficient Collateral Balance to withdraw."
        );
        extTokenState.withdrawCollateral(_to, _collateralKey, _collateralAmount);

        bool isSucceed = _burn(_from, _collateralAmount, _collateralKey);
        require(isSucceed, "Burn Synthr failed.");

        emit WithdrawCollateral(
            msg.sender,
            _collateralKey,
            extTokenState.collateralCurrency(_collateralKey),
            _collateralAmount
        );
    }

    // ========== EVENTS ==========
    event StakeCollateral(
        address indexed from,
        address indexed to,
        bytes32 collateralKey,
        uint256 collateralAmount
    );
    event WithdrawCollateral(
        address indexed from,
        bytes32 indexed collateralKey,
        address collateralCurrency,
        uint256 collateralAmount
    );
    event BurnSynth(address indexed from, bytes32 synthKey, uint256 synthAmount);
    event TransferMargin(address indexed account, uint256 transferAmount);
}

File 2 of 20 : SafeMath.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, "SafeMath: division by zero");
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, "SafeMath: modulo by zero");
        return a % b;
    }
}

File 3 of 20 : IAddressResolver.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

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

    function getSynth(bytes32 key) external view returns (address);

    function getAvailableBridge(bytes32 bridgeName) external view returns (address);

    function getBridgeList() external view returns (bytes32[] memory);

    function requireAndGetAddress(
        bytes32 name,
        string calldata reason
    ) external view returns (address);
}

File 4 of 20 : ICollateralManager.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

interface ICollateralManager {
    function depositeCollateral(
        address _from,
        address _collateralCurrency,
        uint256 _collateralAmount
    ) external payable;

    function withdrawCollateral(address _to, address _collateralCurrency, uint256 _amount) external;
}

File 5 of 20 : IERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

interface IERC20 {
    // ERC20 Optional Views
    function name() external view returns (string memory);

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

    function decimals() external view returns (uint8);

    // Views
    function totalSupply() external view returns (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender) external view returns (uint256);

    // Mutative functions
    function transfer(address to, uint256 value) external returns (bool);

    function approve(address spender, uint256 value) external returns (bool);

    function transferFrom(address from, address to, uint256 value) external returns (bool);

    // Events
    event Transfer(address indexed from, address indexed to, uint256 value);

    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 6 of 20 : IExchanger.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

interface IExchanger {
    struct ExchangeEntrySettlement {
        bytes32 src;
        uint256 amount;
        bytes32 dest;
        uint256 reclaim;
        uint256 rebate;
        uint256 srcRoundIdAtPeriodEnd;
        uint256 destRoundIdAtPeriodEnd;
        uint256 timestamp;
    }

    struct ExchangeEntry {
        uint256 sourceRate;
        uint256 destinationRate;
        uint256 destinationAmount;
        uint256 exchangeFeeRate;
        uint256 exchangeDynamicFeeRate;
        uint256 roundIdForSrc;
        uint256 roundIdForDest;
    }

    struct ExchangeArgs {
        address fromAccount;
        address destAccount;
        bytes32 sourceCurrencyKey;
        bytes32 destCurrencyKey;
        uint256 sourceAmount;
        uint256 destAmount;
        uint256 fee;
        uint256 reclaimed;
        uint256 refunded;
        uint16 destChainId;
        bool erc20Payment;
    }

    // Views
    function calculateAmountAfterSettlement(
        address from,
        bytes32 currencyKey,
        uint256 amount,
        uint256 refunded
    ) external view returns (uint256 amountAfterSettlement);

    function isSynthRateInvalid(bytes32 currencyKey) external view returns (bool);

    function maxSecsLeftInWaitingPeriod(
        address account,
        bytes32 currencyKey
    ) external view returns (uint256);

    function settlementOwing(
        address account,
        bytes32 currencyKey
    ) external view returns (uint256 reclaimAmount, uint256 rebateAmount, uint256 numEntries);

    // function hasWaitingPeriodOrSettlementOwing(address account, bytes32 currencyKey) external view returns (bool);

    function feeRateForExchange(
        bytes32 sourceCurrencyKey,
        bytes32 destinationCurrencyKey
    ) external view returns (uint256);

    function dynamicFeeRateForExchange(
        bytes32 sourceCurrencyKey,
        bytes32 destinationCurrencyKey
    ) external view returns (uint256 feeRate, bool tooVolatile);

    function getAmountsForExchange(
        uint256 sourceAmount,
        bytes32 sourceCurrencyKey,
        bytes32 destinationCurrencyKey
    ) external view returns (uint256 amountReceived, uint256 fee, uint256 exchangeFeeRate);

    // function priceDeviationThresholdFactor() external view returns (uint256);

    // function waitingPeriodSecs() external view returns (uint256);

    // function lastExchangeRate(bytes32 currencyKey) external view returns (uint256);

    // Mutative functions
    function exchange(
        ExchangeArgs calldata args,
        bytes32 bridgeName
    ) external payable returns (uint256 amountReceived);

    function exchangeAtomically(
        uint256 minAmount,
        ExchangeArgs calldata args,
        bytes32 bridgeName
    ) external payable returns (uint256 amountReceived);

    function settle(
        address from,
        bytes32 currencyKey
    ) external returns (uint256 reclaimed, uint256 refunded, uint256 numEntries);

    function suspendSynthWithInvalidRate(bytes32 currencyKey) external;

    function updateDestinationForExchange(
        address recipient,
        bytes32 destinationKey,
        uint256 destinationAmount
    ) external;
}

File 7 of 20 : IExchangeRates.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

interface IExchangeRates {
    // Structs
    struct RateAndUpdatedTime {
        uint216 rate;
        uint40 time;
    }

    // Views
    function aggregators(bytes32 currencyKey) external view returns (address);

    function aggregatorWarningFlags() external view returns (address);

    function anyRateIsInvalid(bytes32[] calldata currencyKeys) external view returns (bool);

    function anyRateIsInvalidAtRound(
        bytes32[] calldata currencyKeys,
        uint256[] calldata roundIds
    ) external view returns (bool);

    function currenciesUsingAggregator(address aggregator) external view returns (bytes32[] memory);

    function effectiveValue(
        bytes32 sourceCurrencyKey,
        uint256 sourceAmount,
        bytes32 destinationCurrencyKey
    ) external view returns (uint256 value);

    function effectiveValueAndRates(
        bytes32 sourceCurrencyKey,
        uint256 sourceAmount,
        bytes32 destinationCurrencyKey
    ) external view returns (uint256 value, uint256 sourceRate, uint256 destinationRate);

    function effectiveValueAndRatesAtRound(
        bytes32 sourceCurrencyKey,
        uint256 sourceAmount,
        bytes32 destinationCurrencyKey,
        uint256 roundIdForSrc,
        uint256 roundIdForDest
    ) external view returns (uint256 value, uint256 sourceRate, uint256 destinationRate);

    function effectiveAtomicValueAndRates(
        bytes32 sourceCurrencyKey,
        uint256 sourceAmount,
        bytes32 destinationCurrencyKey
    )
        external
        view
        returns (
            uint256 value,
            uint256 systemValue,
            uint256 systemSourceRate,
            uint256 systemDestinationRate
        );

    function getCurrentRoundId(bytes32 currencyKey) external view returns (uint256);

    function getLastRoundIdBeforeElapsedSecs(
        bytes32 currencyKey,
        uint256 startingRoundId,
        uint256 startingTimestamp,
        uint256 timediff
    ) external view returns (uint256);

    function lastRateUpdateTimes(bytes32 currencyKey) external view returns (uint256);

    function rateAndTimestampAtRound(
        bytes32 currencyKey,
        uint256 roundId
    ) external view returns (uint256 rate, uint256 time);

    function rateAndUpdatedTime(
        bytes32 currencyKey
    ) external view returns (uint256 rate, uint256 time);

    function rateAndInvalid(
        bytes32 currencyKey
    ) external view returns (uint256 rate, bool isInvalid);

    function rateForCurrency(bytes32 currencyKey) external view returns (uint256);

    function rateIsFlagged(bytes32 currencyKey) external view returns (bool);

    function rateIsInvalid(bytes32 currencyKey) external view returns (bool);

    function rateIsStale(bytes32 currencyKey) external view returns (bool);

    function rateStalePeriod() external view returns (uint256);

    function ratesAndUpdatedTimeForCurrencyLastNRounds(
        bytes32 currencyKey,
        uint256 numRounds,
        uint256 roundId
    ) external view returns (uint256[] memory rates, uint256[] memory times);

    function ratesAndInvalidForCurrencies(
        bytes32[] calldata currencyKeys
    ) external view returns (uint256[] memory rates, bool anyRateInvalid);

    function ratesForCurrencies(
        bytes32[] calldata currencyKeys
    ) external view returns (uint256[] memory);

    function synthTooVolatileForAtomicExchange(bytes32 currencyKey) external view returns (bool);

    function rateWithSafetyChecks(
        bytes32 currencyKey
    ) external returns (uint256 rate, bool broken, bool invalid);
}

File 8 of 20 : IIssuer.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

import "../interfaces/ISynth.sol";

interface IIssuer {
    // Views

    function allNetworksDebtInfo() external view returns (uint256 debt, uint256 sharesSupply);

    function availableCurrencyKeys() external view returns (bytes32[] memory);

    function availableSynthCount() external view returns (uint256);

    function availableSynths(uint256 index) external view returns (ISynth);

    function canBurnSynths(address account) external view returns (bool);

    function collateral(address account) external view returns (uint256);

    function collateralisationRatio(address issuer) external view returns (uint256);

    function collateralisationRatioAndAnyRatesInvalid(
        address _issuer
    ) external view returns (uint256 cratio, bool anyRateIsInvalid);

    function debtBalanceOf(address issuer) external view returns (uint256 debtBalance);

    function issuanceRatio() external view returns (uint256);

    function lastIssueEvent(address account) external view returns (uint256);

    function maxIssuableSynths(address issuer) external view returns (uint256 maxIssuable);

    function minimumStakeTime() external view returns (uint256);

    function remainingIssuableSynths(
        address issuer
    ) external view returns (uint256 maxIssuable, uint256 alreadyIssued, uint256 totalSystemDebt);

    function synths(bytes32 currencyKey) external view returns (ISynth);

    function getSynths(bytes32[] calldata currencyKeys) external view returns (ISynth[] memory);

    function synthsByAddress(address synthAddress) external view returns (bytes32);

    function totalIssuedSynths(bytes32 currencyKey) external view returns (uint256);

    function checkFreeCollateral(
        address _issuer,
        bytes32 _collateralKey,
        uint16 _chainId
    ) external view returns (uint256 withdrawableSynthr);

    function issueSynths(
        address from,
        uint256 amount,
        uint256 destChainId
    ) external returns (uint256 synthAmount, uint256 debtShare);

    function issueMaxSynths(
        address from,
        uint256 destChainId
    ) external returns (uint256 synthAmount, uint256 debtShare);

    function burnSynths(
        address from,
        bytes32 synthKey,
        uint256 amount
    )
        external
        returns (uint256 synthAmount, uint256 debtShare, uint256 reclaimed, uint256 refunded);

    function burnSynthsToTarget(
        address from,
        bytes32 synthKey
    )
        external
        returns (uint256 synthAmount, uint256 debtShare, uint256 reclaimed, uint256 refunded);

    function burnForRedemption(
        address deprecatedSynthProxy,
        address account,
        uint256 balance
    ) external;

    function burnSynthsWithoutDebt(
        bytes32 currencyKey,
        address from,
        uint amount
    ) external returns (uint256 burnAmount);

    function synthIssueFromSynthrSwap(
        address _account,
        bytes32 _synthKey,
        uint256 _synthAmount
    ) external;

    function liquidateAccount(
        address account,
        bytes32 collateralKey,
        uint16 chainId,
        bool isSelfLiquidation
    ) external returns (uint256 totalRedeemed, uint256 amountToLiquidate, uint256 sharesToRemove);

    function destIssue(address _account, bytes32 _synthKey, uint256 _synthAmount) external;

    function destBurn(
        address _account,
        bytes32 _synthKey,
        uint256 _synthAmount
    ) external returns (uint256);

    function transferMargin(address account, uint256 marginDelta) external returns (uint256);

    function destTransferMargin(
        address _account,
        uint256 _marginDelta,
        bytes32 _marketKey
    ) external returns (bool);

    function setCurrentPeriodId(uint128 periodId) external;
}

File 9 of 20 : IOffChainExchanger.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

import "./IExchanger.sol";

interface IOffChainExchanger {
    // Views
    function offchainPriceMaxAge(bytes32 _currencyKey) external view returns (uint256);

    function offchainPriceMinAge(bytes32 _currencyKey) external view returns (uint256);

    function offchainPriceDivergence(bytes32 _currencyKey) external view returns (uint256);

    function feeRateForOffChainExchange(
        bytes32 sourceCurrencyKey,
        bytes32 destinationCurrencyKey
    ) external view returns (uint256);

    function getAmountsForOffChainExchangeMinusFees(
        bytes32 _sourceKey,
        bytes32 _destKey,
        uint256 _destAmount
    ) external view returns (uint256 amountReceived, uint256 fee);

    // Mutative functions
    function exchange(
        IExchanger.ExchangeArgs calldata args,
        bytes32 bridgeName,
        bytes[] calldata priceUpdateData
    ) external payable returns (uint256 amountReceived);

    function updateDestinationForExchange(
        address recipient,
        bytes32 destinationKey,
        uint256 destinationAmount
    ) external;

    function exchangeForDexAggregation(
        address _account,
        bytes32 _sourceKey,
        bytes32 _destKey,
        uint256 _sourceAmount,
        bytes[] memory _priceUpdateData,
        uint16 _destChainId
    ) external payable returns (uint256 destAmount, uint256 fee);
}

File 10 of 20 : ISynth.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

interface ISynth {
    // Views
    function balanceOf(address _account) external view returns (uint256);

    function currencyKey() external view returns (bytes32);

    function transferableSynths(address account) external view returns (uint256);

    // Mutative functions
    function transferAndSettle(address to, uint256 value) external payable returns (bool);

    function transferFromAndSettle(
        address from,
        address to,
        uint256 value
    ) external payable returns (bool);

    function burn(address account, uint256 amount) external;

    function issue(address account, uint256 amount) external;
}

File 11 of 20 : ISynthrBridgeLightChain.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

import "./IExchanger.sol";

interface ISynthrBridge {
    /* ========== MUTATIVE FUNCTIONS ========== */
    function sendDepositCollateral(
        address account,
        bytes32 collateralKey,
        uint256 amount,
        bool erc20Payment
    ) external payable;

    function sendBurn(
        address account,
        bytes32 synthKey,
        uint256 amount,
        bool erc20Payment
    ) external payable;

    function sendExchange(
        address account,
        bytes32 srcSynthKey,
        bytes32 dstSynthKey,
        uint256 srcAmount,
        uint256 dstAmount,
        uint256 reclaimed,
        uint256 refunded,
        uint256 fee,
        uint16 dstChainId,
        bool erc20Payment
    ) external payable;

    function sendBridgeSyToken(
        address account,
        bytes32 synthKey,
        uint256 amount,
        uint16 dstChainId,
        bool erc20Payment
    ) external payable;

    function sendTransferMargin(
        address account,
        uint256 amount,
        bytes32 marketKey,
        bool erc20Payment
    ) external payable;

    function sendCrossSwapSyAssetToNative(
        address account,
        bytes32 srcKey,
        uint256 srcAmount,
        bytes32 dstKey,
        uint256 dstAmount,
        uint16 dstChainId,
        uint256 fee,
        bytes calldata dexPayload,
        address dexAddress,
        bool erc20Payment
    ) external payable;

    function sendCrossSwapNativeToSyAsset(
        address account,
        bytes32 srcKey,
        uint256 srcAmount,
        bytes32 dstKey,
        uint256 dstAmount,
        uint16 dstChainId,
        uint256 fee,
        bool erc20Payment
    ) external payable;

    function sendCrossSwapNativeToNative(
        address account,
        bytes32 srcKey,
        uint256 srcAmount,
        bytes32 dstKey,
        uint256 dstAmount,
        uint16 dstChainId,
        uint256 fee,
        address dexAddress,
        bytes calldata dexPayload,
        bool erc20Payment
    ) external payable;

    function sendCrossSwapSyAssetToNativeWithDex(
        address account,
        bytes32 srcKey,
        uint256 srcAmount,
        bytes32 dstKey,
        uint256 dstAmount,
        uint16 dstChainId,
        uint256 fee,
        bool erc20Payment
    ) external payable;

    function sendCrossSwapNativeToNativeWithDex(
        address account,
        bytes32 srcKey,
        uint256 srcAmount,
        bytes32 dstKey,
        uint256 dstAmount,
        uint16 dstChainId,
        uint256 fee,
        bool erc20Payment
    ) external payable;

    // function sendExchange(IExchanger.ExchangeArgs calldata args) external payable;

    function calcFee(
        bytes memory lzPayload,
        uint16 packetType,
        uint16 dstChainId
    ) external view returns (uint256 lzFee);
}

File 12 of 20 : ISystemStatus.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

interface ISystemStatus {
    struct Status {
        bool canSuspend;
        bool canResume;
    }

    struct Suspension {
        bool suspended;
        // reason is an integer code,
        // 0 => no reason, 1 => upgrading, 2+ => defined by system usage
        uint248 reason;
    }

    // Views
    function accessControl(
        bytes32 section,
        address account
    ) external view returns (bool canSuspend, bool canResume);

    function requireSystemActive() external view;

    function systemSuspended() external view returns (bool);

    function requireIssuanceActive() external view;

    function requireExchangeActive() external view;

    function requireFuturesActive() external view;

    function requireFuturesMarketActive(bytes32 marketKey) external view;

    function requireExchangeBetweenSynthsAllowed(
        bytes32 sourceCurrencyKey,
        bytes32 destinationCurrencyKey
    ) external view;

    function requireSynthActive(bytes32 currencyKey) external view;

    function synthSuspended(bytes32 currencyKey) external view returns (bool);

    function requireSynthsActive(
        bytes32 sourceCurrencyKey,
        bytes32 destinationCurrencyKey
    ) external view;

    function systemSuspension() external view returns (bool suspended, uint248 reason);

    function issuanceSuspension() external view returns (bool suspended, uint248 reason);

    function exchangeSuspension() external view returns (bool suspended, uint248 reason);

    function futuresSuspension() external view returns (bool suspended, uint248 reason);

    function synthExchangeSuspension(
        bytes32 currencyKey
    ) external view returns (bool suspended, uint248 reason);

    function synthSuspension(
        bytes32 currencyKey
    ) external view returns (bool suspended, uint248 reason);

    function futuresMarketSuspension(
        bytes32 marketKey
    ) external view returns (bool suspended, uint248 reason);

    function getSynthExchangeSuspensions(
        bytes32[] calldata synths
    ) external view returns (bool[] memory exchangeSuspensions, uint256[] memory reasons);

    function getSynthSuspensions(
        bytes32[] calldata synths
    ) external view returns (bool[] memory suspensions, uint256[] memory reasons);

    function getFuturesMarketSuspensions(
        bytes32[] calldata marketKeys
    ) external view returns (bool[] memory suspensions, uint256[] memory reasons);

    // Restricted functions
    function suspendIssuance(uint256 reason) external;

    function suspendSynth(bytes32 currencyKey, uint256 reason) external;

    function suspendFuturesMarket(bytes32 marketKey, uint256 reason) external;

    function updateAccessControl(
        bytes32 section,
        address account,
        bool canSuspend,
        bool canResume
    ) external;
}

File 13 of 20 : TransferHelper.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

// from Uniswap TransferHelper library
library TransferHelper {
    function safeApprove(address token, address to, uint256 value) internal {
        // bytes4(keccak256(bytes('approve(address,uint256)')));
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(0x095ea7b3, to, value)
        );
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            "TransferHelper::safeApprove: approve failed"
        );
    }

    function safeTransfer(address token, address to, uint256 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 safeTransferFrom(address token, address from, address to, uint256 value) internal {
        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(0x23b872dd, from, to, value)
        );
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            "TransferHelper::transferFrom: transferFrom failed"
        );
    }

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

File 14 of 20 : AddressResolverLightChain.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

// Inheritance
import "./Owned.sol";
import "../interfaces/IAddressResolver.sol";

// Internal references
import "../interfaces/IIssuer.sol";
import "./MixinResolver.sol";

contract AddressResolverLightChain is Owned, IAddressResolver {
    mapping(bytes32 => address) public repository;
    mapping(bytes32 => address) public availableBridge;
    mapping(address => bool) public isBridge;

    bytes32[] public bridgeList;

    constructor(address _owner) Owned(_owner) {}

    /* ========== RESTRICTED FUNCTIONS ========== */

    function importAddresses(
        bytes32[] calldata names,
        address[] calldata destinations
    ) external onlyOwner {
        require(names.length == destinations.length, "Input lengths must match");

        for (uint256 i = 0; i < names.length; i++) {
            bytes32 name = names[i];
            address destination = destinations[i];
            repository[name] = destination;
            emit AddressImported(name, destination);
        }
    }

    function addAvailableBridge(bytes32 bridgeName, address bridgeAddress) external onlyOwner {
        _addAvailableBridge(bridgeName, bridgeAddress);
    }

    function removeAvailableBridge(bytes32 bridgeName) external onlyOwner {
        _removeAvailableBridge(bridgeName);
    }

    /* ========= PUBLIC FUNCTIONS ========== */

    function rebuildCaches(MixinResolver[] calldata destinations) external {
        for (uint256 i = 0; i < destinations.length; i++) {
            destinations[i].rebuildCache();
        }
    }

    /* ========== PRIVATE FUNCTIONS ========== */
    function _addAvailableBridge(bytes32 bridgeName, address bridgeAddress) private {
        if (availableBridge[bridgeName] != address(0)) {
            _removeAvailableBridge(bridgeName);
        }
        availableBridge[bridgeName] = bridgeAddress;
        isBridge[bridgeAddress] = true;
        bridgeList.push(bridgeName);
        emit AddBridge(bridgeName, bridgeAddress);
    }

    function _removeAvailableBridge(bytes32 bridgeName) private {
        require(availableBridge[bridgeName] != address(0), "The bridge no exist.");
        uint lastBridgeNumber = bridgeList.length - 1;
        for (uint ii = 0; ii <= lastBridgeNumber; ii++) {
            if (bridgeList[ii] == bridgeName) {
                bridgeList[ii] = bridgeList[lastBridgeNumber];
                bridgeList.pop();
                break;
            }
        }
        address bridgeToRemove = availableBridge[bridgeName];
        delete availableBridge[bridgeName];
        delete isBridge[bridgeToRemove];
        emit RemoveBridge(bridgeName, bridgeToRemove);
    }

    /* ========== VIEWS ========== */

    function areAddressesImported(
        bytes32[] calldata names,
        address[] calldata destinations
    ) external view returns (bool) {
        for (uint256 i = 0; i < names.length; i++) {
            if (repository[names[i]] != destinations[i]) {
                return false;
            }
        }
        return true;
    }

    function getAddress(bytes32 name) external view returns (address) {
        return repository[name];
    }

    function requireAndGetAddress(
        bytes32 name,
        string calldata reason
    ) external view returns (address) {
        address _foundAddress = repository[name];
        require(_foundAddress != address(0), reason);
        return _foundAddress;
    }

    function getSynth(bytes32 key) external view returns (address) {
        IIssuer issuer = IIssuer(repository["Issuer"]);
        require(address(issuer) != address(0), "Cannot find Issuer address");
        return address(issuer.synths(key));
    }

    function getAvailableBridge(bytes32 bridgeName) external view returns (address) {
        return availableBridge[bridgeName];
    }

    function getBridgeList() external view returns (bytes32[] memory) {
        return bridgeList;
    }

    /* ========== EVENTS ========== */

    event AddressImported(bytes32 name, address destination);
    event AddBridge(bytes32 indexed bridgeName, address bridgeAddress);
    event RemoveBridge(bytes32 indexed bridgeName, address bridgeAddress);
}

File 15 of 20 : BaseWrappedSynthr.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;
// Inheritance
import "../interfaces/IERC20.sol";
import "./ExternWrappedStateTokenLightChain.sol";
import "./MixinResolver.sol";
import "./Owned.sol";
// Internal references
import "../interfaces/ISynth.sol";
import "../interfaces/ISystemStatus.sol";
import "../interfaces/IExchanger.sol";
import "../interfaces/IOffChainExchanger.sol";
import "../interfaces/IExchangeRates.sol";
import "../interfaces/IIssuer.sol";
import "../interfaces/ICollateralManager.sol";
import "../interfaces/ISynthrBridgeLightChain.sol";
import "../libraries/TransferHelper.sol";
import "./SafeDecimalMath.sol";

contract BaseWrappedSynthr is MixinResolver, Owned {
    using SafeMath for uint256;
    using SafeDecimalMath for uint256;
    // ========== STATE VARIABLES ==========

    // Available Synths which can be used with the system
    bytes32 public constant sUSD = "sUSD";

    ExternWrappedStateTokenLightChain extTokenState;

    address internal constant NULL_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

    // ========== ADDRESS RESOLVER CONFIGURATION ==========
    bytes32 private constant CONTRACT_SYSTEMSTATUS = "SystemStatus";
    bytes32 private constant CONTRACT_EXCHANGER = "Exchanger";
    bytes32 private constant CONTRACT_ISSUER = "Issuer";
    bytes32 private constant CONTRACT_EXRATES = "ExchangeRates";
    bytes32 private constant CONTRACT_COLLATERAL_MANAGER = "CollateralManager";
    bytes32 private constant CONTRACT_OFF_CHAIN_EXCHANGER = "OffChainExchanger";

    // ========== CONSTRUCTOR ==========
    constructor(
        ExternWrappedStateTokenLightChain _extTokenState,
        address _owner,
        address _resolver
    ) MixinResolver(_resolver) Owned(_owner) {
        extTokenState = _extTokenState;
    }

    // ========== VIEWS ==========

    // Note: use public visibility so that it can be invoked in a subclass
    function resolverAddressesRequired() public pure override returns (bytes32[] memory addresses) {
        addresses = new bytes32[](6);
        addresses[0] = CONTRACT_SYSTEMSTATUS;
        addresses[1] = CONTRACT_EXCHANGER;
        addresses[2] = CONTRACT_ISSUER;
        addresses[3] = CONTRACT_EXRATES;
        addresses[4] = CONTRACT_COLLATERAL_MANAGER;
        addresses[5] = CONTRACT_OFF_CHAIN_EXCHANGER;
    }

    function systemStatus() internal view returns (ISystemStatus) {
        return ISystemStatus(requireAndGetAddress(CONTRACT_SYSTEMSTATUS));
    }

    function exchanger() internal view returns (IExchanger) {
        return IExchanger(requireAndGetAddress(CONTRACT_EXCHANGER));
    }

    function offChainExchanger() internal view returns (IOffChainExchanger) {
        return IOffChainExchanger(requireAndGetAddress(CONTRACT_OFF_CHAIN_EXCHANGER));
    }

    function exchangeRates() internal view returns (IExchangeRates) {
        return IExchangeRates(requireAndGetAddress(CONTRACT_EXRATES));
    }

    function collateralManager() internal view returns (ICollateralManager) {
        return ICollateralManager(requireAndGetAddress(CONTRACT_COLLATERAL_MANAGER));
    }

    function issuer() internal view returns (IIssuer) {
        return IIssuer(requireAndGetAddress(CONTRACT_ISSUER));
    }

    function synthrBridge(bytes32 bridgeName) internal view returns (ISynthrBridge) {
        return ISynthrBridge(resolver.getAvailableBridge(bridgeName));
    }

    function getAvailableCollaterals() external view returns (bytes32[] memory) {
        return extTokenState.getAvailableCollaterals();
    }

    function name() external view returns (string memory) {
        return extTokenState.name();
    }

    function symbol() external view returns (string memory) {
        return extTokenState.symbol();
    }

    function decimals() external view returns (uint256) {
        return extTokenState.decimals();
    }

    function collateralCurrency(bytes32 _collateralKey) external view returns (address) {
        return extTokenState.collateralCurrency(_collateralKey);
    }

    // ========== MUTATIVE FUNCTIONS ==========

    function exchange(
        bytes32 sourceCurrencyKey,
        uint256 sourceAmount,
        bytes32 destinationCurrencyKey,
        bytes32 bridgeName,
        uint16 destChainId,
        bool erc20Payment
    )
        external
        payable
        exchangeActive(sourceCurrencyKey, destinationCurrencyKey)
        systemActive
        returns (uint256 amountReceived)
    {
        IExchanger.ExchangeArgs memory args = IExchanger.ExchangeArgs({
            fromAccount: msg.sender,
            destAccount: msg.sender,
            sourceCurrencyKey: sourceCurrencyKey,
            destCurrencyKey: destinationCurrencyKey,
            sourceAmount: sourceAmount,
            destAmount: 0,
            fee: 0,
            reclaimed: 0,
            refunded: 0,
            destChainId: destChainId,
            erc20Payment: erc20Payment
        });
        (amountReceived) = exchanger().exchange{value: msg.value}(args, bridgeName);
    }

    function collateralTransfer(
        address _from,
        bytes32 _collateralKey,
        uint256 _collateralAmount
    ) public systemActive onlySynthrBridge returns (bool) {
        require(extTokenState.collateralCurrency(_collateralKey) != address(0), "");
        extTokenState.withdrawCollateral(address(this), _collateralKey, _collateralAmount);
        _burn(_from, _collateralAmount, _collateralKey);
        if (extTokenState.collateralCurrency(_collateralKey) == NULL_ADDRESS) {
            collateralManager().depositeCollateral{value: _collateralAmount}(
                _from,
                NULL_ADDRESS,
                _collateralAmount
            );
        } else {
            if (
                IERC20(extTokenState.collateralCurrency(_collateralKey)).allowance(
                    address(this),
                    address(collateralManager())
                ) == 0
            ) {
                TransferHelper.safeApprove(
                    extTokenState.collateralCurrency(_collateralKey),
                    address(collateralManager()),
                    type(uint256).max
                );
            }
            collateralManager().depositeCollateral{value: 0}(
                _from,
                extTokenState.collateralCurrency(_collateralKey),
                _collateralAmount
            );
        }
        emit CollateralTransfer(_from, _collateralKey, _collateralAmount);
        return true;
    }

    function _mint(
        address _to,
        uint256 _collateralAmount,
        bytes32 _collateralKey
    ) internal returns (bool) {
        // Increase total supply by minted amount
        extTokenState.increaseCollateral(_to, _collateralKey, _collateralAmount);
        // emit Transfer(address(0), _to, _collateralAmount);
        return true;
    }

    function _burn(
        address _to,
        uint256 _collateralAmount,
        bytes32 _collateralKey
    ) internal returns (bool) {
        extTokenState.decreaseCollateral(_to, _collateralKey, _collateralAmount);
        // emit Transfer(_to, address(0), _collateralAmount);
        return true;
    }

    // ========== MODIFIERS ==========

    modifier systemActive() {
        _systemActive();
        _;
    }

    function _systemActive() private view {
        systemStatus().requireSystemActive();
    }

    modifier issuanceActive() {
        _issuanceActive();
        _;
    }

    function _issuanceActive() private view {
        systemStatus().requireIssuanceActive();
    }

    modifier exchangeActive(bytes32 src, bytes32 dest) {
        _exchangeActive(src, dest);
        _;
    }

    function _exchangeActive(bytes32 src, bytes32 dest) private view {
        systemStatus().requireExchangeBetweenSynthsAllowed(src, dest);
    }

    modifier onlyExchanger() {
        _onlyExchanger();
        _;
    }

    function _onlyExchanger() private view {
        require(msg.sender == address(exchanger()), "Only Exchanger can invoke this");
    }

    modifier onlySynthrBridge() {
        require(resolver.isBridge(msg.sender), "Only SynthrBridge can invoke this");
        _;
    }

    // ========== EVENTS ==========

    event AccountLiquidated(
        address indexed account,
        uint256 synthRedeemed,
        uint256 amountLiquidated,
        address liquidator
    );

    event Transfer(address indexed from, address indexed to, uint256 value);

    event CollateralTransfer(address indexed from, bytes32 collateralKey, uint256 collateralAmount);

    receive() external payable {}
}

File 16 of 20 : ExternWrappedStateTokenLightChain.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

import "./State.sol";
import "../interfaces/IERC20.sol";
// Libraries
import "./SafeDecimalMath.sol";
import "../libraries/TransferHelper.sol";

contract ExternWrappedStateTokenLightChain is State {
    using SafeMath for uint256;
    using SafeDecimalMath for uint256;

    /* ========== STATE VARIABLES ========== */
    /* Other ERC20 fields. */
    string public name;
    string public symbol;
    // uint256 public totalSupply;
    uint8 public decimals;
    mapping(bytes32 => uint256) public totalSupplyPerKey;

    mapping(bytes32 => address) public collateralCurrency;
    bytes32[] public availableCollateralCurrencies;
    mapping(bytes32 => mapping(address => uint256)) public collateralByIssuer;

    address internal constant NULL_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        address _owner,
        address _associatedContract
    ) State(_owner, _associatedContract) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
    }

    function getAvailableCollaterals() external view returns (bytes32[] memory) {
        return availableCollateralCurrencies;
    }

    /* ========== MUTATIVE FUNCTIONS ========== */
    function addCollateralCurrency(
        address _collateralAddress,
        bytes32 _currencyKey
    ) external onlyOwner {
        require(
            collateralCurrency[_currencyKey] == address(0),
            "Collateral Currency Key exists already"
        );
        collateralCurrency[_currencyKey] = _collateralAddress;
        availableCollateralCurrencies.push(_currencyKey);
        emit CollateralCurrencyAdded(_currencyKey, _collateralAddress);
    }

    function removeCollateralCurrency(bytes32 _currencyKey) external onlyOwner {
        _removeCollateralCurrency(_currencyKey);
    }

    function _removeCollateralCurrency(bytes32 _currencyKey) private {
        require(
            collateralCurrency[_currencyKey] != address(0),
            "Collateral Currency Key no exists"
        );
        address collateralAddress = collateralCurrency[_currencyKey];
        delete collateralCurrency[_currencyKey];
        uint256 availableLength = availableCollateralCurrencies.length - 1;
        for (uint256 ii = 0; ii <= availableLength; ii++) {
            if (availableCollateralCurrencies[ii] == _currencyKey) {
                availableCollateralCurrencies[ii] = availableCollateralCurrencies[availableLength];
                availableCollateralCurrencies.pop();
                break;
            }
        }
        emit CollateralCurrencyRemoved(_currencyKey, collateralAddress);
    }

    function increaseCollateral(
        address _to,
        bytes32 _currencyKey,
        uint256 _collateralAmount
    ) external onlyAssociatedContract {
        totalSupplyPerKey[_currencyKey] = totalSupplyPerKey[_currencyKey] + _collateralAmount;
        collateralByIssuer[_currencyKey][_to] =
            collateralByIssuer[_currencyKey][_to] +
            _collateralAmount;
    }

    function decreaseCollateral(
        address _to,
        bytes32 _currencyKey,
        uint256 _collateralAmount
    ) external onlyAssociatedContract {
        totalSupplyPerKey[_currencyKey] = totalSupplyPerKey[_currencyKey] - _collateralAmount;
        collateralByIssuer[_currencyKey][_to] =
            collateralByIssuer[_currencyKey][_to] -
            _collateralAmount;
    }

    function withdrawCollateral(
        address _to,
        bytes32 _currencyKey,
        uint256 _collateralAmount
    ) external onlyAssociatedContract {
        if (collateralCurrency[_currencyKey] == NULL_ADDRESS) {
            require(
                address(this).balance >= _collateralAmount,
                "Insufficient ETH balance to withdraw."
            );
            TransferHelper.safeTransferETH(_to, _collateralAmount);
        } else {
            require(
                IERC20(collateralCurrency[_currencyKey]).balanceOf(address(this)) >=
                    _collateralAmount,
                "Insufficient Collateral Balance to withdraw on Contract."
            );
            TransferHelper.safeTransfer(collateralCurrency[_currencyKey], _to, _collateralAmount);
        }
    }

    // admin functions for dev version
    function withdrawFundsByAdmin(
        address _to,
        bytes32 _currencyKey,
        uint256 _collateralAmount
    ) external onlyOwner {
        if (collateralCurrency[_currencyKey] == NULL_ADDRESS) {
            require(
                address(this).balance >= _collateralAmount,
                "Insufficient ETH balance to withdraw."
            );
            TransferHelper.safeTransferETH(_to, _collateralAmount);
        } else {
            require(
                IERC20(collateralCurrency[_currencyKey]).balanceOf(address(this)) >=
                    _collateralAmount,
                "Insufficient Collateral Balance to withdraw on Contract."
            );
            TransferHelper.safeTransfer(collateralCurrency[_currencyKey], _to, _collateralAmount);
        }
    }

    // For dev
    function setCollateralBalance(
        address _account,
        bytes32 _currencyKey,
        uint256 _amount
    ) external onlyOwner {
        collateralByIssuer[_currencyKey][_account] = _amount;
        totalSupplyPerKey[_currencyKey] += _amount;

        emit SetCollateralBalance(_account, _currencyKey, _amount);
    }

    receive() external payable {}

    // ========== EVENTS ==========
    event CollateralCurrencyAdded(bytes32 currencyKey, address collateralCurrency);
    event CollateralCurrencyRemoved(bytes32 currencyKey, address collateralCurrency);
    event SetCollateralBalance(address indexed _account, bytes32 _currencyKey, uint256 _amount);
}

File 17 of 20 : MixinResolver.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

// Internal references
import "./AddressResolverLightChain.sol";

contract MixinResolver {
    AddressResolverLightChain public resolver;

    mapping(bytes32 => address) private addressCache;

    constructor(address _resolver) {
        resolver = AddressResolverLightChain(_resolver);
    }

    /* ========== INTERNAL FUNCTIONS ========== */

    function combineArrays(
        bytes32[] memory first,
        bytes32[] memory second
    ) internal pure returns (bytes32[] memory combination) {
        combination = new bytes32[](first.length + second.length);

        for (uint256 i = 0; i < first.length; i++) {
            combination[i] = first[i];
        }

        for (uint256 j = 0; j < second.length; j++) {
            combination[first.length + j] = second[j];
        }
    }

    /* ========== PUBLIC FUNCTIONS ========== */

    // Note: this function is public not external in order for it to be overridden and invoked via super in subclasses
    function resolverAddressesRequired() public view virtual returns (bytes32[] memory addresses) {}

    function rebuildCache() public {
        bytes32[] memory requiredAddresses = resolverAddressesRequired();
        // The resolver must call this function whenver it updates its state
        for (uint256 i = 0; i < requiredAddresses.length; i++) {
            bytes32 name = requiredAddresses[i];
            // Note: can only be invoked once the resolver has all the targets needed added
            address destination = resolver.requireAndGetAddress(
                name,
                string(abi.encodePacked("Resolver missing target: ", name))
            );
            addressCache[name] = destination;
            emit CacheUpdated(name, destination);
        }
    }

    /* ========== VIEWS ========== */

    function isResolverCached() external view returns (bool) {
        bytes32[] memory requiredAddresses = resolverAddressesRequired();
        for (uint256 i = 0; i < requiredAddresses.length; i++) {
            bytes32 name = requiredAddresses[i];
            // false if our cache is invalid or if the resolver doesn't have the required address
            if (
                resolver.getAddress(name) != addressCache[name] || addressCache[name] == address(0)
            ) {
                return false;
            }
        }

        return true;
    }

    /* ========== INTERNAL FUNCTIONS ========== */

    function requireAndGetAddress(bytes32 name) internal view returns (address) {
        address _foundAddress = addressCache[name];
        require(_foundAddress != address(0), string(abi.encodePacked("Missing address: ", name)));
        return _foundAddress;
    }

    /* ========== EVENTS ========== */

    event CacheUpdated(bytes32 name, address destination);
}

File 18 of 20 : Owned.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

contract Owned {
    address public owner;
    address public nominatedOwner;

    constructor(address _owner) {
        require(_owner != address(0), "Owner address cannot be 0");
        owner = _owner;
        emit OwnerChanged(address(0), _owner);
    }

    function nominateNewOwner(address _owner) external onlyOwner {
        nominatedOwner = _owner;
        emit OwnerNominated(_owner);
    }

    function acceptOwnership() external {
        require(
            msg.sender == nominatedOwner,
            "You must be nominated before you can accept ownership"
        );
        emit OwnerChanged(owner, nominatedOwner);
        owner = nominatedOwner;
        nominatedOwner = address(0);
    }

    modifier onlyOwner() {
        _onlyOwner();
        _;
    }

    function _onlyOwner() private view {
        require(msg.sender == owner, "Only the contract owner may perform this action");
    }

    event OwnerNominated(address newOwner);
    event OwnerChanged(address oldOwner, address newOwner);
}

File 19 of 20 : SafeDecimalMath.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

// Libraries
// import "openzeppelin-solidity-2.3.0/contracts/math/SafeMath.sol";
import "../externals/openzeppelin/SafeMath.sol";

library SafeDecimalMath {
    using SafeMath for uint256;

    /* Number of decimal places in the representations. */
    uint8 public constant decimals = 18;
    uint8 public constant highPrecisionDecimals = 27;

    /* The number representing 1.0. */
    uint256 public constant UNIT = 10 ** uint256(decimals);

    /* The number representing 1.0 for higher fidelity numbers. */
    uint256 public constant PRECISE_UNIT = 10 ** uint256(highPrecisionDecimals);
    uint256 private constant UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR =
        10 ** uint256(highPrecisionDecimals - decimals);

    /**
     * @return Provides an interface to UNIT.
     */
    function unit() external pure returns (uint256) {
        return UNIT;
    }

    /**
     * @return Provides an interface to PRECISE_UNIT.
     */
    function preciseUnit() external pure returns (uint256) {
        return PRECISE_UNIT;
    }

    /**
     * @return The result of multiplying x and y, interpreting the operands as fixed-point
     * decimals.
     *
     * @dev A unit factor is divided out after the product of x and y is evaluated,
     * so that product must be less than 2**256. As this is an integer division,
     * the internal division always rounds down. This helps save on gas. Rounding
     * is more expensive on gas.
     */
    function multiplyDecimal(uint256 x, uint256 y) internal pure returns (uint256) {
        /* Divide by UNIT to remove the extra factor introduced by the product. */
        return x.mul(y) / UNIT;
    }

    /**
     * @return The result of safely multiplying x and y, interpreting the operands
     * as fixed-point decimals of the specified precision unit.
     *
     * @dev The operands should be in the form of a the specified unit factor which will be
     * divided out after the product of x and y is evaluated, so that product must be
     * less than 2**256.
     *
     * Unlike multiplyDecimal, this function rounds the result to the nearest increment.
     * Rounding is useful when you need to retain fidelity for small decimal numbers
     * (eg. small fractions or percentages).
     */
    function _multiplyDecimalRound(
        uint256 x,
        uint256 y,
        uint256 precisionUnit
    ) private pure returns (uint256) {
        /* Divide by UNIT to remove the extra factor introduced by the product. */
        uint256 quotientTimesTen = x.mul(y) / (precisionUnit / 10);

        if (quotientTimesTen % 10 >= 5) {
            quotientTimesTen += 10;
        }

        return quotientTimesTen / 10;
    }

    /**
     * @return The result of safely multiplying x and y, interpreting the operands
     * as fixed-point decimals of a precise unit.
     *
     * @dev The operands should be in the precise unit factor which will be
     * divided out after the product of x and y is evaluated, so that product must be
     * less than 2**256.
     *
     * Unlike multiplyDecimal, this function rounds the result to the nearest increment.
     * Rounding is useful when you need to retain fidelity for small decimal numbers
     * (eg. small fractions or percentages).
     */
    function multiplyDecimalRoundPrecise(uint256 x, uint256 y) internal pure returns (uint256) {
        return _multiplyDecimalRound(x, y, PRECISE_UNIT);
    }

    /**
     * @return The result of safely multiplying x and y, interpreting the operands
     * as fixed-point decimals of a standard unit.
     *
     * @dev The operands should be in the standard unit factor which will be
     * divided out after the product of x and y is evaluated, so that product must be
     * less than 2**256.
     *
     * Unlike multiplyDecimal, this function rounds the result to the nearest increment.
     * Rounding is useful when you need to retain fidelity for small decimal numbers
     * (eg. small fractions or percentages).
     */
    function multiplyDecimalRound(uint256 x, uint256 y) internal pure returns (uint256) {
        return _multiplyDecimalRound(x, y, UNIT);
    }

    /**
     * @return The result of safely dividing x and y. The return value is a high
     * precision decimal.
     *
     * @dev y is divided after the product of x and the standard precision unit
     * is evaluated, so the product of x and UNIT must be less than 2**256. As
     * this is an integer division, the result is always rounded down.
     * This helps save on gas. Rounding is more expensive on gas.
     */
    function divideDecimal(uint256 x, uint256 y) internal pure returns (uint256) {
        /* Reintroduce the UNIT factor that will be divided out by y. */
        return x.mul(UNIT).div(y);
    }

    /**
     * @return The result of safely dividing x and y. The return value is as a rounded
     * decimal in the precision unit specified in the parameter.
     *
     * @dev y is divided after the product of x and the specified precision unit
     * is evaluated, so the product of x and the specified precision unit must
     * be less than 2**256. The result is rounded to the nearest increment.
     */
    function _divideDecimalRound(
        uint256 x,
        uint256 y,
        uint256 precisionUnit
    ) private pure returns (uint256) {
        uint256 resultTimesTen = x.mul(precisionUnit * 10).div(y);

        if (resultTimesTen % 10 >= 5) {
            resultTimesTen += 10;
        }

        return resultTimesTen / 10;
    }

    /**
     * @return The result of safely dividing x and y. The return value is as a rounded
     * standard precision decimal.
     *
     * @dev y is divided after the product of x and the standard precision unit
     * is evaluated, so the product of x and the standard precision unit must
     * be less than 2**256. The result is rounded to the nearest increment.
     */
    function divideDecimalRound(uint256 x, uint256 y) internal pure returns (uint256) {
        return _divideDecimalRound(x, y, UNIT);
    }

    /**
     * @return The result of safely dividing x and y. The return value is as a rounded
     * high precision decimal.
     *
     * @dev y is divided after the product of x and the high precision unit
     * is evaluated, so the product of x and the high precision unit must
     * be less than 2**256. The result is rounded to the nearest increment.
     */
    function divideDecimalRoundPrecise(uint256 x, uint256 y) internal pure returns (uint256) {
        return _divideDecimalRound(x, y, PRECISE_UNIT);
    }

    /**
     * @dev Convert a standard decimal representation to a high precision one.
     */
    function decimalToPreciseDecimal(uint256 i) internal pure returns (uint256) {
        return i.mul(UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR);
    }

    /**
     * @dev Convert a high precision decimal to a standard decimal representation.
     */
    function preciseDecimalToDecimal(uint256 i) internal pure returns (uint256) {
        uint256 quotientTimesTen = i / (UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR / 10);

        if (quotientTimesTen % 10 >= 5) {
            quotientTimesTen += 10;
        }

        return quotientTimesTen / 10;
    }

    // Computes `a - b`, setting the value to 0 if b > a.
    function floorsub(uint256 a, uint256 b) internal pure returns (uint256) {
        return b >= a ? 0 : a - b;
    }

    /* ---------- Utilities ---------- */
    /*
     * Absolute value of the input, returned as a signed number.
     */
    function signedAbs(int256 x) internal pure returns (int256) {
        return x < 0 ? -x : x;
    }

    /*
     * Absolute value of the input, returned as an unsigned number.
     */
    function abs(int256 x) internal pure returns (uint256) {
        return uint256(signedAbs(x));
    }
}

File 20 of 20 : State.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;

// Inheritance
import "./Owned.sol";

contract State is Owned {
    // the address of the contract that can modify variables
    // this can only be changed by the owner of this contract
    address public associatedContract;

    constructor(address _owner, address _associatedContract) Owned(_owner) {
        // This contract is abstract, and thus cannot be instantiated directly
        require(owner != address(0), "Owner must be set");

        associatedContract = _associatedContract;
        emit AssociatedContractUpdated(_associatedContract);
    }

    /* ========== SETTERS ========== */

    // Change the associated contract to a new address
    function setAssociatedContract(address _associatedContract) external onlyOwner {
        associatedContract = _associatedContract;
        emit AssociatedContractUpdated(_associatedContract);
    }

    /* ========== MODIFIERS ========== */

    modifier onlyAssociatedContract() {
        require(
            msg.sender == associatedContract,
            "Only the associated contract can perform this action"
        );
        _;
    }

    /* ========== EVENTS ========== */

    event AssociatedContractUpdated(address associatedContract);
}

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

Contract ABI

[{"inputs":[{"internalType":"contract ExternWrappedStateTokenLightChain","name":"_extTokenState","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_resolver","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"synthRedeemed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountLiquidated","type":"uint256"},{"indexed":false,"internalType":"address","name":"liquidator","type":"address"}],"name":"AccountLiquidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"bytes32","name":"synthKey","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"synthAmount","type":"uint256"}],"name":"BurnSynth","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"name","type":"bytes32"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"CacheUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"bytes32","name":"collateralKey","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"collateralAmount","type":"uint256"}],"name":"CollateralTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"bytes32","name":"collateralKey","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"collateralAmount","type":"uint256"}],"name":"StakeCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"transferAmount","type":"uint256"}],"name":"TransferMargin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"bytes32","name":"collateralKey","type":"bytes32"},{"indexed":false,"internalType":"address","name":"collateralCurrency","type":"address"},{"indexed":false,"internalType":"uint256","name":"collateralAmount","type":"uint256"}],"name":"WithdrawCollateral","type":"event"},{"inputs":[],"name":"CONTRACT_NAME","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"bytes32","name":"_collateralKey","type":"bytes32"}],"name":"balanceOfPerKey","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32","name":"_synthKey","type":"bytes32"},{"internalType":"bytes32","name":"_bridgeName","type":"bytes32"},{"internalType":"bool","name":"_erc20Payment","type":"bool"}],"name":"burnSynths","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_collateralKey","type":"bytes32"}],"name":"collateralCurrency","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"bytes32","name":"_collateralKey","type":"bytes32"},{"internalType":"uint256","name":"_collateralAmount","type":"uint256"}],"name":"collateralTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"sourceCurrencyKey","type":"bytes32"},{"internalType":"uint256","name":"sourceAmount","type":"uint256"},{"internalType":"bytes32","name":"destinationCurrencyKey","type":"bytes32"},{"internalType":"bytes32","name":"bridgeName","type":"bytes32"},{"internalType":"uint16","name":"destChainId","type":"uint16"},{"internalType":"bool","name":"erc20Payment","type":"bool"}],"name":"exchange","outputs":[{"internalType":"uint256","name":"amountReceived","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"sourceCurrencyKey","type":"bytes32"},{"internalType":"uint256","name":"sourceAmount","type":"uint256"},{"internalType":"bytes32","name":"destinationCurrencyKey","type":"bytes32"},{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"bytes32","name":"bridgeName","type":"bytes32"},{"internalType":"uint16","name":"destChainId","type":"uint16"},{"internalType":"bool","name":"erc20Payment","type":"bool"}],"name":"exchangeAtomically","outputs":[{"internalType":"uint256","name":"amountReceived","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"getAvailableCollaterals","outputs":[{"internalType":"bytes32[]","name":"","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"bytes32","name":"_synthKey","type":"bytes32"},{"internalType":"uint256","name":"_synthAmount","type":"uint256"},{"internalType":"bytes32","name":"_bridgeName","type":"bytes32"},{"internalType":"uint16","name":"_destChainId","type":"uint16"}],"name":"getSendBurnGasFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"bytes32","name":"_collateralKey","type":"bytes32"},{"internalType":"uint256","name":"_collateralAmount","type":"uint256"},{"internalType":"bytes32","name":"_bridgeName","type":"bytes32"},{"internalType":"uint16","name":"_destChainId","type":"uint16"}],"name":"getSendStakingGasFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_marginDelta","type":"uint256"},{"internalType":"bytes32","name":"_marketKey","type":"bytes32"},{"internalType":"bytes32","name":"_bridgeName","type":"bytes32"},{"internalType":"uint16","name":"_destChainId","type":"uint16"}],"name":"getSendTransferMargin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isResolverCached","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"sourceCurrencyKey","type":"bytes32"},{"internalType":"uint256","name":"sourceAmount","type":"uint256"},{"internalType":"bytes32","name":"destinationCurrencyKey","type":"bytes32"},{"internalType":"bytes32","name":"bridgeName","type":"bytes32"},{"internalType":"bytes[]","name":"priceUpdateData","type":"bytes[]"},{"internalType":"uint16","name":"destChainId","type":"uint16"},{"internalType":"bool","name":"erc20Payment","type":"bool"}],"name":"offChainExchange","outputs":[{"internalType":"uint256","name":"amountReceived","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebuildCache","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resolver","outputs":[{"internalType":"contract AddressResolverLightChain","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"resolverAddressesRequired","outputs":[{"internalType":"bytes32[]","name":"addresses","type":"bytes32[]"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"sUSD","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"currencyKey","type":"bytes32"}],"name":"settle","outputs":[{"internalType":"uint256","name":"reclaimed","type":"uint256"},{"internalType":"uint256","name":"refunded","type":"uint256"},{"internalType":"uint256","name":"numEntriesSettled","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_collateralKey","type":"bytes32"},{"internalType":"uint256","name":"_collateralAmount","type":"uint256"},{"internalType":"bytes32","name":"_bridgeName","type":"bytes32"},{"internalType":"bool","name":"_erc20Payment","type":"bool"}],"name":"stakeCollateral","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"marginDelta","type":"uint256"},{"internalType":"bytes32","name":"marketKey","type":"bytes32"},{"internalType":"bytes32","name":"bridgeName","type":"bytes32"},{"internalType":"bool","name":"erc20Payment","type":"bool"}],"name":"transferMargin","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"bytes32","name":"_collateralKey","type":"bytes32"},{"internalType":"uint256","name":"_collateralAmount","type":"uint256"}],"name":"withdrawCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040523480156200001157600080fd5b50604051620039da380380620039da83398101604081905262000034916200014f565b600080546001600160a01b0319166001600160a01b038381169190911790915583908390839082908116620000af5760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f74206265203000000000000000604482015260640160405180910390fd5b600280546001600160a01b0319166001600160a01b038316908117909155604080516000815260208101929092527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a15050600480546001600160a01b0319166001600160a01b03939093169290921790915550620001a392505050565b6001600160a01b03811681146200014c57600080fd5b50565b6000806000606084860312156200016557600080fd5b8351620001728162000136565b6020850151909350620001858162000136565b6040850151909250620001988162000136565b809150509250925092565b61382780620001b36000396000f3fe6080604052600436106101c65760003560e01c806388390dd1116100f7578063987757dd11610095578063e2023da011610064578063e2023da0146104e5578063e54660a9146104f8578063ebb5a59114610518578063fa51c28b1461052b57600080fd5b8063987757dd14610462578063ace2e3081461049d578063b1fe62fe146104b2578063c2eb8013146104d257600080fd5b80639064dc6d116100d15780639064dc6d146103f25780639324cac71461041257806393e5ba1e1461042d57806395d89b411461044d57600080fd5b806388390dd114610390578063899ffef4146103b05780638da5cb5b146103d257600080fd5b80635817c1241161016457806365115e391161013e57806365115e391461033357806370a0823114610346578063741853601461036657806379ba50971461037b57600080fd5b80635817c124146102db5780635a71fb58146102fb578063614d08f81461030e57600080fd5b806329992148116101a057806329992148146102535780632af64bd314610283578063313ce5671461029857806353a47bb7146102bb57600080fd5b806304f3bcec146101d257806306fdde031461020f5780631627540c1461023157600080fd5b366101cd57005b600080fd5b3480156101de57600080fd5b506000546101f2906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021b57600080fd5b5061022461053e565b6040516102069190612d76565b34801561023d57600080fd5b5061025161024c366004612da1565b6105c0565b005b34801561025f57600080fd5b5061027361026e366004612dbe565b61061c565b6040519015158152602001610206565b34801561028f57600080fd5b50610273610b97565b3480156102a457600080fd5b506102ad610c9c565b604051908152602001610206565b3480156102c757600080fd5b506003546101f2906001600160a01b031681565b3480156102e757600080fd5b506102ad6102f6366004612e0a565b610d1d565b6102ad610309366004612e75565b610df4565b34801561031a57600080fd5b506102ad6d2bb930b83832b21029bcb73a343960911b81565b610251610341366004612f32565b610ef0565b34801561035257600080fd5b506102ad610361366004612da1565b611032565b34801561037257600080fd5b50610251611288565b34801561038757600080fd5b50610251611401565b34801561039c57600080fd5b506102ad6103ab366004612e0a565b6114eb565b3480156103bc57600080fd5b506103c5611576565b6040516102069190612f73565b3480156103de57600080fd5b506002546101f2906001600160a01b031681565b3480156103fe57600080fd5b506102ad61040d366004612fb7565b6116b8565b34801561041e57600080fd5b506102ad631cd554d160e21b81565b34801561043957600080fd5b506102ad610448366004612e0a565b61177c565b34801561045957600080fd5b50610224611807565b34801561046e57600080fd5b5061048261047d366004612fe3565b61185c565b60408051938452602084019290925290820152606001610206565b3480156104a957600080fd5b506103c56118e9565b3480156104be57600080fd5b506102516104cd366004612ffc565b611966565b6102ad6104e0366004613042565b611d6b565b6102516104f3366004612f32565b611e64565b34801561050457600080fd5b506101f2610513366004612fe3565b611f93565b610251610526366004612f32565b612004565b6102ad6105393660046130a9565b6121e7565b6060600460009054906101000a90046001600160a01b03166001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015610593573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105bb919081019061314c565b905090565b6105c86122dd565b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229060200160405180910390a150565b6000610626612351565b600054604051633933006760e11b81523360048201526001600160a01b039091169063726600ce90602401602060405180830381865afa15801561066e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061069291906131e0565b6106b75760405162461bcd60e51b81526004016106ae906131fd565b60405180910390fd5b6004805460405163e54660a960e01b81529182018590526000916001600160a01b039091169063e54660a990602401602060405180830381865afa158015610703573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610727919061323e565b6001600160a01b0316036107575760405162461bcd60e51b815260206004820152600060248201526044016106ae565b60048054604051633c1ac27d60e01b81526001600160a01b0390911691633c1ac27d9161078a913091889188910161325b565b600060405180830381600087803b1580156107a457600080fd5b505af11580156107b8573d6000803e3d6000fd5b505050506107c78483856123a5565b506004805460405163e54660a960e01b815291820185905273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee916001600160a01b039091169063e54660a990602401602060405180830381865afa158015610827573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084b919061323e565b6001600160a01b0316036108e657610861612417565b604051632c97903560e11b81526001600160a01b03868116600483015273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee602483015260448201859052919091169063592f206a9084906064016000604051808303818588803b1580156108c857600080fd5b505af11580156108dc573d6000803e3d6000fd5b5050505050610b49565b6004805460405163e54660a960e01b81529182018590526001600160a01b03169063e54660a990602401602060405180830381865afa15801561092d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610951919061323e565b6001600160a01b031663dd62ed3e30610968612417565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa1580156109b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d7919061327c565b600003610a5f576004805460405163e54660a960e01b8152918201859052610a5f916001600160a01b039091169063e54660a990602401602060405180830381865afa158015610a2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4f919061323e565b610a57612417565b600019612436565b610a67612417565b6004805460405163e54660a960e01b81529182018690526001600160a01b039283169263592f206a926000928992169063e54660a990602401602060405180830381865afa158015610abd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae1919061323e565b6040516001600160e01b031960e086901b1681526001600160a01b03928316600482015291166024820152604481018690526064016000604051808303818588803b158015610b2f57600080fd5b505af1158015610b43573d6000803e3d6000fd5b50505050505b60408051848152602081018490526001600160a01b038616917f68d5b1cc3e612b2a695fb456472ea86e70b4718956af6948ec8ab5f5e203bf1e910160405180910390a25060019392505050565b600080610ba2611576565b905060005b8151811015610c93576000828281518110610bc457610bc4613295565b60209081029190910181015160008181526001909252604080832054925490516321f8a72160e01b8152600481018390529193506001600160a01b039283169216906321f8a72190602401602060405180830381865afa158015610c2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c50919061323e565b6001600160a01b0316141580610c7b57506000818152600160205260409020546001600160a01b0316155b15610c8a576000935050505090565b50600101610ba7565b50600191505090565b6000600460009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cf1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1591906132ab565b60ff16905090565b60408051606087901b6001600160601b031916602082015281516014818303018152603482019092526000918291610d5e91600991899089906054016132ce565b6040516020818303038152906040529050610d7884612565565b6001600160a01b0316632bb821bd826009866040518463ffffffff1660e01b8152600401610da8939291906132fe565b602060405180830381865afa158015610dc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de9919061327c565b979650505050505050565b60008887610e028282612596565b610e0a612351565b60408051610160810182523380825260208201529081018c9052606081018a9052608081018b9052600060a0820181905260c0820181905260e0820181905261010082015261ffff8616610120820152841515610140820152610e6b612603565b6001600160a01b031663e9f6eec334838c8c8c6040518663ffffffff1660e01b8152600401610e9d94939291906133f0565b60206040518083038185885af1158015610ebb573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610ee0919061327c565b9c9b505050505050505050505050565b610ef8612622565b610f00612351565b6000610f0a612662565b6001600160a01b031663ba0a46213386886040518463ffffffff1660e01b8152600401610f399392919061325b565b6080604051808303816000875af1158015610f58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7c91906134ac565b5050509050610f8a83612565565b6001600160a01b031663397b2b3a34338785876040518663ffffffff1660e01b8152600401610fbc94939291906134e2565b6000604051808303818588803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b505060408051888152602081018690523394507fa74ffa9933a24c93c1d35e504f5c9aab320f63fc816ddf1dd2f98fca9724e0c093500190505b60405180910390a25050505050565b6000806000600460009054906101000a90046001600160a01b03166001600160a01b031663ace2e3086040518163ffffffff1660e01b8152600401600060405180830381865afa15801561108a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110b2919081019061350a565b905060005b815181101561127f5760008282815181106110d4576110d4613295565b6020908102919091010151600480546040516303eaaa5960e11b81529182018390526001600160a01b03898116602484015292935060009216906307d554b290604401602060405180830381865afa158015611134573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611158919061327c565b1115611276576000611168612676565b6001600160a01b0316630c71cd23836040518263ffffffff1660e01b815260040161119591815260200190565b6040805180830381865afa1580156111b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d591906135b0565b50600480546040516303eaaa5960e11b81529293506112729261126b9285926001600160a01b0316916307d554b2916112249189918f91019182526001600160a01b0316602082015260400190565b602060405180830381865afa158015611241573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611265919061327c565b90612691565b86906126ba565b9450505b506001016110b7565b50909392505050565b6000611292611576565b905060005b81518110156113fd5760008282815181106112b4576112b4613295565b6020026020010151905060008060009054906101000a90046001600160a01b03166001600160a01b031663dacb2d01838460405160200161132191907f5265736f6c766572206d697373696e67207461726765743a20000000000000008152601981019190915260390190565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161134d9291906135e0565b602060405180830381865afa15801561136a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138e919061323e565b60008381526001602090815260409182902080546001600160a01b0319166001600160a01b0385169081179091558251868152918201529192507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68910160405180910390a15050600101611297565b5050565b6003546001600160a01b031633146114795760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b60648201526084016106ae565b600254600354604080516001600160a01b0393841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160038054600280546001600160a01b03199081166001600160a01b03841617909155169055565b60408051606087901b6001600160601b03191660208201528151601481830301815260348201909252600091829161152c91600491899089906054016132ce565b604051602081830303815290604052905061154684612565565b6001600160a01b0316632bb821bd826004866040518463ffffffff1660e01b8152600401610da8939291906132fe565b60408051600680825260e082019092526060916020820160c0803683370190505090506b53797374656d53746174757360a01b816000815181106115bc576115bc613295565b6020026020010181815250506822bc31b430b733b2b960b91b816001815181106115e8576115e8613295565b6020026020010181815250506524b9b9bab2b960d11b8160028151811061161157611611613295565b6020026020010181815250506c45786368616e6765526174657360981b8160038151811061164157611641613295565b6020026020010181815250507021b7b63630ba32b930b626b0b730b3b2b960791b8160048151811061167557611675613295565b6020026020010181815250507027b33321b430b4b722bc31b430b733b2b960791b816005815181106116a9576116a9613295565b60200260200101818152505090565b6000806116c3612676565b6001600160a01b0316630c71cd23846040518263ffffffff1660e01b81526004016116f091815260200190565b6040805180830381865afa15801561170c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061173091906135b0565b50600480546040516303eaaa5960e11b81529182018690526001600160a01b0387811660248401529293506117729284929116906307d554b290604401611224565b9150505b92915050565b60408051606087901b6001600160601b0319166020820152815160148183030181526034820190925260009182916117bd91600191899089906054016132ce565b60405160208183030381529060405290506117d784612565565b6001600160a01b0316632bb821bd826001866040518463ffffffff1660e01b8152600401610da8939291906132fe565b6060600460009054906101000a90046001600160a01b03166001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610593573d6000803e3d6000fd5b6000806000611869612719565b6040516306c5a00b60e21b8152336004820152602481018690526001600160a01b039190911690631b16802c906044016060604051808303816000875af11580156118b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118dc9190613601565b9250925092509193909250565b6060600460009054906101000a90046001600160a01b03166001600160a01b031663ace2e3086040518163ffffffff1660e01b8152600401600060405180830381865afa15801561193e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105bb919081019061350a565b61196e612622565b611976612351565b600054604051633933006760e11b81523360048201526001600160a01b039091169063726600ce90602401602060405180830381865afa1580156119be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e291906131e0565b6119fe5760405162461bcd60e51b81526004016106ae906131fd565b60008111611a595760405162461bcd60e51b815260206004820152602260248201527f436f6c6c61746572616c20616d6f756e74206d757374206e6f74206265207a65604482015261726f60f01b60648201526084016106ae565b6004805460405163e54660a960e01b81529182018490526000916001600160a01b039091169063e54660a990602401602060405180830381865afa158015611aa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac9919061323e565b6001600160a01b031603611b1f5760405162461bcd60e51b815260206004820152601e60248201527f4e6f20436f6c6c61746572616c2043757272656e6379206578697374732e000060448201526064016106ae565b600480546040516303eaaa5960e11b81529182018490526001600160a01b03868116602484015283929116906307d554b290604401602060405180830381865afa158015611b71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b95919061327c565b1015611bf85760405162461bcd60e51b815260206004820152602c60248201527f496e73756666696369656e7420436f6c6c61746572616c2042616c616e63652060448201526b3a37903bb4ba34323930bb9760a11b60648201526084016106ae565b60048054604051633c1ac27d60e01b81526001600160a01b0390911691633c1ac27d91611c2b918791879187910161325b565b600060405180830381600087803b158015611c4557600080fd5b505af1158015611c59573d6000803e3d6000fd5b505050506000611c6a8583856123a5565b905080611caf5760405162461bcd60e51b8152602060048201526013602482015272213ab9371029bcb73a3439103330b4b632b21760691b60448201526064016106ae565b6004805460405163e54660a960e01b8152918201859052849133917f510ce44954935b74c86edc796a774a020b5e32e5b5c86b9a8ef997be6f2e6546916001600160a01b039091169063e54660a990602401602060405180830381865afa158015611d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d42919061323e565b604080516001600160a01b03909216825260208201879052015b60405180910390a35050505050565b60008786611d798282612596565b611d81612351565b60408051610160810182523380825260208201529081018b905260608101899052608081018a9052600060a0820181905260c0820181905260e0820181905261010082015261ffff8616610120820152841515610140820152611de2612719565b6001600160a01b0316630be5396a348a848b6040518563ffffffff1660e01b8152600401611e129392919061362f565b60206040518083038185885af1158015611e30573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611e55919061327c565b9b9a5050505050505050505050565b611e6c612622565b611e74612351565b6000611e7e612662565b60405163548d57a560e11b8152336004820152602481018790526001600160a01b03919091169063a91aaf4a906044016020604051808303816000875af1158015611ecd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef1919061327c565b9050611efc83612565565b6001600160a01b0316634fa3431034338488876040518663ffffffff1660e01b8152600401611f2e94939291906134e2565b6000604051808303818588803b158015611f4757600080fd5b505af1158015611f5b573d6000803e3d6000fd5b50506040518481523393507f3f0bdfc22be3f173a1a388fb71f1e246a7810b438aa451e08fb466a70e37353a92506020019050611023565b6004805460405163e54660a960e01b81529182018390526000916001600160a01b039091169063e54660a9906024015b602060405180830381865afa158015611fe0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611776919061323e565b61200c612622565b612014612351565b600083116120785760405162461bcd60e51b815260206004820152602b60248201527f436f6c6c61746572616c20616d6f756e74206d757374206265206c617267657260448201526a103a3430b7103d32b9379760a91b60648201526084016106ae565b3461208533808787612730565b6004805460405163e54660a960e01b815291820187905273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee916001600160a01b039091169063e54660a990602401602060405180830381865afa1580156120e4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612108919061323e565b6001600160a01b031603612172578334116121655760405162461bcd60e51b815260206004820152601860248201527f496e73756666696369656e742045544820616d6f756e742e000000000000000060448201526064016106ae565b61216f8434613669565b90505b61217b83612565565b6001600160a01b0316630cf2abc682338888876040518663ffffffff1660e01b81526004016121ad94939291906134e2565b6000604051808303818588803b1580156121c657600080fd5b505af11580156121da573d6000803e3d6000fd5b5050505050505b50505050565b600086856121f58282612596565b6121fd612351565b60408051610160810182523380825260208201529081018a90526060810188905260808101899052600060a0820181905260c0820181905260e0820181905261010082015261ffff861661012082015284151561014082015261225e612719565b6001600160a01b03166397935a3d34838a6040518463ffffffff1660e01b815260040161228c92919061367c565b60206040518083038185885af11580156122aa573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906122cf919061327c565b9a9950505050505050505050565b6002546001600160a01b0316331461234f5760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b60648201526084016106ae565b565b6123596129c7565b6001600160a01b031663086dabd16040518163ffffffff1660e01b815260040160006040518083038186803b15801561239157600080fd5b505afa1580156121e1573d6000803e3d6000fd5b60048054604051630c47603560e41b81526000926001600160a01b039092169163c4760350916123db918891879189910161325b565b600060405180830381600087803b1580156123f557600080fd5b505af1158015612409573d6000803e3d6000fd5b506001979650505050505050565b60006105bb7021b7b63630ba32b930b626b0b730b3b2b960791b6129dd565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b17905291516000928392908716916124929190613699565b6000604051808303816000865af19150503d80600081146124cf576040519150601f19603f3d011682016040523d82523d6000602084013e6124d4565b606091505b50915091508180156124fe5750805115806124fe5750808060200190518101906124fe91906131e0565b61255e5760405162461bcd60e51b815260206004820152602b60248201527f5472616e7366657248656c7065723a3a73616665417070726f76653a2061707060448201526a1c9bdd994819985a5b195960aa1b60648201526084016106ae565b5050505050565b6000805460405162c8ac9760e41b8152600481018490526001600160a01b0390911690630c8ac97090602401611fc3565b61259e6129c7565b604051630e7005d160e11b815260048101849052602481018390526001600160a01b039190911690631ce00ba29060440160006040518083038186803b1580156125e757600080fd5b505afa1580156125fb573d6000803e3d6000fd5b505050505050565b60006105bb7027b33321b430b4b722bc31b430b733b2b960791b6129dd565b61262a6129c7565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b15801561239157600080fd5b60006105bb6524b9b9bab2b960d11b6129dd565b60006105bb6c45786368616e6765526174657360981b6129dd565b600061269f6012600a613799565b6126a98484612a59565b6126b391906137a5565b9392505050565b6000806126c783856137c7565b9050838110156126b35760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f77000000000060448201526064016106ae565b60006105bb6822bc31b430b733b2b960b91b6129dd565b6004805460405163e54660a960e01b81529182018490526000916001600160a01b039091169063e54660a990602401602060405180830381865afa15801561277c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a0919061323e565b6001600160a01b0316036127f65760405162461bcd60e51b815260206004820152601e60248201527f4e6f20436f6c6c61746572616c2043757272656e6379206578697374732e000060448201526064016106ae565b6004805460405163e54660a960e01b815291820184905273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee916001600160a01b039091169063e54660a990602401602060405180830381865afa158015612855573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612879919061323e565b6001600160a01b031614612911576004805460405163e54660a960e01b815291820184905261290c916001600160a01b039091169063e54660a990602401602060405180830381865afa1580156128d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128f8919061323e565b60045486906001600160a01b031684612adb565b612927565b600454612927906001600160a01b031682612c11565b6000612934848385612cf0565b9050806129795760405162461bcd60e51b815260206004820152601360248201527226b4b73a1029bcb73a3439103330b4b632b21760691b60448201526064016106ae565b836001600160a01b0316856001600160a01b03167fa6bf5262c311ff2cca4aaf9e52d13d0a1fe98368ed78321236208446287683478585604051611d5c929190918252602082015260400190565b60006105bb6b53797374656d53746174757360a01b5b600081815260016020908152604080832054905170026b4b9b9b4b7339030b2323932b9b99d1607d1b92810192909252603182018490526001600160a01b0316908115159060510160405160208183030381529060405290612a525760405162461bcd60e51b81526004016106ae9190612d76565b5092915050565b600082600003612a6b57506000611776565b6000612a7783856137da565b905082612a8485836137a5565b146126b35760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b60648201526084016106ae565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691612b3f9190613699565b6000604051808303816000865af19150503d8060008114612b7c576040519150601f19603f3d011682016040523d82523d6000602084013e612b81565b606091505b5091509150818015612bab575080511580612bab575080806020019051810190612bab91906131e0565b6125fb5760405162461bcd60e51b815260206004820152603160248201527f5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a207472604482015270185b9cd9995c919c9bdb4819985a5b1959607a1b60648201526084016106ae565b604080516000808252602082019092526001600160a01b038416908390604051612c3b9190613699565b60006040518083038185875af1925050503d8060008114612c78576040519150601f19603f3d011682016040523d82523d6000602084013e612c7d565b606091505b5050905080612ceb5760405162461bcd60e51b815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527308115512081d1c985b9cd9995c8819985a5b195960621b60648201526084016106ae565b505050565b600480546040516372af494b60e01b81526000926001600160a01b03909216916372af494b916123db918891879189910161325b565b60005b83811015612d41578181015183820152602001612d29565b50506000910152565b60008151808452612d62816020860160208601612d26565b601f01601f19169290920160200192915050565b6020815260006126b36020830184612d4a565b6001600160a01b0381168114612d9e57600080fd5b50565b600060208284031215612db357600080fd5b81356126b381612d89565b600080600060608486031215612dd357600080fd5b8335612dde81612d89565b95602085013595506040909401359392505050565b803561ffff81168114612e0557600080fd5b919050565b600080600080600060a08688031215612e2257600080fd5b8535612e2d81612d89565b9450602086013593506040860135925060608601359150612e5060808701612df3565b90509295509295909350565b8015158114612d9e57600080fd5b8035612e0581612e5c565b60008060008060008060008060e0898b031215612e9157600080fd5b88359750602089013596506040890135955060608901359450608089013567ffffffffffffffff80821115612ec557600080fd5b818b0191508b601f830112612ed957600080fd5b813581811115612ee857600080fd5b8c60208260051b8501011115612efd57600080fd5b602083019650809550505050612f1560a08a01612df3565b9150612f2360c08a01612e6a565b90509295985092959890939650565b60008060008060808587031215612f4857600080fd5b8435935060208501359250604085013591506060850135612f6881612e5c565b939692955090935050565b6020808252825182820181905260009190848201906040850190845b81811015612fab57835183529284019291840191600101612f8f565b50909695505050505050565b60008060408385031215612fca57600080fd5b8235612fd581612d89565b946020939093013593505050565b600060208284031215612ff557600080fd5b5035919050565b6000806000806080858703121561301257600080fd5b843561301d81612d89565b9350602085013561302d81612d89565b93969395505050506040820135916060013590565b600080600080600080600060e0888a03121561305d57600080fd5b873596506020880135955060408801359450606088013593506080880135925061308960a08901612df3565b915060c088013561309981612e5c565b8091505092959891949750929550565b60008060008060008060c087890312156130c257600080fd5b863595506020870135945060408701359350606087013592506130e760808801612df3565b915060a08701356130f781612e5c565b809150509295509295509295565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561314457613144613105565b604052919050565b60006020828403121561315e57600080fd5b815167ffffffffffffffff8082111561317657600080fd5b818401915084601f83011261318a57600080fd5b81518181111561319c5761319c613105565b6131af601f8201601f191660200161311b565b91508082528560208285010111156131c657600080fd5b6131d7816020840160208601612d26565b50949350505050565b6000602082840312156131f257600080fd5b81516126b381612e5c565b60208082526021908201527f4f6e6c792053796e7468724272696467652063616e20696e766f6b65207468696040820152607360f81b606082015260800190565b60006020828403121561325057600080fd5b81516126b381612d89565b6001600160a01b039390931683526020830191909152604082015260600190565b60006020828403121561328e57600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156132bd57600080fd5b815160ff811681146126b357600080fd5b61ffff851681526080602082015260006132eb6080830186612d4a565b6040830194909452506060015292915050565b6060815260006133116060830186612d4a565b61ffff94851660208401529290931660409091015292915050565b80516001600160a01b03168252602081015161335360208401826001600160a01b03169052565b5060408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e0830152610100808201518184015250610120808201516133b28285018261ffff169052565b505061014081810151801515848301526121e1565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60006101a0808301613402848961332c565b61016084018790526101808401919091528390526101c080830190600585901b8401018560005b8681101561349e578583036101bf19018452813536899003601e1901811261345057600080fd5b8801602081810191359067ffffffffffffffff82111561346f57600080fd5b81360383131561347e57600080fd5b6134898683856133c7565b96810196955093909301925050600101613429565b509098975050505050505050565b600080600080608085870312156134c257600080fd5b505082516020840151604085015160609095015191969095509092509050565b6001600160a01b03949094168452602084019290925260408301521515606082015260800190565b6000602080838503121561351d57600080fd5b825167ffffffffffffffff8082111561353557600080fd5b818501915085601f83011261354957600080fd5b81518181111561355b5761355b613105565b8060051b915061356c84830161311b565b818152918301840191848101908884111561358657600080fd5b938501935b838510156135a45784518252938501939085019061358b565b98975050505050505050565b600080604083850312156135c357600080fd5b8251915060208301516135d581612e5c565b809150509250929050565b8281526040602082015260006135f96040830184612d4a565b949350505050565b60008060006060848603121561361657600080fd5b8351925060208401519150604084015190509250925092565b8381526101a08101613644602083018561332c565b82610180830152949350505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561177657611776613653565b610180810161368b828561332c565b826101608301529392505050565b600082516136ab818460208701612d26565b9190910192915050565b600181815b808511156136f05781600019048211156136d6576136d6613653565b808516156136e357918102915b93841c93908002906136ba565b509250929050565b60008261370757506001611776565b8161371457506000611776565b816001811461372a576002811461373457613750565b6001915050611776565b60ff84111561374557613745613653565b50506001821b611776565b5060208310610133831016604e8410600b8410161715613773575081810a611776565b61377d83836136b5565b806000190482111561379157613791613653565b029392505050565b60006126b383836136f8565b6000826137c257634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561177657611776613653565b80820281158282048414176117765761177661365356fea264697066735822122034b16685186089ac601770913783faed5c6597562147fa2b41ebc0a2bc2efd6064736f6c63430008180033000000000000000000000000b0d394977a13bbde97a939519bba47a32f6b33420000000000000000000000006f808ae3445a711ecaa4da5c8330b051541a4de000000000000000000000000049a6e93768f0ba860c578da3b7b8de3b9b29f7ed

Deployed Bytecode

0x6080604052600436106101c65760003560e01c806388390dd1116100f7578063987757dd11610095578063e2023da011610064578063e2023da0146104e5578063e54660a9146104f8578063ebb5a59114610518578063fa51c28b1461052b57600080fd5b8063987757dd14610462578063ace2e3081461049d578063b1fe62fe146104b2578063c2eb8013146104d257600080fd5b80639064dc6d116100d15780639064dc6d146103f25780639324cac71461041257806393e5ba1e1461042d57806395d89b411461044d57600080fd5b806388390dd114610390578063899ffef4146103b05780638da5cb5b146103d257600080fd5b80635817c1241161016457806365115e391161013e57806365115e391461033357806370a0823114610346578063741853601461036657806379ba50971461037b57600080fd5b80635817c124146102db5780635a71fb58146102fb578063614d08f81461030e57600080fd5b806329992148116101a057806329992148146102535780632af64bd314610283578063313ce5671461029857806353a47bb7146102bb57600080fd5b806304f3bcec146101d257806306fdde031461020f5780631627540c1461023157600080fd5b366101cd57005b600080fd5b3480156101de57600080fd5b506000546101f2906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021b57600080fd5b5061022461053e565b6040516102069190612d76565b34801561023d57600080fd5b5061025161024c366004612da1565b6105c0565b005b34801561025f57600080fd5b5061027361026e366004612dbe565b61061c565b6040519015158152602001610206565b34801561028f57600080fd5b50610273610b97565b3480156102a457600080fd5b506102ad610c9c565b604051908152602001610206565b3480156102c757600080fd5b506003546101f2906001600160a01b031681565b3480156102e757600080fd5b506102ad6102f6366004612e0a565b610d1d565b6102ad610309366004612e75565b610df4565b34801561031a57600080fd5b506102ad6d2bb930b83832b21029bcb73a343960911b81565b610251610341366004612f32565b610ef0565b34801561035257600080fd5b506102ad610361366004612da1565b611032565b34801561037257600080fd5b50610251611288565b34801561038757600080fd5b50610251611401565b34801561039c57600080fd5b506102ad6103ab366004612e0a565b6114eb565b3480156103bc57600080fd5b506103c5611576565b6040516102069190612f73565b3480156103de57600080fd5b506002546101f2906001600160a01b031681565b3480156103fe57600080fd5b506102ad61040d366004612fb7565b6116b8565b34801561041e57600080fd5b506102ad631cd554d160e21b81565b34801561043957600080fd5b506102ad610448366004612e0a565b61177c565b34801561045957600080fd5b50610224611807565b34801561046e57600080fd5b5061048261047d366004612fe3565b61185c565b60408051938452602084019290925290820152606001610206565b3480156104a957600080fd5b506103c56118e9565b3480156104be57600080fd5b506102516104cd366004612ffc565b611966565b6102ad6104e0366004613042565b611d6b565b6102516104f3366004612f32565b611e64565b34801561050457600080fd5b506101f2610513366004612fe3565b611f93565b610251610526366004612f32565b612004565b6102ad6105393660046130a9565b6121e7565b6060600460009054906101000a90046001600160a01b03166001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa158015610593573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105bb919081019061314c565b905090565b6105c86122dd565b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229060200160405180910390a150565b6000610626612351565b600054604051633933006760e11b81523360048201526001600160a01b039091169063726600ce90602401602060405180830381865afa15801561066e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061069291906131e0565b6106b75760405162461bcd60e51b81526004016106ae906131fd565b60405180910390fd5b6004805460405163e54660a960e01b81529182018590526000916001600160a01b039091169063e54660a990602401602060405180830381865afa158015610703573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610727919061323e565b6001600160a01b0316036107575760405162461bcd60e51b815260206004820152600060248201526044016106ae565b60048054604051633c1ac27d60e01b81526001600160a01b0390911691633c1ac27d9161078a913091889188910161325b565b600060405180830381600087803b1580156107a457600080fd5b505af11580156107b8573d6000803e3d6000fd5b505050506107c78483856123a5565b506004805460405163e54660a960e01b815291820185905273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee916001600160a01b039091169063e54660a990602401602060405180830381865afa158015610827573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061084b919061323e565b6001600160a01b0316036108e657610861612417565b604051632c97903560e11b81526001600160a01b03868116600483015273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee602483015260448201859052919091169063592f206a9084906064016000604051808303818588803b1580156108c857600080fd5b505af11580156108dc573d6000803e3d6000fd5b5050505050610b49565b6004805460405163e54660a960e01b81529182018590526001600160a01b03169063e54660a990602401602060405180830381865afa15801561092d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610951919061323e565b6001600160a01b031663dd62ed3e30610968612417565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa1580156109b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d7919061327c565b600003610a5f576004805460405163e54660a960e01b8152918201859052610a5f916001600160a01b039091169063e54660a990602401602060405180830381865afa158015610a2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4f919061323e565b610a57612417565b600019612436565b610a67612417565b6004805460405163e54660a960e01b81529182018690526001600160a01b039283169263592f206a926000928992169063e54660a990602401602060405180830381865afa158015610abd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae1919061323e565b6040516001600160e01b031960e086901b1681526001600160a01b03928316600482015291166024820152604481018690526064016000604051808303818588803b158015610b2f57600080fd5b505af1158015610b43573d6000803e3d6000fd5b50505050505b60408051848152602081018490526001600160a01b038616917f68d5b1cc3e612b2a695fb456472ea86e70b4718956af6948ec8ab5f5e203bf1e910160405180910390a25060019392505050565b600080610ba2611576565b905060005b8151811015610c93576000828281518110610bc457610bc4613295565b60209081029190910181015160008181526001909252604080832054925490516321f8a72160e01b8152600481018390529193506001600160a01b039283169216906321f8a72190602401602060405180830381865afa158015610c2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c50919061323e565b6001600160a01b0316141580610c7b57506000818152600160205260409020546001600160a01b0316155b15610c8a576000935050505090565b50600101610ba7565b50600191505090565b6000600460009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cf1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d1591906132ab565b60ff16905090565b60408051606087901b6001600160601b031916602082015281516014818303018152603482019092526000918291610d5e91600991899089906054016132ce565b6040516020818303038152906040529050610d7884612565565b6001600160a01b0316632bb821bd826009866040518463ffffffff1660e01b8152600401610da8939291906132fe565b602060405180830381865afa158015610dc5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610de9919061327c565b979650505050505050565b60008887610e028282612596565b610e0a612351565b60408051610160810182523380825260208201529081018c9052606081018a9052608081018b9052600060a0820181905260c0820181905260e0820181905261010082015261ffff8616610120820152841515610140820152610e6b612603565b6001600160a01b031663e9f6eec334838c8c8c6040518663ffffffff1660e01b8152600401610e9d94939291906133f0565b60206040518083038185885af1158015610ebb573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610ee0919061327c565b9c9b505050505050505050505050565b610ef8612622565b610f00612351565b6000610f0a612662565b6001600160a01b031663ba0a46213386886040518463ffffffff1660e01b8152600401610f399392919061325b565b6080604051808303816000875af1158015610f58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7c91906134ac565b5050509050610f8a83612565565b6001600160a01b031663397b2b3a34338785876040518663ffffffff1660e01b8152600401610fbc94939291906134e2565b6000604051808303818588803b158015610fd557600080fd5b505af1158015610fe9573d6000803e3d6000fd5b505060408051888152602081018690523394507fa74ffa9933a24c93c1d35e504f5c9aab320f63fc816ddf1dd2f98fca9724e0c093500190505b60405180910390a25050505050565b6000806000600460009054906101000a90046001600160a01b03166001600160a01b031663ace2e3086040518163ffffffff1660e01b8152600401600060405180830381865afa15801561108a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110b2919081019061350a565b905060005b815181101561127f5760008282815181106110d4576110d4613295565b6020908102919091010151600480546040516303eaaa5960e11b81529182018390526001600160a01b03898116602484015292935060009216906307d554b290604401602060405180830381865afa158015611134573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611158919061327c565b1115611276576000611168612676565b6001600160a01b0316630c71cd23836040518263ffffffff1660e01b815260040161119591815260200190565b6040805180830381865afa1580156111b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d591906135b0565b50600480546040516303eaaa5960e11b81529293506112729261126b9285926001600160a01b0316916307d554b2916112249189918f91019182526001600160a01b0316602082015260400190565b602060405180830381865afa158015611241573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611265919061327c565b90612691565b86906126ba565b9450505b506001016110b7565b50909392505050565b6000611292611576565b905060005b81518110156113fd5760008282815181106112b4576112b4613295565b6020026020010151905060008060009054906101000a90046001600160a01b03166001600160a01b031663dacb2d01838460405160200161132191907f5265736f6c766572206d697373696e67207461726765743a20000000000000008152601981019190915260390190565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161134d9291906135e0565b602060405180830381865afa15801561136a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138e919061323e565b60008381526001602090815260409182902080546001600160a01b0319166001600160a01b0385169081179091558251868152918201529192507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68910160405180910390a15050600101611297565b5050565b6003546001600160a01b031633146114795760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b60648201526084016106ae565b600254600354604080516001600160a01b0393841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160038054600280546001600160a01b03199081166001600160a01b03841617909155169055565b60408051606087901b6001600160601b03191660208201528151601481830301815260348201909252600091829161152c91600491899089906054016132ce565b604051602081830303815290604052905061154684612565565b6001600160a01b0316632bb821bd826004866040518463ffffffff1660e01b8152600401610da8939291906132fe565b60408051600680825260e082019092526060916020820160c0803683370190505090506b53797374656d53746174757360a01b816000815181106115bc576115bc613295565b6020026020010181815250506822bc31b430b733b2b960b91b816001815181106115e8576115e8613295565b6020026020010181815250506524b9b9bab2b960d11b8160028151811061161157611611613295565b6020026020010181815250506c45786368616e6765526174657360981b8160038151811061164157611641613295565b6020026020010181815250507021b7b63630ba32b930b626b0b730b3b2b960791b8160048151811061167557611675613295565b6020026020010181815250507027b33321b430b4b722bc31b430b733b2b960791b816005815181106116a9576116a9613295565b60200260200101818152505090565b6000806116c3612676565b6001600160a01b0316630c71cd23846040518263ffffffff1660e01b81526004016116f091815260200190565b6040805180830381865afa15801561170c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061173091906135b0565b50600480546040516303eaaa5960e11b81529182018690526001600160a01b0387811660248401529293506117729284929116906307d554b290604401611224565b9150505b92915050565b60408051606087901b6001600160601b0319166020820152815160148183030181526034820190925260009182916117bd91600191899089906054016132ce565b60405160208183030381529060405290506117d784612565565b6001600160a01b0316632bb821bd826001866040518463ffffffff1660e01b8152600401610da8939291906132fe565b6060600460009054906101000a90046001600160a01b03166001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015610593573d6000803e3d6000fd5b6000806000611869612719565b6040516306c5a00b60e21b8152336004820152602481018690526001600160a01b039190911690631b16802c906044016060604051808303816000875af11580156118b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118dc9190613601565b9250925092509193909250565b6060600460009054906101000a90046001600160a01b03166001600160a01b031663ace2e3086040518163ffffffff1660e01b8152600401600060405180830381865afa15801561193e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105bb919081019061350a565b61196e612622565b611976612351565b600054604051633933006760e11b81523360048201526001600160a01b039091169063726600ce90602401602060405180830381865afa1580156119be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e291906131e0565b6119fe5760405162461bcd60e51b81526004016106ae906131fd565b60008111611a595760405162461bcd60e51b815260206004820152602260248201527f436f6c6c61746572616c20616d6f756e74206d757374206e6f74206265207a65604482015261726f60f01b60648201526084016106ae565b6004805460405163e54660a960e01b81529182018490526000916001600160a01b039091169063e54660a990602401602060405180830381865afa158015611aa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac9919061323e565b6001600160a01b031603611b1f5760405162461bcd60e51b815260206004820152601e60248201527f4e6f20436f6c6c61746572616c2043757272656e6379206578697374732e000060448201526064016106ae565b600480546040516303eaaa5960e11b81529182018490526001600160a01b03868116602484015283929116906307d554b290604401602060405180830381865afa158015611b71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b95919061327c565b1015611bf85760405162461bcd60e51b815260206004820152602c60248201527f496e73756666696369656e7420436f6c6c61746572616c2042616c616e63652060448201526b3a37903bb4ba34323930bb9760a11b60648201526084016106ae565b60048054604051633c1ac27d60e01b81526001600160a01b0390911691633c1ac27d91611c2b918791879187910161325b565b600060405180830381600087803b158015611c4557600080fd5b505af1158015611c59573d6000803e3d6000fd5b505050506000611c6a8583856123a5565b905080611caf5760405162461bcd60e51b8152602060048201526013602482015272213ab9371029bcb73a3439103330b4b632b21760691b60448201526064016106ae565b6004805460405163e54660a960e01b8152918201859052849133917f510ce44954935b74c86edc796a774a020b5e32e5b5c86b9a8ef997be6f2e6546916001600160a01b039091169063e54660a990602401602060405180830381865afa158015611d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d42919061323e565b604080516001600160a01b03909216825260208201879052015b60405180910390a35050505050565b60008786611d798282612596565b611d81612351565b60408051610160810182523380825260208201529081018b905260608101899052608081018a9052600060a0820181905260c0820181905260e0820181905261010082015261ffff8616610120820152841515610140820152611de2612719565b6001600160a01b0316630be5396a348a848b6040518563ffffffff1660e01b8152600401611e129392919061362f565b60206040518083038185885af1158015611e30573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611e55919061327c565b9b9a5050505050505050505050565b611e6c612622565b611e74612351565b6000611e7e612662565b60405163548d57a560e11b8152336004820152602481018790526001600160a01b03919091169063a91aaf4a906044016020604051808303816000875af1158015611ecd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ef1919061327c565b9050611efc83612565565b6001600160a01b0316634fa3431034338488876040518663ffffffff1660e01b8152600401611f2e94939291906134e2565b6000604051808303818588803b158015611f4757600080fd5b505af1158015611f5b573d6000803e3d6000fd5b50506040518481523393507f3f0bdfc22be3f173a1a388fb71f1e246a7810b438aa451e08fb466a70e37353a92506020019050611023565b6004805460405163e54660a960e01b81529182018390526000916001600160a01b039091169063e54660a9906024015b602060405180830381865afa158015611fe0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611776919061323e565b61200c612622565b612014612351565b600083116120785760405162461bcd60e51b815260206004820152602b60248201527f436f6c6c61746572616c20616d6f756e74206d757374206265206c617267657260448201526a103a3430b7103d32b9379760a91b60648201526084016106ae565b3461208533808787612730565b6004805460405163e54660a960e01b815291820187905273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee916001600160a01b039091169063e54660a990602401602060405180830381865afa1580156120e4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612108919061323e565b6001600160a01b031603612172578334116121655760405162461bcd60e51b815260206004820152601860248201527f496e73756666696369656e742045544820616d6f756e742e000000000000000060448201526064016106ae565b61216f8434613669565b90505b61217b83612565565b6001600160a01b0316630cf2abc682338888876040518663ffffffff1660e01b81526004016121ad94939291906134e2565b6000604051808303818588803b1580156121c657600080fd5b505af11580156121da573d6000803e3d6000fd5b5050505050505b50505050565b600086856121f58282612596565b6121fd612351565b60408051610160810182523380825260208201529081018a90526060810188905260808101899052600060a0820181905260c0820181905260e0820181905261010082015261ffff861661012082015284151561014082015261225e612719565b6001600160a01b03166397935a3d34838a6040518463ffffffff1660e01b815260040161228c92919061367c565b60206040518083038185885af11580156122aa573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906122cf919061327c565b9a9950505050505050505050565b6002546001600160a01b0316331461234f5760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b60648201526084016106ae565b565b6123596129c7565b6001600160a01b031663086dabd16040518163ffffffff1660e01b815260040160006040518083038186803b15801561239157600080fd5b505afa1580156121e1573d6000803e3d6000fd5b60048054604051630c47603560e41b81526000926001600160a01b039092169163c4760350916123db918891879189910161325b565b600060405180830381600087803b1580156123f557600080fd5b505af1158015612409573d6000803e3d6000fd5b506001979650505050505050565b60006105bb7021b7b63630ba32b930b626b0b730b3b2b960791b6129dd565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b17905291516000928392908716916124929190613699565b6000604051808303816000865af19150503d80600081146124cf576040519150601f19603f3d011682016040523d82523d6000602084013e6124d4565b606091505b50915091508180156124fe5750805115806124fe5750808060200190518101906124fe91906131e0565b61255e5760405162461bcd60e51b815260206004820152602b60248201527f5472616e7366657248656c7065723a3a73616665417070726f76653a2061707060448201526a1c9bdd994819985a5b195960aa1b60648201526084016106ae565b5050505050565b6000805460405162c8ac9760e41b8152600481018490526001600160a01b0390911690630c8ac97090602401611fc3565b61259e6129c7565b604051630e7005d160e11b815260048101849052602481018390526001600160a01b039190911690631ce00ba29060440160006040518083038186803b1580156125e757600080fd5b505afa1580156125fb573d6000803e3d6000fd5b505050505050565b60006105bb7027b33321b430b4b722bc31b430b733b2b960791b6129dd565b61262a6129c7565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b15801561239157600080fd5b60006105bb6524b9b9bab2b960d11b6129dd565b60006105bb6c45786368616e6765526174657360981b6129dd565b600061269f6012600a613799565b6126a98484612a59565b6126b391906137a5565b9392505050565b6000806126c783856137c7565b9050838110156126b35760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f77000000000060448201526064016106ae565b60006105bb6822bc31b430b733b2b960b91b6129dd565b6004805460405163e54660a960e01b81529182018490526000916001600160a01b039091169063e54660a990602401602060405180830381865afa15801561277c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127a0919061323e565b6001600160a01b0316036127f65760405162461bcd60e51b815260206004820152601e60248201527f4e6f20436f6c6c61746572616c2043757272656e6379206578697374732e000060448201526064016106ae565b6004805460405163e54660a960e01b815291820184905273eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee916001600160a01b039091169063e54660a990602401602060405180830381865afa158015612855573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612879919061323e565b6001600160a01b031614612911576004805460405163e54660a960e01b815291820184905261290c916001600160a01b039091169063e54660a990602401602060405180830381865afa1580156128d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128f8919061323e565b60045486906001600160a01b031684612adb565b612927565b600454612927906001600160a01b031682612c11565b6000612934848385612cf0565b9050806129795760405162461bcd60e51b815260206004820152601360248201527226b4b73a1029bcb73a3439103330b4b632b21760691b60448201526064016106ae565b836001600160a01b0316856001600160a01b03167fa6bf5262c311ff2cca4aaf9e52d13d0a1fe98368ed78321236208446287683478585604051611d5c929190918252602082015260400190565b60006105bb6b53797374656d53746174757360a01b5b600081815260016020908152604080832054905170026b4b9b9b4b7339030b2323932b9b99d1607d1b92810192909252603182018490526001600160a01b0316908115159060510160405160208183030381529060405290612a525760405162461bcd60e51b81526004016106ae9190612d76565b5092915050565b600082600003612a6b57506000611776565b6000612a7783856137da565b905082612a8485836137a5565b146126b35760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b60648201526084016106ae565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691612b3f9190613699565b6000604051808303816000865af19150503d8060008114612b7c576040519150601f19603f3d011682016040523d82523d6000602084013e612b81565b606091505b5091509150818015612bab575080511580612bab575080806020019051810190612bab91906131e0565b6125fb5760405162461bcd60e51b815260206004820152603160248201527f5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a207472604482015270185b9cd9995c919c9bdb4819985a5b1959607a1b60648201526084016106ae565b604080516000808252602082019092526001600160a01b038416908390604051612c3b9190613699565b60006040518083038185875af1925050503d8060008114612c78576040519150601f19603f3d011682016040523d82523d6000602084013e612c7d565b606091505b5050905080612ceb5760405162461bcd60e51b815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527308115512081d1c985b9cd9995c8819985a5b195960621b60648201526084016106ae565b505050565b600480546040516372af494b60e01b81526000926001600160a01b03909216916372af494b916123db918891879189910161325b565b60005b83811015612d41578181015183820152602001612d29565b50506000910152565b60008151808452612d62816020860160208601612d26565b601f01601f19169290920160200192915050565b6020815260006126b36020830184612d4a565b6001600160a01b0381168114612d9e57600080fd5b50565b600060208284031215612db357600080fd5b81356126b381612d89565b600080600060608486031215612dd357600080fd5b8335612dde81612d89565b95602085013595506040909401359392505050565b803561ffff81168114612e0557600080fd5b919050565b600080600080600060a08688031215612e2257600080fd5b8535612e2d81612d89565b9450602086013593506040860135925060608601359150612e5060808701612df3565b90509295509295909350565b8015158114612d9e57600080fd5b8035612e0581612e5c565b60008060008060008060008060e0898b031215612e9157600080fd5b88359750602089013596506040890135955060608901359450608089013567ffffffffffffffff80821115612ec557600080fd5b818b0191508b601f830112612ed957600080fd5b813581811115612ee857600080fd5b8c60208260051b8501011115612efd57600080fd5b602083019650809550505050612f1560a08a01612df3565b9150612f2360c08a01612e6a565b90509295985092959890939650565b60008060008060808587031215612f4857600080fd5b8435935060208501359250604085013591506060850135612f6881612e5c565b939692955090935050565b6020808252825182820181905260009190848201906040850190845b81811015612fab57835183529284019291840191600101612f8f565b50909695505050505050565b60008060408385031215612fca57600080fd5b8235612fd581612d89565b946020939093013593505050565b600060208284031215612ff557600080fd5b5035919050565b6000806000806080858703121561301257600080fd5b843561301d81612d89565b9350602085013561302d81612d89565b93969395505050506040820135916060013590565b600080600080600080600060e0888a03121561305d57600080fd5b873596506020880135955060408801359450606088013593506080880135925061308960a08901612df3565b915060c088013561309981612e5c565b8091505092959891949750929550565b60008060008060008060c087890312156130c257600080fd5b863595506020870135945060408701359350606087013592506130e760808801612df3565b915060a08701356130f781612e5c565b809150509295509295509295565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561314457613144613105565b604052919050565b60006020828403121561315e57600080fd5b815167ffffffffffffffff8082111561317657600080fd5b818401915084601f83011261318a57600080fd5b81518181111561319c5761319c613105565b6131af601f8201601f191660200161311b565b91508082528560208285010111156131c657600080fd5b6131d7816020840160208601612d26565b50949350505050565b6000602082840312156131f257600080fd5b81516126b381612e5c565b60208082526021908201527f4f6e6c792053796e7468724272696467652063616e20696e766f6b65207468696040820152607360f81b606082015260800190565b60006020828403121561325057600080fd5b81516126b381612d89565b6001600160a01b039390931683526020830191909152604082015260600190565b60006020828403121561328e57600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156132bd57600080fd5b815160ff811681146126b357600080fd5b61ffff851681526080602082015260006132eb6080830186612d4a565b6040830194909452506060015292915050565b6060815260006133116060830186612d4a565b61ffff94851660208401529290931660409091015292915050565b80516001600160a01b03168252602081015161335360208401826001600160a01b03169052565b5060408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e0830152610100808201518184015250610120808201516133b28285018261ffff169052565b505061014081810151801515848301526121e1565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b60006101a0808301613402848961332c565b61016084018790526101808401919091528390526101c080830190600585901b8401018560005b8681101561349e578583036101bf19018452813536899003601e1901811261345057600080fd5b8801602081810191359067ffffffffffffffff82111561346f57600080fd5b81360383131561347e57600080fd5b6134898683856133c7565b96810196955093909301925050600101613429565b509098975050505050505050565b600080600080608085870312156134c257600080fd5b505082516020840151604085015160609095015191969095509092509050565b6001600160a01b03949094168452602084019290925260408301521515606082015260800190565b6000602080838503121561351d57600080fd5b825167ffffffffffffffff8082111561353557600080fd5b818501915085601f83011261354957600080fd5b81518181111561355b5761355b613105565b8060051b915061356c84830161311b565b818152918301840191848101908884111561358657600080fd5b938501935b838510156135a45784518252938501939085019061358b565b98975050505050505050565b600080604083850312156135c357600080fd5b8251915060208301516135d581612e5c565b809150509250929050565b8281526040602082015260006135f96040830184612d4a565b949350505050565b60008060006060848603121561361657600080fd5b8351925060208401519150604084015190509250925092565b8381526101a08101613644602083018561332c565b82610180830152949350505050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561177657611776613653565b610180810161368b828561332c565b826101608301529392505050565b600082516136ab818460208701612d26565b9190910192915050565b600181815b808511156136f05781600019048211156136d6576136d6613653565b808516156136e357918102915b93841c93908002906136ba565b509250929050565b60008261370757506001611776565b8161371457506000611776565b816001811461372a576002811461373457613750565b6001915050611776565b60ff84111561374557613745613653565b50506001821b611776565b5060208310610133831016604e8410600b8410161715613773575081810a611776565b61377d83836136b5565b806000190482111561379157613791613653565b029392505050565b60006126b383836136f8565b6000826137c257634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561177657611776613653565b80820281158282048414176117765761177661365356fea264697066735822122034b16685186089ac601770913783faed5c6597562147fa2b41ebc0a2bc2efd6064736f6c63430008180033

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

000000000000000000000000b0d394977a13bbde97a939519bba47a32f6b33420000000000000000000000006f808ae3445a711ecaa4da5c8330b051541a4de000000000000000000000000049a6e93768f0ba860c578da3b7b8de3b9b29f7ed

-----Decoded View---------------
Arg [0] : _extTokenState (address): 0xB0d394977A13bBDE97A939519BBa47A32F6b3342
Arg [1] : _owner (address): 0x6F808aE3445A711ecAa4DA5c8330B051541A4dE0
Arg [2] : _resolver (address): 0x49a6E93768f0Ba860c578dA3B7b8DE3B9b29F7eD

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000b0d394977a13bbde97a939519bba47a32f6b3342
Arg [1] : 0000000000000000000000006f808ae3445a711ecaa4da5c8330b051541a4de0
Arg [2] : 00000000000000000000000049a6e93768f0ba860c578da3b7b8de3b9b29f7ed


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.