Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
14146583 | 1054 days ago | 422.50870863 ETH | ||||
14146583 | 1054 days ago | 422.50870863 ETH | ||||
14146174 | 1054 days ago | 10.54191905 ETH | ||||
14146174 | 1054 days ago | 10.54191905 ETH | ||||
14130670 | 1056 days ago | 2.35054236 ETH | ||||
14130670 | 1056 days ago | 2.35054236 ETH | ||||
14128644 | 1057 days ago | 4.93577754 ETH | ||||
14128644 | 1057 days ago | 4.93577754 ETH | ||||
14128338 | 1057 days ago | 2.9758225 ETH | ||||
14128338 | 1057 days ago | 2.9758225 ETH | ||||
14123606 | 1057 days ago | 4.17522995 ETH | ||||
14123606 | 1057 days ago | 4.17522995 ETH | ||||
14119968 | 1058 days ago | 3.19999557 ETH | ||||
14119968 | 1058 days ago | 3.19999557 ETH | ||||
14113724 | 1059 days ago | 2.02972877 ETH | ||||
14113724 | 1059 days ago | 2.02972877 ETH | ||||
14113331 | 1059 days ago | 9 ETH | ||||
14113331 | 1059 days ago | 9 ETH | ||||
14108905 | 1060 days ago | 13 ETH | ||||
14108905 | 1060 days ago | 13 ETH | ||||
14101166 | 1061 days ago | 0.17522499 ETH | ||||
14101166 | 1061 days ago | 0.17522499 ETH | ||||
14090367 | 1062 days ago | 1.28449696 ETH | ||||
14090367 | 1062 days ago | 1.28449696 ETH | ||||
14084062 | 1063 days ago | 11.34278918 ETH |
Loading...
Loading
Contract Name:
ERC20Handler
Compiler Version
v0.6.4+commit.1dca32f3
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-05-30 */ pragma solidity 0.6.4; pragma experimental ABIEncoderV2; /** @title Interface for handler contracts that support deposits and deposit executions. @author ChainSafe Systems. */ interface IDepositExecute { /** @notice It is intended that deposit are made using the Bridge contract. @param destinationChainID Chain ID deposit is expected to be bridged to. @param depositNonce This value is generated as an ID by the Bridge contract. @param depositer Address of account making the deposit in the Bridge contract. @param data Consists of additional data needed for a specific deposit. */ function deposit(bytes32 resourceID, uint8 destinationChainID, uint64 depositNonce, address depositer, bytes calldata data) external; /** @notice It is intended that proposals are executed by the Bridge contract. @param data Consists of additional data needed for a specific deposit execution. */ function executeProposal(bytes32 resourceID, bytes calldata data) external; } interface IWETH { function deposit() external payable; function transfer(address to, uint value) external returns (bool); function withdraw(uint) external; } /** @title Interface to be used with handlers that support ERC20s and ERC721s. @author ChainSafe Systems. */ interface IERCHandler { /** @notice Correlates {resourceID} with {contractAddress}. @param resourceID ResourceID to be used when making deposits. @param contractAddress Address of contract to be called when a deposit is made and a deposited is executed. */ function setResource(bytes32 resourceID, address contractAddress) external; /** @notice Marks {contractAddress} as mintable/burnable. @param contractAddress Address of contract to be used when making or executing deposits. */ function setBurnable(address contractAddress) external; /** @notice Used to manually release funds from ERC safes. @param tokenAddress Address of token contract to release. @param recipient Address to release tokens to. @param amountOrTokenID Either the amount of ERC20 tokens or the ERC721 token ID to release. */ function withdraw(address tokenAddress, address recipient, uint256 amountOrTokenID) external; function _wtokenAddress() external returns (address); /** @notice Used to update the _bridgeAddress @param newBridgeAddress Address of the updated bridge address. */ function updateBridgeAddress(address newBridgeAddress) external; } /** @title Function used across handler contracts. @author ChainSafe Systems. @notice This contract is intended to be used with the Bridge contract. */ contract HandlerHelpers is IERCHandler { address public _bridgeAddress; address public override _wtokenAddress; // resourceID => token contract address mapping (bytes32 => address) public _resourceIDToTokenContractAddress; // token contract address => resourceID mapping (address => bytes32) public _tokenContractAddressToResourceID; // token contract address => is whitelisted mapping (address => bool) public _contractWhitelist; // token contract address => is burnable mapping (address => bool) public _burnList; modifier onlyBridge() { _onlyBridge(); _; } function _onlyBridge() private { require(msg.sender == _bridgeAddress, "sender must be bridge contract"); } /** @notice First verifies {_resourceIDToContractAddress}[{resourceID}] and {_contractAddressToResourceID}[{contractAddress}] are not already set, then sets {_resourceIDToContractAddress} with {contractAddress}, {_contractAddressToResourceID} with {resourceID}, and {_contractWhitelist} to true for {contractAddress}. @param resourceID ResourceID to be used when making deposits. @param contractAddress Address of contract to be called when a deposit is made and a deposited is executed. */ function setResource(bytes32 resourceID, address contractAddress) external override onlyBridge { _setResource(resourceID, contractAddress); } /** @notice First verifies {contractAddress} is whitelisted, then sets {_burnList}[{contractAddress}] to true. @param contractAddress Address of contract to be used when making or executing deposits. */ function setBurnable(address contractAddress) external override onlyBridge{ _setBurnable(contractAddress); } /** @notice Used to manually release funds from ERC safes. @param tokenAddress Address of token contract to release. @param recipient Address to release tokens to. @param amountOrTokenID Either the amount of ERC20 tokens or the ERC721 token ID to release. */ function withdraw(address tokenAddress, address recipient, uint256 amountOrTokenID) external virtual override {} function _setResource(bytes32 resourceID, address contractAddress) internal { _resourceIDToTokenContractAddress[resourceID] = contractAddress; _tokenContractAddressToResourceID[contractAddress] = resourceID; _contractWhitelist[contractAddress] = true; } function _setBurnable(address contractAddress) internal { require(_contractWhitelist[contractAddress], "provided contract is not whitelisted"); _burnList[contractAddress] = true; } function updateBridgeAddress(address newBridgeAddress) external virtual override {} } /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } /** * @dev Interface of the ERC20 standard as defined in the EIP. */ 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); } /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.0.0, only sets of type `address` (`AddressSet`) and `uint256` * (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(value))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(value))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(value))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint256(_at(set._inner, index))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } } /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @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"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } } /* * @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 GSN 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. */ contract Context { // Empty internal constructor, to prevent people from mistakenly deploying // an instance of this contract, which should be used via inheritance. constructor () internal { } function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } /** * @dev Contract module that allows children to implement role-based access * control mechanisms. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context { using EnumerableSet for EnumerableSet.AddressSet; using Address for address; struct RoleData { EnumerableSet.AddressSet members; bytes32 adminRole; } mapping (bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view returns (bool) { return _roles[role].members.contains(account); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view returns (uint256) { return _roles[role].members.length(); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view returns (address) { return _roles[role].members.at(index); } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant"); _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual { require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke"); _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { _roles[role].adminRole = adminRole; } function _grantRole(bytes32 role, address account) private { if (_roles[role].members.add(account)) { emit RoleGranted(role, account, _msgSender()); } } function _revokeRole(bytes32 role, address account) private { if (_roles[role].members.remove(account)) { emit RoleRevoked(role, account, _msgSender()); } } } /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20MinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20 { using SafeMath for uint256; using Address for address; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for {name} and {symbol}, initializes {decimals} with * a default value of 18. * * To select a different value for {decimals}, use {_setupDecimals}. * * All three of these values are immutable: they can only be set once during * construction. */ constructor (string memory name, string memory symbol) public { _name = name; _symbol = symbol; _decimals = 18; } /** * @dev Returns the name of the token. */ function name() public view returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is * called. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view returns (uint8) { return _decimals; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}; * * Requirements: * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements * * - `to` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. * * This is internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Sets {decimals} to a value other than the default one of 18. * * WARNING: This function should only be called from the constructor. Most * applications that interact with token contracts will not expect * {decimals} to ever change, and may work incorrectly if it does. */ function _setupDecimals(uint8 decimals_) internal { _decimals = decimals_; } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } } /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ abstract contract ERC20Burnable is Context, ERC20 { /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) public virtual { _burn(_msgSender(), amount); } /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) public virtual { uint256 decreasedAllowance = allowance(account, _msgSender()).sub(amount, "ERC20: burn amount exceeds allowance"); _approve(account, _msgSender(), decreasedAllowance); _burn(account, amount); } } /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor () internal { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. */ modifier whenNotPaused() { require(!_paused, "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. */ modifier whenPaused() { require(_paused, "Pausable: not paused"); _; } /** * @dev Triggers stopped state. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } } /** * @dev ERC20 token with pausable token transfers, minting and burning. * * Useful for scenarios such as preventing trades until the end of an evaluation * period, or having an emergency switch for freezing all token transfers in the * event of a large bug. */ abstract contract ERC20Pausable is ERC20, Pausable { /** * @dev See {ERC20-_beforeTokenTransfer}. * * Requirements: * * - the contract must not be paused. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override { super._beforeTokenTransfer(from, to, amount); require(!paused(), "ERC20Pausable: token transfer while paused"); } } /** * @dev {ERC20} token, including: * * - ability for holders to burn (destroy) their tokens * - a minter role that allows for token minting (creation) * - a pauser role that allows to stop all token transfers * * This contract uses {AccessControl} to lock permissioned functions using the * different roles - head to its documentation for details. * * The account that deploys the contract will be granted the minter and pauser * roles, as well as the default admin role, which will let it grant both minter * and pauser roles to aother accounts */ contract ERC20PresetMinterPauser is Context, AccessControl, ERC20Burnable, ERC20Pausable { bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); /** * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the * account that deploys the contract. * * See {ERC20-constructor}. */ constructor(string memory name, string memory symbol) public ERC20(name, symbol) { _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); _setupRole(MINTER_ROLE, _msgSender()); _setupRole(PAUSER_ROLE, _msgSender()); } /** * @dev Creates `amount` new tokens for `to`. * * See {ERC20-_mint}. * * Requirements: * * - the caller must have the `MINTER_ROLE`. */ function mint(address to, uint256 amount) public { require(hasRole(MINTER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have minter role to mint"); _mint(to, amount); } /** * @dev Pauses all token transfers. * * See {ERC20Pausable} and {Pausable-_pause}. * * Requirements: * * - the caller must have the `PAUSER_ROLE`. */ function pause() public { require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to pause"); _pause(); } /** * @dev Unpauses all token transfers. * * See {ERC20Pausable} and {Pausable-_unpause}. * * Requirements: * * - the caller must have the `PAUSER_ROLE`. */ function unpause() public { require(hasRole(PAUSER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have pauser role to unpause"); _unpause(); } function _beforeTokenTransfer(address from, address to, uint256 amount) internal override(ERC20, ERC20Pausable) { super._beforeTokenTransfer(from, to, amount); } } /** @title Manages deposited ERC20s. @author ChainSafe Systems. @notice This contract is intended to be used with ERC20Handler contract. */ contract ERC20Safe { using SafeMath for uint256; /** @notice Used to transfer tokens into the safe to fund proposals. @param tokenAddress Address of ERC20 to transfer. @param owner Address of current token owner. @param amount Amount of tokens to transfer. */ function fundERC20(address tokenAddress, address owner, uint256 amount) public { IERC20 erc20 = IERC20(tokenAddress); _safeTransferFrom(erc20, owner, address(this), amount); } /** @notice Used to gain custody of deposited token. @param tokenAddress Address of ERC20 to transfer. @param owner Address of current token owner. @param recipient Address to transfer tokens to. @param amount Amount of tokens to transfer. */ function lockERC20(address tokenAddress, address owner, address recipient, uint256 amount) internal { IERC20 erc20 = IERC20(tokenAddress); _safeTransferFrom(erc20, owner, recipient, amount); } /** @notice Transfers custody of token to recipient. @param tokenAddress Address of ERC20 to transfer. @param recipient Address to transfer tokens to. @param amount Amount of tokens to transfer. */ function releaseERC20(address tokenAddress, address recipient, uint256 amount) internal { IERC20 erc20 = IERC20(tokenAddress); _safeTransfer(erc20, recipient, amount); } /** @notice Used to create new ERC20s. @param tokenAddress Address of ERC20 to transfer. @param recipient Address to mint token to. @param amount Amount of token to mint. */ function mintERC20(address tokenAddress, address recipient, uint256 amount) internal { ERC20PresetMinterPauser erc20 = ERC20PresetMinterPauser(tokenAddress); erc20.mint(recipient, amount); } /** @notice Used to burn ERC20s. @param tokenAddress Address of ERC20 to burn. @param owner Current owner of tokens. @param amount Amount of tokens to burn. */ function burnERC20(address tokenAddress, address owner, uint256 amount) internal { ERC20Burnable erc20 = ERC20Burnable(tokenAddress); erc20.burnFrom(owner, amount); } /** @notice used to transfer ERC20s safely @param token Token instance to transfer @param to Address to transfer token to @param value Amount of token to transfer */ function _safeTransfer(IERC20 token, address to, uint256 value) private { _safeCall(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** @notice used to transfer ERC20s safely @param token Token instance to transfer @param from Address to transfer token from @param to Address to transfer token to @param value Amount of token to transfer */ function _safeTransferFrom(IERC20 token, address from, address to, uint256 value) private { _safeCall(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** @notice used to make calls to ERC20s safely @param token Token instance call targets @param data encoded call data */ function _safeCall(IERC20 token, bytes memory data) private { (bool success, bytes memory returndata) = address(token).call(data); require(success, "ERC20: call failed"); if (returndata.length > 0) { require(abi.decode(returndata, (bool)), "ERC20: operation did not succeed"); } } } // SPDX-License-Identifier: GPL-3.0-or-later // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false library TransferHelper { function safeApprove(address token, address to, uint value) internal { // bytes4(keccak256(bytes('approve(address,uint256)'))); //(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); bytes4 SELECTOR = bytes4(keccak256(bytes('approve(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED'); } function safeTransfer(address token, address to, uint value) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); //(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); bytes4 SELECTOR = bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED'); } function safeTransferFrom(address token, address from, address to, uint value) internal { // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); //(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); bytes4 SELECTOR = bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED'); } function safeTransferETH(address to, uint value) internal { (bool success,) = to.call{value:value}(new bytes(0)); require(success, 'TransferHelper: ETH_TRANSFER_FAILED'); } } /** @title Handles ERC20 deposits and deposit executions. @author ChainSafe Systems. @notice This contract is intended to be used with the Bridge contract. */ contract ERC20Handler is IDepositExecute, HandlerHelpers, ERC20Safe { struct DepositRecord { address _tokenAddress; uint8 _lenDestinationRecipientAddress; uint8 _destinationChainID; bytes32 _resourceID; bytes _destinationRecipientAddress; address _depositer; uint _amount; } // depositNonce => Deposit Record mapping (uint8 => mapping(uint64 => DepositRecord)) public _depositRecords; /** @param bridgeAddress Contract address of previously deployed Bridge. @param initialResourceIDs Resource IDs are used to identify a specific contract address. These are the Resource IDs this contract will initially support. @param initialContractAddresses These are the addresses the {initialResourceIDs} will point to, and are the contracts that will be called to perform various deposit calls. @param burnableContractAddresses These addresses will be set as burnable and when {deposit} is called, the deposited token will be burned. When {executeProposal} is called, new tokens will be minted. @dev {initialResourceIDs} and {initialContractAddresses} must have the same length (one resourceID for every address). Also, these arrays must be ordered in the way that {initialResourceIDs}[0] is the intended resourceID for {initialContractAddresses}[0]. */ constructor( address bridgeAddress, address wtokenAddress, bytes32[] memory initialResourceIDs, address[] memory initialContractAddresses, address[] memory burnableContractAddresses ) public { require(initialResourceIDs.length == initialContractAddresses.length, "initialResourceIDs and initialContractAddresses len mismatch"); _bridgeAddress = bridgeAddress; _wtokenAddress = wtokenAddress; for (uint256 i = 0; i < initialResourceIDs.length; i++) { _setResource(initialResourceIDs[i], initialContractAddresses[i]); } for (uint256 i = 0; i < burnableContractAddresses.length; i++) { _setBurnable(burnableContractAddresses[i]); } } // fallback from the WETH receive() external payable { assert(msg.sender == _wtokenAddress); // only accept ETH via fallback from the WETH contract } /** @param depositNonce This ID will have been generated by the Bridge contract. @param destId ID of chain deposit will be bridged to. @return DepositRecord which consists of: - _tokenAddress Address used when {deposit} was executed. - _destinationChainID ChainID deposited tokens are intended to end up on. - _resourceID ResourceID used when {deposit} was executed. - _lenDestinationRecipientAddress Used to parse recipient's address from {_destinationRecipientAddress} - _destinationRecipientAddress Address tokens are intended to be deposited to on desitnation chain. - _depositer Address that initially called {deposit} in the Bridge contract. - _amount Amount of tokens that were deposited. */ function getDepositRecord(uint64 depositNonce, uint8 destId) external view returns (DepositRecord memory) { return _depositRecords[destId][depositNonce]; } /** @notice A deposit is initiatied by making a deposit in the Bridge contract. @param destinationChainID Chain ID of chain tokens are expected to be bridged to. @param depositNonce This value is generated as an ID by the Bridge contract. @param depositer Address of account making the deposit in the Bridge contract. @param data Consists of: {resourceID}, {amount}, {lenRecipientAddress}, and {recipientAddress} all padded to 32 bytes. @notice Data passed into the function should be constructed as follows: amount uint256 bytes 0 - 32 recipientAddress length uint256 bytes 32 - 64 recipientAddress bytes bytes 64 - END @dev Depending if the corresponding {tokenAddress} for the parsed {resourceID} is marked true in {_burnList}, deposited tokens will be burned, if not, they will be locked. */ function deposit( bytes32 resourceID, uint8 destinationChainID, uint64 depositNonce, address depositer, bytes calldata data ) external override onlyBridge { bytes memory recipientAddress; uint256 amount; uint256 lenRecipientAddress; assembly { amount := calldataload(0xC4) recipientAddress := mload(0x40) lenRecipientAddress := calldataload(0xE4) mstore(0x40, add(0x20, add(recipientAddress, lenRecipientAddress))) calldatacopy( recipientAddress, // copy to destinationRecipientAddress 0xE4, // copy from calldata @ 0x104 sub(calldatasize(), 0xE) // copy size (calldatasize - 0x104) ) } address tokenAddress = _resourceIDToTokenContractAddress[resourceID]; require(_contractWhitelist[tokenAddress], "provided tokenAddress is not whitelisted"); // ether case, the weth already in handler, do nothing if (tokenAddress != _wtokenAddress) { if (_burnList[tokenAddress]) { burnERC20(tokenAddress, depositer, amount); } else { lockERC20(tokenAddress, depositer, address(this), amount); } } _depositRecords[destinationChainID][depositNonce] = DepositRecord( tokenAddress, uint8(lenRecipientAddress), destinationChainID, resourceID, recipientAddress, depositer, amount ); } /** @notice Proposal execution should be initiated when a proposal is finalized in the Bridge contract. by a relayer on the deposit's destination chain. @param data Consists of {resourceID}, {amount}, {lenDestinationRecipientAddress}, and {destinationRecipientAddress} all padded to 32 bytes. @notice Data passed into the function should be constructed as follows: amount uint256 bytes 0 - 32 destinationRecipientAddress length uint256 bytes 32 - 64 destinationRecipientAddress bytes bytes 64 - END */ function executeProposal(bytes32 resourceID, bytes calldata data) external override onlyBridge { uint256 amount; bytes memory destinationRecipientAddress; assembly { amount := calldataload(0x64) destinationRecipientAddress := mload(0x40) let lenDestinationRecipientAddress := calldataload(0x84) mstore(0x40, add(0x20, add(destinationRecipientAddress, lenDestinationRecipientAddress))) // in the calldata the destinationRecipientAddress is stored at 0xC4 after accounting for the function signature and length declaration calldatacopy( destinationRecipientAddress, // copy to destinationRecipientAddress 0x84, // copy from calldata @ 0x84 sub(calldatasize(), 0x84) // copy size to the end of calldata ) } bytes20 recipientAddress; address tokenAddress = _resourceIDToTokenContractAddress[resourceID]; assembly { recipientAddress := mload(add(destinationRecipientAddress, 0x20)) } require(_contractWhitelist[tokenAddress], "provided tokenAddress is not whitelisted"); // if it is wtoken, send native if (tokenAddress == _wtokenAddress) { IWETH(_wtokenAddress).withdraw(amount); //payable(address(recipientAddress)).transfer(amount); TransferHelper.safeTransferETH(address(recipientAddress), amount); return; } if (_burnList[tokenAddress]) { mintERC20(tokenAddress, address(recipientAddress), amount); } else { releaseERC20(tokenAddress, address(recipientAddress), amount); } } /** @notice Used to manually release ERC20 tokens from ERC20Safe. @param tokenAddress Address of token contract to release. @param recipient Address to release tokens to. @param amount The amount of ERC20 tokens to release. */ function withdraw(address tokenAddress, address recipient, uint amount) external override onlyBridge { if (tokenAddress == _wtokenAddress) { IWETH(_wtokenAddress).withdraw(amount); //payable(address(recipient)).transfer(amount); TransferHelper.safeTransferETH(recipient, amount); } else { releaseERC20(tokenAddress, recipient, amount); } } /** @notice Used to update the _bridgeAddress. @param newBridgeAddress Address of the updated _bridgeAddress. */ function updateBridgeAddress(address newBridgeAddress) external override onlyBridge { require(_bridgeAddress != newBridgeAddress, "the updated address is the same with the old"); _bridgeAddress = newBridgeAddress; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"bridgeAddress","type":"address"},{"internalType":"address","name":"wtokenAddress","type":"address"},{"internalType":"bytes32[]","name":"initialResourceIDs","type":"bytes32[]"},{"internalType":"address[]","name":"initialContractAddresses","type":"address[]"},{"internalType":"address[]","name":"burnableContractAddresses","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"_bridgeAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_burnList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_contractWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"uint64","name":"","type":"uint64"}],"name":"_depositRecords","outputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint8","name":"_lenDestinationRecipientAddress","type":"uint8"},{"internalType":"uint8","name":"_destinationChainID","type":"uint8"},{"internalType":"bytes32","name":"_resourceID","type":"bytes32"},{"internalType":"bytes","name":"_destinationRecipientAddress","type":"bytes"},{"internalType":"address","name":"_depositer","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"_resourceIDToTokenContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_tokenContractAddressToResourceID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_wtokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"resourceID","type":"bytes32"},{"internalType":"uint8","name":"destinationChainID","type":"uint8"},{"internalType":"uint64","name":"depositNonce","type":"uint64"},{"internalType":"address","name":"depositer","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"resourceID","type":"bytes32"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"fundERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"depositNonce","type":"uint64"},{"internalType":"uint8","name":"destId","type":"uint8"}],"name":"getDepositRecord","outputs":[{"components":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint8","name":"_lenDestinationRecipientAddress","type":"uint8"},{"internalType":"uint8","name":"_destinationChainID","type":"uint8"},{"internalType":"bytes32","name":"_resourceID","type":"bytes32"},{"internalType":"bytes","name":"_destinationRecipientAddress","type":"bytes"},{"internalType":"address","name":"_depositer","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"internalType":"struct ERC20Handler.DepositRecord","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"setBurnable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"resourceID","type":"bytes32"},{"internalType":"address","name":"contractAddress","type":"address"}],"name":"setResource","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newBridgeAddress","type":"address"}],"name":"updateBridgeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162001967380380620019678339810160408190526200003491620002a4565b81518351146200007b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000729062000415565b60405180910390fd5b600080546001600160a01b038088166001600160a01b031992831617835560018054918816919092161790555b8351811015620000f557620000ec848281518110620000c357fe5b6020026020010151848381518110620000d857fe5b60200260200101516200013d60201b60201c565b600101620000a8565b5060005b81518110156200013157620001288282815181106200011457fe5b60200260200101516200018d60201b60201c565b600101620000f9565b505050505050620004b9565b600082815260026020908152604080832080546001600160a01b039095166001600160a01b031990951685179055928252600381528282209390935560049092529020805460ff19166001179055565b6001600160a01b03811660009081526004602052604090205460ff16620001e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200007290620003b8565b6001600160a01b03166000908152600560205260409020805460ff19166001179055565b80516001600160a01b03811681146200021e57600080fd5b92915050565b600082601f83011262000235578081fd5b81516200024c620002468262000499565b62000472565b8181529150602080830190848101818402860182018710156200026e57600080fd5b60005b84811015620002995762000286888362000206565b8452928201929082019060010162000271565b505050505092915050565b600080600080600060a08688031215620002bc578081fd5b620002c8878762000206565b94506020620002da8882890162000206565b60408801519095506001600160401b0380821115620002f7578384fd5b8189018a601f82011262000309578485fd5b805192506200031c620002468462000499565b83815284810190828601868602840187018e101562000339578788fd5b8793505b858410156200035d5780518352600193909301929186019186016200033d565b5060608c0151909850945050508083111562000377578384fd5b620003858a848b0162000224565b945060808901519250808311156200039b578384fd5b5050620003ab8882890162000224565b9150509295509295909350565b60208082526024908201527f70726f766964656420636f6e7472616374206973206e6f742077686974656c6960408201527f7374656400000000000000000000000000000000000000000000000000000000606082015260800190565b6020808252603c908201527f696e697469616c5265736f7572636549447320616e6420696e697469616c436f60408201527f6e7472616374416464726573736573206c656e206d69736d6174636800000000606082015260800190565b6040518181016001600160401b03811182821017156200049157600080fd5b604052919050565b60006001600160401b03821115620004af578081fd5b5060209081020190565b61149e80620004c96000396000f3fe6080604052600436106100ec5760003560e01c80636a70d0811161008a578063ba484c0911610059578063ba484c091461028c578063c8ba6c87146102b9578063d9caed12146102e6578063e248cff21461030657610107565b80636a70d081146101ff5780637f79bea81461022c57806395601f091461024c578063b8fa37361461026c57610107565b806338995da9116100c657806338995da9146101775780634402027f1461019757806353ec4105146101ca578063645c8a4b146101df57610107565b806307b7ed991461010c5780630a6d55d81461012c578063318c136e1461016257610107565b36610107576001546001600160a01b0316331461010557fe5b005b600080fd5b34801561011857600080fd5b50610105610127366004610efd565b610326565b34801561013857600080fd5b5061014c610147366004610f7f565b61033a565b604051610159919061114a565b60405180910390f35b34801561016e57600080fd5b5061014c610355565b34801561018357600080fd5b50610105610192366004611010565b610364565b3480156101a357600080fd5b506101b76101b23660046110c4565b61058f565b604051610159979695949392919061119b565b3480156101d657600080fd5b5061014c61067a565b3480156101eb57600080fd5b506101056101fa366004610efd565b610689565b34801561020b57600080fd5b5061021f61021a366004610efd565b6106e1565b60405161015991906111ea565b34801561023857600080fd5b5061021f610247366004610efd565b6106f6565b34801561025857600080fd5b50610105610267366004610f1f565b61070b565b34801561027857600080fd5b50610105610287366004610f97565b61071e565b34801561029857600080fd5b506102ac6102a7366004611090565b610734565b60405161015991906113b1565b3480156102c557600080fd5b506102d96102d4366004610efd565b61085c565b60405161015991906111f5565b3480156102f257600080fd5b50610105610301366004610f1f565b61086e565b34801561031257600080fd5b50610105610321366004610fc6565b61090d565b61032e610a55565b61033781610a81565b50565b6002602052600090815260409020546001600160a01b031681565b6000546001600160a01b031681565b61036c610a55565b606060008060c4359150604051925060e4359050808301602001604052600e360360e484376000898152600260209081526040808320546001600160a01b031680845260049092529091205460ff166103e05760405162461bcd60e51b81526004016103d790611369565b60405180910390fd5b6001546001600160a01b03828116911614610432576001600160a01b03811660009081526005602052604090205460ff161561042657610421818885610add565b610432565b61043281883086610b45565b6040518060e00160405280826001600160a01b031681526020018360ff1681526020018a60ff1681526020018b8152602001858152602001886001600160a01b0316815260200184815250600660008b60ff1660ff16815260200190815260200160002060008a67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548160ff021916908360ff16021790555060408201518160000160156101000a81548160ff021916908360ff160217905550606082015181600101556080820151816002019080519060200190610550929190610da0565b5060a08201516003820180546001600160a01b0319166001600160a01b0390921691909117905560c09091015160049091015550505050505050505050565b600660209081526000928352604080842082529183529181902080546001808301546002808501805487516101009582161595909502600019011691909104601f81018890048802840188019096528583526001600160a01b03841696600160a01b850460ff90811697600160a81b909604169592949293929083018282801561065a5780601f1061062f5761010080835404028352916020019161065a565b820191906000526020600020905b81548152906001019060200180831161063d57829003601f168201915b50505050600383015460049093015491926001600160a01b031691905087565b6001546001600160a01b031681565b610691610a55565b6000546001600160a01b03828116911614156106bf5760405162461bcd60e51b81526004016103d7906112da565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60056020526000908152604090205460ff1681565b60046020526000908152604090205460ff1681565b8261071881843085610b59565b50505050565b610726610a55565b6107308282610bb1565b5050565b61073c610e1e565b60ff828116600090815260066020908152604080832067ffffffffffffffff88168452825291829020825160e08101845281546001600160a01b0381168252600160a01b8104861682850152600160a81b90049094168484015260018082015460608601526002808301805486516101009482161594909402600019011691909104601f81018590048502830185019095528482529193608086019391929183018282801561082c5780601f106108015761010080835404028352916020019161082c565b820191906000526020600020905b81548152906001019060200180831161080f57829003601f168201915b505050918352505060038201546001600160a01b0316602082015260049091015460409091015290505b92915050565b60036020526000908152604090205481565b610876610a55565b6001546001600160a01b03848116911614156108fd57600154604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d906108bc9084906004016111f5565b600060405180830381600087803b1580156108d657600080fd5b505af11580156108ea573d6000803e3d6000fd5b505050506108f88282610c01565b610908565b610908838383610c8e565b505050565b610915610a55565b60408051608480358201602001909252606435913660831901908237600085815260026020908152604080832054848301516001600160a01b03909116808552600490935292205460ff1661097c5760405162461bcd60e51b81526004016103d790611369565b6001546001600160a01b0382811691161415610a0a57600154604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d906109c29087906004016111f5565b600060405180830381600087803b1580156109dc57600080fd5b505af11580156109f0573d6000803e3d6000fd5b50505050610a018260601c85610c01565b50505050610908565b6001600160a01b03811660009081526005602052604090205460ff1615610a3e57610a39818360601c86610c9a565b610a4c565b610a4c818360601c86610c8e565b50505050505050565b6000546001600160a01b03163314610a7f5760405162461bcd60e51b81526004016103d790611233565b565b6001600160a01b03811660009081526004602052604090205460ff16610ab95760405162461bcd60e51b81526004016103d79061126a565b6001600160a01b03166000908152600560205260409020805460ff19166001179055565b60405163079cc67960e41b815283906001600160a01b038216906379cc679090610b0d9086908690600401611182565b600060405180830381600087803b158015610b2757600080fd5b505af1158015610b3b573d6000803e3d6000fd5b5050505050505050565b83610b5281858585610b59565b5050505050565b610718846323b872dd60e01b858585604051602401610b7a9392919061115e565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610cca565b600082815260026020908152604080832080546001600160a01b039095166001600160a01b031990951685179055928252600381528282209390935560049092529020805460ff19166001179055565b604080516000808252602082019092526001600160a01b038416908390604051610c2b919061112e565b60006040518083038185875af1925050503d8060008114610c68576040519150601f19603f3d011682016040523d82523d6000602084013e610c6d565b606091505b50509050806109085760405162461bcd60e51b81526004016103d790611326565b82610718818484610d81565b6040516340c10f1960e01b815283906001600160a01b038216906340c10f1990610b0d9086908690600401611182565b60006060836001600160a01b031683604051610ce6919061112e565b6000604051808303816000865af19150503d8060008114610d23576040519150601f19603f3d011682016040523d82523d6000602084013e610d28565b606091505b509150915081610d4a5760405162461bcd60e51b81526004016103d7906112ae565b8051156107185780806020019051810190610d659190610f5f565b6107185760405162461bcd60e51b81526004016103d7906111fe565b6109088363a9059cbb60e01b8484604051602401610b7a929190611182565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610de157805160ff1916838001178555610e0e565b82800160010185558215610e0e579182015b82811115610e0e578251825591602001919060010190610df3565b50610e1a929150610e59565b5090565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082015260a0810182905260c081019190915290565b610e7391905b80821115610e1a5760008155600101610e5f565b90565b80356001600160a01b038116811461085657600080fd5b60008083601f840112610e9e578182fd5b50813567ffffffffffffffff811115610eb5578182fd5b602083019150836020828501011115610ecd57600080fd5b9250929050565b803567ffffffffffffffff8116811461085657600080fd5b803560ff8116811461085657600080fd5b600060208284031215610f0e578081fd5b610f188383610e76565b9392505050565b600080600060608486031215610f33578182fd5b8335610f3e81611453565b92506020840135610f4e81611453565b929592945050506040919091013590565b600060208284031215610f70578081fd5b81518015158114610f18578182fd5b600060208284031215610f90578081fd5b5035919050565b60008060408385031215610fa9578182fd5b823591506020830135610fbb81611453565b809150509250929050565b600080600060408486031215610fda578283fd5b83359250602084013567ffffffffffffffff811115610ff7578283fd5b61100386828701610e8d565b9497909650939450505050565b60008060008060008060a08789031215611028578182fd5b863595506110398860208901610eec565b94506110488860408901610ed4565b93506110578860608901610e76565b9250608087013567ffffffffffffffff811115611072578283fd5b61107e89828a01610e8d565b979a9699509497509295939492505050565b600080604083850312156110a2578182fd5b6110ac8484610ed4565b91506110bb8460208501610eec565b90509250929050565b600080604083850312156110d6578182fd5b823560ff811681146110e6578283fd5b9150602083013567ffffffffffffffff81168114610fbb578182fd5b6000815180845261111a816020860160208601611427565b601f01601f19169290920160200192915050565b60008251611140818460208701611427565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b600060018060a01b03808a16835260ff8916602084015260ff8816604084015286606084015260e060808401526111d560e0840187611102565b941660a08301525060c0015295945050505050565b901515815260200190565b90815260200190565b6020808252818101527f45524332303a206f7065726174696f6e20646964206e6f742073756363656564604082015260600190565b6020808252601e908201527f73656e646572206d7573742062652062726964676520636f6e74726163740000604082015260600190565b60208082526024908201527f70726f766964656420636f6e7472616374206973206e6f742077686974656c696040820152631cdd195960e21b606082015260800190565b602080825260129082015271115490cc8c0e8818d85b1b0819985a5b195960721b604082015260600190565b6020808252602c908201527f74686520757064617465642061646472657373206973207468652073616d652060408201526b1dda5d1a081d1a19481bdb1960a21b606082015260800190565b60208082526023908201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960408201526213115160ea1b606082015260800190565b60208082526028908201527f70726f766964656420746f6b656e41646472657373206973206e6f74207768696040820152671d195b1a5cdd195960c21b606082015260800190565b60006020825260018060a01b0380845116602084015260ff602085015116604084015260ff604085015116606084015260608401516080840152608084015160e060a0850152611405610100850182611102565b8260a08701511660c086015260c086015160e086015280935050505092915050565b60005b8381101561144257818101518382015260200161142a565b838111156107185750506000910152565b6001600160a01b038116811461033757600080fdfea2646970667358221220ac6d4f412481bf54cdc110c2679f910f9cbdecce539e5b040d8f19790248e33f64736f6c634300060400330000000000000000000000003267701115c58384e70897739f5bb1c258d620e7000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106100ec5760003560e01c80636a70d0811161008a578063ba484c0911610059578063ba484c091461028c578063c8ba6c87146102b9578063d9caed12146102e6578063e248cff21461030657610107565b80636a70d081146101ff5780637f79bea81461022c57806395601f091461024c578063b8fa37361461026c57610107565b806338995da9116100c657806338995da9146101775780634402027f1461019757806353ec4105146101ca578063645c8a4b146101df57610107565b806307b7ed991461010c5780630a6d55d81461012c578063318c136e1461016257610107565b36610107576001546001600160a01b0316331461010557fe5b005b600080fd5b34801561011857600080fd5b50610105610127366004610efd565b610326565b34801561013857600080fd5b5061014c610147366004610f7f565b61033a565b604051610159919061114a565b60405180910390f35b34801561016e57600080fd5b5061014c610355565b34801561018357600080fd5b50610105610192366004611010565b610364565b3480156101a357600080fd5b506101b76101b23660046110c4565b61058f565b604051610159979695949392919061119b565b3480156101d657600080fd5b5061014c61067a565b3480156101eb57600080fd5b506101056101fa366004610efd565b610689565b34801561020b57600080fd5b5061021f61021a366004610efd565b6106e1565b60405161015991906111ea565b34801561023857600080fd5b5061021f610247366004610efd565b6106f6565b34801561025857600080fd5b50610105610267366004610f1f565b61070b565b34801561027857600080fd5b50610105610287366004610f97565b61071e565b34801561029857600080fd5b506102ac6102a7366004611090565b610734565b60405161015991906113b1565b3480156102c557600080fd5b506102d96102d4366004610efd565b61085c565b60405161015991906111f5565b3480156102f257600080fd5b50610105610301366004610f1f565b61086e565b34801561031257600080fd5b50610105610321366004610fc6565b61090d565b61032e610a55565b61033781610a81565b50565b6002602052600090815260409020546001600160a01b031681565b6000546001600160a01b031681565b61036c610a55565b606060008060c4359150604051925060e4359050808301602001604052600e360360e484376000898152600260209081526040808320546001600160a01b031680845260049092529091205460ff166103e05760405162461bcd60e51b81526004016103d790611369565b60405180910390fd5b6001546001600160a01b03828116911614610432576001600160a01b03811660009081526005602052604090205460ff161561042657610421818885610add565b610432565b61043281883086610b45565b6040518060e00160405280826001600160a01b031681526020018360ff1681526020018a60ff1681526020018b8152602001858152602001886001600160a01b0316815260200184815250600660008b60ff1660ff16815260200190815260200160002060008a67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548160ff021916908360ff16021790555060408201518160000160156101000a81548160ff021916908360ff160217905550606082015181600101556080820151816002019080519060200190610550929190610da0565b5060a08201516003820180546001600160a01b0319166001600160a01b0390921691909117905560c09091015160049091015550505050505050505050565b600660209081526000928352604080842082529183529181902080546001808301546002808501805487516101009582161595909502600019011691909104601f81018890048802840188019096528583526001600160a01b03841696600160a01b850460ff90811697600160a81b909604169592949293929083018282801561065a5780601f1061062f5761010080835404028352916020019161065a565b820191906000526020600020905b81548152906001019060200180831161063d57829003601f168201915b50505050600383015460049093015491926001600160a01b031691905087565b6001546001600160a01b031681565b610691610a55565b6000546001600160a01b03828116911614156106bf5760405162461bcd60e51b81526004016103d7906112da565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60056020526000908152604090205460ff1681565b60046020526000908152604090205460ff1681565b8261071881843085610b59565b50505050565b610726610a55565b6107308282610bb1565b5050565b61073c610e1e565b60ff828116600090815260066020908152604080832067ffffffffffffffff88168452825291829020825160e08101845281546001600160a01b0381168252600160a01b8104861682850152600160a81b90049094168484015260018082015460608601526002808301805486516101009482161594909402600019011691909104601f81018590048502830185019095528482529193608086019391929183018282801561082c5780601f106108015761010080835404028352916020019161082c565b820191906000526020600020905b81548152906001019060200180831161080f57829003601f168201915b505050918352505060038201546001600160a01b0316602082015260049091015460409091015290505b92915050565b60036020526000908152604090205481565b610876610a55565b6001546001600160a01b03848116911614156108fd57600154604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d906108bc9084906004016111f5565b600060405180830381600087803b1580156108d657600080fd5b505af11580156108ea573d6000803e3d6000fd5b505050506108f88282610c01565b610908565b610908838383610c8e565b505050565b610915610a55565b60408051608480358201602001909252606435913660831901908237600085815260026020908152604080832054848301516001600160a01b03909116808552600490935292205460ff1661097c5760405162461bcd60e51b81526004016103d790611369565b6001546001600160a01b0382811691161415610a0a57600154604051632e1a7d4d60e01b81526001600160a01b0390911690632e1a7d4d906109c29087906004016111f5565b600060405180830381600087803b1580156109dc57600080fd5b505af11580156109f0573d6000803e3d6000fd5b50505050610a018260601c85610c01565b50505050610908565b6001600160a01b03811660009081526005602052604090205460ff1615610a3e57610a39818360601c86610c9a565b610a4c565b610a4c818360601c86610c8e565b50505050505050565b6000546001600160a01b03163314610a7f5760405162461bcd60e51b81526004016103d790611233565b565b6001600160a01b03811660009081526004602052604090205460ff16610ab95760405162461bcd60e51b81526004016103d79061126a565b6001600160a01b03166000908152600560205260409020805460ff19166001179055565b60405163079cc67960e41b815283906001600160a01b038216906379cc679090610b0d9086908690600401611182565b600060405180830381600087803b158015610b2757600080fd5b505af1158015610b3b573d6000803e3d6000fd5b5050505050505050565b83610b5281858585610b59565b5050505050565b610718846323b872dd60e01b858585604051602401610b7a9392919061115e565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152610cca565b600082815260026020908152604080832080546001600160a01b039095166001600160a01b031990951685179055928252600381528282209390935560049092529020805460ff19166001179055565b604080516000808252602082019092526001600160a01b038416908390604051610c2b919061112e565b60006040518083038185875af1925050503d8060008114610c68576040519150601f19603f3d011682016040523d82523d6000602084013e610c6d565b606091505b50509050806109085760405162461bcd60e51b81526004016103d790611326565b82610718818484610d81565b6040516340c10f1960e01b815283906001600160a01b038216906340c10f1990610b0d9086908690600401611182565b60006060836001600160a01b031683604051610ce6919061112e565b6000604051808303816000865af19150503d8060008114610d23576040519150601f19603f3d011682016040523d82523d6000602084013e610d28565b606091505b509150915081610d4a5760405162461bcd60e51b81526004016103d7906112ae565b8051156107185780806020019051810190610d659190610f5f565b6107185760405162461bcd60e51b81526004016103d7906111fe565b6109088363a9059cbb60e01b8484604051602401610b7a929190611182565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610de157805160ff1916838001178555610e0e565b82800160010185558215610e0e579182015b82811115610e0e578251825591602001919060010190610df3565b50610e1a929150610e59565b5090565b6040805160e0810182526000808252602082018190529181018290526060808201839052608082015260a0810182905260c081019190915290565b610e7391905b80821115610e1a5760008155600101610e5f565b90565b80356001600160a01b038116811461085657600080fd5b60008083601f840112610e9e578182fd5b50813567ffffffffffffffff811115610eb5578182fd5b602083019150836020828501011115610ecd57600080fd5b9250929050565b803567ffffffffffffffff8116811461085657600080fd5b803560ff8116811461085657600080fd5b600060208284031215610f0e578081fd5b610f188383610e76565b9392505050565b600080600060608486031215610f33578182fd5b8335610f3e81611453565b92506020840135610f4e81611453565b929592945050506040919091013590565b600060208284031215610f70578081fd5b81518015158114610f18578182fd5b600060208284031215610f90578081fd5b5035919050565b60008060408385031215610fa9578182fd5b823591506020830135610fbb81611453565b809150509250929050565b600080600060408486031215610fda578283fd5b83359250602084013567ffffffffffffffff811115610ff7578283fd5b61100386828701610e8d565b9497909650939450505050565b60008060008060008060a08789031215611028578182fd5b863595506110398860208901610eec565b94506110488860408901610ed4565b93506110578860608901610e76565b9250608087013567ffffffffffffffff811115611072578283fd5b61107e89828a01610e8d565b979a9699509497509295939492505050565b600080604083850312156110a2578182fd5b6110ac8484610ed4565b91506110bb8460208501610eec565b90509250929050565b600080604083850312156110d6578182fd5b823560ff811681146110e6578283fd5b9150602083013567ffffffffffffffff81168114610fbb578182fd5b6000815180845261111a816020860160208601611427565b601f01601f19169290920160200192915050565b60008251611140818460208701611427565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b600060018060a01b03808a16835260ff8916602084015260ff8816604084015286606084015260e060808401526111d560e0840187611102565b941660a08301525060c0015295945050505050565b901515815260200190565b90815260200190565b6020808252818101527f45524332303a206f7065726174696f6e20646964206e6f742073756363656564604082015260600190565b6020808252601e908201527f73656e646572206d7573742062652062726964676520636f6e74726163740000604082015260600190565b60208082526024908201527f70726f766964656420636f6e7472616374206973206e6f742077686974656c696040820152631cdd195960e21b606082015260800190565b602080825260129082015271115490cc8c0e8818d85b1b0819985a5b195960721b604082015260600190565b6020808252602c908201527f74686520757064617465642061646472657373206973207468652073616d652060408201526b1dda5d1a081d1a19481bdb1960a21b606082015260800190565b60208082526023908201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960408201526213115160ea1b606082015260800190565b60208082526028908201527f70726f766964656420746f6b656e41646472657373206973206e6f74207768696040820152671d195b1a5cdd195960c21b606082015260800190565b60006020825260018060a01b0380845116602084015260ff602085015116604084015260ff604085015116606084015260608401516080840152608084015160e060a0850152611405610100850182611102565b8260a08701511660c086015260c086015160e086015280935050505092915050565b60005b8381101561144257818101518382015260200161142a565b838111156107185750506000910152565b6001600160a01b038116811461033757600080fdfea2646970667358221220ac6d4f412481bf54cdc110c2679f910f9cbdecce539e5b040d8f19790248e33f64736f6c63430006040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003267701115c58384e70897739f5bb1c258d620e7000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : bridgeAddress (address): 0x3267701115c58384e70897739f5bb1C258D620e7
Arg [1] : wtokenAddress (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000003267701115c58384e70897739f5bb1c258d620e7
Arg [1] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [4] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
55681:9571:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58029:14;;-1:-1:-1;;;;;58029:14:0;58015:10;:28;58008:36;;;;55681:9571;;12:1:-1;9;2:12;4602:122:0;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;4602:122:0;;;;;;;;:::i;3021:69::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;3021:69:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;2893:29;;5:9:-1;2:2;;;27:1;24;17:12;2:2;2893:29:0;;;:::i;60060:1664::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;60060:1664:0;;;;;;;;:::i;56085:74::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;56085:74:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;2929:38;;5:9:-1;2:2;;;27:1;24;17:12;2:2;2929:38:0;;;:::i;65007:240::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;65007:240:0;;;;;;;;:::i;3377:42::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;3377:42:0;;;;;;;;:::i;:::-;;;;;;;;3271:51;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;3271:51:0;;;;;;;;:::i;50000:198::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;50000:198:0;;;;;;;;:::i;4196:157::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;4196:157:0;;;;;;;;:::i;58914:169::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;58914:169:0;;;;;;;;:::i;:::-;;;;;;;;3144:69;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;3144:69:0;;;;;;;;:::i;:::-;;;;;;;;64434:423;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;64434:423:0;;;;;;;;:::i;62381:1771::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;-1:-1;62381:1771:0;;;;;;;;:::i;4602:122::-;3461:13;:11;:13::i;:::-;4687:29:::1;4700:15;4687:12;:29::i;:::-;4602:122:::0;:::o;3021:69::-;;;;;;;;;;;;-1:-1:-1;;;;;3021:69:0;;:::o;2893:29::-;;;-1:-1:-1;;;;;2893:29:0;;:::o;60060:1664::-;3461:13;:11;:13::i;:::-;60281:31:::1;60323:21;60355:34:::0;60451:4:::1;60438:18;60428:28;;60498:4;60492:11;60472:31;;60553:4;60540:18;60517:41;;60617:19;60599:16;60595:42;60589:4;60585:53;60579:4;60572:67;60833:3;60817:14;60813:24;60760:4;60686:16;60655:233;60911:20;60934:45:::0;;;:33:::1;:45;::::0;;;;;;;;-1:-1:-1;;;;;60934:45:0::1;60998:32:::0;;;:18:::1;:32:::0;;;;;;;::::1;;60990:85;;;;-1:-1:-1::0;;;60990:85:0::1;;;;;;;;;;;;;;;;;61180:14;::::0;-1:-1:-1;;;;;61164:30:0;;::::1;61180:14:::0;::::1;61164:30;61160:266;;-1:-1:-1::0;;;;;61215:23:0;::::1;;::::0;;;:9:::1;:23;::::0;;;;;::::1;;61211:204;;;61259:42;61269:12;61283:9;61294:6;61259:9;:42::i;:::-;61211:204;;;61342:57;61352:12;61366:9;61385:4;61392:6;61342:9;:57::i;:::-;61490:226;;;;;;;;61518:12;-1:-1:-1::0;;;;;61490:226:0::1;;;;;61551:19;61490:226;;;;;;61586:18;61490:226;;;;;;61619:10;61490:226;;;;61644:16;61490:226;;;;61675:9;-1:-1:-1::0;;;;;61490:226:0::1;;;;;61699:6;61490:226;;::::0;61438:15:::1;:35;61454:18;61438:35;;;;;;;;;;;;;;;:49;61474:12;61438:49;;;;;;;;;;;;;;;:278;;;;;;;;;;;;;-1:-1:-1::0;;;;;61438:278:0::1;;;;;-1:-1:-1::0;;;;;61438:278:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;61438:278:0::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;-1:-1:-1;;;;;;61438:278:0::1;-1:-1:-1::0;;;;;61438:278:0;;::::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;-1:-1:-1;;;;;;;;;;60060:1664:0:o;56085:74::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;56085:74:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;56085:74:0;;;-1:-1:-1;;;56085:74:0;;;;;;;-1:-1:-1;;;56085:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;56085:74:0;;;;;;;;;;;-1:-1:-1;;;;;56085:74:0;;;-1:-1:-1;56085:74:0;:::o;2929:38::-;;;-1:-1:-1;;;;;2929:38:0;;:::o;65007:240::-;3461:13;:11;:13::i;:::-;65110:14:::1;::::0;-1:-1:-1;;;;;65110:34:0;;::::1;:14:::0;::::1;:34;;65102:91;;;;-1:-1:-1::0;;;65102:91:0::1;;;;;;;;;65206:14;:33:::0;;-1:-1:-1;;;;;;65206:33:0::1;-1:-1:-1::0;;;;;65206:33:0;;;::::1;::::0;;;::::1;::::0;;65007:240::o;3377:42::-;;;;;;;;;;;;;;;:::o;3271:51::-;;;;;;;;;;;;;;;:::o;50000:198::-;50112:12;50136:54;50112:12;50161:5;50176:4;50183:6;50136:17;:54::i;:::-;50000:198;;;;:::o;4196:157::-;3461:13;:11;:13::i;:::-;4304:41:::1;4317:10;4329:15;4304:12;:41::i;:::-;4196:157:::0;;:::o;58914:169::-;58998:20;;:::i;:::-;59038:23;;;;;;;;:15;:23;;;;;;;;:37;;;;;;;;;;;59031:44;;;;;;;;;-1:-1:-1;;;;;59031:44:0;;;;-1:-1:-1;;;59031:44:0;;;;;;;;-1:-1:-1;;;59031:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;59031:44:0;;;;;;;;;;;;;;;;;;;;;;;;59038:37;;59031:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;59031:44:0;;;-1:-1:-1;;59031:44:0;;;;-1:-1:-1;;;;;59031:44:0;;;;;;;;;;;;;;;;-1:-1:-1;58914:169:0;;;;;:::o;3144:69::-;;;;;;;;;;;;;:::o;64434:423::-;3461:13;:11;:13::i;:::-;64566:14:::1;::::0;-1:-1:-1;;;;;64550:30:0;;::::1;64566:14:::0;::::1;64550:30;64546:304;;;64603:14;::::0;64597:38:::1;::::0;-1:-1:-1;;;64597:38:0;;-1:-1:-1;;;;;64603:14:0;;::::1;::::0;64597:30:::1;::::0;:38:::1;::::0;64628:6;;64597:38:::1;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;64597:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;64597:38:0;;;;64711:49;64742:9;64753:6;64711:30;:49::i;:::-;64546:304;;;64793:45;64806:12;64820:9;64831:6;64793:12;:45::i;:::-;64434:423:::0;;;:::o;62381:1771::-;3461:13;:11;:13::i;:::-;62677:4:::1;62671:11:::0;;62747:4:::1;62734:18:::0;::::1;62789:64:::0;::::1;62783:4;62779:75;62766:89:::0;;;62619:4:::1;62606:18;::::0;63192:14:::1;-1:-1:-1::0;;63188:25:0;;62671:11;63020:244:::1;63287:24;63345:45:::0;;;:33:::1;:45;::::0;;;;;;;;63453:38;;::::1;63447:45:::0;-1:-1:-1;;;;;63345:45:0;;::::1;63523:32:::0;;;:18:::1;:32:::0;;;;;;::::1;;63515:85;;;;-1:-1:-1::0;;;63515:85:0::1;;;;;;;;;63675:14;::::0;-1:-1:-1;;;;;63659:30:0;;::::1;63675:14:::0;::::1;63659:30;63655:270;;;63712:14;::::0;63706:38:::1;::::0;-1:-1:-1;;;63706:38:0;;-1:-1:-1;;;;;63712:14:0;;::::1;::::0;63706:30:::1;::::0;:38:::1;::::0;63737:6;;63706:38:::1;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;63706:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;63706:38:0;;;;63827:65;63866:16;63858:25;;63885:6;63827:30;:65::i;:::-;63907:7;;;;;;63655:270;-1:-1:-1::0;;;;;63941:23:0;::::1;;::::0;;;:9:::1;:23;::::0;;;;;::::1;;63937:208;;;63981:58;63991:12;64013:16;64005:25;;64032:6;63981:9;:58::i;:::-;63937:208;;;64072:61;64085:12;64107:16;64099:25;;64126:6;64072:12;:61::i;:::-;3485:1;;;;62381:1771:::0;;;:::o;3502:121::-;3566:14;;-1:-1:-1;;;;;3566:14:0;3552:10;:28;3544:71;;;;-1:-1:-1;;;3544:71:0;;;;;;;;;3502:121::o;5453:203::-;-1:-1:-1;;;;;5528:35:0;;;;;;:18;:35;;;;;;;;5520:84;;;;-1:-1:-1;;;5520:84:0;;;;;;;;;-1:-1:-1;;;;;5615:26:0;;;;;:9;:26;;;;;:33;;-1:-1:-1;;5615:33:0;5644:4;5615:33;;;5453:203::o;51824:189::-;51976:29;;-1:-1:-1;;;51976:29:0;;51952:12;;-1:-1:-1;;;;;51976:14:0;;;;;:29;;51991:5;;51998:6;;51976:29;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;51976:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51976:29:0;;;;51824:189;;;;:::o;50505:215::-;50638:12;50662:50;50638:12;50687:5;50694:9;50705:6;50662:17;:50::i;:::-;50505:215;;;;;:::o;52676:195::-;52777:86;52787:5;52817:27;;;52846:4;52852:2;52856:5;52794:68;;;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;52794:68:0;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;52794:68:0;;;179:29:-1;;;;160:49;;;52777:9:0;:86::i;5158:287::-;5245:45;;;;:33;:45;;;;;;;;:63;;-1:-1:-1;;;;;5245:63:0;;;-1:-1:-1;;;;;;5245:63:0;;;;;;;5319:50;;;:33;:50;;;;;:63;;;;5395:18;:35;;;;;:42;;-1:-1:-1;;5395:42:0;5245:63;5395:42;;;5158:287::o;55302:195::-;55410:12;;;55372;55410;;;;;;;;;-1:-1:-1;;;;;55389:7:0;;;55403:5;;55389:34;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;19;14:27;;;;67:4;61:11;56:16;;134:4;130:9;123:4;105:16;101:27;97:43;94:1;90:51;84:4;77:65;157:16;154:1;147:27;211:16;208:1;201:4;198:1;194:12;179:49;5:228;;14:27;32:4;27:9;;5:228;;55371:52:0;;;55442:7;55434:55;;;;-1:-1:-1;;;55434:55:0;;;;;;;;50973:192;51094:12;51118:39;51094:12;51139:9;51150:6;51118:13;:39::i;51394:215::-;51570:29;;-1:-1:-1;;;51570:29:0;;51546:12;;-1:-1:-1;;;;;51570:10:0;;;;;:29;;51581:9;;51592:6;;51570:29;;;;53039:346;53119:12;53133:23;53168:5;-1:-1:-1;;;;;53160:19:0;53180:4;53160:25;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;19;14:27;;;;67:4;61:11;56:16;;134:4;130:9;123:4;105:16;101:27;97:43;94:1;90:51;84:4;77:65;157:16;154:1;147:27;211:16;208:1;201:4;198:1;194:12;179:49;5:228;;14:27;32:4;27:9;;5:228;;53118:67:0;;;;53204:7;53196:38;;;;-1:-1:-1;;;53196:38:0;;;;;;;;;53251:17;;:21;53247:131;;53310:10;53299:30;;;;;;;;;;;;;;53291:75;;;;-1:-1:-1;;;53291:75:0;;;;;;;;52234:167;52317:76;52327:5;52357:23;;;52382:2;52386:5;52334:58;;;;;;;;;;55681:9571;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55681:9571:0;;;-1:-1:-1;55681:9571:0;:::i;:::-;;;:::o;:::-;;;;;;;;;-1:-1:-1;55681:9571:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::o;5:130:-1:-;72:20;;-1:-1;;;;;19019:54;;19796:35;;19786:2;;19845:1;;19835:12;428:336;;;542:3;535:4;527:6;523:17;519:27;509:2;;-1:-1;;550:12;509:2;-1:-1;580:20;;620:18;609:30;;606:2;;;-1:-1;;642:12;606:2;686:4;678:6;674:17;662:29;;737:3;686:4;717:17;678:6;703:32;;700:41;697:2;;;754:1;;744:12;697:2;502:262;;;;;;909:128;975:20;;19236:18;19225:30;;20285:34;;20275:2;;20333:1;;20323:12;1044:126;1109:20;;19338:4;19327:16;;20406:33;;20396:2;;20453:1;;20443:12;1177:241;;1281:2;1269:9;1260:7;1256:23;1252:32;1249:2;;;-1:-1;;1287:12;1249:2;1349:53;1394:7;1370:22;1349:53;;;1339:63;1243:175;-1:-1;;;1243:175;1425:491;;;;1563:2;1551:9;1542:7;1538:23;1534:32;1531:2;;;-1:-1;;1569:12;1531:2;85:6;72:20;97:33;124:5;97:33;;;1621:63;-1:-1;1721:2;1760:22;;72:20;97:33;72:20;97:33;;;1525:391;;1729:63;;-1:-1;;;1829:2;1868:22;;;;839:20;;1525:391;1923:257;;2035:2;2023:9;2014:7;2010:23;2006:32;2003:2;;;-1:-1;;2041:12;2003:2;223:6;217:13;19942:5;18852:13;18845:21;19920:5;19917:32;19907:2;;-1:-1;;19953:12;2187:241;;2291:2;2279:9;2270:7;2266:23;2262:32;2259:2;;;-1:-1;;2297:12;2259:2;-1:-1;344:20;;2253:175;-1:-1;2253:175;2435:366;;;2556:2;2544:9;2535:7;2531:23;2527:32;2524:2;;;-1:-1;;2562:12;2524:2;357:6;344:20;2614:63;;2714:2;2757:9;2753:22;72:20;97:33;124:5;97:33;;;2722:63;;;;2518:283;;;;;;2808:490;;;;2948:2;2936:9;2927:7;2923:23;2919:32;2916:2;;;-1:-1;;2954:12;2916:2;357:6;344:20;3006:63;;3134:2;3123:9;3119:18;3106:32;3158:18;3150:6;3147:30;3144:2;;;-1:-1;;3180:12;3144:2;3218:64;3274:7;3265:6;3254:9;3250:22;3218:64;;;2910:388;;3208:74;;-1:-1;3208:74;;-1:-1;;;;2910:388;3305:861;;;;;;;3493:3;3481:9;3472:7;3468:23;3464:33;3461:2;;;-1:-1;;3500:12;3461:2;357:6;344:20;3552:63;;3670:51;3713:7;3652:2;3693:9;3689:22;3670:51;;;3660:61;;3776:52;3820:7;3758:2;3800:9;3796:22;3776:52;;;3766:62;;3883:53;3928:7;3865:2;3908:9;3904:22;3883:53;;;3873:63;;4001:3;3990:9;3986:19;3973:33;4026:18;4018:6;4015:30;4012:2;;;-1:-1;;4048:12;4012:2;4086:64;4142:7;4133:6;4122:9;4118:22;4086:64;;;3455:711;;;;-1:-1;3455:711;;-1:-1;3455:711;;4076:74;;3455:711;-1:-1;;;3455:711;4173:360;;;4291:2;4279:9;4270:7;4266:23;4262:32;4259:2;;;-1:-1;;4297:12;4259:2;4359:52;4403:7;4379:22;4359:52;;;4349:62;;4466:51;4509:7;4448:2;4489:9;4485:22;4466:51;;;4456:61;;4253:280;;;;;;4540:360;;;4658:2;4646:9;4637:7;4633:23;4629:32;4626:2;;;-1:-1;;4664:12;4626:2;1122:6;1109:20;19338:4;20432:5;19327:16;20409:5;20406:33;20396:2;;-1:-1;;20443:12;20396:2;4716:61;-1:-1;4814:2;4852:22;;975:20;19236:18;19225:30;;20285:34;;20275:2;;-1:-1;;20323:12;5841:315;;5965:5;17862:12;18136:6;18131:3;18124:19;6048:52;6093:6;18173:4;18168:3;18164:14;18173:4;6074:5;6070:16;6048:52;;;19716:7;19700:14;-1:-1;;19696:28;6112:39;;;;18173:4;6112:39;;5917:239;-1:-1;;5917:239;11368:254;;5638:5;17862:12;5749:52;5794:6;5789:3;5782:4;5775:5;5771:16;5749:52;;;5813:16;;;;;11489:133;-1:-1;;11489:133;11898:213;-1:-1;;;;;19019:54;;;;4968:37;;12016:2;12001:18;;11987:124;12118:435;-1:-1;;;;;19019:54;;;4968:37;;19019:54;;;;12456:2;12441:18;;4968:37;12539:2;12524:18;;5309:37;;;;12292:2;12277:18;;12263:290;12560:324;-1:-1;;;;;19019:54;;;;4968:37;;12870:2;12855:18;;5309:37;12706:2;12691:18;;12677:207;12891:943;;19030:42;;;;;;4998:5;19019:54;4975:3;4968:37;19338:4;11235:5;19327:16;13344:2;13333:9;13329:18;11207:35;19338:4;11235:5;19327:16;13423:2;13412:9;13408:18;11207:35;5339:5;13506:2;13495:9;13491:18;5309:37;13183:3;13543;13532:9;13528:19;13521:49;13584:72;13183:3;13172:9;13168:19;13642:6;13584:72;;;19019:54;;13735:3;13720:19;;4968:37;-1:-1;13819:3;13804:19;5309:37;13576:80;13154:680;-1:-1;;;;;13154:680;13841:201;18852:13;;18845:21;5202:34;;13953:2;13938:18;;13924:118;14049:213;5309:37;;;14167:2;14152:18;;14138:124;14269:407;14460:2;14474:47;;;14445:18;;;18124:19;7121:34;18164:14;;;7101:55;7175:12;;;14431:245;14683:407;14874:2;14888:47;;;7426:2;14859:18;;;18124:19;7462:32;18164:14;;;7442:53;7514:12;;;14845:245;15097:407;15288:2;15302:47;;;7765:2;15273:18;;;18124:19;7801:34;18164:14;;;7781:55;-1:-1;;;7856:12;;;7849:28;7896:12;;;15259:245;15511:407;15702:2;15716:47;;;8147:2;15687:18;;;18124:19;-1:-1;;;18164:14;;;8163:41;8223:12;;;15673:245;15925:407;16116:2;16130:47;;;8474:2;16101:18;;;18124:19;8510:34;18164:14;;;8490:55;-1:-1;;;8565:12;;;8558:36;8613:12;;;16087:245;16339:407;16530:2;16544:47;;;8864:2;16515:18;;;18124:19;8900:34;18164:14;;;8880:55;-1:-1;;;8955:12;;;8948:27;8994:12;;;16501:245;16753:407;16944:2;16958:47;;;9245:2;16929:18;;;18124:19;9281:34;18164:14;;;9261:55;-1:-1;;;9336:12;;;9329:32;9380:12;;;16915:245;17167:385;;17347:2;17368:17;17361:47;19030:42;;;;;;9727:16;9721:23;19019:54;17347:2;17336:9;17332:18;4968:37;19338:4;17347:2;9912:5;9908:16;9902:23;19327:16;9975:14;17336:9;9975:14;11207:35;19338:4;9975:14;10077:5;10073:16;10067:23;19327:16;10140:14;17336:9;10140:14;11207:35;10140:14;10234:5;10230:16;10224:23;10301:14;17336:9;10301:14;5309:37;10301:14;10412:5;10408:16;10402:23;9646:4;10445:14;17336:9;10445:14;10438:38;10491:67;9637:14;17336:9;9637:14;10539:12;10491:67;;;19030:42;10445:14;10642:5;10638:16;10632:23;19019:54;10709:14;17336:9;10709:14;4968:37;10709:14;10799:5;10795:16;10789:23;9646:4;17336:9;10866:14;5309:37;17414:128;;;;;;17318:234;;;;;19356:268;19421:1;19428:101;19442:6;19439:1;19436:13;19428:101;;;19509:11;;;19503:18;19490:11;;;19483:39;19464:2;19457:10;19428:101;;;19544:6;19541:1;19538:13;19535:2;;;-1:-1;;19421:1;19591:16;;19584:27;19405:219;19737:117;-1:-1;;;;;19019:54;;19796:35;;19786:2;;19845:1;;19835:12
Swarm Source
ipfs://ac6d4f412481bf54cdc110c2679f910f9cbdecce539e5b040d8f19790248e33f
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.