ETH Price: $2,470.67 (-20.18%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Exempt_depositor179606322023-08-21 4:10:35532 days ago1692591035IN
0x124Dd8a6...a8Ae1312D
0 ETH0.0007035515.70501344
Global_stop173460332023-05-26 21:47:11618 days ago1685137631IN
0x124Dd8a6...a8Ae1312D
0 ETH0.004296626.39173778
Withdraw_asset173460272023-05-26 21:45:59618 days ago1685137559IN
0x124Dd8a6...a8Ae1312D
0 ETH0.0045202926.82076101
Withdraw_asset173460202023-05-26 21:44:35618 days ago1685137475IN
0x124Dd8a6...a8Ae1312D
0 ETH0.005202727.33360366
Withdraw_asset173460092023-05-26 21:42:23618 days ago1685137343IN
0x124Dd8a6...a8Ae1312D
0 ETH0.0051789328.17011629
Withdraw_asset173459922023-05-26 21:38:59618 days ago1685137139IN
0x124Dd8a6...a8Ae1312D
0 ETH0.0061764130.02500258
Global_resume173459852023-05-26 21:37:35618 days ago1685137055IN
0x124Dd8a6...a8Ae1312D
0 ETH0.0039690528.15914454
Global_stop173382962023-05-25 19:40:59619 days ago1685043659IN
0x124Dd8a6...a8Ae1312D
0 ETH0.0058405437.44512451
Deposit_asset173361242023-05-25 12:21:47619 days ago1685017307IN
0x124Dd8a6...a8Ae1312D
0 ETH0.0037239950.18045081
Withdraw_asset173325812023-05-25 0:24:11620 days ago1684974251IN
0x124Dd8a6...a8Ae1312D
0 ETH0.0060746329.01150168
Deposit_asset173315772023-05-24 20:59:59620 days ago1684961999IN
0x124Dd8a6...a8Ae1312D
0 ETH0.002550538.38516203
Deposit_asset173311862023-05-24 19:40:35620 days ago1684957235IN
0x124Dd8a6...a8Ae1312D
0 ETH0.0033609340.33859247
Deposit_asset173307042023-05-24 18:03:23620 days ago1684951403IN
0x124Dd8a6...a8Ae1312D
0 ETH0.005899989.09824038
Withdraw_asset173297142023-05-24 14:43:47620 days ago1684939427IN
0x124Dd8a6...a8Ae1312D
0 ETH0.012451459.45575746
Deposit_asset173296612023-05-24 14:33:11620 days ago1684938791IN
0x124Dd8a6...a8Ae1312D
0 ETH0.0048726259.63172585
Withdraw_asset173296482023-05-24 14:30:35620 days ago1684938635IN
0x124Dd8a6...a8Ae1312D
0 ETH0.0135185370.2907738
Deposit_asset173294932023-05-24 13:59:11620 days ago1684936751IN
0x124Dd8a6...a8Ae1312D
0 ETH0.007278.85054282
Deposit_asset173294772023-05-24 13:55:59620 days ago1684936559IN
0x124Dd8a6...a8Ae1312D
0 ETH0.0075146882.30758012
Deposit_asset173291222023-05-24 12:44:11620 days ago1684932251IN
0x124Dd8a6...a8Ae1312D
0 ETH0.0020065134.31407994
Deposit_asset173290392023-05-24 12:27:23620 days ago1684931243IN
0x124Dd8a6...a8Ae1312D
0 ETH0.002164834.22558701
Deposit_asset173289982023-05-24 12:19:11620 days ago1684930751IN
0x124Dd8a6...a8Ae1312D
0 ETH0.0029461336.06042296
Deposit_asset173286902023-05-24 11:16:23620 days ago1684926983IN
0x124Dd8a6...a8Ae1312D
0 ETH0.002927935.14134388
Deposit_asset173284882023-05-24 10:35:35620 days ago1684924535IN
0x124Dd8a6...a8Ae1312D
0 ETH0.0023730129.04552167
Withdraw_asset173283462023-05-24 10:06:47620 days ago1684922807IN
0x124Dd8a6...a8Ae1312D
0 ETH0.0076041736.3101069
Deposit_asset173281432023-05-24 9:25:35620 days ago1684920335IN
0x124Dd8a6...a8Ae1312D
0 ETH0.0026877631.06816967
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ERC20_Bridge_Logic_Restricted

Compiler Version
v0.8.8+commit.dddeac2f

Optimization Enabled:
Yes with 20000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 1 of 9: ERC20_Bridge_Logic_Restricted.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.8;

import "./IERC20.sol";
import "./IERC20_Bridge_Logic_Restricted.sol";
import "./IMultisigControl.sol";
import "./ERC20_Asset_Pool.sol";

/// @title ERC20 Bridge Logic
/// @author Vega Protocol
/// @notice This contract is used by Vega network users to deposit and withdraw ERC20 tokens to/from Vega.
// @notice All funds deposited/withdrawn are to/from the assigned ERC20_Asset_Pool
contract ERC20_Bridge_Logic_Restricted is IERC20_Bridge_Logic_Restricted {
    address payable public erc20_asset_pool_address;
    // asset address => is listed
    mapping(address => bool) listed_tokens;
    // Vega asset ID => asset_source
    mapping(bytes32 => address) vega_asset_ids_to_source;
    // asset_source => Vega asset ID
    mapping(address => bytes32) asset_source_to_vega_asset_id;

    /// @param erc20_asset_pool Initial Asset Pool contract address
    constructor(address payable erc20_asset_pool) {
        require(erc20_asset_pool != address(0), "invalid asset pool address");
        erc20_asset_pool_address = erc20_asset_pool;
    }

    function multisig_control_address() internal view returns (address) {
        return ERC20_Asset_Pool(erc20_asset_pool_address).multisig_control_address();
    }

    /***************************FUNCTIONS*************************/
    /// @notice This function lists the given ERC20 token contract as valid for deposit to this bridge
    /// @param asset_source Contract address for given ERC20 token
    /// @param vega_asset_id Vega-generated asset ID for internal use in Vega Core
    /// @param lifetime_limit Initial lifetime deposit limit *RESTRICTION FEATURE*
    /// @param withdraw_threshold Amount at which the withdraw delay goes into effect *RESTRICTION FEATURE*
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @dev Emits Asset_Listed if successful
    function list_asset(
        address asset_source,
        bytes32 vega_asset_id,
        uint256 lifetime_limit,
        uint256 withdraw_threshold,
        uint256 nonce,
        bytes memory signatures
    ) external override {
        require(asset_source != address(0), "invalid asset source");
        require(!listed_tokens[asset_source], "asset already listed");
        bytes memory message = abi.encode(
            asset_source,
            vega_asset_id,
            lifetime_limit,
            withdraw_threshold,
            nonce,
            "list_asset"
        );
        require(
            IMultisigControl(multisig_control_address()).verify_signatures(signatures, message, nonce),
            "bad signatures"
        );
        listed_tokens[asset_source] = true;
        vega_asset_ids_to_source[vega_asset_id] = asset_source;
        asset_source_to_vega_asset_id[asset_source] = vega_asset_id;
        asset_deposit_lifetime_limit[asset_source] = lifetime_limit;
        withdraw_thresholds[asset_source] = withdraw_threshold;
        emit Asset_Listed(asset_source, vega_asset_id, nonce);
    }

    /// @notice This function removes from listing the given ERC20 token contract. This marks the token as invalid for deposit to this bridge
    /// @param asset_source Contract address for given ERC20 token
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @dev Emits Asset_Removed if successful
    function remove_asset(
        address asset_source,
        uint256 nonce,
        bytes memory signatures
    ) external override {
        require(listed_tokens[asset_source], "asset not listed");
        bytes memory message = abi.encode(asset_source, nonce, "remove_asset");
        require(
            IMultisigControl(multisig_control_address()).verify_signatures(signatures, message, nonce),
            "bad signatures"
        );
        listed_tokens[asset_source] = false;
        emit Asset_Removed(asset_source, nonce);
    }

    /************************RESTRICTIONS***************************/
    // user => asset_source => deposit total
    mapping(address => mapping(address => uint256)) user_lifetime_deposits;
    // asset_source => deposit_limit
    mapping(address => uint256) asset_deposit_lifetime_limit;
    uint256 public default_withdraw_delay = 432000;
    // asset_source => threshold
    mapping(address => uint256) withdraw_thresholds;
    bool public is_stopped;

    // depositor => is exempt from deposit limits
    mapping(address => bool) exempt_depositors;

    /// @notice This function sets the lifetime maximum deposit for a given asset
    /// @param asset_source Contract address for given ERC20 token
    /// @param lifetime_limit Deposit limit for a given ethereum address
    /// @param threshold Withdraw size above which the withdraw delay goes into effect
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @dev asset must first be listed
    function set_asset_limits(
        address asset_source,
        uint256 lifetime_limit,
        uint256 threshold,
        uint256 nonce,
        bytes calldata signatures
    ) external override {
        require(listed_tokens[asset_source], "asset not listed");
        bytes memory message = abi.encode(asset_source, lifetime_limit, threshold, nonce, "set_asset_limits");
        require(
            IMultisigControl(multisig_control_address()).verify_signatures(signatures, message, nonce),
            "bad signatures"
        );
        asset_deposit_lifetime_limit[asset_source] = lifetime_limit;
        withdraw_thresholds[asset_source] = threshold;

        emit Asset_Limits_Updated(asset_source, lifetime_limit, threshold);
    }

    /// @notice This view returns the lifetime deposit limit for the given asset
    /// @param asset_source Contract address for given ERC20 token
    /// @return Lifetime limit for the given asset
    function get_asset_deposit_lifetime_limit(address asset_source) external view override returns (uint256) {
        return asset_deposit_lifetime_limit[asset_source];
    }

    /// @notice This view returns the given token's withdraw threshold above which the withdraw delay goes into effect
    /// @param asset_source Contract address for given ERC20 token
    /// @return Withdraw threshold
    function get_withdraw_threshold(address asset_source) external view override returns (uint256) {
        return withdraw_thresholds[asset_source];
    }

    /// @notice This function sets the withdraw delay for withdrawals over the per-asset set thresholds
    /// @param delay Amount of time to delay a withdrawal
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    function set_withdraw_delay(
        uint256 delay,
        uint256 nonce,
        bytes calldata signatures
    ) external override {
        bytes memory message = abi.encode(delay, nonce, "set_withdraw_delay");
        require(
            IMultisigControl(multisig_control_address()).verify_signatures(signatures, message, nonce),
            "bad signatures"
        );
        default_withdraw_delay = delay;
        emit Bridge_Withdraw_Delay_Set(delay);
    }

    /// @notice This function triggers the global bridge stop that halts all withdrawals and deposits until it is resumed
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @dev bridge must not be stopped already
    /// @dev emits Bridge_Stopped if successful
    function global_stop(uint256 nonce, bytes calldata signatures) external override {
        require(!is_stopped, "bridge already stopped");
        bytes memory message = abi.encode(nonce, "global_stop");
        require(
            IMultisigControl(multisig_control_address()).verify_signatures(signatures, message, nonce),
            "bad signatures"
        );
        is_stopped = true;
        emit Bridge_Stopped();
    }

    /// @notice This function resumes bridge operations from the stopped state
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @dev bridge must be stopped
    /// @dev emits Bridge_Resumed if successful
    function global_resume(uint256 nonce, bytes calldata signatures) external override {
        require(is_stopped, "bridge not stopped");
        bytes memory message = abi.encode(nonce, "global_resume");
        require(
            IMultisigControl(multisig_control_address()).verify_signatures(signatures, message, nonce),
            "bad signatures"
        );
        is_stopped = false;
        emit Bridge_Resumed();
    }

    /// @notice this function allows the sender to exempt themselves from the deposit limits
    /// @notice this feature is specifically for liquidity and rewards providers
    /// @dev emits Depositor_Exempted if successful
    function exempt_depositor() external override {
        require(!exempt_depositors[msg.sender], "sender already exempt");
        exempt_depositors[msg.sender] = true;
        emit Depositor_Exempted(msg.sender);
    }

    /// @notice this function allows the exemption_lister to revoke a depositor's exemption from deposit limits
    /// @notice this feature is specifically for liquidity and rewards providers
    /// @dev emits Depositor_Exemption_Revoked if successful
    function revoke_exempt_depositor() external override {
        require(exempt_depositors[msg.sender], "sender not exempt");
        exempt_depositors[msg.sender] = false;
        emit Depositor_Exemption_Revoked(msg.sender);
    }

    /// @notice this view returns true if the given despoitor address has been exempted from deposit limits
    /// @param depositor The depositor to check
    /// @return true if depositor is exempt
    function is_exempt_depositor(address depositor) external view override returns (bool) {
        return exempt_depositors[depositor];
    }

    /***********************END RESTRICTIONS*************************/

    /// @notice This function withdraws assets to the target Ethereum address
    /// @param asset_source Contract address for given ERC20 token
    /// @param amount Amount of ERC20 tokens to withdraw
    /// @param target Target Ethereum address to receive withdrawn ERC20 tokens
    /// @param creation Timestamp of when requestion was created *RESTRICTION FEATURE*
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @dev Emits Asset_Withdrawn if successful
    function withdraw_asset(
        address asset_source,
        uint256 amount,
        address target,
        uint256 creation,
        uint256 nonce,
        bytes memory signatures
    ) external override {
        require(!is_stopped, "bridge stopped");
        require(
            withdraw_thresholds[asset_source] > amount || creation + default_withdraw_delay <= block.timestamp,
            "large withdraw is not old enough"
        );
        bytes memory message = abi.encode(asset_source, amount, target, creation, nonce, "withdraw_asset");
        require(
            IMultisigControl(multisig_control_address()).verify_signatures(signatures, message, nonce),
            "bad signatures"
        );
        ERC20_Asset_Pool(erc20_asset_pool_address).withdraw(asset_source, target, amount);
        emit Asset_Withdrawn(target, asset_source, amount, nonce);
    }

    /// @notice This function allows a user to deposit given ERC20 tokens into Vega
    /// @param asset_source Contract address for given ERC20 token
    /// @param amount Amount of tokens to be deposited into Vega
    /// @param vega_public_key Target Vega public key to be credited with this deposit
    /// @dev emits Asset_Deposited if successful
    /// @dev ERC20 approve function should be run before running this
    /// @notice ERC20 approve function should be run before running this
    function deposit_asset(
        address asset_source,
        uint256 amount,
        bytes32 vega_public_key
    ) external override {
        require(!is_stopped, "bridge stopped");

        if (!exempt_depositors[msg.sender]) {
            require(
                user_lifetime_deposits[msg.sender][asset_source] + amount <= asset_deposit_lifetime_limit[asset_source],
                "deposit over lifetime limit"
            );
            user_lifetime_deposits[msg.sender][asset_source] += amount;
        }

        require(listed_tokens[asset_source], "asset not listed");
        require(is_contract(asset_source), "asset_source must be contract");

        (bool success, bytes memory returndata) = asset_source.call(
            abi.encodeWithSignature(
                "transferFrom(address,address,uint256)",
                msg.sender,
                erc20_asset_pool_address,
                amount
            )
        );
        require(success, "token transfer failed");

        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "token transfer failed");
        }

        emit Asset_Deposited(msg.sender, asset_source, amount, vega_public_key);
    }

    /***************************VIEWS*****************************/
    /// @notice This view returns true if the given ERC20 token contract has been listed valid for deposit
    /// @param asset_source Contract address for given ERC20 token
    /// @return True if asset is listed
    function is_asset_listed(address asset_source) external view override returns (bool) {
        return listed_tokens[asset_source];
    }

    /// @return current multisig_control_address
    function get_multisig_control_address() external view override returns (address) {
        return multisig_control_address();
    }

    /// @param asset_source Contract address for given ERC20 token
    /// @return The assigned Vega Asset Id for given ERC20 token
    function get_vega_asset_id(address asset_source) external view override returns (bytes32) {
        return asset_source_to_vega_asset_id[asset_source];
    }

    /// @param vega_asset_id Vega-assigned asset ID for which you want the ERC20 token address
    /// @return The ERC20 token contract address for a given Vega Asset Id
    function get_asset_source(bytes32 vega_asset_id) external view override returns (address) {
        return vega_asset_ids_to_source[vega_asset_id];
    }

    function is_contract(address addr) internal view returns (bool) {
        uint256 code_size;
        assembly {
            code_size := extcodesize(addr)
        }
        return code_size > 0;
    }
}

