Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 668 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Exempt_depositor | 17960632 | 532 days ago | IN | 0 ETH | 0.00070355 | ||||
Global_stop | 17346033 | 618 days ago | IN | 0 ETH | 0.0042966 | ||||
Withdraw_asset | 17346027 | 618 days ago | IN | 0 ETH | 0.00452029 | ||||
Withdraw_asset | 17346020 | 618 days ago | IN | 0 ETH | 0.0052027 | ||||
Withdraw_asset | 17346009 | 618 days ago | IN | 0 ETH | 0.00517893 | ||||
Withdraw_asset | 17345992 | 618 days ago | IN | 0 ETH | 0.00617641 | ||||
Global_resume | 17345985 | 618 days ago | IN | 0 ETH | 0.00396905 | ||||
Global_stop | 17338296 | 619 days ago | IN | 0 ETH | 0.00584054 | ||||
Deposit_asset | 17336124 | 619 days ago | IN | 0 ETH | 0.00372399 | ||||
Withdraw_asset | 17332581 | 620 days ago | IN | 0 ETH | 0.00607463 | ||||
Deposit_asset | 17331577 | 620 days ago | IN | 0 ETH | 0.0025505 | ||||
Deposit_asset | 17331186 | 620 days ago | IN | 0 ETH | 0.00336093 | ||||
Deposit_asset | 17330704 | 620 days ago | IN | 0 ETH | 0.0058999 | ||||
Withdraw_asset | 17329714 | 620 days ago | IN | 0 ETH | 0.0124514 | ||||
Deposit_asset | 17329661 | 620 days ago | IN | 0 ETH | 0.00487262 | ||||
Withdraw_asset | 17329648 | 620 days ago | IN | 0 ETH | 0.01351853 | ||||
Deposit_asset | 17329493 | 620 days ago | IN | 0 ETH | 0.0072 | ||||
Deposit_asset | 17329477 | 620 days ago | IN | 0 ETH | 0.00751468 | ||||
Deposit_asset | 17329122 | 620 days ago | IN | 0 ETH | 0.00200651 | ||||
Deposit_asset | 17329039 | 620 days ago | IN | 0 ETH | 0.0021648 | ||||
Deposit_asset | 17328998 | 620 days ago | IN | 0 ETH | 0.00294613 | ||||
Deposit_asset | 17328690 | 620 days ago | IN | 0 ETH | 0.0029279 | ||||
Deposit_asset | 17328488 | 620 days ago | IN | 0 ETH | 0.00237301 | ||||
Withdraw_asset | 17328346 | 620 days ago | IN | 0 ETH | 0.00760417 | ||||
Deposit_asset | 17328143 | 620 days ago | IN | 0 ETH | 0.00268776 |
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
Contract Source Code (Solidity Multiple files format)
//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*/
//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*/
//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*/
//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*/
//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); }
//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*/
//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*/
//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*/
//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
- No Contract Security Audit Submitted- Submit Audit Here
[{"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"}]
Contract Creation Code
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
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.