Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 3 internal transactions
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
12120132 | 2 days ago | Contract Creation | 0 S | |||
11909625 | 3 days ago | Contract Creation | 0 S | |||
11904603 | 3 days ago | Contract Creation | 0 S |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
StaticAggregationIsmFactory
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.8.0; // ============ Internal Imports ============ import {StaticAggregationIsm} from "./StaticAggregationIsm.sol"; import {StaticThresholdAddressSetFactory} from "../../libs/StaticAddressSetFactory.sol"; contract StaticAggregationIsmFactory is StaticThresholdAddressSetFactory { function _deployImplementation() internal virtual override returns (address) { return address(new StaticAggregationIsm()); } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.8.0; // ============ Internal Imports ============ import {AbstractAggregationIsm} from "./AbstractAggregationIsm.sol"; import {AggregationIsmMetadata} from "../../isms/libs/AggregationIsmMetadata.sol"; import {MetaProxy} from "../../libs/MetaProxy.sol"; import {PackageVersioned} from "contracts/PackageVersioned.sol"; /** * @title StaticAggregationIsm * @notice Manages per-domain m-of-n ISM sets that are used to verify * interchain messages. */ contract StaticAggregationIsm is AbstractAggregationIsm { // ============ Public Functions ============ /** * @notice Returns the set of ISMs responsible for verifying _message * and the number of ISMs that must verify * @dev Can change based on the content of _message * @return modules The array of ISM addresses * @return threshold The number of ISMs needed to verify */ function modulesAndThreshold( bytes calldata ) public view virtual override returns (address[] memory, uint8) { return abi.decode(MetaProxy.metadata(), (address[], uint8)); } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.8.0; // ============ External Imports ============ import {Address} from "@openzeppelin/contracts/utils/Address.sol"; import {Create2} from "@openzeppelin/contracts/utils/Create2.sol"; // ============ Internal Imports ============ import {MetaProxy} from "./MetaProxy.sol"; import {PackageVersioned} from "../PackageVersioned.sol"; import {IThresholdAddressFactory} from "../interfaces/IThresholdAddressFactory.sol"; abstract contract StaticThresholdAddressSetFactory is PackageVersioned, IThresholdAddressFactory { // ============ Immutables ============ address public immutable implementation; // ============ Constructor ============ constructor() { implementation = _deployImplementation(); } function _deployImplementation() internal virtual returns (address); /** * @notice Deploys a StaticThresholdAddressSet contract address for the given * values * @dev Consider sorting addresses to ensure contract reuse * @param _values An array of addresses * @param _threshold The threshold value to use * @return set The contract address representing this StaticThresholdAddressSet */ function deploy( address[] calldata _values, uint8 _threshold ) public returns (address) { require( 0 < _threshold && _threshold <= _values.length, "Invalid threshold" ); (bytes32 _salt, bytes memory _bytecode) = _saltAndBytecode( _values, _threshold ); address _set = _getAddress(_salt, _bytecode); if (!Address.isContract(_set)) { _set = Create2.deploy(0, _salt, _bytecode); } return _set; } /** * @notice Returns the StaticThresholdAddressSet contract address for the given * values * @dev Consider sorting addresses to ensure contract reuse * @param _values An array of addresses * @param _threshold The threshold value to use * @return set The contract address representing this StaticThresholdAddressSet */ function getAddress( address[] calldata _values, uint8 _threshold ) external view returns (address) { (bytes32 _salt, bytes memory _bytecode) = _saltAndBytecode( _values, _threshold ); return _getAddress(_salt, _bytecode); } /** * @notice Returns the StaticThresholdAddressSet contract address for the given * values * @param _salt The salt used in Create2 * @param _bytecode The metaproxy bytecode used in Create2 * @return set The contract address representing this StaticThresholdAddressSet */ function _getAddress( bytes32 _salt, bytes memory _bytecode ) internal view returns (address) { bytes32 _bytecodeHash = keccak256(_bytecode); return Create2.computeAddress(_salt, _bytecodeHash); } /** * @notice Returns the create2 salt and bytecode for the given values * @param _values An array of addresses * @param _threshold The threshold value to use * @return _salt The salt used in Create2 * @return _bytecode The metaproxy bytecode used in Create2 */ function _saltAndBytecode( address[] calldata _values, uint8 _threshold ) internal view returns (bytes32, bytes memory) { bytes memory _metadata = abi.encode(_values, _threshold); bytes memory _bytecode = MetaProxy.bytecode(implementation, _metadata); bytes32 _salt = keccak256(_metadata); return (_salt, _bytecode); } } abstract contract StaticAddressSetFactory is StaticThresholdAddressSetFactory { /** * @notice Deploys a StaticAddressSet contract address for the given * values * @dev Consider sorting addresses to ensure contract reuse * @param _values An array of addresses * @return set The contract address representing this StaticAddressSet */ function deploy(address[] calldata _values) external returns (address) { return super.deploy(_values, uint8(_values.length)); } /** * @notice Returns the StaticAddressSet contract address for the given * values * @dev Consider sorting addresses to ensure contract reuse * @param _values An array of addresses * @return set The contract address representing this StaticAddressSet */ function getAddress( address[] calldata _values ) external view returns (address) { (bytes32 _salt, bytes memory _bytecode) = _saltAndBytecode( _values, uint8(_values.length) ); return super._getAddress(_salt, _bytecode); } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.8.0; // ============ External Imports ============ import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; // ============ Internal Imports ============ import {IInterchainSecurityModule} from "../../interfaces/IInterchainSecurityModule.sol"; import {IAggregationIsm} from "../../interfaces/isms/IAggregationIsm.sol"; import {AggregationIsmMetadata} from "../../isms/libs/AggregationIsmMetadata.sol"; import {PackageVersioned} from "../../PackageVersioned.sol"; /** * @title AggregationIsm * @notice Manages per-domain m-of-n ISM sets that are used to verify * interchain messages. */ abstract contract AbstractAggregationIsm is IAggregationIsm, PackageVersioned { // ============ Constants ============ // solhint-disable-next-line const-name-snakecase uint8 public constant moduleType = uint8(IInterchainSecurityModule.Types.AGGREGATION); // ============ Virtual Functions ============ // ======= OVERRIDE THESE TO IMPLEMENT ======= /** * @notice Returns the set of ISMs responsible for verifying _message * and the number of ISMs that must verify * @dev Can change based on the content of _message * @param _message Hyperlane formatted interchain message * @return modules The array of ISM addresses * @return threshold The number of ISMs needed to verify */ function modulesAndThreshold( bytes calldata _message ) public view virtual returns (address[] memory, uint8); // ============ Public Functions ============ /** * @notice Requires that m-of-n ISMs verify the provided interchain message. * @param _metadata ABI encoded module metadata (see AggregationIsmMetadata.sol) * @param _message Formatted Hyperlane message (see Message.sol). */ function verify( bytes calldata _metadata, bytes calldata _message ) public returns (bool) { (address[] memory _isms, uint8 _threshold) = modulesAndThreshold( _message ); uint256 _count = _isms.length; for (uint8 i = 0; i < _count; i++) { if (!AggregationIsmMetadata.hasMetadata(_metadata, i)) continue; IInterchainSecurityModule _ism = IInterchainSecurityModule( _isms[i] ); require( _ism.verify( AggregationIsmMetadata.metadataAt(_metadata, i), _message ), "!verify" ); _threshold -= 1; } require(_threshold == 0, "!threshold"); return true; } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.8.0; /** * Format of metadata: * * [????:????] Metadata start/end uint32 ranges, packed as uint64 * [????:????] ISM metadata, packed encoding */ library AggregationIsmMetadata { uint256 private constant RANGE_SIZE = 4; /** * @notice Returns whether or not metadata was provided for the ISM at * `_index` * @dev Callers must ensure _index is less than the number of metadatas * provided * @param _metadata Encoded Aggregation ISM metadata * @param _index The index of the ISM to check for metadata for * @return Whether or not metadata was provided for the ISM at `_index` */ function hasMetadata( bytes calldata _metadata, uint8 _index ) internal pure returns (bool) { (uint32 _start, ) = _metadataRange(_metadata, _index); return _start > 0; } /** * @notice Returns the metadata provided for the ISM at `_index` * @dev Callers must ensure _index is less than the number of metadatas * provided * @dev Callers must ensure `hasMetadata(_metadata, _index)` * @param _metadata Encoded Aggregation ISM metadata * @param _index The index of the ISM to return metadata for * @return The metadata provided for the ISM at `_index` */ function metadataAt( bytes calldata _metadata, uint8 _index ) internal pure returns (bytes calldata) { (uint32 _start, uint32 _end) = _metadataRange(_metadata, _index); return _metadata[_start:_end]; } /** * @notice Returns the range of the metadata provided for the ISM at * `_index`, or zeroes if not provided * @dev Callers must ensure _index is less than the number of metadatas * provided * @param _metadata Encoded Aggregation ISM metadata * @param _index The index of the ISM to return metadata range for * @return The range of the metadata provided for the ISM at `_index`, or * zeroes if not provided */ function _metadataRange( bytes calldata _metadata, uint8 _index ) private pure returns (uint32, uint32) { uint256 _start = (uint32(_index) * RANGE_SIZE * 2); uint256 _mid = _start + RANGE_SIZE; uint256 _end = _mid + RANGE_SIZE; return ( uint32(bytes4(_metadata[_start:_mid])), uint32(bytes4(_metadata[_mid:_end])) ); } }
// SPDX-License-Identifier: CC0-1.0 pragma solidity >=0.7.6; /// @dev Adapted from https://eips.ethereum.org/EIPS/eip-3448 library MetaProxy { bytes32 private constant PREFIX = hex"600b380380600b3d393df3363d3d373d3d3d3d60368038038091363936013d73"; bytes13 private constant SUFFIX = hex"5af43d3d93803e603457fd5bf3"; function bytecode( address _implementation, bytes memory _metadata ) internal pure returns (bytes memory) { return abi.encodePacked( PREFIX, bytes20(_implementation), SUFFIX, _metadata, _metadata.length ); } function metadata() internal pure returns (bytes memory) { bytes memory data; assembly { let posOfMetadataSize := sub(calldatasize(), 32) let size := calldataload(posOfMetadataSize) let dataPtr := sub(posOfMetadataSize, size) data := mload(64) // increment free memory pointer by metadata size + 32 bytes (length) mstore(64, add(data, add(size, 32))) mstore(data, size) let memPtr := add(data, 32) calldatacopy(memPtr, dataPtr, size) } return data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Create2.sol) pragma solidity ^0.8.0; /** * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer. * `CREATE2` can be used to compute in advance the address where a smart * contract will be deployed, which allows for interesting new mechanisms known * as 'counterfactual interactions'. * * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more * information. */ library Create2 { /** * @dev Deploys a contract using `CREATE2`. The address where the contract * will be deployed can be known in advance via {computeAddress}. * * The bytecode for a contract can be obtained from Solidity with * `type(contractName).creationCode`. * * Requirements: * * - `bytecode` must not be empty. * - `salt` must have not been used for `bytecode` already. * - the factory must have a balance of at least `amount`. * - if `amount` is non-zero, `bytecode` must have a `payable` constructor. */ function deploy(uint256 amount, bytes32 salt, bytes memory bytecode) internal returns (address addr) { require(address(this).balance >= amount, "Create2: insufficient balance"); require(bytecode.length != 0, "Create2: bytecode length is zero"); /// @solidity memory-safe-assembly assembly { addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt) } require(addr != address(0), "Create2: Failed on deploy"); } /** * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the * `bytecodeHash` or `salt` will result in a new destination address. */ function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) { return computeAddress(salt, bytecodeHash, address(this)); } /** * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}. */ function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address addr) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) // Get free memory pointer // | | ↓ ptr ... ↓ ptr + 0x0B (start) ... ↓ ptr + 0x20 ... ↓ ptr + 0x40 ... | // |-------------------|---------------------------------------------------------------------------| // | bytecodeHash | CCCCCCCCCCCCC...CC | // | salt | BBBBBBBBBBBBB...BB | // | deployer | 000000...0000AAAAAAAAAAAAAAAAAAA...AA | // | 0xFF | FF | // |-------------------|---------------------------------------------------------------------------| // | memory | 000000...00FFAAAAAAAAAAAAAAAAAAA...AABBBBBBBBBBBBB...BBCCCCCCCCCCCCC...CC | // | keccak(start, 85) | ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ | mstore(add(ptr, 0x40), bytecodeHash) mstore(add(ptr, 0x20), salt) mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff mstore8(start, 0xff) addr := keccak256(start, 85) } } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.6.11; /** * @title PackageVersioned * @notice Package version getter for contracts **/ abstract contract PackageVersioned { // GENERATED CODE - DO NOT EDIT string public constant PACKAGE_VERSION = "5.11.4"; }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.8.0; interface IThresholdAddressFactory { function deploy( address[] calldata _values, uint8 _threshold ) external returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @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 { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. 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. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @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) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // 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 (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): 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. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.6.11; interface IInterchainSecurityModule { enum Types { UNUSED, ROUTING, AGGREGATION, LEGACY_MULTISIG, MERKLE_ROOT_MULTISIG, MESSAGE_ID_MULTISIG, NULL, // used with relayer carrying no metadata CCIP_READ, ARB_L2_TO_L1, WEIGHTED_MERKLE_ROOT_MULTISIG, WEIGHTED_MESSAGE_ID_MULTISIG, OP_L2_TO_L1 } /** * @notice Returns an enum that represents the type of security model * encoded by this ISM. * @dev Relayers infer how to fetch and format metadata. */ function moduleType() external view returns (uint8); /** * @notice Defines a security model responsible for verifying interchain * messages based on the provided metadata. * @param _metadata Off-chain metadata provided by a relayer, specific to * the security model encoded by the module (e.g. validator signatures) * @param _message Hyperlane encoded interchain message * @return True if the message was verified */ function verify( bytes calldata _metadata, bytes calldata _message ) external returns (bool); } interface ISpecifiesInterchainSecurityModule { function interchainSecurityModule() external view returns (IInterchainSecurityModule); }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.6.11; import {IInterchainSecurityModule} from "../IInterchainSecurityModule.sol"; interface IAggregationIsm is IInterchainSecurityModule { /** * @notice Returns the set of modules responsible for verifying _message * and the number of modules that must verify * @dev Can change based on the content of _message * @param _message Hyperlane formatted interchain message * @return modules The array of ISM addresses * @return threshold The number of modules needed to verify */ function modulesAndThreshold( bytes calldata _message ) external view returns (address[] memory modules, uint8 threshold); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
{ "optimizer": { "enabled": true, "runs": 999999 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"PACKAGE_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_values","type":"address[]"},{"internalType":"uint8","name":"_threshold","type":"uint8"}],"name":"deploy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_values","type":"address[]"},{"internalType":"uint8","name":"_threshold","type":"uint8"}],"name":"getAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a060405234801561001057600080fd5b5061001961002a565b6001600160a01b0316608052610067565b60006040516100389061005a565b604051809103906000f080158015610054573d6000803e3d6000fd5b50905090565b6109638061074f83390190565b6080516106c7610088600039600081816056015261024401526106c76000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80635c60da1b1461005157806393c44847146100a2578063d4277ebc146100eb578063ed547bf7146100fe575b600080fd5b6100787f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100de6040518060400160405280600681526020017f352e31312e34000000000000000000000000000000000000000000000000000081525081565b60405161009991906104c8565b6100786100f9366004610519565b610111565b61007861010c366004610519565b61013b565b6000806000610121868686610211565b9150915061012f8282610281565b925050505b9392505050565b60008160ff166000108015610153575060ff82168310155b6101be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f496e76616c6964207468726573686f6c6400000000000000000000000000000060448201526064015b60405180910390fd5b6000806101cc868686610211565b9150915060006101dc8383610281565b905073ffffffffffffffffffffffffffffffffffffffff81163b61012f576102066000848461029d565b979650505050505050565b60006060600085858560405160200161022c939291906105a5565b604051602081830303815290604052905060006102697f0000000000000000000000000000000000000000000000000000000000000000836103fc565b82516020909301929092209791965090945050505050565b805160208201206000906102958482610472565b949350505050565b600083471015610309576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e636500000060448201526064016101b5565b8151600003610374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f60448201526064016101b5565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff8116610134576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f790000000000000060448201526064016101b5565b60607f600b380380600b3d393df3363d3d373d3d3d3d60368038038091363936013d738360601b7f5af43d3d93803e603457fd5bf30000000000000000000000000000000000000084855160405160200161045b959493929190610612565b604051602081830303815290604052905092915050565b60006101348383306000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b60005b838110156104bf5781810151838201526020016104a7565b50506000910152565b60208152600082518060208401526104e78160408501602087016104a4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060006040848603121561052e57600080fd5b833567ffffffffffffffff8082111561054657600080fd5b818601915086601f83011261055a57600080fd5b81358181111561056957600080fd5b8760208260051b850101111561057e57600080fd5b6020928301955093505084013560ff8116811461059a57600080fd5b809150509250925092565b604080825281018390526000846060830182805b878110156105fa57833573ffffffffffffffffffffffffffffffffffffffff81168082146105e5578384fd5b845250602093840193909201916001016105b9565b5050809250505060ff83166020830152949350505050565b8581527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000851660208201527fffffffffffffffffffffffffff00000000000000000000000000000000000000841660348201526000835161067a8160418501602088016104a4565b60419201918201929092526061019594505050505056fea2646970667358221220e1e12d346bf04ecf713289c34cfa638812fcac69aa951b9477edd1b7fe797d9464736f6c63430008130033608060405234801561001057600080fd5b50610943806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80636465e69f146100515780636f72df751461007057806393c4484714610091578063f7e83aee146100da575b600080fd5b610059600281565b60405160ff90911681526020015b60405180910390f35b61008361007e366004610455565b6100fd565b604051610067929190610497565b6100cd6040518060400160405280600681526020017f352e31312e34000000000000000000000000000000000000000000000000000081525081565b60405161006791906104fb565b6100ed6100e8366004610567565b610128565b6040519015158152602001610067565b6060600061010961030e565b80602001905181019061011c919061063c565b915091505b9250929050565b600080600061013785856100fd565b8151919350915060005b818160ff1610156102945761015789898361033e565b15610282576000848260ff168151811061017357610173610731565b602002602001015190508073ffffffffffffffffffffffffffffffffffffffff1663f7e83aee6101a48c8c8661035e565b8b8b6040518563ffffffff1660e01b81526004016101c594939291906107a9565b6020604051808303816000875af11580156101e4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061020891906107db565b610273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f217665726966790000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b61027e600185610833565b9350505b8061028c81610852565b915050610141565b5060ff821615610300576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f217468726573686f6c6400000000000000000000000000000000000000000000604482015260640161026a565b506001979650505050505050565b60608060203603803580820391506040519250602081018301604052808352602083018183823750919392505050565b60008061034c858585610397565b5063ffffffff16151595945050505050565b36600080600061036f878787610397565b909250905061038963ffffffff808316908416888a610871565b935093505050935093915050565b600080806103a9600460ff861661089b565b6103b490600261089b565b905060006103c36004836108b2565b905060006103d26004836108b2565b90506103e08284898b610871565b6103e9916108c5565b60e01c6103f882848a8c610871565b610401916108c5565b60e01c94509450505050935093915050565b60008083601f84011261042557600080fd5b50813567ffffffffffffffff81111561043d57600080fd5b60208301915083602082850101111561012157600080fd5b6000806020838503121561046857600080fd5b823567ffffffffffffffff81111561047f57600080fd5b61048b85828601610413565b90969095509350505050565b604080825283519082018190526000906020906060840190828701845b828110156104e657815173ffffffffffffffffffffffffffffffffffffffff16845292840192908401906001016104b4565b50505060ff9490941692019190915250919050565b600060208083528351808285015260005b818110156105285785810183015185820160400152820161050c565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b6000806000806040858703121561057d57600080fd5b843567ffffffffffffffff8082111561059557600080fd5b6105a188838901610413565b909650945060208701359150808211156105ba57600080fd5b506105c787828801610413565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b805173ffffffffffffffffffffffffffffffffffffffff8116811461062657600080fd5b919050565b805160ff8116811461062657600080fd5b6000806040838503121561064f57600080fd5b825167ffffffffffffffff8082111561066757600080fd5b818501915085601f83011261067b57600080fd5b815160208282111561068f5761068f6105d3565b8160051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f830116810181811086821117156106d2576106d26105d3565b6040529283528183019350848101820192898411156106f057600080fd5b948201945b838610156107155761070686610602565b855294820194938201936106f5565b9650610724905087820161062b565b9450505050509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b6040815260006107bd604083018688610760565b82810360208401526107d0818587610760565b979650505050505050565b6000602082840312156107ed57600080fd5b815180151581146107fd57600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff828116828216039081111561084c5761084c610804565b92915050565b600060ff821660ff810361086857610868610804565b60010192915050565b6000808585111561088157600080fd5b8386111561088e57600080fd5b5050820193919092039150565b808202811582820484141761084c5761084c610804565b8082018082111561084c5761084c610804565b7fffffffff0000000000000000000000000000000000000000000000000000000081358181169160048510156109055780818660040360031b1b83161692505b50509291505056fea26469706673582212205f3ff2a61f8dca7ed08fb8bec6978f298848c6b86b951aad2cde9983deec8d1764736f6c63430008130033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80635c60da1b1461005157806393c44847146100a2578063d4277ebc146100eb578063ed547bf7146100fe575b600080fd5b6100787f0000000000000000000000007b5f6bd1685543e1129d4176a32ecb373375793f81565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100de6040518060400160405280600681526020017f352e31312e34000000000000000000000000000000000000000000000000000081525081565b60405161009991906104c8565b6100786100f9366004610519565b610111565b61007861010c366004610519565b61013b565b6000806000610121868686610211565b9150915061012f8282610281565b925050505b9392505050565b60008160ff166000108015610153575060ff82168310155b6101be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f496e76616c6964207468726573686f6c6400000000000000000000000000000060448201526064015b60405180910390fd5b6000806101cc868686610211565b9150915060006101dc8383610281565b905073ffffffffffffffffffffffffffffffffffffffff81163b61012f576102066000848461029d565b979650505050505050565b60006060600085858560405160200161022c939291906105a5565b604051602081830303815290604052905060006102697f0000000000000000000000007b5f6bd1685543e1129d4176a32ecb373375793f836103fc565b82516020909301929092209791965090945050505050565b805160208201206000906102958482610472565b949350505050565b600083471015610309576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e636500000060448201526064016101b5565b8151600003610374576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f60448201526064016101b5565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff8116610134576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f790000000000000060448201526064016101b5565b60607f600b380380600b3d393df3363d3d373d3d3d3d60368038038091363936013d738360601b7f5af43d3d93803e603457fd5bf30000000000000000000000000000000000000084855160405160200161045b959493929190610612565b604051602081830303815290604052905092915050565b60006101348383306000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b60005b838110156104bf5781810151838201526020016104a7565b50506000910152565b60208152600082518060208401526104e78160408501602087016104a4565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60008060006040848603121561052e57600080fd5b833567ffffffffffffffff8082111561054657600080fd5b818601915086601f83011261055a57600080fd5b81358181111561056957600080fd5b8760208260051b850101111561057e57600080fd5b6020928301955093505084013560ff8116811461059a57600080fd5b809150509250925092565b604080825281018390526000846060830182805b878110156105fa57833573ffffffffffffffffffffffffffffffffffffffff81168082146105e5578384fd5b845250602093840193909201916001016105b9565b5050809250505060ff83166020830152949350505050565b8581527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000851660208201527fffffffffffffffffffffffffff00000000000000000000000000000000000000841660348201526000835161067a8160418501602088016104a4565b60419201918201929092526061019594505050505056fea2646970667358221220e1e12d346bf04ecf713289c34cfa638812fcac69aa951b9477edd1b7fe797d9464736f6c63430008130033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.