/**
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMWEMMMMMMMMMMMMMMMMMMMMMMMMMM...............MMMMMMMMMMMMM
MMMMMMLOVEMMMMMMMMMMMMMMMMMMMMMM...............MMMMMMMMMMMMM
MMMMMMMMMMHIXELMMMMMMMMMMMM....................MMMMMNNMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMM....................MMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMM88=........................+MMMMMMMMMM
MMMMMMMMMMMMMMMMM....................MMMMM...MMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMM....................MMMMM...MMMMMMMMMMMMMMM
MMMMMMMMMMMM.........................MM+..MMM....+MMMMMMMMMM
MMMMMMMMMNMM...................... ..MM?..MMM.. .+MMMMMMMMMM
MMMMNDDMM+........................+MM........MM..+MMMMMMMMMM
MMMMZ.............................+MM....................MMM
MMMMZ.............................+MM....................MMM
MMMMZ.............................+MM....................DDD
MMMMZ.............................+MM..ZMMMMMMMMMMMMMMMMMMMM
MMMMZ.............................+MM..ZMMMMMMMMMMMMMMMMMMMM
MM..............................MMZ....ZMMMMMMMMMMMMMMMMMMMM
MM............................MM.......ZMMMMMMMMMMMMMMMMMMMM
MM............................MM.......ZMMMMMMMMMMMMMMMMMMMM
MM......................ZMMMMM.......MMMMMMMMMMMMMMMMMMMMMMM
MM............... ......ZMMMMM.... ..MMMMMMMMMMMMMMMMMMMMMMM
MM...............MMMMM88~.........+MM..ZMMMMMMMMMMMMMMMMMMMM
MM.......$DDDDDDD.......$DDDDD..DDNMM..ZMMMMMMMMMMMMMMMMMMMM
MM.......$DDDDDDD.......$DDDDD..DDNMM..ZMMMMMMMMMMMMMMMMMMMM
MM.......ZMMMMMMM.......ZMMMMM..MMMMM..ZMMMMMMMMMMMMMMMMMMMM
MMMMMMMMM+.......MMMMM88NMMMMM..MMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMM+.......MMMMM88NMMMMM..MMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM*/

File 2 of 9: ERC20_Asset_Pool.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.8;

import "./IMultisigControl.sol";
import "./IERC20.sol";

/// @title ERC20 Asset Pool
/// @author Vega Protocol
/// @notice This contract is the target for all deposits to the ERC20 Bridge via ERC20_Bridge_Logic
contract ERC20_Asset_Pool {
    event Multisig_Control_Set(address indexed new_address);
    event Bridge_Address_Set(address indexed new_address);

    /// @return Current MultisigControl contract address
    address public multisig_control_address;

    /// @return Current ERC20_Bridge_Logic contract address
    address public erc20_bridge_address;

    /// @param multisig_control The initial MultisigControl contract address
    /// @notice Emits Multisig_Control_Set event
    constructor(address multisig_control) {
        require(multisig_control != address(0), "invalid MultisigControl address");
        multisig_control_address = multisig_control;
        emit Multisig_Control_Set(multisig_control);
    }

    /// @notice this contract is not intended to accept ether directly
    receive() external payable {
        revert("this contract does not accept ETH");
    }

    /// @param new_address The new MultisigControl contract address.
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed set_multisig_control order
    /// @notice See MultisigControl for more about signatures
    /// @notice Emits Multisig_Control_Set event
    function set_multisig_control(
        address new_address,
        uint256 nonce,
        bytes memory signatures
    ) external {
        require(new_address != address(0), "invalid MultisigControl address");
        require(is_contract(new_address), "new address must be contract");

        bytes memory message = abi.encode(new_address, nonce, "set_multisig_control");
        require(
            IMultisigControl(multisig_control_address).verify_signatures(signatures, message, nonce),
            "bad signatures"
        );
        multisig_control_address = new_address;
        emit Multisig_Control_Set(new_address);
    }

    /// @param new_address The new ERC20_Bridge_Logic contract address.
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed set_bridge_address order
    /// @notice See MultisigControl for more about signatures
    /// @notice Emits Bridge_Address_Set event
    function set_bridge_address(
        address new_address,
        uint256 nonce,
        bytes memory signatures
    ) external {
        bytes memory message = abi.encode(new_address, nonce, "set_bridge_address");
        require(
            IMultisigControl(multisig_control_address).verify_signatures(signatures, message, nonce),
            "bad signatures"
        );
        erc20_bridge_address = new_address;
        emit Bridge_Address_Set(new_address);
    }

    /// @notice This function can only be run by the current "multisig_control_address" and, if available, will send the target tokens to the target
    /// @param token_address Contract address of the ERC20 token to be withdrawn
    /// @param target Target Ethereum address that the ERC20 tokens will be sent to
    /// @param amount Amount of ERC20 tokens to withdraw
    /// @dev amount is in whatever the lowest decimal value the ERC20 token has. For instance, an 18 decimal ERC20 token, 1 "amount" == 0.000000000000000001
    function withdraw(
        address token_address,
        address target,
        uint256 amount
    ) external {
        require(msg.sender == erc20_bridge_address, "msg.sender not authorized bridge");
        require(is_contract(token_address), "token_address must be contract");

        (bool success, bytes memory returndata) = token_address.call(
            abi.encodeWithSignature("transfer(address,uint256)", target, amount)
        );
        require(success, "token transfer failed");

        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "token transfer failed");
        }
    }

    function is_contract(address addr) internal view returns (bool) {
        uint256 code_size;
        assembly {
            code_size := extcodesize(addr)
        }
        return code_size > 0;
    }
}

/**
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMWEMMMMMMMMMMMMMMMMMMMMMMMMMM...............MMMMMMMMMMMMM
MMMMMMLOVEMMMMMMMMMMMMMMMMMMMMMM...............MMMMMMMMMMMMM
MMMMMMMMMMHIXELMMMMMMMMMMMM....................MMMMMNNMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMM....................MMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMM88=........................+MMMMMMMMMM
MMMMMMMMMMMMMMMMM....................MMMMM...MMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMM....................MMMMM...MMMMMMMMMMMMMMM
MMMMMMMMMMMM.........................MM+..MMM....+MMMMMMMMMM
MMMMMMMMMNMM...................... ..MM?..MMM.. .+MMMMMMMMMM
MMMMNDDMM+........................+MM........MM..+MMMMMMMMMM
MMMMZ.............................+MM....................MMM
MMMMZ.............................+MM....................MMM
MMMMZ.............................+MM....................DDD
MMMMZ.............................+MM..ZMMMMMMMMMMMMMMMMMMMM
MMMMZ.............................+MM..ZMMMMMMMMMMMMMMMMMMMM
MM..............................MMZ....ZMMMMMMMMMMMMMMMMMMMM
MM............................MM.......ZMMMMMMMMMMMMMMMMMMMM
MM............................MM.......ZMMMMMMMMMMMMMMMMMMMM
MM......................ZMMMMM.......MMMMMMMMMMMMMMMMMMMMMMM
MM............... ......ZMMMMM.... ..MMMMMMMMMMMMMMMMMMMMMMM
MM...............MMMMM88~.........+MM..ZMMMMMMMMMMMMMMMMMMMM
MM.......$DDDDDDD.......$DDDDD..DDNMM..ZMMMMMMMMMMMMMMMMMMMM
MM.......$DDDDDDD.......$DDDDD..DDNMM..ZMMMMMMMMMMMMMMMMMMMM
MM.......ZMMMMMMM.......ZMMMMM..MMMMM..ZMMMMMMMMMMMMMMMMMMMM
MMMMMMMMM+.......MMMMM88NMMMMM..MMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMM+.......MMMMM88NMMMMM..MMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM*/

File 3 of 9: ETH_Asset_Pool.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.8;

import "./IMultisigControl.sol";

/// @title ETH Asset Pool
/// @author Vega Protocol
/// @notice This contract is the target for all deposits to the ETH Bridge via ETH_Bridge_Logic
contract ETH_Asset_Pool {
    event Multisig_Control_Set(address indexed new_address);
    event Bridge_Address_Set(address indexed new_address);
    event Received(address indexed sender, uint256 amount);

    /// @return Current MultisigControl contract address
    address public multisig_control_address;

    /// @return Current ETH_Bridge_Logic contract address
    address public ETH_bridge_address;

    /// @param multisig_control The initial MultisigControl contract address
    /// @notice Emits Multisig_Control_Set event
    constructor(address multisig_control) {
        require(multisig_control != address(0), "invalid MultisigControl address");
        multisig_control_address = multisig_control;
        emit Multisig_Control_Set(multisig_control);
    }

    /// @param new_address The new MultisigControl contract address.
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed set_multisig_control order
    /// @notice See MultisigControl for more about signatures
    /// @notice Emits Multisig_Control_Set event
    function set_multisig_control(
        address new_address,
        uint256 nonce,
        bytes memory signatures
    ) external {
        require(new_address != address(0), "invalid MultisigControl address");
        uint256 size;
        assembly {
            size := extcodesize(new_address)
        }
        require(size > 0, "new address must be contract");
        bytes memory message = abi.encode(new_address, nonce, "set_multisig_control");
        require(
            IMultisigControl(multisig_control_address).verify_signatures(signatures, message, nonce),
            "bad signatures"
        );
        multisig_control_address = new_address;
        emit Multisig_Control_Set(new_address);
    }

    /// @param new_address The new ETH_Bridge_Logic contract address.
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed set_bridge_address order
    /// @notice See MultisigControl for more about signatures
    /// @notice Emits Bridge_Address_Set event
    function set_bridge_address(
        address new_address,
        uint256 nonce,
        bytes memory signatures
    ) external {
        require(new_address != address(0), "invalid bridge address");
        bytes memory message = abi.encode(new_address, nonce, "set_bridge_address");
        require(
            IMultisigControl(multisig_control_address).verify_signatures(signatures, message, nonce),
            "bad signatures"
        );
        ETH_bridge_address = new_address;
        emit Bridge_Address_Set(new_address);
    }

    /// @notice This function can only be run by the current "multisig_control_address" and, if available, will send the target eth to the target
    /// @param target Target Ethereum address that the ETH will be sent to
    /// @param amount Amount of ETH to withdraw
    /// @dev amount is in wei, 1 wei == 0.000000000000000001 ETH
    function withdraw(address payable target, uint256 amount) external {
        require(target != address(0), "invalid target address");
        require(msg.sender == ETH_bridge_address, "msg.sender not authorized bridge");
        /// @dev reentry is protected by the non-reusable nonce in the signature check in the ETH_Bridge_Logic
        (bool success, ) = target.call{value: amount}("");
        require(success, "eth transfer failed");
    }

    /// @notice A contract can have at most one receive function,
    /// declared using receive() external payable { ... }
    /// (without the function keyword). This function cannot have arguments,
    /// cannot return anything and must have external visibility and payable state
    /// mutability. It is executed on a call to the contract with empty calldata.
    /// This is the function that is executed on plain Ether transfers (e.g. via .send()
    /// or .transfer()). If no such function exists, but a payable fallback
    /// function exists, the fallback function will be called on a plain Ether
    /// transfer. If neither a receive Ether nor a payable fallback function is
    /// present, the contract cannot receive Ether through regular transactions
    /// and throws an exception.
    receive() external payable {
        emit Received(msg.sender, msg.value);
    }
}

/**
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMWEMMMMMMMMMMMMMMMMMMMMMMMMMM...............MMMMMMMMMMMMM
MMMMMMLOVEMMMMMMMMMMMMMMMMMMMMMM...............MMMMMMMMMMMMM
MMMMMMMMMMHIXELMMMMMMMMMMMM....................MMMMMNNMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMM....................MMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMM88=........................+MMMMMMMMMM
MMMMMMMMMMMMMMMMM....................MMMMM...MMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMM....................MMMMM...MMMMMMMMMMMMMMM
MMMMMMMMMMMM.........................MM+..MMM....+MMMMMMMMMM
MMMMMMMMMNMM...................... ..MM?..MMM.. .+MMMMMMMMMM
MMMMNDDMM+........................+MM........MM..+MMMMMMMMMM
MMMMZ.............................+MM....................MMM
MMMMZ.............................+MM....................MMM
MMMMZ.............................+MM....................DDD
MMMMZ.............................+MM..ZMMMMMMMMMMMMMMMMMMMM
MMMMZ.............................+MM..ZMMMMMMMMMMMMMMMMMMMM
MM..............................MMZ....ZMMMMMMMMMMMMMMMMMMMM
MM............................MM.......ZMMMMMMMMMMMMMMMMMMMM
MM............................MM.......ZMMMMMMMMMMMMMMMMMMMM
MM......................ZMMMMM.......MMMMMMMMMMMMMMMMMMMMMMM
MM............... ......ZMMMMM.... ..MMMMMMMMMMMMMMMMMMMMMMM
MM...............MMMMM88~.........+MM..ZMMMMMMMMMMMMMMMMMMMM
MM.......$DDDDDDD.......$DDDDD..DDNMM..ZMMMMMMMMMMMMMMMMMMMM
MM.......$DDDDDDD.......$DDDDD..DDNMM..ZMMMMMMMMMMMMMMMMMMMM
MM.......ZMMMMMMM.......ZMMMMM..MMMMM..ZMMMMMMMMMMMMMMMMMMMM
MMMMMMMMM+.......MMMMM88NMMMMM..MMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMM+.......MMMMM88NMMMMM..MMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM*/

File 4 of 9: ETH_Bridge_Logic.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.8;

