Address Contract Verified
Address
0xE9410B5AA32b270154c37752EcC0607c8c7aBC5F
Balance
20.0909 ETH
Nonce
1
Code Size
9259 bytes
Creator
0x0E17C1a7...f4c2 at tx 0x0d18e9d4...ff618f
Indexed Transactions
0
Contract Bytecode
9259 bytes
0x6080604052600436106100fe5760003560e01c80637f5a22f911610095578063c9a9735811610064578063c9a97358146102da578063e78cea9214610303578063ea82e2281461032e578063f275c0ce1461034a578063f2fde38b14610375576100fe565b80637f5a22f91461023257806384045be61461025b5780638da5cb5b14610284578063c6c0f59e146102af576100fe565b80634f2e70a9116100d15780634f2e70a91461019e578063565764a6146101c9578063650bd364146101f2578063715018a61461021b576100fe565b806301ffc9a71461010357806306e30dfc146101405780632ee111ed1461014a5780634500ca4d14610173575b600080fd5b34801561010f57600080fd5b5061012a6004803603810190610125919061152c565b61039e565b6040516101379190611574565b60405180910390f35b610148610418565b005b34801561015657600080fd5b50610171600480360381019061016c91906115ed565b610492565b005b34801561017f57600080fd5b50610188610521565b6040516101959190611574565b60405180910390f35b3480156101aa57600080fd5b506101b3610534565b6040516101c09190611629565b60405180910390f35b3480156101d557600080fd5b506101f060048036038101906101eb9190611670565b610539565b005b3480156101fe57600080fd5b5061021960048036038101906102149190611702565b61058d565b005b34801561022757600080fd5b506102306106d8565b005b34801561023e57600080fd5b50610259600480360381019061025491906117a0565b6106ec565b005b34801561026757600080fd5b50610282600480360381019061027d9190611815565b61077a565b005b34801561029057600080fd5b506102996107ff565b6040516102a69190611629565b60405180910390f35b3480156102bb57600080fd5b506102c4610828565b6040516102d19190611629565b60405180910390f35b3480156102e657600080fd5b5061030160048036038101906102fc9190611670565b61084e565b005b34801561030f57600080fd5b506103186108a2565b60405161032591906118c7565b60405180910390f35b61034860048036038101906103439190611815565b6108c6565b005b34801561035657600080fd5b5061035f610cc9565b60405161036c9190611574565b60405180910390f35b34801561038157600080fd5b5061039c600480360381019061039791906115ed565b610cdc565b005b60007f650bd364000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610411575061041082610d5f565b5b9050919050565b610420610dc9565b60003411610463576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161045a9061193f565b60405180910390fd5b347f840be946bba3df0d184eb7e6cd7c9e57bb380cf6078516c7441db5709d58509860405160405180910390a2565b61049a610dc9565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167f679cb5acfebd038830b61daadd5f2f74e2114862b1c289a5d2db82bc6eda32a660405160405180910390a250565b600260019054906101000a900460ff1681565b600081565b610541610dc9565b80600260016101000a81548160ff0219169083151502179055508015157f2dd4e84c86f1d0ec949d1582751c7d8242fe120578eeece179a92603c8390ec660405160405180910390a250565b60028054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461061b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610612906119ab565b60405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146106ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106a290611a3d565b60405180910390fd5b600080600084848101906106bf9190611a9b565b9250925092506106d0838383610e47565b505050505050565b6106e0610dc9565b6106ea6000611072565b565b6106f4610dc9565b806002806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff167fe5be83d44a251cb79ef6eb972655ca2528f5bb94376d7c2cb221c44d7bef6a8860405160405180910390a250565b610782610dc9565b61078d838383610e47565b816fffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f35581ac10323fb0300d485a0a3bd1bac90d3f96e3fc635bfabfdd8f584c6dc4760405160405180910390a4505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610856610dc9565b80600260006101000a81548160ff0219169083151502179055508015157f2c009dd90a018abf2687d6137dd2e32b025c58eb76dfc41a63f233f39a0b937e60405160405180910390a250565b60028054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260009054906101000a900460ff16610915576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090c90611b3a565b60405180910390fd5b6000349050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610a615760028054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166350dcb0276040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109dd9190611b90565b836fffffffffffffffffffffffffffffffff166109fa9190611bec565b341015610a3c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3390611c92565b60405180910390fd5b826fffffffffffffffffffffffffffffffff1681610a5a9190611cb2565b9050610b72565b60028054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166350dcb0276040518163ffffffff1660e01b8152600401602060405180830381865afa158015610acc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af09190611b90565b341015610b32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b2990611d58565b60405180910390fd5b610b713330856fffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16611136909392919063ffffffff16565b5b826fffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f6c1d053057c267c256657713ed64b4713d4391c73733b7d03028a68028e5143f85604051610be29190611629565b60405180910390a46000848484604051602001610c0193929190611d87565b604051602081830303815290604052905060028054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bb5ddb0f83600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518463ffffffff1660e01b8152600401610c90929190611e4e565b6000604051808303818588803b158015610ca957600080fd5b505af1158015610cbd573d6000803e3d6000fd5b50505050505050505050565b600260009054906101000a900460ff1681565b610ce4610dc9565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610d53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d4a90611ef0565b60405180910390fd5b610d5c81611072565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b610dd16111bf565b73ffffffffffffffffffffffffffffffffffffffff16610def6107ff565b73ffffffffffffffffffffffffffffffffffffffff1614610e45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3c90611f5c565b60405180910390fd5b565b600260015403610e8c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e8390611fc8565b60405180910390fd5b6002600181905550600260019054906101000a900460ff16610ee3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eda90612034565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610fdb5760008173ffffffffffffffffffffffffffffffffffffffff16836fffffffffffffffffffffffffffffffff16604051610f4f90612085565b60006040518083038185875af1925050503d8060008114610f8c576040519150601f19603f3d011682016040523d82523d6000602084013e610f91565b606091505b5050905080610fd5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fcc906120e6565b60405180910390fd5b50610ff9565b610ff88382846fffffffffffffffffffffffffffffffff166111c7565b5b816fffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167ff7c94207a71e9e28815faa70ca42021f47a1d25c25fbec0973eb7beb92f4219260405160405180910390a460018081905550505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6111b9846323b872dd60e01b85858560405160240161115793929190612115565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061124d565b50505050565b600033905090565b6112488363a9059cbb60e01b84846040516024016111e692919061214c565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061124d565b505050565b60006112af826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166113149092919063ffffffff16565b905060008151111561130f57808060200190518101906112cf919061218a565b61130e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161130590612229565b60405180910390fd5b5b505050565b6060611323848460008561132c565b90509392505050565b606082471015611371576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611368906122bb565b60405180910390fd5b61137a85611440565b6113b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113b090612327565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516113e29190612378565b60006040518083038185875af1925050503d806000811461141f576040519150601f19603f3d011682016040523d82523d6000602084013e611424565b606091505b5091509150611434828286611463565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60608315611473578290506114c3565b6000835111156114865782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ba91906123d3565b60405180910390fd5b9392505050565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611509816114d4565b811461151457600080fd5b50565b60008135905061152681611500565b92915050565b600060208284031215611542576115416114ca565b5b600061155084828501611517565b91505092915050565b60008115159050919050565b61156e81611559565b82525050565b60006020820190506115896000830184611565565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006115ba8261158f565b9050919050565b6115ca816115af565b81146115d557600080fd5b50565b6000813590506115e7816115c1565b92915050565b600060208284031215611603576116026114ca565b5b6000611611848285016115d8565b91505092915050565b611623816115af565b82525050565b600060208201905061163e600083018461161a565b92915050565b61164d81611559565b811461165857600080fd5b50565b60008135905061166a81611644565b92915050565b600060208284031215611686576116856114ca565b5b60006116948482850161165b565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126116c2576116c161169d565b5b8235905067ffffffffffffffff8111156116df576116de6116a2565b5b6020830191508360018202830111156116fb576116fa6116a7565b5b9250929050565b60008060006040848603121561171b5761171a6114ca565b5b6000611729868287016115d8565b935050602084013567ffffffffffffffff81111561174a576117496114cf565b5b611756868287016116ac565b92509250509250925092565b600061176d826115af565b9050919050565b61177d81611762565b811461178857600080fd5b50565b60008135905061179a81611774565b92915050565b6000602082840312156117b6576117b56114ca565b5b60006117c48482850161178b565b91505092915050565b60006fffffffffffffffffffffffffffffffff82169050919050565b6117f2816117cd565b81146117fd57600080fd5b50565b60008135905061180f816117e9565b92915050565b60008060006060848603121561182e5761182d6114ca565b5b600061183c868287016115d8565b935050602061184d86828701611800565b925050604061185e868287016115d8565b9150509250925092565b6000819050919050565b600061188d6118886118838461158f565b611868565b61158f565b9050919050565b600061189f82611872565b9050919050565b60006118b182611894565b9050919050565b6118c1816118a6565b82525050565b60006020820190506118dc60008301846118b8565b92915050565b600082825260208201905092915050565b7f45524332305065673a206d75737420656e646f77206e6f6e7a65726f00000000600082015250565b6000611929601c836118e2565b9150611934826118f3565b602082019050919050565b600060208201905081810360008301526119588161191c565b9050919050565b7f45524332305065673a206f6e6c79206272696467652063616e2063616c6c0000600082015250565b6000611995601e836118e2565b91506119a08261195f565b602082019050919050565b600060208201905081810360008301526119c481611988565b9050919050565b7f45524332305065673a20736f75726365206d757374206265207065672070616c60008201527f6c65742061646472657373000000000000000000000000000000000000000000602082015250565b6000611a27602b836118e2565b9150611a32826119cb565b604082019050919050565b60006020820190508181036000830152611a5681611a1a565b9050919050565b6000611a688261158f565b9050919050565b611a7881611a5d565b8114611a8357600080fd5b50565b600081359050611a9581611a6f565b92915050565b600080600060608486031215611ab457611ab36114ca565b5b6000611ac286828701611a86565b9350506020611ad386828701611800565b9250506040611ae486828701611a86565b9150509250925092565b7f45524332305065673a206465706f736974732070617573656400000000000000600082015250565b6000611b246019836118e2565b9150611b2f82611aee565b602082019050919050565b60006020820190508181036000830152611b5381611b17565b9050919050565b6000819050919050565b611b6d81611b5a565b8114611b7857600080fd5b50565b600081519050611b8a81611b64565b92915050565b600060208284031215611ba657611ba56114ca565b5b6000611bb484828501611b7b565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611bf782611b5a565b9150611c0283611b5a565b9250828201905080821115611c1a57611c19611bbd565b5b92915050565b7f45524332305065673a20696e636f7272656374206465706f73697420616d6f7560008201527f6e7420287265717569726573206465706f736974206665652900000000000000602082015250565b6000611c7c6039836118e2565b9150611c8782611c20565b604082019050919050565b60006020820190508181036000830152611cab81611c6f565b9050919050565b6000611cbd82611b5a565b9150611cc883611b5a565b9250828203905081811115611ce057611cdf611bbd565b5b92915050565b7f45524332305065673a20696e636f727265637420746f6b656e2061646472657360008201527f7320287265717569726573206465706f73697420666565290000000000000000602082015250565b6000611d426038836118e2565b9150611d4d82611ce6565b604082019050919050565b60006020820190508181036000830152611d7181611d35565b9050919050565b611d81816117cd565b82525050565b6000606082019050611d9c600083018661161a565b611da96020830185611d78565b611db6604083018461161a565b949350505050565b600081519050919050565b600082825260208201905092915050565b60005b83811015611df8578082015181840152602081019050611ddd565b60008484015250505050565b6000601f19601f8301169050919050565b6000611e2082611dbe565b611e2a8185611dc9565b9350611e3a818560208601611dda565b611e4381611e04565b840191505092915050565b6000604082019050611e63600083018561161a565b8181036020830152611e758184611e15565b90509392505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000611eda6026836118e2565b9150611ee582611e7e565b604082019050919050565b60006020820190508181036000830152611f0981611ecd565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000611f466020836118e2565b9150611f5182611f10565b602082019050919050565b60006020820190508181036000830152611f7581611f39565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b6000611fb2601f836118e2565b9150611fbd82611f7c565b602082019050919050565b60006020820190508181036000830152611fe181611fa5565b9050919050565b7f45524332305065673a207769746864726177616c732070617573656400000000600082015250565b600061201e601c836118e2565b915061202982611fe8565b602082019050919050565b6000602082019050818103600083015261204d81612011565b9050919050565b600081905092915050565b50565b600061206f600083612054565b915061207a8261205f565b600082019050919050565b600061209082612062565b9150819050919050565b7f45524332305065673a206661696c656420746f2073656e642045746865720000600082015250565b60006120d0601e836118e2565b91506120db8261209a565b602082019050919050565b600060208201905081810360008301526120ff816120c3565b9050919050565b61210f81611b5a565b82525050565b600060608201905061212a600083018661161a565b612137602083018561161a565b6121446040830184612106565b949350505050565b6000604082019050612161600083018561161a565b61216e6020830184612106565b9392505050565b60008151905061218481611644565b92915050565b6000602082840312156121a05761219f6114ca565b5b60006121ae84828501612175565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000612213602a836118e2565b915061221e826121b7565b604082019050919050565b6000602082019050818103600083015261224281612206565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006122a56026836118e2565b91506122b082612249565b604082019050919050565b600060208201905081810360008301526122d481612298565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000612311601d836118e2565b915061231c826122db565b602082019050919050565b6000602082019050818103600083015261234081612304565b9050919050565b600061235282611dbe565b61235c8185612054565b935061236c818560208601611dda565b80840191505092915050565b60006123848284612347565b915081905092915050565b600081519050919050565b60006123a58261238f565b6123af81856118e2565b93506123bf818560208601611dda565b6123c881611e04565b840191505092915050565b600060208201905081810360008301526123ed818461239a565b90509291505056fea2646970667358221220349df2814e6de23c3621e254c2b3418193c3a33473eefa2573f4f956604a48b364736f6c63430008110033
Verified Source Code Full Match
Compiler: v0.8.17+commit.8df45f5f
EVM: london
Optimization: No
draft-IERC20Permit.sol 60 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
ERC20Peg.sol 132 lines
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.17;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "./IBridge.sol";
/// @title ERC20 Peg contract on ethereum
/// @author Root Network
/// @notice Provides an Eth/ERC20/GA Root network peg
/// - depositing: lock Eth/ERC20 tokens to redeem Root network "generic asset" (GA) 1:1
/// - withdrawing: burn or lock GAs to redeem Eth/ERC20 tokens 1:1
contract ERC20Peg is Ownable, IBridgeReceiver, ReentrancyGuard, ERC165 {
using SafeERC20 for IERC20;
// Reserved address for native Eth deposits/withdraw
address constant public ETH_RESERVED_TOKEN_ADDRESS = address(0);
// whether the peg is accepting deposits
bool public depositsActive;
// whether the peg is accepting withdrawals
bool public withdrawalsActive;
// Bridge contract address
IBridge public bridge;
// the (pseudo) pallet address this contract is paired with on root
address public palletAddress = address(0x6D6f646c65726332307065670000000000000000);
event DepositActiveStatus(bool indexed active);
event WithdrawalActiveStatus(bool indexed active);
event BridgeAddressUpdated(address indexed bridge);
event PalletAddressUpdated(address indexed palletAddress);
event Endowed(uint256 indexed amount);
event Deposit(address indexed _address, address indexed tokenAddress, uint128 indexed amount, address destination);
event Withdraw(address indexed _address, address indexed tokenAddress, uint128 indexed amount);
event AdminWithdraw(address indexed _address, address indexed tokenAddress, uint128 indexed amount);
constructor(IBridge _bridge) {
bridge = _bridge;
}
/// @notice Deposit amount of tokenAddress the pegged version of the token will be claim-able on Root network.
/// @dev `tokenAddress` `0` is reserved for native Eth
function deposit(address _tokenAddress, uint128 _amount, address _destination) payable external {
require(depositsActive, "ERC20Peg: deposits paused");
uint256 bridgeMessageFee = msg.value;
if (_tokenAddress == ETH_RESERVED_TOKEN_ADDRESS) {
require(msg.value >= (_amount + bridge.sendMessageFee()), "ERC20Peg: incorrect deposit amount (requires deposit fee)");
bridgeMessageFee = bridgeMessageFee - _amount; // extract bridge fee from deposit amount
} else {
require(msg.value >= bridge.sendMessageFee(), "ERC20Peg: incorrect token address (requires deposit fee)");
IERC20(_tokenAddress).safeTransferFrom(msg.sender, address(this), _amount);
}
emit Deposit(msg.sender, _tokenAddress, _amount, _destination);
// send message to bridge - with fee to feeRecipient via bridge
bytes memory message = abi.encode(_tokenAddress, _amount, _destination);
bridge.sendMessage{value: bridgeMessageFee }(palletAddress, message);
}
function onMessageReceived(address _source, bytes calldata _message) external override {
// only accept calls from the bridge contract
require(msg.sender == address(bridge), "ERC20Peg: only bridge can call");
// only accept messages from the peg pallet
require(_source == palletAddress, "ERC20Peg: source must be peg pallet address");
(address tokenAddress, uint128 amount, address recipient) = abi.decode(_message, (address, uint128, address));
_withdraw(tokenAddress, amount, recipient);
}
/// @notice Withdraw tokens from this contract
/// tokenAddress '0' is reserved for native Eth
/// Requires signatures from a threshold of current Root network validators.
function _withdraw(address _tokenAddress, uint128 _amount, address _recipient) internal nonReentrant {
require(withdrawalsActive, "ERC20Peg: withdrawals paused");
if (_tokenAddress == ETH_RESERVED_TOKEN_ADDRESS) {
(bool sent, ) = _recipient.call{value: _amount}("");
require(sent, "ERC20Peg: failed to send Ether");
} else {
SafeERC20.safeTransfer(IERC20(_tokenAddress), _recipient, _amount);
}
emit Withdraw(_recipient, _tokenAddress, _amount);
}
/// @dev See {IERC165-supportsInterface}. Docs: https://docs.openzeppelin.com/contracts/4.x/api/utils#IERC165
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return
interfaceId == type(IBridgeReceiver).interfaceId ||
super.supportsInterface(interfaceId);
}
// ============================================================================================================= //
// ============================================== Admin functions ============================================== //
// ============================================================================================================= //
/// @dev Endow the contract with ether
function endow() external onlyOwner payable {
require(msg.value > 0, "ERC20Peg: must endow nonzero");
emit Endowed(msg.value);
}
function setDepositsActive(bool _active) external onlyOwner {
depositsActive = _active;
emit DepositActiveStatus(_active);
}
function setWithdrawalsActive(bool _active) external onlyOwner {
withdrawalsActive = _active;
emit WithdrawalActiveStatus(_active);
}
function setBridgeAddress(IBridge _bridge) external onlyOwner {
bridge = _bridge;
emit BridgeAddressUpdated(address(_bridge));
}
function setPalletAddress(address _palletAddress) external onlyOwner {
palletAddress = _palletAddress;
emit PalletAddressUpdated(_palletAddress);
}
function adminEmergencyWithdraw(address _tokenAddress, uint128 _amount, address _recipient) external onlyOwner {
_withdraw(_tokenAddress, _amount, _recipient);
emit AdminWithdraw(_recipient, _tokenAddress, _amount);
}
}
IBridge.sol 37 lines
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.17;
// Proof of a witnessed event by validators
struct EventProof {
// The Id (nonce) of the event
uint256 eventId;
// The validator set Id which witnessed the event
uint32 validatorSetId;
// v,r,s are sparse arrays expected to align w public key in 'validators'
// i.e. v[i], r[i], s[i] matches the i-th validator[i]
// v part of validator signatures
uint8[] v;
// r part of validator signatures
bytes32[] r;
// s part of validator signatures
bytes32[] s;
// The validator addresses
address[] validators;
}
interface IBridge {
// A sent message event
event SendMessage(uint messageId, address source, address destination, bytes message, uint256 fee);
// Receive a bridge message from the remote chain
function receiveMessage(address source, address destination, bytes calldata message, EventProof calldata proof) external payable;
// Send a bridge message to the remote chain
function sendMessage(address destination, bytes calldata message) external payable;
// Send message fee - used by sendMessage caller to obtain required fee for sendMessage
function sendMessageFee() external view returns (uint256);
}
interface IBridgeReceiver {
// Handle a bridge message received from the remote chain
// It is guaranteed to be valid
function onMessageReceived(address source, bytes calldata message) external;
}
SafeERC20.sol 116 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
ReentrancyGuard.sol 63 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}
Ownable.sol 83 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
IERC165.sol 25 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
Address.sol 222 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
IERC20.sol 82 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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);
/**
* @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 `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, 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 `from` to `to` 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 from,
address to,
uint256 amount
) external returns (bool);
}
Context.sol 24 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
ERC165.sol 29 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
Read Contract
ETH_RESERVED_TOKEN_ADDRESS 0x4f2e70a9 → address
bridge 0xe78cea92 → address
depositsActive 0xf275c0ce → bool
owner 0x8da5cb5b → address
palletAddress 0xc6c0f59e → address
supportsInterface 0x01ffc9a7 → bool
withdrawalsActive 0x4500ca4d → bool
Write Contract 10 functions
These functions modify contract state and require a wallet transaction to execute.
adminEmergencyWithdraw 0x84045be6
address _tokenAddress
uint128 _amount
address _recipient
deposit 0xea82e228
address _tokenAddress
uint128 _amount
address _destination
endow 0x06e30dfc
No parameters
onMessageReceived 0x650bd364
address _source
bytes _message
renounceOwnership 0x715018a6
No parameters
setBridgeAddress 0x7f5a22f9
address _bridge
setDepositsActive 0xc9a97358
bool _active
setPalletAddress 0x2ee111ed
address _palletAddress
setWithdrawalsActive 0x565764a6
bool _active
transferOwnership 0xf2fde38b
address newOwner
Token Balances (4)
View Transfers →Recent Transactions
No transactions found for this address