More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 107,679 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Execute | 8636078 | 4 mins ago | IN | 0 GLMR | 0.227942 | ||||
Execute | 8635997 | 12 mins ago | IN | 0 GLMR | 0.11158 | ||||
Execute | 8635978 | 14 mins ago | IN | 0 GLMR | 0.09562737 | ||||
Execute | 8634704 | 2 hrs ago | IN | 0 GLMR | 0.07970063 | ||||
Execute | 8634691 | 2 hrs ago | IN | 0 GLMR | 0.08330754 | ||||
Execute | 8634493 | 2 hrs ago | IN | 0 GLMR | 0.07995663 | ||||
Execute | 8634143 | 3 hrs ago | IN | 0 GLMR | 0.07995663 | ||||
Execute | 8634022 | 3 hrs ago | IN | 0 GLMR | 0.07995663 | ||||
Execute | 8633193 | 5 hrs ago | IN | 0 GLMR | 0.07970063 | ||||
Execute | 8633004 | 5 hrs ago | IN | 0 GLMR | 0.32044034 | ||||
Execute | 8632951 | 5 hrs ago | IN | 0 GLMR | 0.07970063 | ||||
Execute | 8632498 | 6 hrs ago | IN | 0 GLMR | 0.1594 | ||||
Execute | 8632138 | 6 hrs ago | IN | 0 GLMR | 0.0879516 | ||||
Execute | 8631925 | 7 hrs ago | IN | 0 GLMR | 0.07995663 | ||||
Execute | 8631715 | 7 hrs ago | IN | 0 GLMR | 0.07970063 | ||||
Execute | 8631592 | 7 hrs ago | IN | 0 GLMR | 0.0806564 | ||||
Execute | 8630200 | 10 hrs ago | IN | 0 GLMR | 0.13435795 | ||||
Execute | 8630129 | 10 hrs ago | IN | 0 GLMR | 0.07995663 | ||||
Execute | 8629941 | 10 hrs ago | IN | 0 GLMR | 0.09564 | ||||
Execute | 8629828 | 10 hrs ago | IN | 0 GLMR | 0.186212 | ||||
Execute | 8629740 | 11 hrs ago | IN | 0 GLMR | 0.09683024 | ||||
Execute | 8629462 | 11 hrs ago | IN | 0 GLMR | 0.07970063 | ||||
Execute | 8629295 | 11 hrs ago | IN | 0 GLMR | 0.08315424 | ||||
Execute | 8627988 | 14 hrs ago | IN | 0 GLMR | 0.085393 | ||||
Execute | 8627818 | 14 hrs ago | IN | 0 GLMR | 0.09035028 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
8479206 | 11 days ago | 0 GLMR | ||||
8479206 | 11 days ago | Contract Creation | 0 GLMR | |||
8479206 | 11 days ago | 0 GLMR | ||||
8479206 | 11 days ago | Contract Creation | 0 GLMR | |||
8469831 | 11 days ago | 0 GLMR | ||||
8469831 | 11 days ago | Contract Creation | 0 GLMR | |||
7858201 | 55 days ago | 0 GLMR | ||||
7858201 | 55 days ago | Contract Creation | 0 GLMR | |||
7549752 | 76 days ago | 0 GLMR | ||||
7549752 | 76 days ago | Contract Creation | 0 GLMR | |||
7507204 | 79 days ago | 0 GLMR | ||||
7507204 | 79 days ago | Contract Creation | 0 GLMR | |||
7506036 | 79 days ago | 0 GLMR | ||||
7506036 | 79 days ago | Contract Creation | 0 GLMR | |||
7506036 | 79 days ago | 0 GLMR | ||||
7506036 | 79 days ago | Contract Creation | 0 GLMR | |||
7362717 | 89 days ago | 0 GLMR | ||||
7362717 | 89 days ago | Contract Creation | 0 GLMR | |||
7266780 | 96 days ago | 0 GLMR | ||||
7266780 | 96 days ago | Contract Creation | 0 GLMR | |||
6848099 | 126 days ago | 0 GLMR | ||||
6848099 | 126 days ago | Contract Creation | 0 GLMR | |||
6829248 | 127 days ago | 0 GLMR | ||||
6829248 | 127 days ago | Contract Creation | 0 GLMR | |||
6790055 | 130 days ago | 0 GLMR |
Loading...
Loading
Contract Name:
AxelarGatewayProxyMultisig
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity)
/** *Submitted for verification at moonbeam.moonscan.io on 2022-02-16 */ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0 <0.9.0; /** * @title EternalStorage * @dev This contract holds all the necessary state variables to carry out the storage of any contract. */ contract EternalStorage { mapping(bytes32 => uint256) private _uintStorage; mapping(bytes32 => string) private _stringStorage; mapping(bytes32 => address) private _addressStorage; mapping(bytes32 => bytes) private _bytesStorage; mapping(bytes32 => bool) private _boolStorage; mapping(bytes32 => int256) private _intStorage; // *** Getter Methods *** function getUint(bytes32 key) public view returns (uint256) { return _uintStorage[key]; } function getString(bytes32 key) public view returns (string memory) { return _stringStorage[key]; } function getAddress(bytes32 key) public view returns (address) { return _addressStorage[key]; } function getBytes(bytes32 key) public view returns (bytes memory) { return _bytesStorage[key]; } function getBool(bytes32 key) public view returns (bool) { return _boolStorage[key]; } function getInt(bytes32 key) public view returns (int256) { return _intStorage[key]; } // *** Setter Methods *** function _setUint(bytes32 key, uint256 value) internal { _uintStorage[key] = value; } function _setString(bytes32 key, string memory value) internal { _stringStorage[key] = value; } function _setAddress(bytes32 key, address value) internal { _addressStorage[key] = value; } function _setBytes(bytes32 key, bytes memory value) internal { _bytesStorage[key] = value; } function _setBool(bytes32 key, bool value) internal { _boolStorage[key] = value; } function _setInt(bytes32 key, int256 value) internal { _intStorage[key] = value; } // *** Delete Methods *** function _deleteUint(bytes32 key) internal { delete _uintStorage[key]; } function _deleteString(bytes32 key) internal { delete _stringStorage[key]; } function _deleteAddress(bytes32 key) internal { delete _addressStorage[key]; } function _deleteBytes(bytes32 key) internal { delete _bytesStorage[key]; } function _deleteBool(bytes32 key) internal { delete _boolStorage[key]; } function _deleteInt(bytes32 key) internal { delete _intStorage[key]; } } contract Burner { constructor(address tokenAddress, bytes32 salt) { BurnableMintableCappedERC20(tokenAddress).burn(salt); selfdestruct(payable(address(0))); } } abstract contract Ownable { address public owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); constructor() { owner = msg.sender; emit OwnershipTransferred(address(0), msg.sender); } modifier onlyOwner() { require(owner == msg.sender, 'NOT_OWNER'); _; } function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), 'ZERO_ADDR'); emit OwnershipTransferred(owner, newOwner); owner = newOwner; } } interface IAxelarGateway { /**********\ |* Events *| \**********/ event Executed(bytes32 indexed commandId); event TokenDeployed(string symbol, address tokenAddresses); event TokenFrozen(string indexed symbol); event TokenUnfrozen(string indexed symbol); event AllTokensFrozen(); event AllTokensUnfrozen(); event AccountBlacklisted(address indexed account); event AccountWhitelisted(address indexed account); event Upgraded(address indexed implementation); /***********\ |* Getters *| \***********/ function allTokensFrozen() external view returns (bool); function implementation() external view returns (address); function tokenAddresses(string memory symbol) external view returns (address); function tokenFrozen(string memory symbol) external view returns (bool); function isCommandExecuted(bytes32 commandId) external view returns (bool); /*******************\ |* Admin Functions *| \*******************/ function freezeToken(string memory symbol) external; function unfreezeToken(string memory symbol) external; function freezeAllTokens() external; function unfreezeAllTokens() external; function upgrade(address newImplementation, bytes calldata setupParams) external; /**********************\ |* External Functions *| \**********************/ function setup(bytes calldata params) external; function execute(bytes calldata input) external; } contract AxelarGatewayProxy is EternalStorage { /// @dev Storage slot with the address of the current factory. `keccak256('eip1967.proxy.implementation') - 1`. bytes32 internal constant KEY_IMPLEMENTATION = bytes32(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc); fallback() external payable { address implementation = getAddress(KEY_IMPLEMENTATION); assembly { calldatacopy(0, 0, calldatasize()) let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) returndatacopy(0, 0, returndatasize()) switch result case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } receive() external payable { revert('NO_ETHER'); } } interface IAxelarGatewayMultisig is IAxelarGateway { event OwnershipTransferred(address[] preOwners, uint256 prevThreshold, address[] newOwners, uint256 newThreshold); event OperatorshipTransferred(address[] preOperators, uint256 prevThreshold, address[] newOperators, uint256 newThreshold); function owners() external view returns (address[] memory); function operators() external view returns (address[] memory); } /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address signer) { // Check the signature length require(signature.length == 65, 'INV_LEN'); // Divide the signature in r, s and v variables bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. // solhint-disable-next-line no-inline-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, 'INV_S'); require(v == 27 || v == 28, 'INV_V'); // If the signature is valid (and not malleable), return the signer address require((signer = ecrecover(hash, v, r, s)) != address(0), 'INV_SIG'); } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * replicates the behavior of the * https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`] * JSON-RPC method. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked('\x19Ethereum Signed Message:\n32', hash)); } } /** * @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 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. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return payable(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 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 {ERC20PresetMinterPauser}. * * 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 { mapping(address => uint256) public override balanceOf; mapping(address => mapping(address => uint256)) public override allowance; uint256 public override totalSupply; string public name; string public symbol; uint8 public immutable decimals; /** * @dev Sets the values for {name}, {symbol}, and {decimals}. * * All three of these values are immutable: they can only be set once during * construction. */ constructor( string memory name_, string memory symbol_, uint8 decimals_ ) { name = name_; symbol = symbol_; decimals = decimals_; } /** * @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-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(), allowance[sender][_msgSender()] - amount); 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, allowance[_msgSender()][spender] + 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, allowance[_msgSender()][spender] - subtractedValue); 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), 'ZERO_ADDR'); require(recipient != address(0), 'ZERO_ADDR'); _beforeTokenTransfer(sender, recipient, amount); balanceOf[sender] -= amount; balanceOf[recipient] += 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), 'ZERO_ADDR'); _beforeTokenTransfer(address(0), account, amount); totalSupply += amount; balanceOf[account] += 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), 'ZERO_ADDR'); _beforeTokenTransfer(account, address(0), amount); balanceOf[account] -= amount; totalSupply -= amount; emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This 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), 'ZERO_ADDR'); require(spender != address(0), 'ZERO_ADDR'); allowance[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @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 {} } contract BurnableMintableCappedERC20 is ERC20, Ownable { uint256 public cap; bytes32 private constant PREFIX_TOKEN_FROZEN = keccak256('token-frozen'); bytes32 private constant KEY_ALL_TOKENS_FROZEN = keccak256('all-tokens-frozen'); event Frozen(address indexed owner); event Unfrozen(address indexed owner); constructor( string memory name, string memory symbol, uint8 decimals, uint256 capacity ) ERC20(name, symbol, decimals) Ownable() { cap = capacity; } function depositAddress(bytes32 salt) public view returns (address) { // This would be easier, cheaper, simpler, and result in globally consistent deposit addresses for any salt (all chains, all tokens). // return address(uint160(uint256(keccak256(abi.encodePacked(bytes32(0x000000000000000000000000000000000000000000000000000000000000dead), salt))))); /* Convert a hash which is bytes32 to an address which is 20-byte long according to https://docs.soliditylang.org/en/v0.8.1/control-structures.html?highlight=create2#salted-contract-creations-create2 */ return address( uint160( uint256( keccak256( abi.encodePacked( bytes1(0xff), owner, salt, keccak256(abi.encodePacked(type(Burner).creationCode, abi.encode(address(this)), salt)) ) ) ) ) ); } function mint(address account, uint256 amount) public onlyOwner { uint256 capacity = cap; require(capacity == 0 || totalSupply + amount <= capacity, 'CAP_EXCEEDED'); _mint(account, amount); } function burn(bytes32 salt) public onlyOwner { address account = depositAddress(salt); _burn(account, balanceOf[account]); } function _beforeTokenTransfer( address, address, uint256 ) internal view override { require(!EternalStorage(owner).getBool(KEY_ALL_TOKENS_FROZEN), 'IS_FROZEN'); require(!EternalStorage(owner).getBool(keccak256(abi.encodePacked(PREFIX_TOKEN_FROZEN, symbol))), 'IS_FROZEN'); } } contract AdminMultisigBase is EternalStorage { // AUDIT: slot names should be prefixed with some standard string // AUDIT: constants should be literal and their derivation should be in comments bytes32 internal constant KEY_ADMIN_EPOCH = keccak256('admin-epoch'); bytes32 internal constant PREFIX_ADMIN = keccak256('admin'); bytes32 internal constant PREFIX_ADMIN_COUNT = keccak256('admin-count'); bytes32 internal constant PREFIX_ADMIN_THRESHOLD = keccak256('admin-threshold'); bytes32 internal constant PREFIX_ADMIN_VOTE_COUNTS = keccak256('admin-vote-counts'); bytes32 internal constant PREFIX_ADMIN_VOTED = keccak256('admin-voted'); bytes32 internal constant PREFIX_IS_ADMIN = keccak256('is-admin'); modifier onlyAdmin() { uint256 adminEpoch = _adminEpoch(); require(_isAdmin(adminEpoch, msg.sender), 'NOT_ADMIN'); bytes32 topic = keccak256(msg.data); // Check that admin has not voted, then record that they have voted. require(!_hasVoted(adminEpoch, topic, msg.sender), 'VOTED'); _setHasVoted(adminEpoch, topic, msg.sender, true); // Determine the new vote count and update it. uint256 adminVoteCount = _getVoteCount(adminEpoch, topic) + uint256(1); _setVoteCount(adminEpoch, topic, adminVoteCount); // Do not proceed with operation execution if insufficient votes. if (adminVoteCount < _getAdminThreshold(adminEpoch)) return; _; // Clear vote count and voted booleans. _setVoteCount(adminEpoch, topic, uint256(0)); uint256 adminCount = _getAdminCount(adminEpoch); for (uint256 i; i < adminCount; i++) { _setHasVoted(adminEpoch, topic, _getAdmin(adminEpoch, i), false); } } /********************\ |* Pure Key Getters *| \********************/ function _getAdminKey(uint256 adminEpoch, uint256 index) internal pure returns (bytes32) { return keccak256(abi.encodePacked(PREFIX_ADMIN, adminEpoch, index)); } function _getAdminCountKey(uint256 adminEpoch) internal pure returns (bytes32) { return keccak256(abi.encodePacked(PREFIX_ADMIN_COUNT, adminEpoch)); } function _getAdminThresholdKey(uint256 adminEpoch) internal pure returns (bytes32) { return keccak256(abi.encodePacked(PREFIX_ADMIN_THRESHOLD, adminEpoch)); } function _getAdminVoteCountsKey(uint256 adminEpoch, bytes32 topic) internal pure returns (bytes32) { return keccak256(abi.encodePacked(PREFIX_ADMIN_VOTE_COUNTS, adminEpoch, topic)); } function _getAdminVotedKey( uint256 adminEpoch, bytes32 topic, address account ) internal pure returns (bytes32) { return keccak256(abi.encodePacked(PREFIX_ADMIN_VOTED, adminEpoch, topic, account)); } function _getIsAdminKey(uint256 adminEpoch, address account) internal pure returns (bytes32) { return keccak256(abi.encodePacked(PREFIX_IS_ADMIN, adminEpoch, account)); } /***********\ |* Getters *| \***********/ function _adminEpoch() internal view returns (uint256) { return getUint(KEY_ADMIN_EPOCH); } function _getAdmin(uint256 adminEpoch, uint256 index) internal view returns (address) { return getAddress(_getAdminKey(adminEpoch, index)); } function _getAdminCount(uint256 adminEpoch) internal view returns (uint256) { return getUint(_getAdminCountKey(adminEpoch)); } function _getAdminThreshold(uint256 adminEpoch) internal view returns (uint256) { return getUint(_getAdminThresholdKey(adminEpoch)); } function _getVoteCount(uint256 adminEpoch, bytes32 topic) internal view returns (uint256) { return getUint(_getAdminVoteCountsKey(adminEpoch, topic)); } function _hasVoted( uint256 adminEpoch, bytes32 topic, address account ) internal view returns (bool) { return getBool(_getAdminVotedKey(adminEpoch, topic, account)); } function _isAdmin(uint256 adminEpoch, address account) internal view returns (bool) { return getBool(_getIsAdminKey(adminEpoch, account)); } /***********\ |* Setters *| \***********/ function _setAdminEpoch(uint256 adminEpoch) internal { _setUint(KEY_ADMIN_EPOCH, adminEpoch); } function _setAdmin( uint256 adminEpoch, uint256 index, address account ) internal { _setAddress(_getAdminKey(adminEpoch, index), account); } function _setAdminCount(uint256 adminEpoch, uint256 adminCount) internal { _setUint(_getAdminCountKey(adminEpoch), adminCount); } function _setAdmins( uint256 adminEpoch, address[] memory accounts, uint256 threshold ) internal { uint256 adminLength = accounts.length; require(adminLength >= threshold, 'INV_ADMINS'); require(threshold > uint256(0), 'INV_ADMIN_THLD'); _setAdminThreshold(adminEpoch, threshold); _setAdminCount(adminEpoch, adminLength); for (uint256 i; i < adminLength; i++) { address account = accounts[i]; // Check that the account wasn't already set as an admin for this epoch. require(!_isAdmin(adminEpoch, account), 'DUP_ADMIN'); // Set this account as the i-th admin in this epoch (needed to we can clear topic votes in `onlyAdmin`). _setAdmin(adminEpoch, i, account); _setIsAdmin(adminEpoch, account, true); } } function _setAdminThreshold(uint256 adminEpoch, uint256 adminThreshold) internal { _setUint(_getAdminThresholdKey(adminEpoch), adminThreshold); } function _setVoteCount( uint256 adminEpoch, bytes32 topic, uint256 voteCount ) internal { _setUint(_getAdminVoteCountsKey(adminEpoch, topic), voteCount); } function _setHasVoted( uint256 adminEpoch, bytes32 topic, address account, bool voted ) internal { _setBool(_getAdminVotedKey(adminEpoch, topic, account), voted); } function _setIsAdmin( uint256 adminEpoch, address account, bool isAdmin ) internal { _setBool(_getIsAdminKey(adminEpoch, account), isAdmin); } } abstract contract AxelarGateway is IAxelarGateway, AdminMultisigBase { /// @dev Storage slot with the address of the current factory. `keccak256('eip1967.proxy.implementation') - 1`. bytes32 internal constant KEY_IMPLEMENTATION = bytes32(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc); // AUDIT: slot names should be prefixed with some standard string // AUDIT: constants should be literal and their derivation should be in comments bytes32 internal constant KEY_ALL_TOKENS_FROZEN = keccak256('all-tokens-frozen'); bytes32 internal constant PREFIX_COMMAND_EXECUTED = keccak256('command-executed'); bytes32 internal constant PREFIX_TOKEN_ADDRESS = keccak256('token-address'); bytes32 internal constant PREFIX_TOKEN_FROZEN = keccak256('token-frozen'); bytes32 internal constant SELECTOR_BURN_TOKEN = keccak256('burnToken'); bytes32 internal constant SELECTOR_DEPLOY_TOKEN = keccak256('deployToken'); bytes32 internal constant SELECTOR_MINT_TOKEN = keccak256('mintToken'); bytes32 internal constant SELECTOR_TRANSFER_OPERATORSHIP = keccak256('transferOperatorship'); bytes32 internal constant SELECTOR_TRANSFER_OWNERSHIP = keccak256('transferOwnership'); uint8 internal constant OLD_KEY_RETENTION = 16; modifier onlySelf() { require(msg.sender == address(this), 'NOT_SELF'); _; } /***********\ |* Getters *| \***********/ function allTokensFrozen() public view override returns (bool) { return getBool(KEY_ALL_TOKENS_FROZEN); } function implementation() public view override returns (address) { return getAddress(KEY_IMPLEMENTATION); } function tokenAddresses(string memory symbol) public view override returns (address) { return getAddress(_getTokenAddressKey(symbol)); } function tokenFrozen(string memory symbol) public view override returns (bool) { return getBool(_getFreezeTokenKey(symbol)); } function isCommandExecuted(bytes32 commandId) public view override returns (bool) { return getBool(_getIsCommandExecutedKey(commandId)); } /*******************\ |* Admin Functions *| \*******************/ function freezeToken(string memory symbol) external override onlyAdmin { _setBool(_getFreezeTokenKey(symbol), true); emit TokenFrozen(symbol); } function unfreezeToken(string memory symbol) external override onlyAdmin { _setBool(_getFreezeTokenKey(symbol), false); emit TokenUnfrozen(symbol); } function freezeAllTokens() external override onlyAdmin { _setBool(KEY_ALL_TOKENS_FROZEN, true); emit AllTokensFrozen(); } function unfreezeAllTokens() external override onlyAdmin { _setBool(KEY_ALL_TOKENS_FROZEN, false); emit AllTokensUnfrozen(); } function upgrade(address newImplementation, bytes calldata setupParams) external override onlyAdmin { emit Upgraded(newImplementation); // AUDIT: If `newImplementation.setup` performs `selfdestruct`, it will result in the loss of _this_ implementation (thereby losing the gateway) // if `upgrade` is entered within the context of _this_ implementation itself. (bool success, ) = newImplementation.delegatecall( abi.encodeWithSelector(IAxelarGateway.setup.selector, setupParams) ); require(success, 'SETUP_FAILED'); _setImplementation(newImplementation); } /**********************\ |* Internal Functions *| \**********************/ function _deployToken( string memory name, string memory symbol, uint8 decimals, uint256 cap ) internal { require(tokenAddresses(symbol) == address(0), 'TOKEN_EXIST'); bytes32 salt = keccak256(abi.encodePacked(symbol)); address token = address(new BurnableMintableCappedERC20{ salt: salt }(name, symbol, decimals, cap)); _setTokenAddress(symbol, token); emit TokenDeployed(symbol, token); } function _mintToken( string memory symbol, address account, uint256 amount ) internal { address tokenAddress = tokenAddresses(symbol); require(tokenAddress != address(0), 'TOKEN_NOT_EXIST'); BurnableMintableCappedERC20(tokenAddress).mint(account, amount); } function _burnToken(string memory symbol, bytes32 salt) internal { address tokenAddress = tokenAddresses(symbol); require(tokenAddress != address(0), 'TOKEN_NOT_EXIST'); BurnableMintableCappedERC20(tokenAddress).burn(salt); } /********************\ |* Pure Key Getters *| \********************/ function _getFreezeTokenKey(string memory symbol) internal pure returns (bytes32) { return keccak256(abi.encodePacked(PREFIX_TOKEN_FROZEN, symbol)); } function _getTokenAddressKey(string memory symbol) internal pure returns (bytes32) { return keccak256(abi.encodePacked(PREFIX_TOKEN_ADDRESS, symbol)); } function _getIsCommandExecutedKey(bytes32 commandId) internal pure returns (bytes32) { return keccak256(abi.encodePacked(PREFIX_COMMAND_EXECUTED, commandId)); } /********************\ |* Internal Getters *| \********************/ function _getChainID() internal view returns (uint256 id) { assembly { id := chainid() } } /********************\ |* Internal Setters *| \********************/ function _setTokenAddress(string memory symbol, address tokenAddr) internal { _setAddress(_getTokenAddressKey(symbol), tokenAddr); } function _setCommandExecuted(bytes32 commandId, bool executed) internal { _setBool(_getIsCommandExecutedKey(commandId), executed); } function _setImplementation(address newImplementation) internal { _setAddress(KEY_IMPLEMENTATION, newImplementation); } } contract AxelarGatewayMultisig is IAxelarGatewayMultisig, AxelarGateway { // AUDIT: slot names should be prefixed with some standard string // AUDIT: constants should be literal and their derivation should be in comments bytes32 internal constant KEY_OWNER_EPOCH = keccak256('owner-epoch'); bytes32 internal constant PREFIX_OWNER = keccak256('owner'); bytes32 internal constant PREFIX_OWNER_COUNT = keccak256('owner-count'); bytes32 internal constant PREFIX_OWNER_THRESHOLD = keccak256('owner-threshold'); bytes32 internal constant PREFIX_IS_OWNER = keccak256('is-owner'); bytes32 internal constant KEY_OPERATOR_EPOCH = keccak256('operator-epoch'); bytes32 internal constant PREFIX_OPERATOR = keccak256('operator'); bytes32 internal constant PREFIX_OPERATOR_COUNT = keccak256('operator-count'); bytes32 internal constant PREFIX_OPERATOR_THRESHOLD = keccak256('operator-threshold'); bytes32 internal constant PREFIX_IS_OPERATOR = keccak256('is-operator'); function _containsDuplicates(address[] memory accounts) internal pure returns (bool) { uint256 count = accounts.length; for (uint256 i; i < count; ++i) { for (uint256 j = i + 1; j < count; ++j) { if (accounts[i] == accounts[j]) return true; } } return false; } /************************\ |* Owners Functionality *| \************************/ /********************\ |* Pure Key Getters *| \********************/ function _getOwnerKey(uint256 ownerEpoch, uint256 index) internal pure returns (bytes32) { return keccak256(abi.encodePacked(PREFIX_OWNER, ownerEpoch, index)); } function _getOwnerCountKey(uint256 ownerEpoch) internal pure returns (bytes32) { return keccak256(abi.encodePacked(PREFIX_OWNER_COUNT, ownerEpoch)); } function _getOwnerThresholdKey(uint256 ownerEpoch) internal pure returns (bytes32) { return keccak256(abi.encodePacked(PREFIX_OWNER_THRESHOLD, ownerEpoch)); } function _getIsOwnerKey(uint256 ownerEpoch, address account) internal pure returns (bytes32) { return keccak256(abi.encodePacked(PREFIX_IS_OWNER, ownerEpoch, account)); } /***********\ |* Getters *| \***********/ function _ownerEpoch() internal view returns (uint256) { return getUint(KEY_OWNER_EPOCH); } function _getOwner(uint256 ownerEpoch, uint256 index) internal view returns (address) { return getAddress(_getOwnerKey(ownerEpoch, index)); } function _getOwnerCount(uint256 ownerEpoch) internal view returns (uint256) { return getUint(_getOwnerCountKey(ownerEpoch)); } function _getOwnerThreshold(uint256 ownerEpoch) internal view returns (uint256) { return getUint(_getOwnerThresholdKey(ownerEpoch)); } function _isOwner(uint256 ownerEpoch, address account) internal view returns (bool) { return getBool(_getIsOwnerKey(ownerEpoch, account)); } /// @dev Returns true if a sufficient quantity of `accounts` are owners in the same `ownerEpoch`, within the last `OLD_KEY_RETENTION + 1` owner epochs. function _areValidRecentOwners(address[] memory accounts) internal view returns (bool) { uint256 ownerEpoch = _ownerEpoch(); uint256 recentEpochs = OLD_KEY_RETENTION + uint256(1); uint256 lowerBoundOwnerEpoch = ownerEpoch > recentEpochs ? ownerEpoch - recentEpochs : uint256(0); while (ownerEpoch > lowerBoundOwnerEpoch) { if (_areValidOwnersInEpoch(ownerEpoch--, accounts)) return true; } return false; } /// @dev Returns true if a sufficient quantity of `accounts` are owners in the `ownerEpoch`. function _areValidOwnersInEpoch(uint256 ownerEpoch, address[] memory accounts) internal view returns (bool) { if (_containsDuplicates(accounts)) return false; uint256 threshold = _getOwnerThreshold(ownerEpoch); uint256 validSignerCount; for (uint256 i; i < accounts.length; i++) { if (_isOwner(ownerEpoch, accounts[i]) && ++validSignerCount >= threshold) return true; } return false; } /// @dev Returns the array of owners within the current `ownerEpoch`. function owners() public view override returns (address[] memory results) { uint256 ownerEpoch = _ownerEpoch(); uint256 ownerCount = _getOwnerCount(ownerEpoch); results = new address[](ownerCount); for (uint256 i; i < ownerCount; i++) { results[i] = _getOwner(ownerEpoch, i); } } /***********\ |* Setters *| \***********/ function _setOwnerEpoch(uint256 ownerEpoch) internal { _setUint(KEY_OWNER_EPOCH, ownerEpoch); } function _setOwner( uint256 ownerEpoch, uint256 index, address account ) internal { require(account != address(0), 'ZERO_ADDR'); _setAddress(_getOwnerKey(ownerEpoch, index), account); } function _setOwnerCount(uint256 ownerEpoch, uint256 ownerCount) internal { _setUint(_getOwnerCountKey(ownerEpoch), ownerCount); } function _setOwners( uint256 ownerEpoch, address[] memory accounts, uint256 threshold ) internal { uint256 accountLength = accounts.length; require(accountLength >= threshold, 'INV_OWNERS'); require(threshold > uint256(0), 'INV_OWNER_THLD'); _setOwnerThreshold(ownerEpoch, threshold); _setOwnerCount(ownerEpoch, accountLength); for (uint256 i; i < accountLength; i++) { address account = accounts[i]; // Check that the account wasn't already set as an owner for this ownerEpoch. require(!_isOwner(ownerEpoch, account), 'DUP_OWNER'); // Set this account as the i-th owner in this ownerEpoch (needed to we can get all the owners for `owners`). _setOwner(ownerEpoch, i, account); _setIsOwner(ownerEpoch, account, true); } } function _setOwnerThreshold(uint256 ownerEpoch, uint256 ownerThreshold) internal { _setUint(_getOwnerThresholdKey(ownerEpoch), ownerThreshold); } function _setIsOwner( uint256 ownerEpoch, address account, bool isOwner ) internal { _setBool(_getIsOwnerKey(ownerEpoch, account), isOwner); } /**************************\ |* Operator Functionality *| \**************************/ /********************\ |* Pure Key Getters *| \********************/ function _getOperatorKey(uint256 operatorEpoch, uint256 index) internal pure returns (bytes32) { return keccak256(abi.encodePacked(PREFIX_OPERATOR, operatorEpoch, index)); } function _getOperatorCountKey(uint256 operatorEpoch) internal pure returns (bytes32) { return keccak256(abi.encodePacked(PREFIX_OPERATOR_COUNT, operatorEpoch)); } function _getOperatorThresholdKey(uint256 operatorEpoch) internal pure returns (bytes32) { return keccak256(abi.encodePacked(PREFIX_OPERATOR_THRESHOLD, operatorEpoch)); } function _getIsOperatorKey(uint256 operatorEpoch, address account) internal pure returns (bytes32) { return keccak256(abi.encodePacked(PREFIX_IS_OPERATOR, operatorEpoch, account)); } /***********\ |* Getters *| \***********/ function _operatorEpoch() internal view returns (uint256) { return getUint(KEY_OPERATOR_EPOCH); } function _getOperator(uint256 operatorEpoch, uint256 index) internal view returns (address) { return getAddress(_getOperatorKey(operatorEpoch, index)); } function _getOperatorCount(uint256 operatorEpoch) internal view returns (uint256) { return getUint(_getOperatorCountKey(operatorEpoch)); } function _getOperatorThreshold(uint256 operatorEpoch) internal view returns (uint256) { return getUint(_getOperatorThresholdKey(operatorEpoch)); } function _isOperator(uint256 operatorEpoch, address account) internal view returns (bool) { return getBool(_getIsOperatorKey(operatorEpoch, account)); } /// @dev Returns true if a sufficient quantity of `accounts` are operator in the same `operatorEpoch`, within the last `OLD_KEY_RETENTION + 1` operator epochs. function _areValidRecentOperators(address[] memory accounts) internal view returns (bool) { uint256 operatorEpoch = _operatorEpoch(); uint256 recentEpochs = OLD_KEY_RETENTION + uint256(1); uint256 lowerBoundOperatorEpoch = operatorEpoch > recentEpochs ? operatorEpoch - recentEpochs : uint256(0); while (operatorEpoch > lowerBoundOperatorEpoch) { if (_areValidOperatorsInEpoch(operatorEpoch--, accounts)) return true; } return false; } /// @dev Returns true if a sufficient quantity of `accounts` are operator in the `operatorEpoch`. function _areValidOperatorsInEpoch(uint256 operatorEpoch, address[] memory accounts) internal view returns (bool) { if (_containsDuplicates(accounts)) return false; uint256 threshold = _getOperatorThreshold(operatorEpoch); uint256 validSignerCount; for (uint256 i; i < accounts.length; i++) { if (_isOperator(operatorEpoch, accounts[i]) && ++validSignerCount >= threshold) return true; } return false; } /// @dev Returns the array of operators within the current `operatorEpoch`. function operators() public view override returns (address[] memory results) { uint256 operatorEpoch = _operatorEpoch(); uint256 operatorCount = _getOperatorCount(operatorEpoch); results = new address[](operatorCount); for (uint256 i; i < operatorCount; i++) { results[i] = _getOperator(operatorEpoch, i); } } /***********\ |* Setters *| \***********/ function _setOperatorEpoch(uint256 operatorEpoch) internal { _setUint(KEY_OPERATOR_EPOCH, operatorEpoch); } function _setOperator( uint256 operatorEpoch, uint256 index, address account ) internal { // AUDIT: Should have `require(account != address(0), 'ZERO_ADDR');` like Singlesig? _setAddress(_getOperatorKey(operatorEpoch, index), account); } function _setOperatorCount(uint256 operatorEpoch, uint256 operatorCount) internal { _setUint(_getOperatorCountKey(operatorEpoch), operatorCount); } function _setOperators( uint256 operatorEpoch, address[] memory accounts, uint256 threshold ) internal { uint256 accountLength = accounts.length; require(accountLength >= threshold, 'INV_OPERATORS'); require(threshold > uint256(0), 'INV_OPERATOR_THLD'); _setOperatorThreshold(operatorEpoch, threshold); _setOperatorCount(operatorEpoch, accountLength); for (uint256 i; i < accountLength; i++) { address account = accounts[i]; // Check that the account wasn't already set as an operator for this operatorEpoch. require(!_isOperator(operatorEpoch, account), 'DUP_OPERATOR'); // Set this account as the i-th operator in this operatorEpoch (needed to we can get all the operators for `operators`). _setOperator(operatorEpoch, i, account); _setIsOperator(operatorEpoch, account, true); } } function _setOperatorThreshold(uint256 operatorEpoch, uint256 operatorThreshold) internal { _setUint(_getOperatorThresholdKey(operatorEpoch), operatorThreshold); } function _setIsOperator( uint256 operatorEpoch, address account, bool isOperator ) internal { _setBool(_getIsOperatorKey(operatorEpoch, account), isOperator); } /**********************\ |* Self Functionality *| \**********************/ function deployToken(bytes calldata params) external onlySelf { (string memory name, string memory symbol, uint8 decimals, uint256 cap) = abi.decode( params, (string, string, uint8, uint256) ); _deployToken(name, symbol, decimals, cap); } function mintToken(bytes calldata params) external onlySelf { (string memory symbol, address account, uint256 amount) = abi.decode(params, (string, address, uint256)); _mintToken(symbol, account, amount); } function burnToken(bytes calldata params) external onlySelf { (string memory symbol, bytes32 salt) = abi.decode(params, (string, bytes32)); _burnToken(symbol, salt); } function transferOwnership(bytes calldata params) external onlySelf { (address[] memory newOwners, uint256 newThreshold) = abi.decode(params, (address[], uint256)); uint256 ownerEpoch = _ownerEpoch(); emit OwnershipTransferred(owners(), _getOwnerThreshold(ownerEpoch), newOwners, newThreshold); _setOwnerEpoch(++ownerEpoch); _setOwners(ownerEpoch, newOwners, newThreshold); } function transferOperatorship(bytes calldata params) external onlySelf { (address[] memory newOperators, uint256 newThreshold) = abi.decode(params, (address[], uint256)); uint256 ownerEpoch = _ownerEpoch(); emit OperatorshipTransferred(operators(), _getOperatorThreshold(ownerEpoch), newOperators, newThreshold); uint256 operatorEpoch = _operatorEpoch(); _setOperatorEpoch(++operatorEpoch); _setOperators(operatorEpoch, newOperators, newThreshold); } /**************************\ |* External Functionality *| \**************************/ function setup(bytes calldata params) external override { // Prevent setup from being called on a non-proxy (the implementation). require(implementation() != address(0), 'NOT_PROXY'); ( address[] memory adminAddresses, uint256 adminThreshold, address[] memory ownerAddresses, uint256 ownerThreshold, address[] memory operatorAddresses, uint256 operatorThreshold ) = abi.decode(params, (address[], uint256, address[], uint256, address[], uint256)); uint256 adminEpoch = _adminEpoch() + uint256(1); _setAdminEpoch(adminEpoch); _setAdmins(adminEpoch, adminAddresses, adminThreshold); uint256 ownerEpoch = _ownerEpoch() + uint256(1); _setOwnerEpoch(ownerEpoch); _setOwners(ownerEpoch, ownerAddresses, ownerThreshold); uint256 operatorEpoch = _operatorEpoch() + uint256(1); _setOperatorEpoch(operatorEpoch); _setOperators(operatorEpoch, operatorAddresses, operatorThreshold); emit OwnershipTransferred(new address[](uint256(0)), uint256(0), ownerAddresses, ownerThreshold); emit OperatorshipTransferred(new address[](uint256(0)), uint256(0), operatorAddresses, operatorThreshold); } function execute(bytes calldata input) external override { (bytes memory data, bytes[] memory signatures) = abi.decode(input, (bytes, bytes[])); _execute(data, signatures); } function _execute(bytes memory data, bytes[] memory signatures) internal { uint256 signatureCount = signatures.length; address[] memory signers = new address[](signatureCount); for (uint256 i; i < signatureCount; i++) { signers[i] = ECDSA.recover(ECDSA.toEthSignedMessageHash(keccak256(data)), signatures[i]); } (uint256 chainId, bytes32[] memory commandIds, string[] memory commands, bytes[] memory params) = abi.decode( data, (uint256, bytes32[], string[], bytes[]) ); require(chainId == _getChainID(), 'INV_CHAIN'); uint256 commandsLength = commandIds.length; require(commandsLength == commands.length && commandsLength == params.length, 'INV_CMDS'); bool areValidCurrentOwners = _areValidOwnersInEpoch(_ownerEpoch(), signers); bool areValidRecentOwners = areValidCurrentOwners || _areValidRecentOwners(signers); bool areValidRecentOperators = _areValidRecentOperators(signers); for (uint256 i; i < commandsLength; i++) { bytes32 commandId = commandIds[i]; if (isCommandExecuted(commandId)) continue; /* Ignore if duplicate commandId received */ bytes4 commandSelector; bytes32 commandHash = keccak256(abi.encodePacked(commands[i])); if (commandHash == SELECTOR_DEPLOY_TOKEN) { if (!areValidRecentOwners) continue; commandSelector = AxelarGatewayMultisig.deployToken.selector; } else if (commandHash == SELECTOR_MINT_TOKEN) { if (!areValidRecentOperators && !areValidRecentOwners) continue; commandSelector = AxelarGatewayMultisig.mintToken.selector; } else if (commandHash == SELECTOR_BURN_TOKEN) { if (!areValidRecentOperators && !areValidRecentOwners) continue; commandSelector = AxelarGatewayMultisig.burnToken.selector; } else if (commandHash == SELECTOR_TRANSFER_OWNERSHIP) { if (!areValidCurrentOwners) continue; commandSelector = AxelarGatewayMultisig.transferOwnership.selector; } else if (commandHash == SELECTOR_TRANSFER_OPERATORSHIP) { if (!areValidCurrentOwners) continue; commandSelector = AxelarGatewayMultisig.transferOperatorship.selector; } else { continue; /* Ignore if unknown command received */ } // Prevent a re-entrancy from executing this command before it can be marked as successful. _setCommandExecuted(commandId, true); (bool success, ) = address(this).call(abi.encodeWithSelector(commandSelector, params[i])); _setCommandExecuted(commandId, success); if (success) { emit Executed(commandId); } } } } contract AxelarGatewayProxyMultisig is AxelarGatewayProxy { constructor(bytes memory params) { // AUDIT: constructor contains entire AxelarGatewayMultisig bytecode. Consider passing in an AxelarGatewayMultisig address. address gateway = address(new AxelarGatewayMultisig()); _setAddress(KEY_IMPLEMENTATION, gateway); (bool success, ) = gateway.delegatecall(abi.encodeWithSelector(IAxelarGateway.setup.selector, params)); require(success, 'SETUP_FAILED'); } function setup(bytes calldata params) external {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"bytes","name":"params","type":"bytes"}],"stateMutability":"nonpayable","type":"constructor"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"getAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"getBool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"getBytes","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"getInt","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"getString","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"getUint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"params","type":"bytes"}],"name":"setup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b5060405161541638038061541683398101604081905261002f91610201565b600060405161003d906101ae565b604051809103906000f080158015610059573d6000803e3d6000fd5b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60005260026020527f11141f466c69fd409e1990e063b49cd6d61ed2ecff27a2e402e259ca6b9a01a380546001600160a01b0319166001600160a01b03831617905590506000816001600160a01b0316639ded06df60e01b846040516024016100e491906102ad565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905161012291906102e0565b600060405180830381855af49150503d806000811461015d576040519150601f19603f3d011682016040523d82523d6000602084013e610162565b606091505b50509050806101a65760405162461bcd60e51b815260206004820152600c60248201526b14d155155417d1905253115160a21b604482015260640160405180910390fd5b5050506102fc565b614c56806107c083390190565b634e487b7160e01b600052604160045260246000fd5b60005b838110156101ec5781810151838201526020016101d4565b838111156101fb576000848401525b50505050565b60006020828403121561021357600080fd5b81516001600160401b038082111561022a57600080fd5b818401915084601f83011261023e57600080fd5b815181811115610250576102506101bb565b604051601f8201601f19908116603f01168101908382118183101715610278576102786101bb565b8160405282815287602084870101111561029157600080fd5b6102a28360208301602088016101d1565b979650505050505050565b60208152600082518060208401526102cc8160408501602087016101d1565b601f01601f19169190910160400192915050565b600082516102f28184602087016101d1565b9190910192915050565b6104b58061030b6000396000f3fe6080604052600436106100745760003560e01c80639ded06df1161004e5780639ded06df146101ea578063bd02d0f51461020b578063c031a18014610246578063dc97d96214610266576100b0565b806321f8a7211461012a5780637ae1cfca1461017d578063986e791a146101bd576100b0565b366100b05760405162461bcd60e51b81526020600482015260086024820152672727afa2aa2422a960c11b604482015260640160405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc600090815260026020527f11141f466c69fd409e1990e063b49cd6d61ed2ecff27a2e402e259ca6b9a01a3546001600160a01b03169036908037600080366000845af43d6000803e808015610125573d6000f35b3d6000fd5b34801561013657600080fd5b50610160610145366004610352565b6000908152600260205260409020546001600160a01b031690565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561018957600080fd5b506101ad610198366004610352565b60009081526004602052604090205460ff1690565b6040519015158152602001610174565b3480156101c957600080fd5b506101dd6101d8366004610352565b610293565b60405161017491906103b8565b3480156101f657600080fd5b506102096102053660046103d2565b5050565b005b34801561021757600080fd5b50610238610226366004610352565b60009081526020819052604090205490565b604051908152602001610174565b34801561025257600080fd5b506101dd610261366004610352565b610335565b34801561027257600080fd5b50610238610281366004610352565b60009081526005602052604090205490565b60008181526001602052604090208054606091906102b090610444565b80601f01602080910402602001604051908101604052809291908181526020018280546102dc90610444565b80156103295780601f106102fe57610100808354040283529160200191610329565b820191906000526020600020905b81548152906001019060200180831161030c57829003601f168201915b50505050509050919050565b60008181526003602052604090208054606091906102b090610444565b60006020828403121561036457600080fd5b5035919050565b6000815180845260005b8181101561039157602081850181015186830182015201610375565b818111156103a3576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006103cb602083018461036b565b9392505050565b600080602083850312156103e557600080fd5b823567ffffffffffffffff808211156103fd57600080fd5b818501915085601f83011261041157600080fd5b81358181111561042057600080fd5b86602082850101111561043257600080fd5b60209290920196919550909350505050565b600181811c9082168061045857607f821691505b6020821081141561047957634e487b7160e01b600052602260045260246000fd5b5091905056fea2646970667358221220de895ffe962788e1214df4d87d6cb2898ccd094eda688dc0ec9f1c9eabb1415064736f6c63430008090033608060405234801561001057600080fd5b50614c36806100206000396000f3fe60806040523480156200001157600080fd5b5060043610620001925760003560e01c80639ded06df11620000f0578063d1cf834f11620000a3578063d2bc37f8116200007a578063d2bc37f8146200042a578063dc97d9621462000434578063e3dfa2991462000457578063e673df8a146200046157600080fd5b8063d1cf834f14620003e5578063d26ff21014620003fc578063d289d1cb146200041357600080fd5b80639ded06df1462000301578063aa1e1f0a1462000318578063affe39c1146200036c578063bd02d0f51462000385578063c031a18014620003b7578063c987336c14620003ce57600080fd5b806360c6ff43116200014957806360c6ff431462000248578063646c5d34146200025f5780637ae1cfca14620002765780637b1b769e14620002ad578063935b13f614620002c4578063986e791a14620002db57600080fd5b8063037699c1146200019757806309c5eabe14620001b057806321f8a72114620001c757806334ff698314620002105780633cd6ee6d14620002275780635c60da1b146200023e575b600080fd5b620001ae620001a836600462002dd9565b6200046b565b005b620001ae620001c136600462002dd9565b620004bd565b620001f3620001d836600462002e1e565b6000908152600260205260409020546001600160a01b031690565b6040516001600160a01b0390911681526020015b60405180910390f35b620001ae6200022136600462002f07565b620004de565b620001ae6200023836600462002dd9565b6200066c565b620001f3620006b7565b620001ae6200025936600462002dd9565b6200070e565b620001ae6200027036600462002f07565b6200075c565b6200029c6200028736600462002e1e565b60009081526004602052604090205460ff1690565b604051901515815260200162000207565b6200029c620002be36600462002f07565b620008da565b620001f3620002d536600462002f07565b620008f1565b620002f2620002ec36600462002e1e565b62000902565b60405162000207919062002f9c565b620001ae6200031236600462002dd9565b620009ac565b7f75a31d1ce8e5f9892188befc328d3b9bd3fa5037457e881abc21f388471b8d9660005260046020527fa0b596b8942d6ef5cc77ce0ad89a75f0bfcc7f0132cd8db58e8449dcf04a858a5460ff166200029c565b6200037662000ba6565b60405162000207919062002ff7565b620003a86200039636600462002e1e565b60009081526020819052604090205490565b60405190815260200162000207565b620002f2620003c836600462002e1e565b62000c6d565b620001ae620003df36600462003022565b62000c8c565b620001ae620003f636600462002dd9565b62000eec565b6200029c6200040d36600462002e1e565b62000fa8565b620001ae6200042436600462002dd9565b62000fb9565b620001ae62001083565b620003a86200044536600462002e1e565b60009081526005602052604090205490565b620001ae620011ff565b620003766200137b565b333014620004965760405162461bcd60e51b81526004016200048d906200307c565b60405180910390fd5b600080620004a7838501856200309e565b91509150620004b782826200143c565b50505050565b600080620004ce838501856200310c565b91509150620004b78282620014f6565b6000620004ea62001a10565b9050620004f8813362001a5e565b620005175760405162461bcd60e51b81526004016200048d90620031ef565b600080366040516200052b92919062003212565b604051809103902090506200054282823362001a77565b15620005625760405162461bcd60e51b81526004016200048d9062003222565b62000571828233600162001a92565b6000600162000581848462001aaa565b6200058d919062003257565b90506200059c83838362001abc565b620005a78362001ae4565b811015620005b55750505050565b620005cc620005c48562001af5565b600062001b49565b83604051620005dc919062003272565b604051908190038120907f5327e3af9cd2d5c19a8dff23ef487d7a4d5f6fc985464f1792a33c212057598990600090a26200061a8383600062001abc565b6000620006278462001b69565b905060005b8181101562000664576200064f858562000647888562001b7a565b600062001a92565b806200065b8162003290565b9150506200062c565b505050505050565b3330146200068e5760405162461bcd60e51b81526004016200048d906200307c565b6000808080620006a185870187620032ae565b9350935093509350620006648484848462001b8c565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60005260026020527f11141f466c69fd409e1990e063b49cd6d61ed2ecff27a2e402e259ca6b9a01a3546001600160a01b031690565b333014620007305760405162461bcd60e51b81526004016200048d906200307c565b60008080620007428486018662003339565b9250925092506200075583838362001ca3565b5050505050565b60006200076862001a10565b905062000776813362001a5e565b620007955760405162461bcd60e51b81526004016200048d90620031ef565b60008036604051620007a992919062003212565b60405180910390209050620007c082823362001a77565b15620007e05760405162461bcd60e51b81526004016200048d9062003222565b620007ef828233600162001a92565b60006001620007ff848462001aaa565b6200080b919062003257565b90506200081a83838362001abc565b620008258362001ae4565b811015620008335750505050565b6200084a620008428562001af5565b600162001b49565b836040516200085a919062003272565b604051908190038120907f11260c92ecb021c33706db3a9699410f343d5f2175201a4551fe7634347a0cf190600090a2620008988383600062001abc565b6000620008a58462001b69565b905060005b818110156200066457620008c5858562000647888562001b7a565b80620008d18162003290565b915050620008aa565b6000620008eb620002878362001af5565b92915050565b6000620008eb620001d88362001d5c565b6000818152600160205260409020805460609190620009219062003398565b80601f01602080910402602001604051908101604052809291908181526020018280546200094f9062003398565b8015620009a05780601f106200097457610100808354040283529160200191620009a0565b820191906000526020600020905b8154815290600101906020018083116200098257829003601f168201915b50505050509050919050565b6000620009b8620006b7565b6001600160a01b03161415620009fd5760405162461bcd60e51b81526020600482015260096024820152684e4f545f50524f585960b81b60448201526064016200048d565b6000808080808062000a12878901896200344d565b9550955095509550955095506000600162000a2c62001a10565b62000a38919062003257565b905062000a8c817fd51dc9b187568bb94760866e1d0d066ca470037d2d331afb1a02ec74bfb8990c60009081526020527ff8d0c05cd32e3272241fdc9d5839565f8bcf94139cb4bd09e230e1b57a60ddc255565b62000a9981888862001d96565b6000600162000aa762001ed7565b62000ab3919062003257565b905062000ac08162001f25565b62000acd81878762001f72565b6000600162000adb620020b3565b62000ae7919062003257565b905062000af48162002101565b62000b018186866200214e565b60408051600080825260208201928390527fd167b96814cd24898418cc293e8d47d54afe6dcf0631283f0830e1eae621f6bd9262000b459291908b908b90620034fa565b60405180910390a160408051600080825260208201928390527fe7475da747ead33c03118a4b2cca5e521e930dd8ddc556751fe12d1e8395db2c9262000b9192919089908990620034fa565b60405180910390a15050505050505050505050565b6060600062000bb462001ed7565b9050600062000bc38262002298565b9050806001600160401b0381111562000be05762000be062002e38565b60405190808252806020026020018201604052801562000c0a578160200160208202803683370190505b50925060005b8181101562000c675762000c258382620022a9565b84828151811062000c3a5762000c3a6200353b565b6001600160a01b03909216602092830291909101909101528062000c5e8162003290565b91505062000c10565b50505090565b6000818152600360205260409020805460609190620009219062003398565b600062000c9862001a10565b905062000ca6813362001a5e565b62000cc55760405162461bcd60e51b81526004016200048d90620031ef565b6000803660405162000cd992919062003212565b6040518091039020905062000cf082823362001a77565b1562000d105760405162461bcd60e51b81526004016200048d9062003222565b62000d1f828233600162001a92565b6000600162000d2f848462001aaa565b62000d3b919062003257565b905062000d4a83838362001abc565b62000d558362001ae4565b81101562000d6557505050505050565b6040516001600160a01b038716907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a26000866001600160a01b0316639ded06df60e01b878760405160240162000dc292919062003551565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905162000e02919062003272565b600060405180830381855af49150503d806000811462000e3f576040519150601f19603f3d011682016040523d82523d6000602084013e62000e44565b606091505b505090508062000e865760405162461bcd60e51b815260206004820152600c60248201526b14d155155417d1905253115160a21b60448201526064016200048d565b62000e9187620022bb565b5062000ea08383600062001abc565b600062000ead8462001b69565b905060005b8181101562000ee25762000ecd858562000647888562001b7a565b8062000ed98162003290565b91505062000eb2565b5050505050505050565b33301462000f0e5760405162461bcd60e51b81526004016200048d906200307c565b60008062000f1f8385018562003580565b91509150600062000f2f62001ed7565b90507fd167b96814cd24898418cc293e8d47d54afe6dcf0631283f0830e1eae621f6bd62000f5c62000ba6565b62000f6783620022e7565b858560405162000f7b9493929190620034fa565b60405180910390a162000f9b62000f928262003290565b91508162001f25565b6200075581848462001f72565b6000620008eb6200028783620022f8565b33301462000fdb5760405162461bcd60e51b81526004016200048d906200307c565b60008062000fec8385018562003580565b91509150600062000ffc62001ed7565b90507fe7475da747ead33c03118a4b2cca5e521e930dd8ddc556751fe12d1e8395db2c620010296200137b565b620010348362002334565b8585604051620010489493929190620034fa565b60405180910390a160006200105c620020b3565b9050620010766200106d8262003290565b91508162002101565b620006648185856200214e565b60006200108f62001a10565b90506200109d813362001a5e565b620010bc5760405162461bcd60e51b81526004016200048d90620031ef565b60008036604051620010d092919062003212565b60405180910390209050620010e782823362001a77565b15620011075760405162461bcd60e51b81526004016200048d9062003222565b62001116828233600162001a92565b6000600162001126848462001aaa565b62001132919062003257565b90506200114183838362001abc565b6200114c8362001ae4565b8110156200115957505050565b620011867f75a31d1ce8e5f9892188befc328d3b9bd3fa5037457e881abc21f388471b8d96600162001b49565b6040517f9f428b56ca209118783db391e8a5a62827b6b218add33411061060d308af6ead90600090a1620011bd8383600062001abc565b6000620011ca8462001b69565b905060005b818110156200075557620011ea858562000647888562001b7a565b80620011f68162003290565b915050620011cf565b60006200120b62001a10565b905062001219813362001a5e565b620012385760405162461bcd60e51b81526004016200048d90620031ef565b600080366040516200124c92919062003212565b604051809103902090506200126382823362001a77565b15620012835760405162461bcd60e51b81526004016200048d9062003222565b62001292828233600162001a92565b60006001620012a2848462001aaa565b620012ae919062003257565b9050620012bd83838362001abc565b620012c88362001ae4565b811015620012d557505050565b620013027f75a31d1ce8e5f9892188befc328d3b9bd3fa5037457e881abc21f388471b8d96600062001b49565b6040517f0e821ff109470f6aa1aebb161aa0e7328b1a8552aa48e09ed2d03184ecece9a690600090a1620013398383600062001abc565b6000620013468462001b69565b905060005b81811015620007555762001366858562000647888562001b7a565b80620013728162003290565b9150506200134b565b6060600062001389620020b3565b90506000620013988262002345565b9050806001600160401b03811115620013b557620013b562002e38565b604051908082528060200260200182016040528015620013df578160200160208202803683370190505b50925060005b8181101562000c6757620013fa838262002356565b8482815181106200140f576200140f6200353b565b6001600160a01b039092166020928302919091019091015280620014338162003290565b915050620013e5565b60006200144983620008f1565b90506001600160a01b038116620014955760405162461bcd60e51b815260206004820152600f60248201526e1513d2d15397d393d517d1561254d5608a1b60448201526064016200048d565b6040516308a1eee160e01b8152600481018390526001600160a01b038216906308a1eee190602401600060405180830381600087803b158015620014d857600080fd5b505af1158015620014ed573d6000803e3d6000fd5b50505050505050565b80516000816001600160401b0381111562001515576200151562002e38565b6040519080825280602002602001820160405280156200153f578160200160208202803683370190505b50905060005b82811015620015c9576200158762001564868051906020012062002368565b8583815181106200157957620015796200353b565b6020026020010151620023a4565b8282815181106200159c576200159c6200353b565b6001600160a01b039092166020928302919091019091015280620015c08162003290565b91505062001545565b5060008060008087806020019051810190620015e691906200372d565b9350935093509350620015f64690565b8414620016325760405162461bcd60e51b815260206004820152600960248201526824a72b2fa1a420a4a760b91b60448201526064016200048d565b8251825181148015620016455750815181145b6200167e5760405162461bcd60e51b8152602060048201526008602482015267494e565f434d445360c01b60448201526064016200048d565b6000620016956200168e62001ed7565b8862002549565b905060008180620016ac5750620016ac88620025f8565b90506000620016bb896200267e565b905060005b8481101562001a01576000888281518110620016e057620016e06200353b565b60200260200101519050620016f58162000fa8565b15620017025750620019ec565b6000808984815181106200171a576200171a6200353b565b602002602001015160405160200162001734919062003272565b6040516020818303038152906040528051906020012090507f5763814b98a3aa86f212797af3273868b5dd6e2a532d764a79b98ca859e7bbad8114156200179457856200178457505050620019ec565b633cd6ee6d60e01b9150620018d7565b7fec78d9c22c08bb9f0ecd5d95571ae83e3f22219c5a9278c3270691d50abfd91b811415620017e95784158015620017ca575085155b15620017d957505050620019ec565b6360c6ff4360e01b9150620018d7565b7fda199c0e76f665e0450020791c7f8eacc75f3cdbace313272c28f93e5390b62c8114156200183e57841580156200181f575085155b156200182e57505050620019ec565b63037699c160e01b9150620018d7565b7f1d4a390f291e2e1f29874769efdef47ddad94d76f77ff516fad206a385e8995f8114156200188657866200187657505050620019ec565b63d1cf834f60e01b9150620018d7565b7fb460dcb6fd5797fc0e7ea0f13406c80d30702ba7f73a42bd91394775dcbca718811415620018ce5786620018be57505050620019ec565b63d289d1cb60e01b9150620018d7565b505050620019ec565b620018e4836001620026f9565b6000306001600160a01b0316838b87815181106200190657620019066200353b565b602002602001015160405160240162001920919062002f9c565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252905162001960919062003272565b6000604051808303816000865af19150503d80600081146200199f576040519150601f19603f3d011682016040523d82523d6000602084013e620019a4565b606091505b50509050620019b48482620026f9565b8015620019e75760405184907fa74c8847d513feba22a0f0cb38d53081abf97562cdb293926ba243689e7c41ca90600090a25b505050505b80620019f88162003290565b915050620016c0565b50505050505050505050505050565b7fd51dc9b187568bb94760866e1d0d066ca470037d2d331afb1a02ec74bfb8990c60009081526020527ff8d0c05cd32e3272241fdc9d5839565f8bcf94139cb4bd09e230e1b57a60ddc25490565b600062001a706200028784846200270c565b9392505050565b600062001a8a6200028785858562002763565b949350505050565b620004b762001aa385858562002763565b8262001b49565b600062001a70620003968484620027d7565b62001adf62001acc8484620027d7565b8260009182526020829052604090912055565b505050565b6000620008eb62000396836200281a565b60007f1a7261d3a36c4ce4235d10859911c9444a6963a3591ec5725b96871d9810626b8260405160200162001b2c92919062003825565b604051602081830303815290604052805190602001209050919050565b600091825260046020526040909120805460ff1916911515919091179055565b6000620008eb620003968362002856565b600062001a70620001d8848462002892565b600062001b9984620008f1565b6001600160a01b03161462001bdf5760405162461bcd60e51b815260206004820152600b60248201526a1513d2d15397d1561254d560aa1b60448201526064016200048d565b60008360405160200162001bf4919062003272565b6040516020818303038152906040528051906020012090506000818686868660405162001c219062002d80565b62001c3094939291906200384d565b8190604051809103906000f590508015801562001c51573d6000803e3d6000fd5b50905062001c608582620028d5565b7fbf90b5a1ec9763e8bf4b9245cef0c28db92bab309fc2c5177f17814f38246938858260405162001c939291906200388d565b60405180910390a1505050505050565b600062001cb084620008f1565b90506001600160a01b03811662001cfc5760405162461bcd60e51b815260206004820152600f60248201526e1513d2d15397d393d517d1561254d5608a1b60448201526064016200048d565b6040516340c10f1960e01b81526001600160a01b038481166004830152602482018490528216906340c10f1990604401600060405180830381600087803b15801562001d4757600080fd5b505af115801562000ee2573d6000803e3d6000fd5b60007fc4e632779a6a7838736dd7e5e6a0eadf171dd37dfb6230720e265576dfcf42bb8260405160200162001b2c92919062003825565b50565b81518181101562001dd75760405162461bcd60e51b815260206004820152600a602482015269494e565f41444d494e5360b01b60448201526064016200048d565b6000821162001e1a5760405162461bcd60e51b815260206004820152600e60248201526d12539597d05113525397d512131160921b60448201526064016200048d565b62001e268483620028eb565b62001e328482620028fa565b60005b818110156200075557600084828151811062001e555762001e556200353b565b6020026020010151905062001e6b868262001a5e565b1562001ea65760405162461bcd60e51b8152602060048201526009602482015268222aa82fa0a226a4a760b91b60448201526064016200048d565b62001eb386838362002909565b62001ec18682600162002919565b508062001ece8162003290565b91505062001e35565b7f67cbdff49954077d2dd5637524b03bfe3e6506d456859017a888fad567e1af0360009081526020527f06f01c2f096e745c2a207fbf93babd5e7ee6acfd26f0f34a0e4ac68373c21d0e5490565b7f67cbdff49954077d2dd5637524b03bfe3e6506d456859017a888fad567e1af0360009081526020527f06f01c2f096e745c2a207fbf93babd5e7ee6acfd26f0f34a0e4ac68373c21d0e55565b81518181101562001fb35760405162461bcd60e51b815260206004820152600a602482015269494e565f4f574e45525360b01b60448201526064016200048d565b6000821162001ff65760405162461bcd60e51b815260206004820152600e60248201526d12539597d3d5d3915497d512131160921b60448201526064016200048d565b62002002848362002929565b6200200e848262002938565b60005b81811015620007555760008482815181106200203157620020316200353b565b6020026020010151905062002047868262002947565b15620020825760405162461bcd60e51b8152602060048201526009602482015268222aa82fa7aba722a960b91b60448201526064016200048d565b6200208f86838362002959565b6200209d86826001620029ad565b5080620020aa8162003290565b91505062002011565b7f5369fb791f26307f8e69b07625302ccac6930af09ab22d753b17d2042e9992e760009081526020527f07174c149a4f7627ac1dd39b679bd42f12fc4e8d7e850b055662bbee7188da105490565b7f5369fb791f26307f8e69b07625302ccac6930af09ab22d753b17d2042e9992e760009081526020527f07174c149a4f7627ac1dd39b679bd42f12fc4e8d7e850b055662bbee7188da1055565b815181811015620021925760405162461bcd60e51b815260206004820152600d60248201526c494e565f4f50455241544f525360981b60448201526064016200048d565b60008211620021d85760405162461bcd60e51b815260206004820152601160248201527012539597d3d41154905513d497d5121311607a1b60448201526064016200048d565b620021e48483620029bd565b620021f08482620029cc565b60005b81811015620007555760008482815181106200221357620022136200353b565b60200260200101519050620022298682620029db565b15620022675760405162461bcd60e51b815260206004820152600c60248201526b222aa82fa7a822a920aa27a960a11b60448201526064016200048d565b62002274868383620029ed565b6200228286826001620029fd565b50806200228f8162003290565b915050620021f3565b6000620008eb620003968362002a0d565b600062001a70620001d8848462002a49565b62001d937f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8262002a8c565b6000620008eb620003968362002aba565b604080517f957705a374326b30f4a1069c936d736cc9993ed6c820b4e0e2fd94a8beca0d1d602082015290810182905260009060600162001b2c565b6000620008eb620003968362002af6565b6000620008eb620003968362002b32565b600062001a70620001d8848462002b6e565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c0162001b2c565b60008151604114620023e35760405162461bcd60e51b815260206004820152600760248201526624a72b2fa622a760c91b60448201526064016200048d565b60208201516040830151606084015160001a7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08211156200244f5760405162461bcd60e51b8152602060048201526005602482015264494e565f5360d81b60448201526064016200048d565b8060ff16601b14806200246557508060ff16601c145b6200249b5760405162461bcd60e51b815260206004820152600560248201526424a72b2fab60d91b60448201526064016200048d565b6040805160008082526020820180845289905260ff841692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015620024f0573d6000803e3d6000fd5b505050602060405103519450846001600160a01b03161415620025405760405162461bcd60e51b8152602060048201526007602482015266494e565f53494760c81b60448201526064016200048d565b50505092915050565b6000620025568262002bb1565b156200256557506000620008eb565b60006200257284620022e7565b90506000805b8451811015620025ec57620025aa868683815181106200259c576200259c6200353b565b602002602001015162002947565b8015620025c4575082620025be8362003290565b92508210155b15620025d75760019350505050620008eb565b80620025e38162003290565b91505062002578565b50600095945050505050565b6000806200260562001ed7565b90506000620026176001601062003257565b905060008183116200262b57600062002637565b620026378284620038b9565b90505b8083111562002673576200265c836200265381620038d3565b94508662002549565b156200266d57506001949350505050565b6200263a565b506000949350505050565b6000806200268b620020b3565b905060006200269d6001601062003257565b90506000818311620026b1576000620026bd565b620026bd8284620038b9565b90505b808311156200267357620026e283620026d981620038d3565b94508662002c6b565b15620026f357506001949350505050565b620026c0565b6200270862001aa383620022f8565b5050565b60007f63fa879cb478fddf1de08d49e29115fb768866711bc799ff9ab419a7f16c9afb83836040516020016200274593929190620038ed565b60405160208183030381529060405280519060200120905092915050565b604080517f3ced7a8caf1111e0fbf4b784c5b41aebd0f2389d9f2f64d5c3424aeed3adbd3c6020820152908101849052606080820184905282901b6bffffffffffffffffffffffff191660808201526000906094016040516020818303038152906040528051906020012090509392505050565b604080517fbaea1c6c0f16a0a340b10a9e980806696a68ddbb5e8361fd64630dd21abf515f60208201529081018390526060810182905260009060800162002745565b604080517f79bd914addd90bd67ad800bf0230bb85ffdef5aeba5fd8249f116d3f17f4fb4b602082015290810182905260009060600162001b2c565b604080517f05112ef894367de1270cfae12afcd2285c225830eb8f74e7e938f721bb510cba602082015290810182905260009060600162001b2c565b604080517ff23ec0bb4210edd5cba85afd05127efcd2fc6a781bfed49188da1081670b22d860208201529081018390526060810182905260009060800162002745565b62002708620028e48362001d5c565b8262002a8c565b6200270862001acc836200281a565b6200270862001acc8362002856565b62001adf620028e4848462002892565b62001adf62001aa384846200270c565b6200270862001acc8362002aba565b6200270862001acc8362002a0d565b600062001a7062000287848462002d0e565b6001600160a01b0381166200299d5760405162461bcd60e51b81526020600482015260096024820152682d22a927afa0a2222960b91b60448201526064016200048d565b62001adf620028e4848462002a49565b62001adf62001aa3848462002d0e565b6200270862001acc8362002af6565b6200270862001acc8362002b32565b600062001a7062000287848462002d47565b62001adf620028e4848462002b6e565b62001adf62001aa3848462002d47565b604080517f4ededbb904acd1258c7b9a6b12f5a8a8870a8ec295809cf35dc1f098018d4d20602082015290810182905260009060600162001b2c565b604080517f02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c060208201529081018390526060810182905260009060800162002745565b60009182526002602052604090912080546001600160a01b0319166001600160a01b03909216919091179055565b604080517f2bd864201f87ce8cc2d875453b39cc3e981d8ee12e4b7d4b7492fd9404bd8229602082015290810182905260009060600162001b2c565b604080517fc0e594a04ce768761133f7238cd95a55441f8ee2d50a03e7d5c44fb26c04d76f602082015290810182905260009060600162001b2c565b604080517f6199febc552b750a8cf661862e77cb2dbed9f3fb6fcc10bd34f8ff9e1992362b602082015290810182905260009060600162001b2c565b604080517f46a52cf33029de9f84853745a87af28464c80bf0346df1b32e205fc73319f62260208201529081018390526060810182905260009060800162002745565b8051600090815b8181101562002c6157600062002bd082600162003257565b90505b8281101562002c4d5784818151811062002bf15762002bf16200353b565b60200260200101516001600160a01b031685838151811062002c175762002c176200353b565b60200260200101516001600160a01b0316141562002c3a57506001949350505050565b62002c458162003290565b905062002bd3565b5062002c598162003290565b905062002bb8565b5060009392505050565b600062002c788262002bb1565b1562002c8757506000620008eb565b600062002c948462002334565b90506000805b8451811015620025ec5762002ccc8686838151811062002cbe5762002cbe6200353b565b6020026020010151620029db565b801562002ce657508262002ce08362003290565b92508210155b1562002cf95760019350505050620008eb565b8062002d058162003290565b91505062002c9a565b60007fffbbd206dad2a77ed223a0ff3d2dcac502bc8c9a91fa18140757561e84f365c083836040516020016200274593929190620038ed565b60007f934404a25b467ba4b73107cf91baadb1313f82988678493324b442216995358683836040516020016200274593929190620038ed565b6112eb806200391683390190565b60008083601f84011262002da157600080fd5b5081356001600160401b0381111562002db957600080fd5b60208301915083602082850101111562002dd257600080fd5b9250929050565b6000806020838503121562002ded57600080fd5b82356001600160401b0381111562002e0457600080fd5b62002e128582860162002d8e565b90969095509350505050565b60006020828403121562002e3157600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171562002e795762002e7962002e38565b604052919050565b60006001600160401b0382111562002e9d5762002e9d62002e38565b50601f01601f191660200190565b600082601f83011262002ebd57600080fd5b813562002ed462002ece8262002e81565b62002e4e565b81815284602083860101111562002eea57600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121562002f1a57600080fd5b81356001600160401b0381111562002f3157600080fd5b62001a8a8482850162002eab565b60005b8381101562002f5c57818101518382015260200162002f42565b83811115620004b75750506000910152565b6000815180845262002f8881602086016020860162002f3f565b601f01601f19169290920160200192915050565b60208152600062001a70602083018462002f6e565b600081518084526020808501945080840160005b8381101562002fec5781516001600160a01b03168752958201959082019060010162002fc5565b509495945050505050565b60208152600062001a70602083018462002fb1565b6001600160a01b038116811462001d9357600080fd5b6000806000604084860312156200303857600080fd5b833562003045816200300c565b925060208401356001600160401b038111156200306157600080fd5b6200306f8682870162002d8e565b9497909650939450505050565b6020808252600890820152672727aa2fa9a2a62360c11b604082015260600190565b60008060408385031215620030b257600080fd5b82356001600160401b03811115620030c957600080fd5b620030d78582860162002eab565b95602094909401359450505050565b60006001600160401b0382111562003102576200310262002e38565b5060051b60200190565b600080604083850312156200312057600080fd5b82356001600160401b03808211156200313857600080fd5b620031468683870162002eab565b93506020915081850135818111156200315e57600080fd5b8501601f810187136200317057600080fd5b80356200318162002ece82620030e6565b81815260059190911b82018401908481019089831115620031a157600080fd5b8584015b83811015620031de57803586811115620031bf5760008081fd5b620031cf8c898389010162002eab565b845250918601918601620031a5565b508096505050505050509250929050565b6020808252600990820152682727aa2fa0a226a4a760b91b604082015260600190565b8183823760009101908152919050565b6020808252600590820152641593d5115160da1b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082198211156200326d576200326d62003241565b500190565b600082516200328681846020870162002f3f565b9190910192915050565b6000600019821415620032a757620032a762003241565b5060010190565b60008060008060808587031215620032c557600080fd5b84356001600160401b0380821115620032dd57600080fd5b620032eb8883890162002eab565b955060208701359150808211156200330257600080fd5b50620033118782880162002eab565b935050604085013560ff811681146200332957600080fd5b9396929550929360600135925050565b6000806000606084860312156200334f57600080fd5b83356001600160401b038111156200336657600080fd5b620033748682870162002eab565b935050602084013562003387816200300c565b929592945050506040919091013590565b600181811c90821680620033ad57607f821691505b60208210811415620033cf57634e487b7160e01b600052602260045260246000fd5b50919050565b600082601f830112620033e757600080fd5b81356020620033fa62002ece83620030e6565b82815260059290921b840181019181810190868411156200341a57600080fd5b8286015b848110156200344257803562003434816200300c565b83529183019183016200341e565b509695505050505050565b60008060008060008060c087890312156200346757600080fd5b86356001600160401b03808211156200347f57600080fd5b6200348d8a838b01620033d5565b9750602089013596506040890135915080821115620034ab57600080fd5b620034b98a838b01620033d5565b9550606089013594506080890135915080821115620034d757600080fd5b50620034e689828a01620033d5565b92505060a087013590509295509295509295565b6080815260006200350f608083018762002fb1565b856020840152828103604084015262003529818662002fb1565b91505082606083015295945050505050565b634e487b7160e01b600052603260045260246000fd5b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b600080604083850312156200359457600080fd5b82356001600160401b03811115620035ab57600080fd5b620030d785828601620033d5565b6000620035ca62002ece8462002e81565b9050828152838383011115620035df57600080fd5b62001a7083602083018462002f3f565b600082601f8301126200360157600080fd5b815160206200361462002ece83620030e6565b82815260059290921b840181019181810190868411156200363457600080fd5b8286015b84811015620034425780516001600160401b03811115620036595760008081fd5b8701603f810189136200366c5760008081fd5b6200367f898683015160408401620035b9565b84525091830191830162003638565b600082601f830112620036a057600080fd5b81516020620036b362002ece83620030e6565b82815260059290921b84018101918181019086841115620036d357600080fd5b8286015b84811015620034425780516001600160401b03811115620036f85760008081fd5b8701603f810189136200370b5760008081fd5b6200371e898683015160408401620035b9565b845250918301918301620036d7565b600080600080608085870312156200374457600080fd5b845193506020808601516001600160401b03808211156200376457600080fd5b818801915088601f8301126200377957600080fd5b81516200378a62002ece82620030e6565b81815260059190911b8301840190848101908b831115620037aa57600080fd5b938501935b82851015620037ca57845182529385019390850190620037af565b60408b01519098509450505080831115620037e457600080fd5b620037f289848a01620035ef565b945060608801519250808311156200380957600080fd5b505062003819878288016200368e565b91505092959194509250565b828152600082516200383f81602085016020870162002f3f565b919091016020019392505050565b60808152600062003862608083018762002f6e565b828103602084015262003876818762002f6e565b60ff95909516604084015250506060015292915050565b604081526000620038a2604083018562002f6e565b905060018060a01b03831660208301529392505050565b600082821015620038ce57620038ce62003241565b500390565b600081620038e557620038e562003241565b506000190190565b928352602083019190915260601b6bffffffffffffffffffffffff191660408201526054019056fe60a06040523480156200001157600080fd5b50604051620012eb380380620012eb83398101604081905262000034916200022e565b83838382600390805190602001906200004f929190620000bb565b50815162000065906004906020850190620000bb565b5060ff166080525050600580546001600160a01b031916339081179091556040516000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a360065550620002f6915050565b828054620000c990620002b9565b90600052602060002090601f016020900481019282620000ed576000855562000138565b82601f106200010857805160ff191683800117855562000138565b8280016001018555821562000138579182015b82811115620001385782518255916020019190600101906200011b565b50620001469291506200014a565b5090565b5b808211156200014657600081556001016200014b565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200018957600080fd5b81516001600160401b0380821115620001a657620001a662000161565b604051601f8301601f19908116603f01168101908282118183101715620001d157620001d162000161565b81604052838152602092508683858801011115620001ee57600080fd5b600091505b83821015620002125785820183015181830184015290820190620001f3565b83821115620002245760008385830101525b9695505050505050565b600080600080608085870312156200024557600080fd5b84516001600160401b03808211156200025d57600080fd5b6200026b8883890162000177565b955060208701519150808211156200028257600080fd5b50620002918782880162000177565b935050604085015160ff81168114620002a957600080fd5b6060959095015193969295505050565b600181811c90821680620002ce57607f821691505b60208210811415620002f057634e487b7160e01b600052602260045260246000fd5b50919050565b608051610fd96200031260003960006101950152610fd96000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806339509351116100a257806395d89b411161007157806395d89b4114610256578063a457c2d71461025e578063a9059cbb14610271578063dd62ed3e14610284578063f2fde38b146102af57600080fd5b806339509351146101fd57806340c10f191461021057806370a08231146102235780638da5cb5b1461024357600080fd5b806323b872dd116100de57806323b872dd1461017d578063313ce5671461019057806331eecaf4146101c9578063355274ea146101f457600080fd5b806306fdde031461011057806308a1eee11461012e578063095ea7b31461014357806318160ddd14610166575b600080fd5b6101186102c2565b6040516101259190610bf8565b60405180910390f35b61014161013c366004610c2b565b610350565b005b610156610151366004610c60565b6103b9565b6040519015158152602001610125565b61016f60025481565b604051908152602001610125565b61015661018b366004610c8a565b6103cf565b6101b77f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610125565b6101dc6101d7366004610c2b565b610421565b6040516001600160a01b039091168152602001610125565b61016f60065481565b61015661020b366004610c60565b610505565b61014161021e366004610c60565b61053c565b61016f610231366004610cc6565b60006020819052908152604090205481565b6005546101dc906001600160a01b031681565b6101186105cd565b61015661026c366004610c60565b6105da565b61015661027f366004610c60565b610611565b61016f610292366004610ce8565b600160209081526000928352604080842090915290825290205481565b6101416102bd366004610cc6565b61061e565b600380546102cf90610d1b565b80601f01602080910402602001604051908101604052809291908181526020018280546102fb90610d1b565b80156103485780601f1061031d57610100808354040283529160200191610348565b820191906000526020600020905b81548152906001019060200180831161032b57829003601f168201915b505050505081565b6005546001600160a01b031633146103835760405162461bcd60e51b815260040161037a90610d56565b60405180910390fd5b600061038e82610421565b6001600160a01b0381166000908152602081905260409020549091506103b59082906106ca565b5050565b60006103c6338484610788565b50600192915050565b60006103dc848484610836565b6001600160a01b038416600090815260016020908152604080832033808552925290912054610417918691610412908690610d8f565b610788565b5060019392505050565b6005546040516000916001600160f81b0319916001600160a01b0390911690849061044e60208201610bbc565b601f1982820381018352601f9091011660408181523060208301520160408051601f198184030181529082905261048a92918890602001610da6565b604051602081830303815290604052805190602001206040516020016104e794939291906001600160f81b031994909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051601f19818403018152919052805160209091012092915050565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916103c6918590610412908690610ddb565b6005546001600160a01b031633146105665760405162461bcd60e51b815260040161037a90610d56565b600654801580610583575080826002546105809190610ddb565b11155b6105be5760405162461bcd60e51b815260206004820152600c60248201526b10d05417d15610d15151115160a21b604482015260640161037a565b6105c8838361092e565b505050565b600480546102cf90610d1b565b3360008181526001602090815260408083206001600160a01b038716845290915281205490916103c6918590610412908690610d8f565b60006103c6338484610836565b6005546001600160a01b031633146106485760405162461bcd60e51b815260040161037a90610d56565b6001600160a01b03811661066e5760405162461bcd60e51b815260040161037a90610df3565b6005546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600580546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b0382166106f05760405162461bcd60e51b815260040161037a90610df3565b6106fc826000836109e2565b6001600160a01b03821660009081526020819052604081208054839290610724908490610d8f565b92505081905550806002600082825461073d9190610d8f565b90915550506040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b6001600160a01b0383166107ae5760405162461bcd60e51b815260040161037a90610df3565b6001600160a01b0382166107d45760405162461bcd60e51b815260040161037a90610df3565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b03831661085c5760405162461bcd60e51b815260040161037a90610df3565b6001600160a01b0382166108825760405162461bcd60e51b815260040161037a90610df3565b61088d8383836109e2565b6001600160a01b038316600090815260208190526040812080548392906108b5908490610d8f565b90915550506001600160a01b038216600090815260208190526040812080548392906108e2908490610ddb565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161082991815260200190565b6001600160a01b0382166109545760405162461bcd60e51b815260040161037a90610df3565b610960600083836109e2565b80600260008282546109729190610ddb565b90915550506001600160a01b0382166000908152602081905260408120805483929061099f908490610ddb565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200161077c565b600554604051633d70e7e560e11b81527f75a31d1ce8e5f9892188befc328d3b9bd3fa5037457e881abc21f388471b8d9660048201526001600160a01b0390911690637ae1cfca9060240160206040518083038186803b158015610a4557600080fd5b505afa158015610a59573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7d9190610e16565b15610ab65760405162461bcd60e51b815260206004820152600960248201526824a9afa32927ad22a760b91b604482015260640161037a565b6005546040516001600160a01b0390911690637ae1cfca90610aff907f1a7261d3a36c4ce4235d10859911c9444a6963a3591ec5725b96871d9810626b90600490602001610e38565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b8152600401610b3391815260200190565b60206040518083038186803b158015610b4b57600080fd5b505afa158015610b5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b839190610e16565b156105c85760405162461bcd60e51b815260206004820152600960248201526824a9afa32927ad22a760b91b604482015260640161037a565b60c280610ee283390190565b60005b83811015610be3578181015183820152602001610bcb565b83811115610bf2576000848401525b50505050565b6020815260008251806020840152610c17816040850160208701610bc8565b601f01601f19169190910160400192915050565b600060208284031215610c3d57600080fd5b5035919050565b80356001600160a01b0381168114610c5b57600080fd5b919050565b60008060408385031215610c7357600080fd5b610c7c83610c44565b946020939093013593505050565b600080600060608486031215610c9f57600080fd5b610ca884610c44565b9250610cb660208501610c44565b9150604084013590509250925092565b600060208284031215610cd857600080fd5b610ce182610c44565b9392505050565b60008060408385031215610cfb57600080fd5b610d0483610c44565b9150610d1260208401610c44565b90509250929050565b600181811c90821680610d2f57607f821691505b60208210811415610d5057634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600990820152682727aa2fa7aba722a960b91b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082821015610da157610da1610d79565b500390565b60008451610db8818460208901610bc8565b845190830190610dcc818360208901610bc8565b01928352505060200192915050565b60008219821115610dee57610dee610d79565b500190565b6020808252600990820152682d22a927afa0a2222960b91b604082015260600190565b600060208284031215610e2857600080fd5b81518015158114610ce157600080fd5b828152600060206000845481600182811c915080831680610e5a57607f831692505b858310811415610e7857634e487b7160e01b85526022600452602485fd5b808015610e8c5760018114610ea157610ed2565b60ff1985168988015283890187019550610ed2565b60008a81526020902060005b85811015610ec85781548b82018a0152908401908801610ead565b505086848a010195505b5093999850505050505050505056fe6080604052348015600f57600080fd5b506040516100c23803806100c2833981016040819052602c916089565b6040516308a1eee160e01b8152600481018290526001600160a01b038316906308a1eee190602401600060405180830381600087803b158015606d57600080fd5b505af11580156080573d6000803e3d6000fd5b50600092505050ff5b60008060408385031215609b57600080fd5b82516001600160a01b038116811460b157600080fd5b602093909301519294929350505056fea26469706673582212200b9d4704dcf13dfd9787296fefb091302153358bea4f3d74f0ba4e11a9cb95aa64736f6c63430008090033a2646970667358221220650a3d16decebe4547c4596d6c58eb39fc086a5e2785d73373e140c33d3203ab64736f6c634300080900330000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000066000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000080000000000000000000000003f5876a2b06e54949ab106651ab6694d0289b2b40000000000000000000000009256fd872118ed3a97754b0fb42c15015d17e0cc0000000000000000000000005c8ef9ca7b43c93ac4a146bef77fafbc7d3e69b70000000000000000000000001486157d505c7f7e546ad00e3e2eee25bf665c9b0000000000000000000000002ec991b5c0b742abd9d2ea31fe6c14a85e91c821000000000000000000000000f505462a29e36e26f25ef0175ca1ecba09cc118f000000000000000000000000027c1882b975e2cd771ae068b0389fa38b9dda7300000000000000000000000030932ac1f0477fbd63e4c5be1928f367a58a45a1000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000c5c8500f53ddfdf8d0bb04f4f270306b2b8a633200000000000000000000000039c15758ee8284c3fe0ed2a3589ff75b3ef6fa2e000000000000000000000000a96ca0d007e125cffe0ca85d18d7a2244ee408f80000000000000000000000008a5801360654fd524445da0f83768d1f620cdcc7000000000000000000000000d19a13b9cd0b6e934f4100bcc42b4aad0e63ebd5000000000000000000000000b6edece026e1159257d3d67a9355516d4c47eef6000000000000000000000000fae04b5f3f1a83ed4f77fd9daa8708851716de7800000000000000000000000008a582727c36db85b5e5a1266e4860a87324d4f1000000000000000000000000d5aa95f7d9f8be3ee5b7d337836568d58a096261000000000000000000000000e86441dcb68d14ed3cbb0d148e86460cd52e2c230000000000000000000000000c45b4fc3ad6ab66cc36ef5acf45c62f52a3476800000000000000000000000098af8829f6ca1abb8674a10f42329794b0fb21800000000000000000000000004d24b4dd9b7e69da4ac69d4d6f56b9e286f9a16a0000000000000000000000008cd44eca0a537432749f5565da1e4fdd9ec4f3c00000000000000000000000000000000000000000000000000000000000000014000000000000000000000000deed2171fa638ca13b3bfba63020468e8da383c70000000000000000000000001151d7306e3462277ccd94c95afe82cb10633c440000000000000000000000008a3684f08a94790f1607f1bd096d83ca755df7a7000000000000000000000000feb6e7d7c162295b1543cd1572a1de2a645c96ae0000000000000000000000003494de797aa3760f8914cdb90b211bdbd444fe950000000000000000000000009bc7432bcb671c235c49df0b1de91fa7cde70ce60000000000000000000000003febf6653973f858da73c923ee1eaea462efb816000000000000000000000000bfefe770bbde7bb4f76f9c5365709554dbaaf2cd00000000000000000000000052033d48a66578ae276a3cb0002db36f7827edb3000000000000000000000000729e9a365965f5e2e21b8a85f074e6b63f5cfce3000000000000000000000000d1e769a77bacd485339721d9b3e2a2ed7d10c93d000000000000000000000000e2586d2942a9d8f7d4dd264e2b1cc03f6cc2f984000000000000000000000000fe719d5fa48d1a1b3104e2b6ffa4e883d11cab7d00000000000000000000000053e7a59ef519bf4f1347eb4a9673da05ac5e8e1e00000000000000000000000052c6cb9a6d01cc84fce54cc2e4a39a5e84ed94c10000000000000000000000000928bfdfad830b6fe53af867d958e0e2317270bd000000000000000000000000378bcfe67a1f64d0616124d49abaedb4a794f28a000000000000000000000000f814cbaea329a9066c089c2177e9b5617da7f602000000000000000000000000bbb53d907d5acf91140afc5e6a915b718cc2771c0000000000000000000000006de2a18658e92e3153431d82c2749398fe735416
Deployed Bytecode
0x6080604052600436106100745760003560e01c80639ded06df1161004e5780639ded06df146101ea578063bd02d0f51461020b578063c031a18014610246578063dc97d96214610266576100b0565b806321f8a7211461012a5780637ae1cfca1461017d578063986e791a146101bd576100b0565b366100b05760405162461bcd60e51b81526020600482015260086024820152672727afa2aa2422a960c11b604482015260640160405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc600090815260026020527f11141f466c69fd409e1990e063b49cd6d61ed2ecff27a2e402e259ca6b9a01a3546001600160a01b03169036908037600080366000845af43d6000803e808015610125573d6000f35b3d6000fd5b34801561013657600080fd5b50610160610145366004610352565b6000908152600260205260409020546001600160a01b031690565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561018957600080fd5b506101ad610198366004610352565b60009081526004602052604090205460ff1690565b6040519015158152602001610174565b3480156101c957600080fd5b506101dd6101d8366004610352565b610293565b60405161017491906103b8565b3480156101f657600080fd5b506102096102053660046103d2565b5050565b005b34801561021757600080fd5b50610238610226366004610352565b60009081526020819052604090205490565b604051908152602001610174565b34801561025257600080fd5b506101dd610261366004610352565b610335565b34801561027257600080fd5b50610238610281366004610352565b60009081526005602052604090205490565b60008181526001602052604090208054606091906102b090610444565b80601f01602080910402602001604051908101604052809291908181526020018280546102dc90610444565b80156103295780601f106102fe57610100808354040283529160200191610329565b820191906000526020600020905b81548152906001019060200180831161030c57829003601f168201915b50505050509050919050565b60008181526003602052604090208054606091906102b090610444565b60006020828403121561036457600080fd5b5035919050565b6000815180845260005b8181101561039157602081850181015186830182015201610375565b818111156103a3576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006103cb602083018461036b565b9392505050565b600080602083850312156103e557600080fd5b823567ffffffffffffffff808211156103fd57600080fd5b818501915085601f83011261041157600080fd5b81358181111561042057600080fd5b86602082850101111561043257600080fd5b60209290920196919550909350505050565b600181811c9082168061045857607f821691505b6020821081141561047957634e487b7160e01b600052602260045260246000fd5b5091905056fea2646970667358221220de895ffe962788e1214df4d87d6cb2898ccd094eda688dc0ec9f1c9eabb1415064736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000066000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000080000000000000000000000003f5876a2b06e54949ab106651ab6694d0289b2b40000000000000000000000009256fd872118ed3a97754b0fb42c15015d17e0cc0000000000000000000000005c8ef9ca7b43c93ac4a146bef77fafbc7d3e69b70000000000000000000000001486157d505c7f7e546ad00e3e2eee25bf665c9b0000000000000000000000002ec991b5c0b742abd9d2ea31fe6c14a85e91c821000000000000000000000000f505462a29e36e26f25ef0175ca1ecba09cc118f000000000000000000000000027c1882b975e2cd771ae068b0389fa38b9dda7300000000000000000000000030932ac1f0477fbd63e4c5be1928f367a58a45a1000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000c5c8500f53ddfdf8d0bb04f4f270306b2b8a633200000000000000000000000039c15758ee8284c3fe0ed2a3589ff75b3ef6fa2e000000000000000000000000a96ca0d007e125cffe0ca85d18d7a2244ee408f80000000000000000000000008a5801360654fd524445da0f83768d1f620cdcc7000000000000000000000000d19a13b9cd0b6e934f4100bcc42b4aad0e63ebd5000000000000000000000000b6edece026e1159257d3d67a9355516d4c47eef6000000000000000000000000fae04b5f3f1a83ed4f77fd9daa8708851716de7800000000000000000000000008a582727c36db85b5e5a1266e4860a87324d4f1000000000000000000000000d5aa95f7d9f8be3ee5b7d337836568d58a096261000000000000000000000000e86441dcb68d14ed3cbb0d148e86460cd52e2c230000000000000000000000000c45b4fc3ad6ab66cc36ef5acf45c62f52a3476800000000000000000000000098af8829f6ca1abb8674a10f42329794b0fb21800000000000000000000000004d24b4dd9b7e69da4ac69d4d6f56b9e286f9a16a0000000000000000000000008cd44eca0a537432749f5565da1e4fdd9ec4f3c00000000000000000000000000000000000000000000000000000000000000014000000000000000000000000deed2171fa638ca13b3bfba63020468e8da383c70000000000000000000000001151d7306e3462277ccd94c95afe82cb10633c440000000000000000000000008a3684f08a94790f1607f1bd096d83ca755df7a7000000000000000000000000feb6e7d7c162295b1543cd1572a1de2a645c96ae0000000000000000000000003494de797aa3760f8914cdb90b211bdbd444fe950000000000000000000000009bc7432bcb671c235c49df0b1de91fa7cde70ce60000000000000000000000003febf6653973f858da73c923ee1eaea462efb816000000000000000000000000bfefe770bbde7bb4f76f9c5365709554dbaaf2cd00000000000000000000000052033d48a66578ae276a3cb0002db36f7827edb3000000000000000000000000729e9a365965f5e2e21b8a85f074e6b63f5cfce3000000000000000000000000d1e769a77bacd485339721d9b3e2a2ed7d10c93d000000000000000000000000e2586d2942a9d8f7d4dd264e2b1cc03f6cc2f984000000000000000000000000fe719d5fa48d1a1b3104e2b6ffa4e883d11cab7d00000000000000000000000053e7a59ef519bf4f1347eb4a9673da05ac5e8e1e00000000000000000000000052c6cb9a6d01cc84fce54cc2e4a39a5e84ed94c10000000000000000000000000928bfdfad830b6fe53af867d958e0e2317270bd000000000000000000000000378bcfe67a1f64d0616124d49abaedb4a794f28a000000000000000000000000f814cbaea329a9066c089c2177e9b5617da7f602000000000000000000000000bbb53d907d5acf91140afc5e6a915b718cc2771c0000000000000000000000006de2a18658e92e3153431d82c2749398fe735416
-----Decoded View---------------
Arg [0] : params (bytes): 0x00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000b00000000000000000000000000000000000000000000000000000000000000080000000000000000000000003f5876a2b06e54949ab106651ab6694d0289b2b40000000000000000000000009256fd872118ed3a97754b0fb42c15015d17e0cc0000000000000000000000005c8ef9ca7b43c93ac4a146bef77fafbc7d3e69b70000000000000000000000001486157d505c7f7e546ad00e3e2eee25bf665c9b0000000000000000000000002ec991b5c0b742abd9d2ea31fe6c14a85e91c821000000000000000000000000f505462a29e36e26f25ef0175ca1ecba09cc118f000000000000000000000000027c1882b975e2cd771ae068b0389fa38b9dda7300000000000000000000000030932ac1f0477fbd63e4c5be1928f367a58a45a1000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000c5c8500f53ddfdf8d0bb04f4f270306b2b8a633200000000000000000000000039c15758ee8284c3fe0ed2a3589ff75b3ef6fa2e000000000000000000000000a96ca0d007e125cffe0ca85d18d7a2244ee408f80000000000000000000000008a5801360654fd524445da0f83768d1f620cdcc7000000000000000000000000d19a13b9cd0b6e934f4100bcc42b4aad0e63ebd5000000000000000000000000b6edece026e1159257d3d67a9355516d4c47eef6000000000000000000000000fae04b5f3f1a83ed4f77fd9daa8708851716de7800000000000000000000000008a582727c36db85b5e5a1266e4860a87324d4f1000000000000000000000000d5aa95f7d9f8be3ee5b7d337836568d58a096261000000000000000000000000e86441dcb68d14ed3cbb0d148e86460cd52e2c230000000000000000000000000c45b4fc3ad6ab66cc36ef5acf45c62f52a3476800000000000000000000000098af8829f6ca1abb8674a10f42329794b0fb21800000000000000000000000004d24b4dd9b7e69da4ac69d4d6f56b9e286f9a16a0000000000000000000000008cd44eca0a537432749f5565da1e4fdd9ec4f3c00000000000000000000000000000000000000000000000000000000000000014000000000000000000000000deed2171fa638ca13b3bfba63020468e8da383c70000000000000000000000001151d7306e3462277ccd94c95afe82cb10633c440000000000000000000000008a3684f08a94790f1607f1bd096d83ca755df7a7000000000000000000000000feb6e7d7c162295b1543cd1572a1de2a645c96ae0000000000000000000000003494de797aa3760f8914cdb90b211bdbd444fe950000000000000000000000009bc7432bcb671c235c49df0b1de91fa7cde70ce60000000000000000000000003febf6653973f858da73c923ee1eaea462efb816000000000000000000000000bfefe770bbde7bb4f76f9c5365709554dbaaf2cd00000000000000000000000052033d48a66578ae276a3cb0002db36f7827edb3000000000000000000000000729e9a365965f5e2e21b8a85f074e6b63f5cfce3000000000000000000000000d1e769a77bacd485339721d9b3e2a2ed7d10c93d000000000000000000000000e2586d2942a9d8f7d4dd264e2b1cc03f6cc2f984000000000000000000000000fe719d5fa48d1a1b3104e2b6ffa4e883d11cab7d00000000000000000000000053e7a59ef519bf4f1347eb4a9673da05ac5e8e1e00000000000000000000000052c6cb9a6d01cc84fce54cc2e4a39a5e84ed94c10000000000000000000000000928bfdfad830b6fe53af867d958e0e2317270bd000000000000000000000000378bcfe67a1f64d0616124d49abaedb4a794f28a000000000000000000000000f814cbaea329a9066c089c2177e9b5617da7f602000000000000000000000000bbb53d907d5acf91140afc5e6a915b718cc2771c0000000000000000000000006de2a18658e92e3153431d82c2749398fe735416
-----Encoded View---------------
53 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000660
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [4] : 00000000000000000000000000000000000000000000000000000000000001e0
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [6] : 00000000000000000000000000000000000000000000000000000000000003c0
Arg [7] : 000000000000000000000000000000000000000000000000000000000000000b
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [9] : 0000000000000000000000003f5876a2b06e54949ab106651ab6694d0289b2b4
Arg [10] : 0000000000000000000000009256fd872118ed3a97754b0fb42c15015d17e0cc
Arg [11] : 0000000000000000000000005c8ef9ca7b43c93ac4a146bef77fafbc7d3e69b7
Arg [12] : 0000000000000000000000001486157d505c7f7e546ad00e3e2eee25bf665c9b
Arg [13] : 0000000000000000000000002ec991b5c0b742abd9d2ea31fe6c14a85e91c821
Arg [14] : 000000000000000000000000f505462a29e36e26f25ef0175ca1ecba09cc118f
Arg [15] : 000000000000000000000000027c1882b975e2cd771ae068b0389fa38b9dda73
Arg [16] : 00000000000000000000000030932ac1f0477fbd63e4c5be1928f367a58a45a1
Arg [17] : 000000000000000000000000000000000000000000000000000000000000000e
Arg [18] : 000000000000000000000000c5c8500f53ddfdf8d0bb04f4f270306b2b8a6332
Arg [19] : 00000000000000000000000039c15758ee8284c3fe0ed2a3589ff75b3ef6fa2e
Arg [20] : 000000000000000000000000a96ca0d007e125cffe0ca85d18d7a2244ee408f8
Arg [21] : 0000000000000000000000008a5801360654fd524445da0f83768d1f620cdcc7
Arg [22] : 000000000000000000000000d19a13b9cd0b6e934f4100bcc42b4aad0e63ebd5
Arg [23] : 000000000000000000000000b6edece026e1159257d3d67a9355516d4c47eef6
Arg [24] : 000000000000000000000000fae04b5f3f1a83ed4f77fd9daa8708851716de78
Arg [25] : 00000000000000000000000008a582727c36db85b5e5a1266e4860a87324d4f1
Arg [26] : 000000000000000000000000d5aa95f7d9f8be3ee5b7d337836568d58a096261
Arg [27] : 000000000000000000000000e86441dcb68d14ed3cbb0d148e86460cd52e2c23
Arg [28] : 0000000000000000000000000c45b4fc3ad6ab66cc36ef5acf45c62f52a34768
Arg [29] : 00000000000000000000000098af8829f6ca1abb8674a10f42329794b0fb2180
Arg [30] : 0000000000000000000000004d24b4dd9b7e69da4ac69d4d6f56b9e286f9a16a
Arg [31] : 0000000000000000000000008cd44eca0a537432749f5565da1e4fdd9ec4f3c0
Arg [32] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [33] : 000000000000000000000000deed2171fa638ca13b3bfba63020468e8da383c7
Arg [34] : 0000000000000000000000001151d7306e3462277ccd94c95afe82cb10633c44
Arg [35] : 0000000000000000000000008a3684f08a94790f1607f1bd096d83ca755df7a7
Arg [36] : 000000000000000000000000feb6e7d7c162295b1543cd1572a1de2a645c96ae
Arg [37] : 0000000000000000000000003494de797aa3760f8914cdb90b211bdbd444fe95
Arg [38] : 0000000000000000000000009bc7432bcb671c235c49df0b1de91fa7cde70ce6
Arg [39] : 0000000000000000000000003febf6653973f858da73c923ee1eaea462efb816
Arg [40] : 000000000000000000000000bfefe770bbde7bb4f76f9c5365709554dbaaf2cd
Arg [41] : 00000000000000000000000052033d48a66578ae276a3cb0002db36f7827edb3
Arg [42] : 000000000000000000000000729e9a365965f5e2e21b8a85f074e6b63f5cfce3
Arg [43] : 000000000000000000000000d1e769a77bacd485339721d9b3e2a2ed7d10c93d
Arg [44] : 000000000000000000000000e2586d2942a9d8f7d4dd264e2b1cc03f6cc2f984
Arg [45] : 000000000000000000000000fe719d5fa48d1a1b3104e2b6ffa4e883d11cab7d
Arg [46] : 00000000000000000000000053e7a59ef519bf4f1347eb4a9673da05ac5e8e1e
Arg [47] : 00000000000000000000000052c6cb9a6d01cc84fce54cc2e4a39a5e84ed94c1
Arg [48] : 0000000000000000000000000928bfdfad830b6fe53af867d958e0e2317270bd
Arg [49] : 000000000000000000000000378bcfe67a1f64d0616124d49abaedb4a794f28a
Arg [50] : 000000000000000000000000f814cbaea329a9066c089c2177e9b5617da7f602
Arg [51] : 000000000000000000000000bbb53d907d5acf91140afc5e6a915b718cc2771c
Arg [52] : 0000000000000000000000006de2a18658e92e3153431d82c2749398fe735416
Deployed Bytecode Sourcemap
55505:575:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5822:18;;-1:-1:-1;;;5822:18:0;;216:2:1;5822:18:0;;;198:21:1;255:1;235:18;;;228:29;-1:-1:-1;;;273:18:1;;;266:38;321:18;;5822::0;;;;;;;55505:575;5179:66;5294:22;916:20;;;:15;:20;;;;-1:-1:-1;;;;;916:20:0;;5405:14;;5294:22;5386:34;5508:1;5505;5489:14;5486:1;5470:14;5463:5;5450:60;5547:16;5544:1;5541;5526:38;5587:6;5607:68;;;;5726:16;5723:1;5716:27;5607:68;5643:16;5640:1;5633:27;835:109;;;;;;;;;;-1:-1:-1;835:109:0;;;;;:::i;:::-;889:7;916:20;;;:15;:20;;;;;;-1:-1:-1;;;;;916:20:0;;835:109;;;;-1:-1:-1;;;;;699:32:1;;;681:51;;669:2;654:18;835:109:0;;;;;;;;1070:100;;;;;;;;;;-1:-1:-1;1070:100:0;;;;;:::i;:::-;1121:4;1145:17;;;:12;:17;;;;;;;;;1070:100;;;;908:14:1;;901:22;883:41;;871:2;856:18;1070:100:0;743:187:1;714:113:0;;;;;;;;;;-1:-1:-1;714:113:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;56028:49::-;;;;;;;;;;-1:-1:-1;56028:49:0;;;;;:::i;:::-;;;;;;603:103;;;;;;;;;;-1:-1:-1;603:103:0;;;;;:::i;:::-;654:7;681:17;;;;;;;;;;;;603:103;;;;2379:25:1;;;2367:2;2352:18;603:103:0;2233:177:1;952:110:0;;;;;;;;;;-1:-1:-1;952:110:0;;;;;:::i;:::-;;:::i;1178:100::-;;;;;;;;;;-1:-1:-1;1178:100:0;;;;;:::i;:::-;1228:6;1254:16;;;:11;:16;;;;;;;1178:100;714:113;800:19;;;;:14;:19;;;;;793:26;;767:13;;800:19;793:26;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;714:113;;;:::o;952:110::-;1036:18;;;;:13;:18;;;;;1029:25;;1004:12;;1036:18;1029:25;;;:::i;350:180:1:-;409:6;462:2;450:9;441:7;437:23;433:32;430:52;;;478:1;475;468:12;430:52;-1:-1:-1;501:23:1;;350:180;-1:-1:-1;350:180:1:o;935:472::-;977:3;1015:5;1009:12;1042:6;1037:3;1030:19;1067:1;1077:162;1091:6;1088:1;1085:13;1077:162;;;1153:4;1209:13;;;1205:22;;1199:29;1181:11;;;1177:20;;1170:59;1106:12;1077:162;;;1257:6;1254:1;1251:13;1248:87;;;1323:1;1316:4;1307:6;1302:3;1298:16;1294:27;1287:38;1248:87;-1:-1:-1;1389:2:1;1368:15;-1:-1:-1;;1364:29:1;1355:39;;;;1396:4;1351:50;;935:472;-1:-1:-1;;935:472:1:o;1412:220::-;1561:2;1550:9;1543:21;1524:4;1581:45;1622:2;1611:9;1607:18;1599:6;1581:45;:::i;:::-;1573:53;1412:220;-1:-1:-1;;;1412:220:1:o;1637:591::-;1707:6;1715;1768:2;1756:9;1747:7;1743:23;1739:32;1736:52;;;1784:1;1781;1774:12;1736:52;1824:9;1811:23;1853:18;1894:2;1886:6;1883:14;1880:34;;;1910:1;1907;1900:12;1880:34;1948:6;1937:9;1933:22;1923:32;;1993:7;1986:4;1982:2;1978:13;1974:27;1964:55;;2015:1;2012;2005:12;1964:55;2055:2;2042:16;2081:2;2073:6;2070:14;2067:34;;;2097:1;2094;2087:12;2067:34;2142:7;2137:2;2128:6;2124:2;2120:15;2116:24;2113:37;2110:57;;;2163:1;2160;2153:12;2110:57;2194:2;2186:11;;;;;2216:6;;-1:-1:-1;1637:591:1;;-1:-1:-1;;;;1637:591:1:o;2818:380::-;2897:1;2893:12;;;;2940;;;2961:61;;3015:4;3007:6;3003:17;2993:27;;2961:61;3068:2;3060:6;3057:14;3037:18;3034:38;3031:161;;;3114:10;3109:3;3105:20;3102:1;3095:31;3149:4;3146:1;3139:15;3177:4;3174:1;3167:15;3031:161;;2818:380;;;:::o
Swarm Source
ipfs://650a3d16decebe4547c4596d6c58eb39fc086a5e2785d73373e140c33d3203ab
Loading...
Loading
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 28.32% | $1 | 32,190,357.1222 | $32,222,547.48 | |
ETH | 26.33% | $98,602 | 303.7859 | $29,953,896.36 | |
ETH | 24.17% | $3,979.59 | 6,910.6723 | $27,501,619.4 | |
ETH | 7.58% | $1.06 | 8,144,213.5992 | $8,624,722.2 | |
ETH | 5.70% | $4,590.28 | 1,413.9815 | $6,490,570.92 | |
ETH | 2.56% | $1 | 2,911,843.5685 | $2,914,755.41 | |
ETH | 1.30% | $0.98483 | 1,497,178.7359 | $1,474,466.53 | |
ETH | 0.80% | $0.021519 | 42,456,122.11 | $913,610.32 | |
ETH | 0.70% | $1 | 799,973.1071 | $800,773.08 | |
ETH | 0.52% | $0.036495 | 16,365,547.7018 | $597,262.63 | |
ETH | 0.47% | $3,905.97 | 138.1061 | $539,438.39 | |
ETH | 0.36% | $23.22 | 17,507.2036 | $406,517.27 | |
ETH | 0.27% | $0.995971 | 311,668.0836 | $310,412.37 | |
ETH | 0.20% | $0.000021 | 10,891,170,773.7318 | $227,843.29 | |
ETH | 0.19% | $4,247.78 | 50.521 | $214,601.93 | |
ETH | 0.08% | $0.00003 | 3,159,763,498.3034 | $95,898.82 | |
ETH | 0.08% | $4,267.53 | 20.5908 | $87,871.74 | |
ETH | 0.06% | $0.785587 | 93,041.1077 | $73,091.88 | |
ETH | 0.04% | $3.68 | 13,025.5625 | $47,934.07 | |
ETH | 0.02% | $3.03 | 5,951.7451 | $18,033.79 | |
ETH | 0.01% | $4,358.03 | 3.3415 | $14,562.2 | |
ETH | <0.01% | $4.81 | 2,277.2339 | $10,953.5 | |
ETH | <0.01% | $2,162.25 | 4.1691 | $9,014.73 | |
ETH | <0.01% | $16.56 | 426.136 | $7,056.81 | |
ETH | <0.01% | $3,979.59 | 0.9063 | $3,606.73 | |
ETH | <0.01% | $0.007112 | 338,479.4479 | $2,407.42 | |
ETH | <0.01% | $1.09 | 868.7939 | $948.72 | |
ETH | <0.01% | $4,252.11 | 0.1434 | $609.61 | |
ETH | <0.01% | $270.4 | 0.76 | $205.5 | |
ETH | <0.01% | $3,926.28 | 0.0451 | $177.02 | |
ETH | <0.01% | $0.523642 | 54.2856 | $28.43 | |
ETH | <0.01% | <$0.000001 | 247,339,202.9321 | $27.13 | |
ETH | <0.01% | $1.85 | 6 | $11.1 | |
ETH | <0.01% | $0.428779 | 10 | $4.29 | |
ETH | <0.01% | $0.034822 | 50.0029 | $1.74 | |
ETH | <0.01% | $0.001017 | 1,000 | $1.02 | |
GLMR | 0.18% | $10.36 | 19,299.3232 | $199,893.5 | |
GLMR | <0.01% | $0.373942 | 7,049.2752 | $2,636.02 | |
GLMR | <0.01% | $0.995758 | 20 | $19.92 | |
BSC | <0.01% | $1.86 | 4,984.1625 | $9,290.75 | |
BASE | <0.01% | $0.007029 | 20 | $0.1405 | |
POL | <0.01% | $0.000232 | 500 | $0.1159 | |
POL | <0.01% | $0.691349 | 0.0018 | $0.001244 |
[ 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.