import "./IETH_Bridge_Logic.sol";
import "./IMultisigControl.sol";
import "./ETH_Asset_Pool.sol";

/// @title ETH Bridge Logic
/// @author Vega Protocol
/// @notice This contract is used by Vega network users to deposit and withdraw ETH to/from Vega.
// @notice All funds deposited/withdrawn are to/from the assigned ETH_Asset_Pool
contract ETH_Bridge_Logic is IETH_Bridge_Logic {
    address payable ETH_asset_pool_address;

    // minimum deposit amt
    uint256 minimum_deposit;
    // maximum deposit amt
    uint256 maximum_deposit;

    /// @param ETH_asset_pool Initial Asset Pool contract address
    constructor(address payable ETH_asset_pool) {
        require(ETH_asset_pool != address(0), "invalid asset pool address");
        ETH_asset_pool_address = ETH_asset_pool;
    }

    function multisig_control_address() internal view returns (address) {
        return ETH_Asset_Pool(ETH_asset_pool_address).multisig_control_address();
    }

    /// @notice This function sets the minimum allowable deposit for ETH
    /// @param minimum_amount Minimum deposit amount
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @dev Emits ETH_Deposit_Minimum_Set if successful
    function set_deposit_minimum(
        uint256 minimum_amount,
        uint256 nonce,
        bytes memory signatures
    ) external override {
        bytes memory message = abi.encode(minimum_amount, nonce, "set_deposit_minimum");
        require(
            IMultisigControl(multisig_control_address()).verify_signatures(signatures, message, nonce),
            "bad signatures"
        );
        minimum_deposit = minimum_amount;
        emit ETH_Deposit_Minimum_Set(minimum_amount, nonce);
    }

    /// @notice This function sets the maximum allowable deposit for ETH
    /// @param maximum_amount Maximum deposit amount
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @dev Emits ETH_Deposit_Maximum_Set if successful
    function set_deposit_maximum(
        uint256 maximum_amount,
        uint256 nonce,
        bytes memory signatures
    ) external override {
        bytes memory message = abi.encode(maximum_amount, nonce, "set_deposit_maximum");
        require(
            IMultisigControl(multisig_control_address()).verify_signatures(signatures, message, nonce),
            "bad signatures"
        );
        maximum_deposit = maximum_amount;
        emit ETH_Deposit_Maximum_Set(maximum_amount, nonce);
    }

    /// @notice This function allows the withdrawal of ETH
    /// @param amount Amount of ETH to withdraw
    /// @param expiry Vega-assigned timestamp of withdrawal order expiration
    /// @param target Target Ethereum address to receive withdrawn ETH
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @dev Emits ETH_Withdrawn if successful
    function withdraw_asset(
        uint256 amount,
        uint256 expiry,
        address payable target,
        uint256 nonce,
        bytes memory signatures
    ) external override {
        require(expiry > block.timestamp, "withdrawal has expired");
        bytes memory message = abi.encode(amount, expiry, target, nonce, "withdraw_asset");
        require(
            IMultisigControl(multisig_control_address()).verify_signatures(signatures, message, nonce),
            "bad signatures"
        );
        ETH_Asset_Pool(ETH_asset_pool_address).withdraw(target, amount);
        emit ETH_Withdrawn(target, amount, nonce);
    }

    /// @notice This function allows a user to deposit ETH into Vega
    /// @param vega_public_key Target vega public key to be credited with this deposit
    /// @dev Emits ETH_Deposited if successful
    function deposit_asset(bytes32 vega_public_key) external payable override {
        require(maximum_deposit == 0 || msg.value <= maximum_deposit, "deposit above maximum");
        require(msg.value >= minimum_deposit, "deposit below minimum");
        ETH_asset_pool_address.transfer(msg.value);
        emit ETH_Deposited(msg.sender, msg.value, vega_public_key);
    }

    /***************************VIEWS*****************************/
    /// @notice This view returns minimum valid deposit
    /// @return Minimum valid deposit of ETH
    function get_deposit_minimum() external view override returns (uint256) {
        return minimum_deposit;
    }

    /// @notice This view returns maximum valid deposit
    /// @return Maximum valid deposit of ETH
    function get_deposit_maximum() external view override returns (uint256) {
        return maximum_deposit;
    }

    /// @return current multisig_control_address
    function get_multisig_control_address() external view override returns (address) {
        return multisig_control_address();
    }
}

/**
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMWEMMMMMMMMMMMMMMMMMMMMMMMMMM...............MMMMMMMMMMMMM
MMMMMMLOVEMMMMMMMMMMMMMMMMMMMMMM...............MMMMMMMMMMMMM
MMMMMMMMMMHIXELMMMMMMMMMMMM....................MMMMMNNMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMM....................MMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMM88=........................+MMMMMMMMMM
MMMMMMMMMMMMMMMMM....................MMMMM...MMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMM....................MMMMM...MMMMMMMMMMMMMMM
MMMMMMMMMMMM.........................MM+..MMM....+MMMMMMMMMM
MMMMMMMMMNMM...................... ..MM?..MMM.. .+MMMMMMMMMM
MMMMNDDMM+........................+MM........MM..+MMMMMMMMMM
MMMMZ.............................+MM....................MMM
MMMMZ.............................+MM....................MMM
MMMMZ.............................+MM....................DDD
MMMMZ.............................+MM..ZMMMMMMMMMMMMMMMMMMMM
MMMMZ.............................+MM..ZMMMMMMMMMMMMMMMMMMMM
MM..............................MMZ....ZMMMMMMMMMMMMMMMMMMMM
MM............................MM.......ZMMMMMMMMMMMMMMMMMMMM
MM............................MM.......ZMMMMMMMMMMMMMMMMMMMM
MM......................ZMMMMM.......MMMMMMMMMMMMMMMMMMMMMMM
MM............... ......ZMMMMM.... ..MMMMMMMMMMMMMMMMMMMMMMM
MM...............MMMMM88~.........+MM..ZMMMMMMMMMMMMMMMMMMMM
MM.......$DDDDDDD.......$DDDDD..DDNMM..ZMMMMMMMMMMMMMMMMMMMM
MM.......$DDDDDDD.......$DDDDD..DDNMM..ZMMMMMMMMMMMMMMMMMMMM
MM.......ZMMMMMMM.......ZMMMMM..MMMMM..ZMMMMMMMMMMMMMMMMMMMM
MMMMMMMMM+.......MMMMM88NMMMMM..MMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMM+.......MMMMM88NMMMMM..MMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM*/

File 5 of 9: IERC20.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.8;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
 * the optional functions; to access them see {ERC20Detailed}.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 6 of 9: IERC20_Bridge_Logic_Restricted.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.8;

/// @title ERC20 Bridge Logic Interface
/// @author Vega Protocol
/// @notice Implementations of this interface are used by Vega network users to deposit and withdraw ERC20 tokens to/from Vega.
// @notice All funds deposited/withdrawn are to/from the ERC20_Asset_Pool
abstract contract IERC20_Bridge_Logic_Restricted {
    /***************************EVENTS****************************/
    event Asset_Withdrawn(address indexed user_address, address indexed asset_source, uint256 amount, uint256 nonce);
    event Asset_Deposited(
        address indexed user_address,
        address indexed asset_source,
        uint256 amount,
        bytes32 vega_public_key
    );
    event Asset_Listed(address indexed asset_source, bytes32 indexed vega_asset_id, uint256 nonce);
    event Asset_Removed(address indexed asset_source, uint256 nonce);
    event Asset_Limits_Updated(address indexed asset_source, uint256 lifetime_limit, uint256 withdraw_threshold);
    event Bridge_Withdraw_Delay_Set(uint256 withdraw_delay);
    event Bridge_Stopped();
    event Bridge_Resumed();
    event Depositor_Exempted(address indexed depositor);
    event Depositor_Exemption_Revoked(address indexed depositor);

    /***************************FUNCTIONS*************************/
    /// @notice This function lists the given ERC20 token contract as valid for deposit to this bridge
    /// @param asset_source Contract address for given ERC20 token
    /// @param vega_asset_id Vega-generated asset ID for internal use in Vega Core
    /// @param lifetime_limit Initial lifetime deposit limit *RESTRICTION FEATURE*
    /// @param withdraw_threshold Amount at which the withdraw delay goes into effect *RESTRICTION FEATURE*
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @dev MUST emit Asset_Listed if successful
    function list_asset(
        address asset_source,
        bytes32 vega_asset_id,
        uint256 lifetime_limit,
        uint256 withdraw_threshold,
        uint256 nonce,
        bytes memory signatures
    ) external virtual;

    /// @notice This function removes from listing the given ERC20 token contract. This marks the token as invalid for deposit to this bridge
    /// @param asset_source Contract address for given ERC20 token
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @dev MUST emit Asset_Removed if successful
    function remove_asset(
        address asset_source,
        uint256 nonce,
        bytes memory signatures
    ) external virtual;

    /// @notice This function sets the lifetime maximum deposit for a given asset
    /// @param asset_source Contract address for given ERC20 token
    /// @param lifetime_limit Deposit limit for a given ethereum address
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @dev asset must first be listed
    function set_asset_limits(
        address asset_source,
        uint256 lifetime_limit,
        uint256 threshold,
        uint256 nonce,
        bytes calldata signatures
    ) external virtual;

    /// @notice This function sets the withdraw delay for withdrawals over the per-asset set thresholds
    /// @param delay Amount of time to delay a withdrawal
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    function set_withdraw_delay(
        uint256 delay,
        uint256 nonce,
        bytes calldata signatures
    ) external virtual;

    /// @notice This function triggers the global bridge stop that halts all withdrawals and deposits until it is resumed
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @dev bridge must not be stopped already
    /// @dev MUST emit Bridge_Stopped if successful
    function global_stop(uint256 nonce, bytes calldata signatures) external virtual;

    /// @notice This function resumes bridge operations from the stopped state
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @dev bridge must be stopped
    /// @dev MUST emit Bridge_Resumed if successful
    function global_resume(uint256 nonce, bytes calldata signatures) external virtual;

    /// @notice this function allows the exemption_lister to exempt a depositor from the deposit limits
    /// @notice this feature is specifically for liquidity and rewards providers
    /// @dev MUST emit Depositor_Exempted if successful
    function exempt_depositor() external virtual;

    /// @notice this function allows the exemption_lister to revoke a depositor's exemption from deposit limits
    /// @notice this feature is specifically for liquidity and rewards providers
    /// @dev MUST emit Depositor_Exemption_Revoked if successful
    function revoke_exempt_depositor() external virtual;

    /// @notice This function withdrawals assets to the target Ethereum address
    /// @param asset_source Contract address for given ERC20 token
    /// @param amount Amount of ERC20 tokens to withdraw
    /// @param target Target Ethereum address to receive withdrawn ERC20 tokens
    /// @param creation Timestamp of when requestion was created *RESTRICTION FEATURE*
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @dev MUST emit Asset_Withdrawn if successful
    function withdraw_asset(
        address asset_source,
        uint256 amount,
        address target,
        uint256 creation,
        uint256 nonce,
        bytes memory signatures
    ) external virtual;

    /// @notice this view returns true if the given despoitor address has been exempted from deposit limits
    /// @param depositor The depositor to check
    /// @return true if depositor is exempt
    function is_exempt_depositor(address depositor) external view virtual returns (bool);

    /// @notice This function allows a user to deposit given ERC20 tokens into Vega
    /// @param asset_source Contract address for given ERC20 token
    /// @param amount Amount of tokens to be deposited into Vega
    /// @param vega_public_key Target Vega public key to be credited with this deposit
    /// @dev MUST emit Asset_Deposited if successful
    /// @dev ERC20 approve function should be run before running this
    /// @notice ERC20 approve function should be run before running this
    function deposit_asset(
        address asset_source,
        uint256 amount,
        bytes32 vega_public_key
    ) external virtual;

    /***************************VIEWS*****************************/
    /// @notice This view returns true if the given ERC20 token contract has been listed valid for deposit
    /// @param asset_source Contract address for given ERC20 token
    /// @return True if asset is listed
    function is_asset_listed(address asset_source) external view virtual returns (bool);

    /// @notice This view returns the lifetime deposit limit for the given asset
    /// @param asset_source Contract address for given ERC20 token
    /// @return Lifetime limit for the given asset
    function get_asset_deposit_lifetime_limit(address asset_source) external view virtual returns (uint256);

    /// @notice This view returns the given token's withdraw threshold above which the withdraw delay goes into effect
    /// @param asset_source Contract address for given ERC20 token
    /// @return Withdraw threshold
    function get_withdraw_threshold(address asset_source) external view virtual returns (uint256);

    /// @return current multisig_control_address
    function get_multisig_control_address() external view virtual returns (address);

    /// @param asset_source Contract address for given ERC20 token
    /// @return The assigned Vega Asset ID for given ERC20 token
    function get_vega_asset_id(address asset_source) external view virtual returns (bytes32);

    /// @param vega_asset_id Vega-assigned asset ID for which you want the ERC20 token address
    /// @return The ERC20 token contract address for a given Vega Asset ID
    function get_asset_source(bytes32 vega_asset_id) external view virtual returns (address);
}

/**
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMWEMMMMMMMMMMMMMMMMMMMMMMMMMM...............MMMMMMMMMMMMM
MMMMMMLOVEMMMMMMMMMMMMMMMMMMMMMM...............MMMMMMMMMMMMM
MMMMMMMMMMHIXELMMMMMMMMMMMM....................MMMMMNNMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMM....................MMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMM88=........................+MMMMMMMMMM
MMMMMMMMMMMMMMMMM....................MMMMM...MMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMM....................MMMMM...MMMMMMMMMMMMMMM
MMMMMMMMMMMM.........................MM+..MMM....+MMMMMMMMMM
MMMMMMMMMNMM...................... ..MM?..MMM.. .+MMMMMMMMMM
MMMMNDDMM+........................+MM........MM..+MMMMMMMMMM
MMMMZ.............................+MM....................MMM
MMMMZ.............................+MM....................MMM
MMMMZ.............................+MM....................DDD
MMMMZ.............................+MM..ZMMMMMMMMMMMMMMMMMMMM
MMMMZ.............................+MM..ZMMMMMMMMMMMMMMMMMMMM
MM..............................MMZ....ZMMMMMMMMMMMMMMMMMMMM
MM............................MM.......ZMMMMMMMMMMMMMMMMMMMM
MM............................MM.......ZMMMMMMMMMMMMMMMMMMMM
MM......................ZMMMMM.......MMMMMMMMMMMMMMMMMMMMMMM
MM............... ......ZMMMMM.... ..MMMMMMMMMMMMMMMMMMMMMMM
MM...............MMMMM88~.........+MM..ZMMMMMMMMMMMMMMMMMMMM
MM.......$DDDDDDD.......$DDDDD..DDNMM..ZMMMMMMMMMMMMMMMMMMMM
MM.......$DDDDDDD.......$DDDDD..DDNMM..ZMMMMMMMMMMMMMMMMMMMM
MM.......ZMMMMMMM.......ZMMMMM..MMMMM..ZMMMMMMMMMMMMMMMMMMMM
MMMMMMMMM+.......MMMMM88NMMMMM..MMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMM+.......MMMMM88NMMMMM..MMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM*/

File 7 of 9: IETH_Bridge_Logic.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.8;

/// @title ETH Bridge Logic Interface
/// @author Vega Protocol
/// @notice Implementations of this interface are used by Vega network users to deposit and withdraw ETH to/from Vega.
// @notice All funds deposited/withdrawn are to/from the ETH_Asset_Pool
abstract contract IETH_Bridge_Logic {
    /***************************EVENTS****************************/
    event ETH_Withdrawn(address indexed user_address, uint256 amount, uint256 nonce);
    event ETH_Deposited(address indexed user_address, uint256 amount, bytes32 vega_public_key);
    event ETH_Deposit_Minimum_Set(uint256 new_minimum, uint256 nonce);
    event ETH_Deposit_Maximum_Set(uint256 new_maximum, uint256 nonce);

    /***************************FUNCTIONS*************************/
    /// @notice This function sets the minimum allowable deposit for ETH
    /// @param minimum_amount Minimum deposit amount
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @dev MUST emit Asset_Deposit_Minimum_Set if successful
    function set_deposit_minimum(
        uint256 minimum_amount,
        uint256 nonce,
        bytes memory signatures
    ) external virtual;

    /// @notice This function sets the maximum allowable deposit for ETH
    /// @param maximum_amount Maximum deposit amount
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @dev MUST emit Asset_Deposit_Maximum_Set if successful
    function set_deposit_maximum(
        uint256 maximum_amount,
        uint256 nonce,
        bytes memory signatures
    ) external virtual;

    /// @notice This function withdraws assets to the target Ethereum address
    /// @param amount Amount of ETH to withdraw
    /// @param expiry Vega-assigned timestamp of withdrawal order expiration
    /// @param target Target Ethereum address to receive withdrawn ETH
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @dev MUST emit Asset_Withdrawn if successful
    function withdraw_asset(
        uint256 amount,
        uint256 expiry,
        address payable target,
        uint256 nonce,
        bytes memory signatures
    ) external virtual;

    /// @notice This function allows a user to deposit ETH into Vega
    /// @param vega_public_key Target vega public key to be credited with this deposit
    /// @dev MUST emit Asset_Deposited if successful
    /// @dev ETH approve function should be run before running this
    /// @notice ETH approve function should be run before running this
    function deposit_asset(bytes32 vega_public_key) external payable virtual;

    /***************************VIEWS*****************************/
    /// @notice This view returns minimum valid deposit
    /// @return Minimum valid deposit of ETH
    function get_deposit_minimum() external view virtual returns (uint256);

    /// @notice This view returns maximum valid deposit
    /// @return Maximum valid deposit of ETH
    function get_deposit_maximum() external view virtual returns (uint256);

    /// @return current multisig_control_address
    function get_multisig_control_address() external view virtual returns (address);
}

/**
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMWEMMMMMMMMMMMMMMMMMMMMMMMMMM...............MMMMMMMMMMMMM
MMMMMMLOVEMMMMMMMMMMMMMMMMMMMMMM...............MMMMMMMMMMMMM
MMMMMMMMMMHIXELMMMMMMMMMMMM....................MMMMMNNMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMM....................MMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMM88=........................+MMMMMMMMMM
MMMMMMMMMMMMMMMMM....................MMMMM...MMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMM....................MMMMM...MMMMMMMMMMMMMMM
MMMMMMMMMMMM.........................MM+..MMM....+MMMMMMMMMM
MMMMMMMMMNMM...................... ..MM?..MMM.. .+MMMMMMMMMM
MMMMNDDMM+........................+MM........MM..+MMMMMMMMMM
MMMMZ.............................+MM....................MMM
MMMMZ.............................+MM....................MMM
MMMMZ.............................+MM....................DDD
MMMMZ.............................+MM..ZMMMMMMMMMMMMMMMMMMMM
MMMMZ.............................+MM..ZMMMMMMMMMMMMMMMMMMMM
MM..............................MMZ....ZMMMMMMMMMMMMMMMMMMMM
MM............................MM.......ZMMMMMMMMMMMMMMMMMMMM
MM............................MM.......ZMMMMMMMMMMMMMMMMMMMM
MM......................ZMMMMM.......MMMMMMMMMMMMMMMMMMMMMMM
MM............... ......ZMMMMM.... ..MMMMMMMMMMMMMMMMMMMMMMM
MM...............MMMMM88~.........+MM..ZMMMMMMMMMMMMMMMMMMMM
MM.......$DDDDDDD.......$DDDDD..DDNMM..ZMMMMMMMMMMMMMMMMMMMM
MM.......$DDDDDDD.......$DDDDD..DDNMM..ZMMMMMMMMMMMMMMMMMMMM
MM.......ZMMMMMMM.......ZMMMMM..MMMMM..ZMMMMMMMMMMMMMMMMMMMM
MMMMMMMMM+.......MMMMM88NMMMMM..MMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMM+.......MMMMM88NMMMMM..MMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM*/

File 8 of 9: IMultisigControl.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.8;

/// @title MultisigControl Interface
/// @author Vega Protocol
/// @notice Implementations of this interface are used by the Vega network to control smart contracts without the need for Vega to have any Ethereum of its own.
/// @notice To do this, the Vega validators sign a MultisigControl order to construct a signature bundle. Any interested party can then take that signature bundle and pay the gas to run the command on Ethereum
abstract contract IMultisigControl {
    /***************************EVENTS****************************/
    event SignerAdded(address new_signer, uint256 nonce);
    event SignerRemoved(address old_signer, uint256 nonce);
    event ThresholdSet(uint16 new_threshold, uint256 nonce);
    event NonceBurnt(uint256 nonce);

    /**************************FUNCTIONS*********************/
    /// @notice Sets threshold of signatures that must be met before function is executed.
    /// @param new_threshold New threshold value
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @notice Ethereum has no decimals, threshold is % * 10 so 50% == 500 100% == 1000
    /// @notice signatures are OK if they are >= threshold count of total valid signers
    /// @dev MUST emit ThresholdSet event
    function set_threshold(
        uint16 new_threshold,
        uint256 nonce,
        bytes calldata signatures
    ) external virtual;

    /// @notice Adds new valid signer and adjusts signer count.
    /// @param new_signer New signer address
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @dev MUST emit 'SignerAdded' event
    function add_signer(
        address new_signer,
        uint256 nonce,
        bytes calldata signatures
    ) external virtual;

    /// @notice Removes currently valid signer and adjusts signer count.
    /// @param old_signer Address of signer to be removed.
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @dev MUST emit 'SignerRemoved' event
    function remove_signer(
        address old_signer,
        uint256 nonce,
        bytes calldata signatures
    ) external virtual;

    /// @notice Burn an nonce before it gets used by a user. Useful in case the validators needs to prevents a malicious user to do un-permitted action.
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @dev Emits 'NonceBurnt' event
    function burn_nonce(uint256 nonce, bytes calldata signatures) external virtual;

    /// @notice Verifies a signature bundle and returns true only if the threshold of valid signers is met,
    /// @notice this is a function that any function controlled by Vega MUST call to be securely controlled by the Vega network
    /// @notice message to hash to sign follows this pattern:
    /// @notice abi.encode( abi.encode(param1, param2, param3, ... , nonce, function_name_string), validating_contract_or_submitter_address);
    /// @notice Note that validating_contract_or_submitter_address is the the submitting party. If on MultisigControl contract itself, it's the submitting ETH address
    /// @notice if function on bridge that then calls Multisig, then it's the address of that contract
    /// @notice Note also the embedded encoding, this is required to verify what function/contract the function call goes to
    /// @return MUST return true if valid signatures are over the threshold
    function verify_signatures(
        bytes calldata signatures,
        bytes memory message,
        uint256 nonce
    ) public virtual returns (bool);

    /**********************VIEWS*********************/
    /// @return Number of valid signers
    function get_valid_signer_count() external view virtual returns (uint8);

    /// @return Current threshold
    function get_current_threshold() external view virtual returns (uint16);

    /// @param signer_address target potential signer address
    /// @return true if address provided is valid signer
    function is_valid_signer(address signer_address) external view virtual returns (bool);

    /// @param nonce Nonce to lookup
    /// @return true if nonce has been used
    function is_nonce_used(uint256 nonce) external view virtual returns (bool);
}

/**
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMWEMMMMMMMMMMMMMMMMMMMMMMMMMM...............MMMMMMMMMMMMM
MMMMMMLOVEMMMMMMMMMMMMMMMMMMMMMM...............MMMMMMMMMMMMM
MMMMMMMMMMHIXELMMMMMMMMMMMM....................MMMMMNNMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMM....................MMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMM88=........................+MMMMMMMMMM
MMMMMMMMMMMMMMMMM....................MMMMM...MMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMM....................MMMMM...MMMMMMMMMMMMMMM
MMMMMMMMMMMM.........................MM+..MMM....+MMMMMMMMMM
MMMMMMMMMNMM...................... ..MM?..MMM.. .+MMMMMMMMMM
MMMMNDDMM+........................+MM........MM..+MMMMMMMMMM
MMMMZ.............................+MM....................MMM
MMMMZ.............................+MM....................MMM
MMMMZ.............................+MM....................DDD
MMMMZ.............................+MM..ZMMMMMMMMMMMMMMMMMMMM
MMMMZ.............................+MM..ZMMMMMMMMMMMMMMMMMMMM
MM..............................MMZ....ZMMMMMMMMMMMMMMMMMMMM
MM............................MM.......ZMMMMMMMMMMMMMMMMMMMM
MM............................MM.......ZMMMMMMMMMMMMMMMMMMMM
MM......................ZMMMMM.......MMMMMMMMMMMMMMMMMMMMMMM
MM............... ......ZMMMMM.... ..MMMMMMMMMMMMMMMMMMMMMMM
MM...............MMMMM88~.........+MM..ZMMMMMMMMMMMMMMMMMMMM
MM.......$DDDDDDD.......$DDDDD..DDNMM..ZMMMMMMMMMMMMMMMMMMMM
MM.......$DDDDDDD.......$DDDDD..DDNMM..ZMMMMMMMMMMMMMMMMMMMM
MM.......ZMMMMMMM.......ZMMMMM..MMMMM..ZMMMMMMMMMMMMMMMMMMMM
MMMMMMMMM+.......MMMMM88NMMMMM..MMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMM+.......MMMMM88NMMMMM..MMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM*/

File 9 of 9: MultisigControl.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.8;

import "./IMultisigControl.sol";

/// @title MultisigControl
/// @author Vega Protocol
/// @notice This contract enables validators, through a multisignature process, to run functions on contracts by consensus
contract MultisigControl is IMultisigControl {
    constructor() {
        // set initial threshold to 50%
        threshold = 500;
        signers[msg.sender] = true;
        signer_count++;
        emit SignerAdded(msg.sender, 0);
    }

    uint16 threshold;
    uint8 signer_count;
    mapping(address => bool) public signers;
    mapping(uint256 => bool) used_nonces;

    /**************************FUNCTIONS*********************/
    /// @notice Sets threshold of signatures that must be met before function is executed.
    /// @param new_threshold New threshold value
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @notice Ethereum has no decimals, threshold is % * 10 so 50% == 500 100% == 1000
    /// @notice signatures are OK if they are >= threshold count of total valid signers
    /// @dev Emits ThresholdSet event
    function set_threshold(
        uint16 new_threshold,
        uint256 nonce,
        bytes calldata signatures
    ) external override {
        require(new_threshold < 1000 && new_threshold > 0, "new threshold outside range");
        bytes memory message = abi.encode(new_threshold, nonce, "set_threshold");
        require(verify_signatures(signatures, message, nonce), "bad signatures");
        threshold = new_threshold;
        emit ThresholdSet(new_threshold, nonce);
    }

    /// @notice Adds new valid signer and adjusts signer count.
    /// @param new_signer New signer address
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @dev Emits 'SignerAdded' event
    function add_signer(
        address new_signer,
        uint256 nonce,
        bytes calldata signatures
    ) external override {
        bytes memory message = abi.encode(new_signer, nonce, "add_signer");
        require(!signers[new_signer], "signer already exists");
        require(verify_signatures(signatures, message, nonce), "bad signatures");
        signers[new_signer] = true;
        signer_count++;
        emit SignerAdded(new_signer, nonce);
    }

    /// @notice Removes currently valid signer and adjusts signer count.
    /// @param old_signer Address of signer to be removed.
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @dev Emits 'SignerRemoved' event
    function remove_signer(
        address old_signer,
        uint256 nonce,
        bytes calldata signatures
    ) external override {
        bytes memory message = abi.encode(old_signer, nonce, "remove_signer");
        require(signers[old_signer], "signer doesn't exist");
        require(verify_signatures(signatures, message, nonce), "bad signatures");
        signers[old_signer] = false;
        signer_count--;
        emit SignerRemoved(old_signer, nonce);
    }

    /// @notice Burn an nonce before it gets used by a user. Useful in case the validators needs to prevents a malicious user to do un-permitted action.
    /// @param nonce Vega-assigned single-use number that provides replay attack protection
    /// @param signatures Vega-supplied signature bundle of a validator-signed order
    /// @notice See MultisigControl for more about signatures
    /// @dev Emits 'NonceBurnt' event
    function burn_nonce(uint256 nonce, bytes calldata signatures) external override {
        bytes memory message = abi.encode(nonce, "burn_nonce");
        require(verify_signatures(signatures, message, nonce), "bad signatures");
        emit NonceBurnt(nonce);
    }

    /// @notice Verifies a signature bundle and returns true only if the threshold of valid signers is met,
    /// @notice this is a function that any function controlled by Vega MUST call to be securely controlled by the Vega network
    /// @notice message to hash to sign follows this pattern:
    /// @notice abi.encode( abi.encode(param1, param2, param3, ... , nonce, function_name_string), validating_contract_or_submitter_address);
    /// @notice Note that validating_contract_or_submitter_address is the submitting party. If on MultisigControl contract itself, it's the submitting ETH address
    /// @notice if function on bridge that then calls Multisig, then it's the address of that contract
    /// @notice Note also the embedded encoding, this is required to verify what function/contract the function call goes to
    /// @return Returns true if valid signatures are over the threshold
    function verify_signatures(
        bytes calldata signatures,
        bytes memory message,
        uint256 nonce
    ) public override returns (bool) {
        require(signatures.length % 65 == 0, "bad sig length");
        require(signatures.length > 0, "must contain at least 1 sig");
        require(!used_nonces[nonce], "nonce already used");

        uint8 size = 0;
        address[] memory signers_temp = new address[](signer_count);

        bytes32 message_hash = keccak256(abi.encode(message, msg.sender));
        uint256 offset;
        assembly {
            offset := signatures.offset
        }
        for (uint256 msg_idx = 0; msg_idx < signatures.length; msg_idx += 65) {
            //recover address from that msg
            bytes32 r;
            bytes32 s;
            uint8 v;
            assembly {
                // first 32 bytes, after the length prefix
                r := calldataload(add(offset, msg_idx))
                // second 32 bytes
                s := calldataload(add(add(offset, msg_idx), 32))
                // final byte (first byte of the next 32 bytes)
                v := byte(0, calldataload(add(add(offset, msg_idx), 64)))
            }
            // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
            // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
            // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most
            // signatures from current libraries generate a unique signature with an s-value in the lower half order.
            //
            // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
            // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
            // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
            // these malleable signatures as well.
            require(
                uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,
                "Malleable signature error"
            );
            if (v < 27) v += 27;

            address recovered_address = ecrecover(message_hash, v, r, s);

            if (signers[recovered_address] && !has_signed(signers_temp, recovered_address, size)) {
                signers_temp[size] = recovered_address;
                size++;
            }
        }

        used_nonces[nonce] = ((uint256(size) * 1000) / (uint256(signer_count))) > threshold;
        return used_nonces[nonce];
    }

    function has_signed(
        address[] memory signers_temp,
        address signer,
        uint8 size
    ) private pure returns (bool) {
        for (uint256 i; i < size; i++) {
            if (signers_temp[i] == signer) {
                return true;
            }
        }
        return false;
    }

    /// @return Number of valid signers
    function get_valid_signer_count() external view override returns (uint8) {
        return signer_count;
    }

    /// @return Current threshold
    function get_current_threshold() external view override returns (uint16) {
        return threshold;
    }

    /// @param signer_address target potential signer address
    /// @return true if address provided is valid signer
    function is_valid_signer(address signer_address) external view override returns (bool) {
        return signers[signer_address];
    }

    /// @param nonce Nonce to lookup
    /// @return true if nonce has been used
    function is_nonce_used(uint256 nonce) external view override returns (bool) {
        return used_nonces[nonce];
    }
}

/**
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMWEMMMMMMMMMMMMMMMMMMMMMMMMMM...............MMMMMMMMMMMMM
MMMMMMLOVEMMMMMMMMMMMMMMMMMMMMMM...............MMMMMMMMMMMMM
MMMMMMMMMMHIXELMMMMMMMMMMMM....................MMMMMNNMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMM....................MMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMM88=........................+MMMMMMMMMM
MMMMMMMMMMMMMMMMM....................MMMMM...MMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMM....................MMMMM...MMMMMMMMMMMMMMM
MMMMMMMMMMMM.........................MM+..MMM....+MMMMMMMMMM
MMMMMMMMMNMM...................... ..MM?..MMM.. .+MMMMMMMMMM
MMMMNDDMM+........................+MM........MM..+MMMMMMMMMM
MMMMZ.............................+MM....................MMM
MMMMZ.............................+MM....................MMM
MMMMZ.............................+MM....................DDD
MMMMZ.............................+MM..ZMMMMMMMMMMMMMMMMMMMM
MMMMZ.............................+MM..ZMMMMMMMMMMMMMMMMMMMM
MM..............................MMZ....ZMMMMMMMMMMMMMMMMMMMM
MM............................MM.......ZMMMMMMMMMMMMMMMMMMMM
MM............................MM.......ZMMMMMMMMMMMMMMMMMMMM
MM......................ZMMMMM.......MMMMMMMMMMMMMMMMMMMMMMM
MM............... ......ZMMMMM.... ..MMMMMMMMMMMMMMMMMMMMMMM
MM...............MMMMM88~.........+MM..ZMMMMMMMMMMMMMMMMMMMM
MM.......$DDDDDDD.......$DDDDD..DDNMM..ZMMMMMMMMMMMMMMMMMMMM
MM.......$DDDDDDD.......$DDDDD..DDNMM..ZMMMMMMMMMMMMMMMMMMMM
MM.......ZMMMMMMM.......ZMMMMM..MMMMM..ZMMMMMMMMMMMMMMMMMMMM
MMMMMMMMM+.......MMMMM88NMMMMM..MMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMM+.......MMMMM88NMMMMM..MMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM*/

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address payable","name":"erc20_asset_pool","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user_address","type":"address"},{"indexed":true,"internalType":"address","name":"asset_source","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"vega_public_key","type":"bytes32"}],"name":"Asset_Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset_source","type":"address"},{"indexed":false,"internalType":"uint256","name":"lifetime_limit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"withdraw_threshold","type":"uint256"}],"name":"Asset_Limits_Updated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset_source","type":"address"},{"indexed":true,"internalType":"bytes32","name":"vega_asset_id","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"Asset_Listed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset_source","type":"address"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"Asset_Removed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user_address","type":"address"},{"indexed":true,"internalType":"address","name":"asset_source","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"}],"name":"Asset_Withdrawn","type":"event"},{"anonymous":false,"inputs":[],"name":"Bridge_Resumed","type":"event"},{"anonymous":false,"inputs":[],"name":"Bridge_Stopped","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"withdraw_delay","type":"uint256"}],"name":"Bridge_Withdraw_Delay_Set","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"depositor","type":"address"}],"name":"Depositor_Exempted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"depositor","type":"address"}],"name":"Depositor_Exemption_Revoked","type":"event"},{"inputs":[],"name":"default_withdraw_delay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset_source","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"vega_public_key","type":"bytes32"}],"name":"deposit_asset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"erc20_asset_pool_address","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exempt_depositor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset_source","type":"address"}],"name":"get_asset_deposit_lifetime_limit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"vega_asset_id","type":"bytes32"}],"name":"get_asset_source","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"get_multisig_control_address","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset_source","type":"address"}],"name":"get_vega_asset_id","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset_source","type":"address"}],"name":"get_withdraw_threshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"signatures","type":"bytes"}],"name":"global_resume","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"signatures","type":"bytes"}],"name":"global_stop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset_source","type":"address"}],"name":"is_asset_listed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"depositor","type":"address"}],"name":"is_exempt_depositor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"is_stopped","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset_source","type":"address"},{"internalType":"bytes32","name":"vega_asset_id","type":"bytes32"},{"internalType":"uint256","name":"lifetime_limit","type":"uint256"},{"internalType":"uint256","name":"withdraw_threshold","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"signatures","type":"bytes"}],"name":"list_asset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset_source","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"signatures","type":"bytes"}],"name":"remove_asset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revoke_exempt_depositor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset_source","type":"address"},{"internalType":"uint256","name":"lifetime_limit","type":"uint256"},{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"signatures","type":"bytes"}],"name":"set_asset_limits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"delay","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"signatures","type":"bytes"}],"name":"set_withdraw_delay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset_source","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"creation","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"signatures","type":"bytes"}],"name":"withdraw_asset","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052620697806006553480156200001857600080fd5b50604051620023ba380380620023ba8339810160408190526200003b91620000bc565b6001600160a01b038116620000965760405162461bcd60e51b815260206004820152601a60248201527f696e76616c696420617373657420706f6f6c2061646472657373000000000000604482015260640160405180910390fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055620000ee565b600060208284031215620000cf57600080fd5b81516001600160a01b0381168114620000e757600080fd5b9392505050565b6122bc80620000fe6000396000f3fe608060405234801561001057600080fd5b506004361061016c5760003560e01c80639356aab8116100cd578063c76de35811610081578063e272e9d011610066578063e272e9d014610395578063e8a7bce0146103a2578063f7683932146103d857600080fd5b8063c76de3581461036f578063d72ed5291461038257600080fd5b8063a06b5d39116100b2578063a06b5d3914610329578063b76fbb751461035f578063c58dc3b91461036757600080fd5b80639356aab8146102f65780639dfd3c881461031657600080fd5b806341fb776d116101245780636a1c6fa4116101095780636a1c6fa41461025a578063786b0bc0146102625780637fd27b7f146102bd57600080fd5b806341fb776d146102345780635a2467281461024757600080fd5b8063354a897a11610155578063354a897a146101d45780633ad90635146102185780633f4f199d1461022b57600080fd5b80630ff3562c1461017157806315c0df9d14610186575b600080fd5b61018461017f366004611dce565b6103eb565b005b6101bf610194366004611e43565b73ffffffffffffffffffffffffffffffffffffffff1660009081526009602052604090205460ff1690565b60405190151581526020015b60405180910390f35b61020a6101e2366004611e43565b73ffffffffffffffffffffffffffffffffffffffff1660009081526005602052604090205490565b6040519081526020016101cb565b610184610226366004611e67565b610762565b61020a60065481565b610184610242366004611f15565b610ae0565b610184610255366004611f88565b610d61565b610184610ef9565b610298610270366004611fdb565b60009081526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cb565b6101bf6102cb366004611e43565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604090205460ff1690565b6000546102989073ffffffffffffffffffffffffffffffffffffffff1681565b610184610324366004611ff4565b610fcf565b61020a610337366004611e43565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b6101846111ef565b6102986112c9565b61018461037d366004612040565b6112d8565b610184610390366004611ff4565b61155e565b6008546101bf9060ff1681565b61020a6103b0366004611e43565b73ffffffffffffffffffffffffffffffffffffffff1660009081526007602052604090205490565b6101846103e6366004612099565b61177a565b73ffffffffffffffffffffffffffffffffffffffff861661046d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f696e76616c696420617373657420736f7572636500000000000000000000000060448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff861660009081526001602052604090205460ff16156104fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f617373657420616c7265616479206c69737465640000000000000000000000006044820152606401610464565b6040805173ffffffffffffffffffffffffffffffffffffffff88166020820152908101869052606081018590526080810184905260a0810183905260c080820152600a60e08201527f6c6973745f61737365740000000000000000000000000000000000000000000061010082015260009061012001604051602081830303815290604052905061058c611c2e565b73ffffffffffffffffffffffffffffffffffffffff1663ba73659a8383866040518463ffffffff1660e01b81526004016105c893929190612148565b602060405180830381600087803b1580156105e257600080fd5b505af11580156105f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061a919061217e565b610680576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f626164207369676e6174757265730000000000000000000000000000000000006044820152606401610464565b73ffffffffffffffffffffffffffffffffffffffff8716600081815260016020818152604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169093179092558983526002815281832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001685179055838352600381528183208a9055600581528183208990556007815291819020879055518581528892917f4180d77d05ff0d31650c548c23f2de07a3da3ad42e3dd6edd817b438a150452e91015b60405180910390a350505050505050565b60085460ff16156107cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f6272696467652073746f707065640000000000000000000000000000000000006044820152606401610464565b73ffffffffffffffffffffffffffffffffffffffff861660009081526007602052604090205485108061080f5750426006548461080c91906121a0565b11155b610875576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f6c61726765207769746864726177206973206e6f74206f6c6420656e6f7567686044820152606401610464565b6040805173ffffffffffffffffffffffffffffffffffffffff808916602083015291810187905290851660608201526080810184905260a0810183905260c080820152600e60e08201527f77697468647261775f6173736574000000000000000000000000000000000000610100820152600090610120016040516020818303038152906040529050610906611c2e565b73ffffffffffffffffffffffffffffffffffffffff1663ba73659a8383866040518463ffffffff1660e01b815260040161094293929190612148565b602060405180830381600087803b15801561095c57600080fd5b505af1158015610970573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610994919061217e565b6109fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f626164207369676e6174757265730000000000000000000000000000000000006044820152606401610464565b6000546040517fd9caed1200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff89811660048301528781166024830152604482018990529091169063d9caed1290606401600060405180830381600087803b158015610a7657600080fd5b505af1158015610a8a573d6000803e3d6000fd5b5050604080518981526020810187905273ffffffffffffffffffffffffffffffffffffffff808c169450891692507fa79be4f3361e32d396d64c478ecef73732cb40b2a75702c3b3b3226a2c83b5df9101610751565b73ffffffffffffffffffffffffffffffffffffffff861660009081526001602052604090205460ff16610b6f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6173736574206e6f74206c6973746564000000000000000000000000000000006044820152606401610464565b6040805173ffffffffffffffffffffffffffffffffffffffff88166020820152908101869052606081018590526080810184905260a080820152601060c08201527f7365745f61737365745f6c696d6974730000000000000000000000000000000060e0820152600090610100016040516020818303038152906040529050610bf6611c2e565b73ffffffffffffffffffffffffffffffffffffffff1663ba73659a848484886040518563ffffffff1660e01b8152600401610c3494939291906121df565b602060405180830381600087803b158015610c4e57600080fd5b505af1158015610c62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c86919061217e565b610cec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f626164207369676e6174757265730000000000000000000000000000000000006044820152606401610464565b73ffffffffffffffffffffffffffffffffffffffff871660008181526005602090815260408083208a9055600782529182902088905581518981529081018890527ffc7eab762b8751ad85c101fd1025c763b4e8d48f2093f506629b606618e884fe910160405180910390a250505050505050565b6040805160208101869052908101849052606080820152601260808201527f7365745f77697468647261775f64656c6179000000000000000000000000000060a082015260009060c0016040516020818303038152906040529050610dc4611c2e565b73ffffffffffffffffffffffffffffffffffffffff1663ba73659a848484886040518563ffffffff1660e01b8152600401610e0294939291906121df565b602060405180830381600087803b158015610e1c57600080fd5b505af1158015610e30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e54919061217e565b610eba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f626164207369676e6174757265730000000000000000000000000000000000006044820152606401610464565b60068590556040518581527f1c7e8f73a01b8af4e18dd34455a42a45ad742bdb79cfda77bbdf50db2391fc889060200160405180910390a15050505050565b3360009081526009602052604090205460ff16610f72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f73656e646572206e6f74206578656d70740000000000000000000000000000006044820152606401610464565b3360008181526009602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517fe74b113dca87276d976f476a9b4b9da3c780a3262eaabad051ee4e98912936a49190a2565b60085460ff161561103c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f62726964676520616c72656164792073746f70706564000000000000000000006044820152606401610464565b600083604051602001611086918152604060208201819052600b908201527f676c6f62616c5f73746f70000000000000000000000000000000000000000000606082015260800190565b604051602081830303815290604052905061109f611c2e565b73ffffffffffffffffffffffffffffffffffffffff1663ba73659a848484886040518563ffffffff1660e01b81526004016110dd94939291906121df565b602060405180830381600087803b1580156110f757600080fd5b505af115801561110b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112f919061217e565b611195576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f626164207369676e6174757265730000000000000000000000000000000000006044820152606401610464565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517f129d99581c8e70519df1f0733d3212f33d0ed3ea6144adacc336c647f1d3638290600090a150505050565b3360009081526009602052604090205460ff1615611269576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f73656e64657220616c7265616479206578656d707400000000000000000000006044820152606401610464565b3360008181526009602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517ff56e0868b913034a60dbca9c89ee79f8b0fa18dadbc5f6665f2f9a2cf3f51cdb9190a2565b60006112d3611c2e565b905090565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604090205460ff16611367576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6173736574206e6f74206c6973746564000000000000000000000000000000006044820152606401610464565b6040805173ffffffffffffffffffffffffffffffffffffffff85166020820152908101839052606080820152600c60808201527f72656d6f76655f6173736574000000000000000000000000000000000000000060a082015260009060c00160405160208183030381529060405290506113df611c2e565b73ffffffffffffffffffffffffffffffffffffffff1663ba73659a8383866040518463ffffffff1660e01b815260040161141b93929190612148565b602060405180830381600087803b15801561143557600080fd5b505af1158015611449573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146d919061217e565b6114d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f626164207369676e6174757265730000000000000000000000000000000000006044820152606401610464565b73ffffffffffffffffffffffffffffffffffffffff84166000818152600160205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f58ad5e799e2df93ab408be0e5c1870d44c80b5bca99dfaf7ddf0dab5e6b155c9906115509086815260200190565b60405180910390a250505050565b60085460ff166115ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f627269646765206e6f742073746f7070656400000000000000000000000000006044820152606401610464565b600083604051602001611614918152604060208201819052600d908201527f676c6f62616c5f726573756d6500000000000000000000000000000000000000606082015260800190565b604051602081830303815290604052905061162d611c2e565b73ffffffffffffffffffffffffffffffffffffffff1663ba73659a848484886040518563ffffffff1660e01b815260040161166b94939291906121df565b602060405180830381600087803b15801561168557600080fd5b505af1158015611699573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116bd919061217e565b611723576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f626164207369676e6174757265730000000000000000000000000000000000006044820152606401610464565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040517f79c02b0e60e0f00fe0370791204f2f175fe3f06f4816f3506ad4fa1b8e8cde0f90600090a150505050565b60085460ff16156117e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f6272696467652073746f707065640000000000000000000000000000000000006044820152606401610464565b3360009081526009602052604090205460ff166118f45773ffffffffffffffffffffffffffffffffffffffff831660008181526005602090815260408083205433845260048352818420948452939091529020546118469084906121a0565b11156118ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f6465706f736974206f766572206c69666574696d65206c696d697400000000006044820152606401610464565b33600090815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812080548492906118ee9084906121a0565b90915550505b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604090205460ff16611983576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6173736574206e6f74206c6973746564000000000000000000000000000000006044820152606401610464565b823b6119eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f61737365745f736f75726365206d75737420626520636f6e74726163740000006044820152606401610464565b6000805460405133602482015273ffffffffffffffffffffffffffffffffffffffff9182166044820152606481018590528291861690608401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905251611aa5919061224d565b6000604051808303816000865af19150503d8060008114611ae2576040519150601f19603f3d011682016040523d82523d6000602084013e611ae7565b606091505b509150915081611b53576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f6b656e207472616e73666572206661696c656400000000000000000000006044820152606401610464565b805115611bd45780806020019051810190611b6e919061217e565b611bd4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f6b656e207472616e73666572206661696c656400000000000000000000006044820152606401610464565b604080518581526020810185905273ffffffffffffffffffffffffffffffffffffffff87169133917f3724ff5e82ddc640a08d68b0b782a5991aea0de51a8dd10a59cdbe5b3ec4e6bf910160405180910390a35050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b82d5abd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611c9757600080fd5b505afa158015611cab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d39190612269565b73ffffffffffffffffffffffffffffffffffffffff81168114611cf157600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112611d3457600080fd5b813567ffffffffffffffff80821115611d4f57611d4f611cf4565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715611d9557611d95611cf4565b81604052838152866020858801011115611dae57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060008060008060c08789031215611de757600080fd5b8635611df281611ccf565b95506020870135945060408701359350606087013592506080870135915060a087013567ffffffffffffffff811115611e2a57600080fd5b611e3689828a01611d23565b9150509295509295509295565b600060208284031215611e5557600080fd5b8135611e6081611ccf565b9392505050565b60008060008060008060c08789031215611e8057600080fd5b8635611e8b81611ccf565b9550602087013594506040870135611ea281611ccf565b9350606087013592506080870135915060a087013567ffffffffffffffff811115611e2a57600080fd5b60008083601f840112611ede57600080fd5b50813567ffffffffffffffff811115611ef657600080fd5b602083019150836020828501011115611f0e57600080fd5b9250929050565b60008060008060008060a08789031215611f2e57600080fd5b8635611f3981611ccf565b9550602087013594506040870135935060608701359250608087013567ffffffffffffffff811115611f6a57600080fd5b611f7689828a01611ecc565b979a9699509497509295939492505050565b60008060008060608587031215611f9e57600080fd5b8435935060208501359250604085013567ffffffffffffffff811115611fc357600080fd5b611fcf87828801611ecc565b95989497509550505050565b600060208284031215611fed57600080fd5b5035919050565b60008060006040848603121561200957600080fd5b83359250602084013567ffffffffffffffff81111561202757600080fd5b61203386828701611ecc565b9497909650939450505050565b60008060006060848603121561205557600080fd5b833561206081611ccf565b925060208401359150604084013567ffffffffffffffff81111561208357600080fd5b61208f86828701611d23565b9150509250925092565b6000806000606084860312156120ae57600080fd5b83356120b981611ccf565b95602085013595506040909401359392505050565b60005b838110156120e95781810151838201526020016120d1565b838111156120f8576000848401525b50505050565b600081518084526121168160208601602086016120ce565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60608152600061215b60608301866120fe565b828103602084015261216d81866120fe565b915050826040830152949350505050565b60006020828403121561219057600080fd5b81518015158114611e6057600080fd5b600082198211156121da577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b606081528360608201528385608083013760006080858301015260007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8601168201608083820301602084015261223b60808201866120fe565b91505082604083015295945050505050565b6000825161225f8184602087016120ce565b9190910192915050565b60006020828403121561227b57600080fd5b8151611e6081611ccf56fea2646970667358221220564040cd5f92f777f0b532760585171690d4896a828abf9437b37135b0636cdb64736f6c63430008080033000000000000000000000000f0f0fcda832415b935802c6dad0a6da2c7eaed8f

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061016c5760003560e01c80639356aab8116100cd578063c76de35811610081578063e272e9d011610066578063e272e9d014610395578063e8a7bce0146103a2578063f7683932146103d857600080fd5b8063c76de3581461036f578063d72ed5291461038257600080fd5b8063a06b5d39116100b2578063a06b5d3914610329578063b76fbb751461035f578063c58dc3b91461036757600080fd5b80639356aab8146102f65780639dfd3c881461031657600080fd5b806341fb776d116101245780636a1c6fa4116101095780636a1c6fa41461025a578063786b0bc0146102625780637fd27b7f146102bd57600080fd5b806341fb776d146102345780635a2467281461024757600080fd5b8063354a897a11610155578063354a897a146101d45780633ad90635146102185780633f4f199d1461022b57600080fd5b80630ff3562c1461017157806315c0df9d14610186575b600080fd5b61018461017f366004611dce565b6103eb565b005b6101bf610194366004611e43565b73ffffffffffffffffffffffffffffffffffffffff1660009081526009602052604090205460ff1690565b60405190151581526020015b60405180910390f35b61020a6101e2366004611e43565b73ffffffffffffffffffffffffffffffffffffffff1660009081526005602052604090205490565b6040519081526020016101cb565b610184610226366004611e67565b610762565b61020a60065481565b610184610242366004611f15565b610ae0565b610184610255366004611f88565b610d61565b610184610ef9565b610298610270366004611fdb565b60009081526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101cb565b6101bf6102cb366004611e43565b73ffffffffffffffffffffffffffffffffffffffff1660009081526001602052604090205460ff1690565b6000546102989073ffffffffffffffffffffffffffffffffffffffff1681565b610184610324366004611ff4565b610fcf565b61020a610337366004611e43565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b6101846111ef565b6102986112c9565b61018461037d366004612040565b6112d8565b610184610390366004611ff4565b61155e565b6008546101bf9060ff1681565b61020a6103b0366004611e43565b73ffffffffffffffffffffffffffffffffffffffff1660009081526007602052604090205490565b6101846103e6366004612099565b61177a565b73ffffffffffffffffffffffffffffffffffffffff861661046d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f696e76616c696420617373657420736f7572636500000000000000000000000060448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff861660009081526001602052604090205460ff16156104fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f617373657420616c7265616479206c69737465640000000000000000000000006044820152606401610464565b6040805173ffffffffffffffffffffffffffffffffffffffff88166020820152908101869052606081018590526080810184905260a0810183905260c080820152600a60e08201527f6c6973745f61737365740000000000000000000000000000000000000000000061010082015260009061012001604051602081830303815290604052905061058c611c2e565b73ffffffffffffffffffffffffffffffffffffffff1663ba73659a8383866040518463ffffffff1660e01b81526004016105c893929190612148565b602060405180830381600087803b1580156105e257600080fd5b505af11580156105f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061a919061217e565b610680576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f626164207369676e6174757265730000000000000000000000000000000000006044820152606401610464565b73ffffffffffffffffffffffffffffffffffffffff8716600081815260016020818152604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169093179092558983526002815281832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001685179055838352600381528183208a9055600581528183208990556007815291819020879055518581528892917f4180d77d05ff0d31650c548c23f2de07a3da3ad42e3dd6edd817b438a150452e91015b60405180910390a350505050505050565b60085460ff16156107cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f6272696467652073746f707065640000000000000000000000000000000000006044820152606401610464565b73ffffffffffffffffffffffffffffffffffffffff861660009081526007602052604090205485108061080f5750426006548461080c91906121a0565b11155b610875576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f6c61726765207769746864726177206973206e6f74206f6c6420656e6f7567686044820152606401610464565b6040805173ffffffffffffffffffffffffffffffffffffffff808916602083015291810187905290851660608201526080810184905260a0810183905260c080820152600e60e08201527f77697468647261775f6173736574000000000000000000000000000000000000610100820152600090610120016040516020818303038152906040529050610906611c2e565b73ffffffffffffffffffffffffffffffffffffffff1663ba73659a8383866040518463ffffffff1660e01b815260040161094293929190612148565b602060405180830381600087803b15801561095c57600080fd5b505af1158015610970573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610994919061217e565b6109fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f626164207369676e6174757265730000000000000000000000000000000000006044820152606401610464565b6000546040517fd9caed1200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff89811660048301528781166024830152604482018990529091169063d9caed1290606401600060405180830381600087803b158015610a7657600080fd5b505af1158015610a8a573d6000803e3d6000fd5b5050604080518981526020810187905273ffffffffffffffffffffffffffffffffffffffff808c169450891692507fa79be4f3361e32d396d64c478ecef73732cb40b2a75702c3b3b3226a2c83b5df9101610751565b73ffffffffffffffffffffffffffffffffffffffff861660009081526001602052604090205460ff16610b6f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6173736574206e6f74206c6973746564000000000000000000000000000000006044820152606401610464565b6040805173ffffffffffffffffffffffffffffffffffffffff88166020820152908101869052606081018590526080810184905260a080820152601060c08201527f7365745f61737365745f6c696d6974730000000000000000000000000000000060e0820152600090610100016040516020818303038152906040529050610bf6611c2e565b73ffffffffffffffffffffffffffffffffffffffff1663ba73659a848484886040518563ffffffff1660e01b8152600401610c3494939291906121df565b602060405180830381600087803b158015610c4e57600080fd5b505af1158015610c62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c86919061217e565b610cec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f626164207369676e6174757265730000000000000000000000000000000000006044820152606401610464565b73ffffffffffffffffffffffffffffffffffffffff871660008181526005602090815260408083208a9055600782529182902088905581518981529081018890527ffc7eab762b8751ad85c101fd1025c763b4e8d48f2093f506629b606618e884fe910160405180910390a250505050505050565b6040805160208101869052908101849052606080820152601260808201527f7365745f77697468647261775f64656c6179000000000000000000000000000060a082015260009060c0016040516020818303038152906040529050610dc4611c2e565b73ffffffffffffffffffffffffffffffffffffffff1663ba73659a848484886040518563ffffffff1660e01b8152600401610e0294939291906121df565b602060405180830381600087803b158015610e1c57600080fd5b505af1158015610e30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e54919061217e565b610eba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f626164207369676e6174757265730000000000000000000000000000000000006044820152606401610464565b60068590556040518581527f1c7e8f73a01b8af4e18dd34455a42a45ad742bdb79cfda77bbdf50db2391fc889060200160405180910390a15050505050565b3360009081526009602052604090205460ff16610f72576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f73656e646572206e6f74206578656d70740000000000000000000000000000006044820152606401610464565b3360008181526009602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517fe74b113dca87276d976f476a9b4b9da3c780a3262eaabad051ee4e98912936a49190a2565b60085460ff161561103c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f62726964676520616c72656164792073746f70706564000000000000000000006044820152606401610464565b600083604051602001611086918152604060208201819052600b908201527f676c6f62616c5f73746f70000000000000000000000000000000000000000000606082015260800190565b604051602081830303815290604052905061109f611c2e565b73ffffffffffffffffffffffffffffffffffffffff1663ba73659a848484886040518563ffffffff1660e01b81526004016110dd94939291906121df565b602060405180830381600087803b1580156110f757600080fd5b505af115801561110b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112f919061217e565b611195576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f626164207369676e6174757265730000000000000000000000000000000000006044820152606401610464565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556040517f129d99581c8e70519df1f0733d3212f33d0ed3ea6144adacc336c647f1d3638290600090a150505050565b3360009081526009602052604090205460ff1615611269576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f73656e64657220616c7265616479206578656d707400000000000000000000006044820152606401610464565b3360008181526009602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517ff56e0868b913034a60dbca9c89ee79f8b0fa18dadbc5f6665f2f9a2cf3f51cdb9190a2565b60006112d3611c2e565b905090565b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604090205460ff16611367576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6173736574206e6f74206c6973746564000000000000000000000000000000006044820152606401610464565b6040805173ffffffffffffffffffffffffffffffffffffffff85166020820152908101839052606080820152600c60808201527f72656d6f76655f6173736574000000000000000000000000000000000000000060a082015260009060c00160405160208183030381529060405290506113df611c2e565b73ffffffffffffffffffffffffffffffffffffffff1663ba73659a8383866040518463ffffffff1660e01b815260040161141b93929190612148565b602060405180830381600087803b15801561143557600080fd5b505af1158015611449573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146d919061217e565b6114d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f626164207369676e6174757265730000000000000000000000000000000000006044820152606401610464565b73ffffffffffffffffffffffffffffffffffffffff84166000818152600160205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f58ad5e799e2df93ab408be0e5c1870d44c80b5bca99dfaf7ddf0dab5e6b155c9906115509086815260200190565b60405180910390a250505050565b60085460ff166115ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f627269646765206e6f742073746f7070656400000000000000000000000000006044820152606401610464565b600083604051602001611614918152604060208201819052600d908201527f676c6f62616c5f726573756d6500000000000000000000000000000000000000606082015260800190565b604051602081830303815290604052905061162d611c2e565b73ffffffffffffffffffffffffffffffffffffffff1663ba73659a848484886040518563ffffffff1660e01b815260040161166b94939291906121df565b602060405180830381600087803b15801561168557600080fd5b505af1158015611699573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116bd919061217e565b611723576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f626164207369676e6174757265730000000000000000000000000000000000006044820152606401610464565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690556040517f79c02b0e60e0f00fe0370791204f2f175fe3f06f4816f3506ad4fa1b8e8cde0f90600090a150505050565b60085460ff16156117e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f6272696467652073746f707065640000000000000000000000000000000000006044820152606401610464565b3360009081526009602052604090205460ff166118f45773ffffffffffffffffffffffffffffffffffffffff831660008181526005602090815260408083205433845260048352818420948452939091529020546118469084906121a0565b11156118ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f6465706f736974206f766572206c69666574696d65206c696d697400000000006044820152606401610464565b33600090815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812080548492906118ee9084906121a0565b90915550505b73ffffffffffffffffffffffffffffffffffffffff831660009081526001602052604090205460ff16611983576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6173736574206e6f74206c6973746564000000000000000000000000000000006044820152606401610464565b823b6119eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f61737365745f736f75726365206d75737420626520636f6e74726163740000006044820152606401610464565b6000805460405133602482015273ffffffffffffffffffffffffffffffffffffffff9182166044820152606481018590528291861690608401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905251611aa5919061224d565b6000604051808303816000865af19150503d8060008114611ae2576040519150601f19603f3d011682016040523d82523d6000602084013e611ae7565b606091505b509150915081611b53576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f6b656e207472616e73666572206661696c656400000000000000000000006044820152606401610464565b805115611bd45780806020019051810190611b6e919061217e565b611bd4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f6b656e207472616e73666572206661696c656400000000000000000000006044820152606401610464565b604080518581526020810185905273ffffffffffffffffffffffffffffffffffffffff87169133917f3724ff5e82ddc640a08d68b0b782a5991aea0de51a8dd10a59cdbe5b3ec4e6bf910160405180910390a35050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b82d5abd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611c9757600080fd5b505afa158015611cab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d39190612269565b73ffffffffffffffffffffffffffffffffffffffff81168114611cf157600080fd5b50565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112611d3457600080fd5b813567ffffffffffffffff80821115611d4f57611d4f611cf4565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715611d9557611d95611cf4565b81604052838152866020858801011115611dae57600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060008060008060c08789031215611de757600080fd5b8635611df281611ccf565b95506020870135945060408701359350606087013592506080870135915060a087013567ffffffffffffffff811115611e2a57600080fd5b611e3689828a01611d23565b9150509295509295509295565b600060208284031215611e5557600080fd5b8135611e6081611ccf565b9392505050565b60008060008060008060c08789031215611e8057600080fd5b8635611e8b81611ccf565b9550602087013594506040870135611ea281611ccf565b9350606087013592506080870135915060a087013567ffffffffffffffff811115611e2a57600080fd5b60008083601f840112611ede57600080fd5b50813567ffffffffffffffff811115611ef657600080fd5b602083019150836020828501011115611f0e57600080fd5b9250929050565b60008060008060008060a08789031215611f2e57600080fd5b8635611f3981611ccf565b9550602087013594506040870135935060608701359250608087013567ffffffffffffffff811115611f6a57600080fd5b611f7689828a01611ecc565b979a9699509497509295939492505050565b60008060008060608587031215611f9e57600080fd5b8435935060208501359250604085013567ffffffffffffffff811115611fc357600080fd5b611fcf87828801611ecc565b95989497509550505050565b600060208284031215611fed57600080fd5b5035919050565b60008060006040848603121561200957600080fd5b83359250602084013567ffffffffffffffff81111561202757600080fd5b61203386828701611ecc565b9497909650939450505050565b60008060006060848603121561205557600080fd5b833561206081611ccf565b925060208401359150604084013567ffffffffffffffff81111561208357600080fd5b61208f86828701611d23565b9150509250925092565b6000806000606084860312156120ae57600080fd5b83356120b981611ccf565b95602085013595506040909401359392505050565b60005b838110156120e95781810151838201526020016120d1565b838111156120f8576000848401525b50505050565b600081518084526121168160208601602086016120ce565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60608152600061215b60608301866120fe565b828103602084015261216d81866120fe565b915050826040830152949350505050565b60006020828403121561219057600080fd5b81518015158114611e6057600080fd5b600082198211156121da577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b606081528360608201528385608083013760006080858301015260007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8601168201608083820301602084015261223b60808201866120fe565b91505082604083015295945050505050565b6000825161225f8184602087016120ce565b9190910192915050565b60006020828403121561227b57600080fd5b8151611e6081611ccf56fea2646970667358221220564040cd5f92f777f0b532760585171690d4896a828abf9437b37135b0636cdb64736f6c63430008080033

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

000000000000000000000000f0f0fcda832415b935802c6dad0a6da2c7eaed8f

-----Decoded View---------------
Arg [0] : erc20_asset_pool (address): 0xF0f0FcDA832415b935802c6dAD0a6dA2c7EAed8f

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000f0f0fcda832415b935802c6dad0a6da2c7eaed8f


Deployed Bytecode Sourcemap

438:14876:1:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2067:1121;;;;;;:::i;:::-;;:::i;:::-;;10376:138;;;;;;:::i;:::-;10479:28;;10456:4;10479:28;;;:17;:28;;;;;;;;;10376:138;;;;2296:14:9;;2289:22;2271:41;;2259:2;2244:18;10376:138:1;;;;;;;;6265:171;;;;;;:::i;:::-;6387:42;;6361:7;6387:42;;;:28;:42;;;;;;;6265:171;;;;2469:25:9;;;2457:2;2442:18;6265:171:1;2323:177:9;11249:877:1;;;;;;:::i;:::-;;:::i;4525:46::-;;;;;;5317:743;;;;;;:::i;:::-;;:::i;7160:467::-;;;;;;:::i;:::-;;:::i;9940:230::-;;;:::i;14953:153::-;;;;;;:::i;:::-;15034:7;15060:39;;;:24;:39;;;;;;;;;14953:153;;;;5331:42:9;5319:55;;;5301:74;;5289:2;5274:18;14953:153:1;5155:226:9;14160:136:1;;;;;;:::i;:::-;14262:27;;14239:4;14262:27;;;:13;:27;;;;;;;;;14160:136;517:47;;;;;;;;;8028:428;;;;;;:::i;:::-;;:::i;14620:157::-;;;;;;:::i;:::-;14727:43;;14701:7;14727:43;;;:29;:43;;;;;;;14620:157;9462:218;;;:::i;14351:131::-;;;:::i;3689:540::-;;;;;;:::i;:::-;;:::i;8802:428::-;;;;;;:::i;:::-;;:::i;4663:22::-;;;;;;;;;6663:152;;;;;;:::i;:::-;6775:33;;6749:7;6775:33;;;:19;:33;;;;;;;6663:152;12627:1245;;;;;;:::i;:::-;;:::i;2067:1121::-;2314:26;;;2306:59;;;;;;;7415:2:9;2306:59:1;;;7397:21:9;7454:2;7434:18;;;7427:30;7493:22;7473:18;;;7466:50;7533:18;;2306:59:1;;;;;;;;;2384:27;;;;;;;:13;:27;;;;;;;;2383:28;2375:61;;;;;;;7764:2:9;2375:61:1;;;7746:21:9;7803:2;7783:18;;;7776:30;7842:22;7822:18;;;7815:50;7882:18;;2375:61:1;7562:344:9;2375:61:1;2469:178;;;8265:42:9;8253:55;;2469:178:1;;;8235:74:9;8325:18;;;8318:34;;;8368:18;;;8361:34;;;8411:18;;;8404:34;;;8454:19;;;8447:35;;;8519:3;8498:19;;;8491:32;8560:2;8539:19;;;8532:31;8600:12;8579:19;;;8572:41;2446:20:1;;8630:19:9;;2469:178:1;;;;;;;;;;;;2446:201;;2695:26;:24;:26::i;:::-;2678:62;;;2741:10;2753:7;2762:5;2678:90;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2657:151;;;;;;;10181:2:9;2657:151:1;;;10163:21:9;10220:2;10200:18;;;10193:30;10259:16;10239:18;;;10232:44;10293:18;;2657:151:1;9979:338:9;2657:151:1;2818:27;;;;;;;2848:4;2818:27;;;;;;;;:34;;;;;;;;;;2862:39;;;:24;:39;;;;;:54;;;;;;;;2926:43;;;:29;:43;;;;;:59;;;2995:28;:42;;;;;:59;;;3064:19;:33;;;;;;:54;;;3133:48;2469:25:9;;;2862:39:1;;2818:27;3133:48;;2442:18:9;3133:48:1;;;;;;;;2296:892;2067:1121;;;;;;:::o;11249:877::-;11476:10;;;;11475:11;11467:38;;;;;;;10524:2:9;11467:38:1;;;10506:21:9;10563:2;10543:18;;;10536:30;10602:16;10582:18;;;10575:44;10636:18;;11467:38:1;10322:338:9;11467:38:1;11536:33;;;;;;;:19;:33;;;;;;:42;-1:-1:-1;11536:42:1;:98;;;11619:15;11593:22;;11582:8;:33;;;;:::i;:::-;:52;;11536:98;11515:177;;;;;;;11154:2:9;11515:177:1;;;11136:21:9;;;11173:18;;;11166:30;11232:34;11212:18;;;11205:62;11284:18;;11515:177:1;10952:356:9;11515:177:1;11725:75;;;11647:42:9;11716:15;;;11725:75:1;;;11698:34:9;11748:18;;;11741:34;;;11811:15;;;11791:18;;;11784:43;11843:18;;;11836:34;;;11886:19;;;11879:35;;;11951:3;11930:19;;;11923:32;11992:2;11971:19;;;11964:31;12032:16;12011:19;;;12004:45;11702:20:1;;12066:19:9;;11725:75:1;;;;;;;;;;;;11702:98;;11848:26;:24;:26::i;:::-;11831:62;;;11894:10;11906:7;11915:5;11831:90;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11810:151;;;;;;;10181:2:9;11810:151:1;;;10163:21:9;10220:2;10200:18;;;10193:30;10259:16;10239:18;;;10232:44;10293:18;;11810:151:1;9979:338:9;11810:151:1;11988:24;;11971:81;;;;;11988:24;12377:15:9;;;11971:81:1;;;12359:34:9;12429:15;;;12409:18;;;12402:43;12461:18;;;12454:34;;;11988:24:1;;;;11971:51;;12271:18:9;;11971:81:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;12067:52:1;;;12673:25:9;;;12729:2;12714:18;;12707:34;;;12067:52:1;;;;;-1:-1:-1;12067:52:1;;;-1:-1:-1;12067:52:1;;12646:18:9;12067:52:1;12499:248:9;5317:743:1;5532:27;;;;;;;:13;:27;;;;;;;;5524:56;;;;;;;12954:2:9;5524:56:1;;;12936:21:9;12993:2;12973:18;;;12966:30;13032:18;13012;;;13005:46;13068:18;;5524:56:1;12752:340:9;5524:56:1;5613:78;;;13423:42:9;13411:55;;5613:78:1;;;13393:74:9;13483:18;;;13476:34;;;13526:18;;;13519:34;;;13569:18;;;13562:34;;;13633:3;13612:19;;;13605:32;13674:2;13653:19;;;13646:31;13714:18;13693:19;;;13686:47;5590:20:1;;13750:19:9;;5613:78:1;;;;;;;;;;;;5590:101;;5739:26;:24;:26::i;:::-;5722:62;;;5785:10;;5797:7;5806:5;5722:90;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5701:151;;;;;;;10181:2:9;5701:151:1;;;10163:21:9;10220:2;10200:18;;;10193:30;10259:16;10239:18;;;10232:44;10293:18;;5701:151:1;9979:338:9;5701:151:1;5862:42;;;;;;;:28;:42;;;;;;;;:59;;;5931:19;:33;;;;;;:45;;;5992:61;;12673:25:9;;;12714:18;;;12707:34;;;5992:61:1;;12646:18:9;5992:61:1;;;;;;;5514:546;5317:743;;;;;;:::o;7160:467::-;7326:46;;;;;;14706:25:9;;;14747:18;;;14740:34;;;14810:2;14790:18;;;14783:30;14849:2;14829:18;;;14822:30;14889:20;14868:19;;;14861:49;7303:20:1;;14927:19:9;;7326:46:1;;;;;;;;;;;;7303:69;;7420:26;:24;:26::i;:::-;7403:62;;;7466:10;;7478:7;7487:5;7403:90;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7382:151;;;;;;;10181:2:9;7382:151:1;;;10163:21:9;10220:2;10200:18;;;10193:30;10259:16;10239:18;;;10232:44;10293:18;;7382:151:1;9979:338:9;7382:151:1;7543:22;:30;;;7588:32;;2469:25:9;;;7588:32:1;;2457:2:9;2442:18;7588:32:1;;;;;;;7293:334;7160:467;;;;:::o;9940:230::-;10029:10;10011:29;;;;:17;:29;;;;;;;;10003:59;;;;;;;15159:2:9;10003:59:1;;;15141:21:9;15198:2;15178:18;;;15171:30;15237:19;15217:18;;;15210:47;15274:18;;10003:59:1;14957:341:9;10003:59:1;10090:10;10104:5;10072:29;;;:17;:29;;;;;;:37;;;;;;10124:39;;;10104:5;10124:39;9940:230::o;8028:428::-;8128:10;;;;8127:11;8119:46;;;;;;;15505:2:9;8119:46:1;;;15487:21:9;15544:2;15524:18;;;15517:30;15583:24;15563:18;;;15556:52;15625:18;;8119:46:1;15303:346:9;8119:46:1;8175:20;8209:5;8198:32;;;;;;15866:25:9;;15927:2;15922;15907:18;;15900:30;;;15966:2;15946:18;;;15939:30;16005:13;16000:2;15985:18;;15978:41;16051:3;16036:19;;15654:407;8198:32:1;;;;;;;;;;;;;8175:55;;8278:26;:24;:26::i;:::-;8261:62;;;8324:10;;8336:7;8345:5;8261:90;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8240:151;;;;;;;10181:2:9;8240:151:1;;;10163:21:9;10220:2;10200:18;;;10193:30;10259:16;10239:18;;;10232:44;10293:18;;8240:151:1;9979:338:9;8240:151:1;8401:10;:17;;;;8414:4;8401:17;;;8433:16;;;;8401:10;;8433:16;8109:347;8028:428;;;:::o;9462:218::-;9545:10;9527:29;;;;:17;:29;;;;;;;;9526:30;9518:64;;;;;;;16268:2:9;9518:64:1;;;16250:21:9;16307:2;16287:18;;;16280:30;16346:23;16326:18;;;16319:51;16387:18;;9518:64:1;16066:345:9;9518:64:1;9610:10;9592:29;;;;:17;:29;;;;;;:36;;;;9624:4;9592:36;;;9643:30;;;9592:29;9643:30;9462:218::o;14351:131::-;14423:7;14449:26;:24;:26::i;:::-;14442:33;;14351:131;:::o;3689:540::-;3839:27;;;;;;;:13;:27;;;;;;;;3831:56;;;;;;;12954:2:9;3831:56:1;;;12936:21:9;12993:2;12973:18;;;12966:30;13032:18;13012;;;13005:46;13068:18;;3831:56:1;12752:340:9;3831:56:1;3920:47;;;16686:42:9;16674:55;;3920:47:1;;;16656:74:9;16746:18;;;16739:34;;;16809:2;16789:18;;;16782:30;16848:2;16828:18;;;16821:30;16888:14;16867:19;;;16860:43;3897:20:1;;16920:19:9;;3920:47:1;;;;;;;;;;;;3897:70;;4015:26;:24;:26::i;:::-;3998:62;;;4061:10;4073:7;4082:5;3998:90;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3977:151;;;;;;;10181:2:9;3977:151:1;;;10163:21:9;10220:2;10200:18;;;10193:30;10259:16;10239:18;;;10232:44;10293:18;;3977:151:1;9979:338:9;3977:151:1;4138:27;;;4168:5;4138:27;;;:13;:27;;;;;;;:35;;;;;;4188:34;;;;;4216:5;2469:25:9;;2457:2;2442:18;;2323:177;4188:34:1;;;;;;;;3821:408;3689:540;;;:::o;8802:428::-;8903:10;;;;8895:41;;;;;;;17152:2:9;8895:41:1;;;17134:21:9;17191:2;17171:18;;;17164:30;17230:20;17210:18;;;17203:48;17268:18;;8895:41:1;16950:342:9;8895:41:1;8946:20;8980:5;8969:34;;;;;;17509:25:9;;17570:2;17565;17550:18;;17543:30;;;17609:2;17589:18;;;17582:30;17648:15;17643:2;17628:18;;17621:43;17696:3;17681:19;;17297:409;8969:34:1;;;;;;;;;;;;;8946:57;;9051:26;:24;:26::i;:::-;9034:62;;;9097:10;;9109:7;9118:5;9034:90;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;9013:151;;;;;;;10181:2:9;9013:151:1;;;10163:21:9;10220:2;10200:18;;;10193:30;10259:16;10239:18;;;10232:44;10293:18;;9013:151:1;9979:338:9;9013:151:1;9174:10;:18;;;;;;9207:16;;;;9187:5;;9207:16;8885:345;8802:428;;;:::o;12627:1245::-;12780:10;;;;12779:11;12771:38;;;;;;;10524:2:9;12771:38:1;;;10506:21:9;10563:2;10543:18;;;10536:30;10602:16;10582:18;;;10575:44;10636:18;;12771:38:1;10322:338:9;12771:38:1;12843:10;12825:29;;;;:17;:29;;;;;;;;12820:322;;12956:42;;;;;;;:28;:42;;;;;;;;;12918:10;12895:34;;:22;:34;;;;;:48;;;;;;;;;;:57;;12946:6;;12895:57;:::i;:::-;:103;;12870:189;;;;;;;17913:2:9;12870:189:1;;;17895:21:9;17952:2;17932:18;;;17925:30;17991:29;17971:18;;;17964:57;18038:18;;12870:189:1;17711:351:9;12870:189:1;13096:10;13073:34;;;;:22;:34;;;;;;;;;:48;;;;;;;;;:58;;13125:6;;13073:34;:58;;13125:6;;13073:58;:::i;:::-;;;;-1:-1:-1;;12820:322:1;13160:27;;;;;;;:13;:27;;;;;;;;13152:56;;;;;;;12954:2:9;13152:56:1;;;12936:21:9;12993:2;12973:18;;;12966:30;13032:18;13012;;;13005:46;13068:18;;13152:56:1;12752:340:9;13152:56:1;15249:17;;13218:67;;;;;;;18269:2:9;13218:67:1;;;18251:21:9;18308:2;18288:18;;;18281:30;18347:31;18327:18;;;18320:59;18396:18;;13218:67:1;18067:353:9;13218:67:1;13297:12;13495:24;;13369:188;;13467:10;13369:188;;;12359:34:9;13338:17:1;13495:24;;;12409:18:9;;;12402:43;12461:18;;;12454:34;;;13297:12:1;;13338:17;;;12271:18:9;;13369:188:1;;;;;;;;;;;;;;;;;;;;;;;;13338:229;;;13369:188;13338:229;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13296:271;;;;13585:7;13577:41;;;;;;;19325:2:9;13577:41:1;;;19307:21:9;19364:2;19344:18;;;19337:30;19403:23;19383:18;;;19376:51;19444:18;;13577:41:1;19123:345:9;13577:41:1;13633:17;;:21;13629:155;;13728:10;13717:30;;;;;;;;;;;;:::i;:::-;13709:64;;;;;;;19325:2:9;13709:64:1;;;19307:21:9;19364:2;19344:18;;;19337:30;19403:23;19383:18;;;19376:51;19444:18;;13709:64:1;19123:345:9;13709:64:1;13799:66;;;12673:25:9;;;12729:2;12714:18;;12707:34;;;13799:66:1;;;;13815:10;;13799:66;;12646:18:9;13799:66:1;;;;;;;12761:1111;;12627:1245;;;:::o;1103:161::-;1162:7;1205:24;;;;;;;;;;;1188:67;;;:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;14:154:9:-;100:42;93:5;89:54;82:5;79:65;69:93;;158:1;155;148:12;69:93;14:154;:::o;173:184::-;225:77;222:1;215:88;322:4;319:1;312:15;346:4;343:1;336:15;362:777;404:5;457:3;450:4;442:6;438:17;434:27;424:55;;475:1;472;465:12;424:55;511:6;498:20;537:18;574:2;570;567:10;564:36;;;580:18;;:::i;:::-;714:2;708:9;776:4;768:13;;619:66;764:22;;;788:2;760:31;756:40;744:53;;;812:18;;;832:22;;;809:46;806:72;;;858:18;;:::i;:::-;898:10;894:2;887:22;933:2;925:6;918:18;979:3;972:4;967:2;959:6;955:15;951:26;948:35;945:55;;;996:1;993;986:12;945:55;1060:2;1053:4;1045:6;1041:17;1034:4;1026:6;1022:17;1009:54;1107:1;1100:4;1095:2;1087:6;1083:15;1079:26;1072:37;1127:6;1118:15;;;;;;362:777;;;;:::o;1144:730::-;1257:6;1265;1273;1281;1289;1297;1350:3;1338:9;1329:7;1325:23;1321:33;1318:53;;;1367:1;1364;1357:12;1318:53;1406:9;1393:23;1425:31;1450:5;1425:31;:::i;:::-;1475:5;-1:-1:-1;1527:2:9;1512:18;;1499:32;;-1:-1:-1;1578:2:9;1563:18;;1550:32;;-1:-1:-1;1629:2:9;1614:18;;1601:32;;-1:-1:-1;1680:3:9;1665:19;;1652:33;;-1:-1:-1;1736:3:9;1721:19;;1708:33;1764:18;1753:30;;1750:50;;;1796:1;1793;1786:12;1750:50;1819:49;1860:7;1851:6;1840:9;1836:22;1819:49;:::i;:::-;1809:59;;;1144:730;;;;;;;;:::o;1879:247::-;1938:6;1991:2;1979:9;1970:7;1966:23;1962:32;1959:52;;;2007:1;2004;1997:12;1959:52;2046:9;2033:23;2065:31;2090:5;2065:31;:::i;:::-;2115:5;1879:247;-1:-1:-1;;;1879:247:9:o;2505:803::-;2618:6;2626;2634;2642;2650;2658;2711:3;2699:9;2690:7;2686:23;2682:33;2679:53;;;2728:1;2725;2718:12;2679:53;2767:9;2754:23;2786:31;2811:5;2786:31;:::i;:::-;2836:5;-1:-1:-1;2888:2:9;2873:18;;2860:32;;-1:-1:-1;2944:2:9;2929:18;;2916:32;2957:33;2916:32;2957:33;:::i;:::-;3009:7;-1:-1:-1;3063:2:9;3048:18;;3035:32;;-1:-1:-1;3114:3:9;3099:19;;3086:33;;-1:-1:-1;3170:3:9;3155:19;;3142:33;3198:18;3187:30;;3184:50;;;3230:1;3227;3220:12;3313:347;3364:8;3374:6;3428:3;3421:4;3413:6;3409:17;3405:27;3395:55;;3446:1;3443;3436:12;3395:55;-1:-1:-1;3469:20:9;;3512:18;3501:30;;3498:50;;;3544:1;3541;3534:12;3498:50;3581:4;3573:6;3569:17;3557:29;;3633:3;3626:4;3617:6;3609;3605:19;3601:30;3598:39;3595:59;;;3650:1;3647;3640:12;3595:59;3313:347;;;;;:::o;3665:750::-;3771:6;3779;3787;3795;3803;3811;3864:3;3852:9;3843:7;3839:23;3835:33;3832:53;;;3881:1;3878;3871:12;3832:53;3920:9;3907:23;3939:31;3964:5;3939:31;:::i;:::-;3989:5;-1:-1:-1;4041:2:9;4026:18;;4013:32;;-1:-1:-1;4092:2:9;4077:18;;4064:32;;-1:-1:-1;4143:2:9;4128:18;;4115:32;;-1:-1:-1;4198:3:9;4183:19;;4170:33;4226:18;4215:30;;4212:50;;;4258:1;4255;4248:12;4212:50;4297:58;4347:7;4338:6;4327:9;4323:22;4297:58;:::i;:::-;3665:750;;;;-1:-1:-1;3665:750:9;;-1:-1:-1;3665:750:9;;4374:8;;3665:750;-1:-1:-1;;;3665:750:9:o;4420:545::-;4508:6;4516;4524;4532;4585:2;4573:9;4564:7;4560:23;4556:32;4553:52;;;4601:1;4598;4591:12;4553:52;4637:9;4624:23;4614:33;;4694:2;4683:9;4679:18;4666:32;4656:42;;4749:2;4738:9;4734:18;4721:32;4776:18;4768:6;4765:30;4762:50;;;4808:1;4805;4798:12;4762:50;4847:58;4897:7;4888:6;4877:9;4873:22;4847:58;:::i;:::-;4420:545;;;;-1:-1:-1;4924:8:9;-1:-1:-1;;;;4420:545:9:o;4970:180::-;5029:6;5082:2;5070:9;5061:7;5057:23;5053:32;5050:52;;;5098:1;5095;5088:12;5050:52;-1:-1:-1;5121:23:9;;4970:180;-1:-1:-1;4970:180:9:o;5633:477::-;5712:6;5720;5728;5781:2;5769:9;5760:7;5756:23;5752:32;5749:52;;;5797:1;5794;5787:12;5749:52;5833:9;5820:23;5810:33;;5894:2;5883:9;5879:18;5866:32;5921:18;5913:6;5910:30;5907:50;;;5953:1;5950;5943:12;5907:50;5992:58;6042:7;6033:6;6022:9;6018:22;5992:58;:::i;:::-;5633:477;;6069:8;;-1:-1:-1;5966:84:9;;-1:-1:-1;;;;5633:477:9:o;6297:523::-;6383:6;6391;6399;6452:2;6440:9;6431:7;6427:23;6423:32;6420:52;;;6468:1;6465;6458:12;6420:52;6507:9;6494:23;6526:31;6551:5;6526:31;:::i;:::-;6576:5;-1:-1:-1;6628:2:9;6613:18;;6600:32;;-1:-1:-1;6683:2:9;6668:18;;6655:32;6710:18;6699:30;;6696:50;;;6742:1;6739;6732:12;6696:50;6765:49;6806:7;6797:6;6786:9;6782:22;6765:49;:::i;:::-;6755:59;;;6297:523;;;;;:::o;6825:383::-;6902:6;6910;6918;6971:2;6959:9;6950:7;6946:23;6942:32;6939:52;;;6987:1;6984;6977:12;6939:52;7026:9;7013:23;7045:31;7070:5;7045:31;:::i;:::-;7095:5;7147:2;7132:18;;7119:32;;-1:-1:-1;7198:2:9;7183:18;;;7170:32;;6825:383;-1:-1:-1;;;6825:383:9:o;8660:258::-;8732:1;8742:113;8756:6;8753:1;8750:13;8742:113;;;8832:11;;;8826:18;8813:11;;;8806:39;8778:2;8771:10;8742:113;;;8873:6;8870:1;8867:13;8864:48;;;8908:1;8899:6;8894:3;8890:16;8883:27;8864:48;;8660:258;;;:::o;8923:316::-;8964:3;9002:5;8996:12;9029:6;9024:3;9017:19;9045:63;9101:6;9094:4;9089:3;9085:14;9078:4;9071:5;9067:16;9045:63;:::i;:::-;9153:2;9141:15;9158:66;9137:88;9128:98;;;;9228:4;9124:109;;8923:316;-1:-1:-1;;8923:316:9:o;9244:448::-;9465:2;9454:9;9447:21;9428:4;9491:44;9531:2;9520:9;9516:18;9508:6;9491:44;:::i;:::-;9583:9;9575:6;9571:22;9566:2;9555:9;9551:18;9544:50;9611:32;9636:6;9628;9611:32;:::i;:::-;9603:40;;;9679:6;9674:2;9663:9;9659:18;9652:34;9244:448;;;;;;:::o;9697:277::-;9764:6;9817:2;9805:9;9796:7;9792:23;9788:32;9785:52;;;9833:1;9830;9823:12;9785:52;9865:9;9859:16;9918:5;9911:13;9904:21;9897:5;9894:32;9884:60;;9940:1;9937;9930:12;10665:282;10705:3;10736:1;10732:6;10729:1;10726:13;10723:193;;;10772:77;10769:1;10762:88;10873:4;10870:1;10863:15;10901:4;10898:1;10891:15;10723:193;-1:-1:-1;10932:9:9;;10665:282::o;13780:681::-;14011:2;14000:9;13993:21;14050:6;14045:2;14034:9;14030:18;14023:34;14108:6;14100;14094:3;14083:9;14079:19;14066:49;14165:1;14159:3;14150:6;14139:9;14135:22;14131:32;14124:43;13974:4;14222:66;14217:2;14209:6;14205:15;14201:88;14190:9;14186:104;14352:3;14340:9;14336:2;14332:18;14328:28;14321:4;14310:9;14306:20;14299:58;14374:38;14407:3;14403:2;14399:12;14391:6;14374:38;:::i;:::-;14366:46;;;14448:6;14443:2;14432:9;14428:18;14421:34;13780:681;;;;;;;:::o;18844:274::-;18973:3;19011:6;19005:13;19027:53;19073:6;19068:3;19061:4;19053:6;19049:17;19027:53;:::i;:::-;19096:16;;;;;18844:274;-1:-1:-1;;18844:274:9:o;19726:251::-;19796:6;19849:2;19837:9;19828:7;19824:23;19820:32;19817:52;;;19865:1;19862;19855:12;19817:52;19897:9;19891:16;19916:31;19941:5;19916:31;:::i

Swarm Source

ipfs://564040cd5f92f777f0b532760585171690d4896a828abf9437b37135b0636cdb

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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