Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
CSEarlyAdoption
Compiler Version
v0.8.24+commit.e11b9ed9
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-FileCopyrightText: 2024 Lido <[email protected]> // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.24; import { MerkleProof } from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import { ICSEarlyAdoption } from "./interfaces/ICSEarlyAdoption.sol"; contract CSEarlyAdoption is ICSEarlyAdoption { /// @dev Root of the EA members Merkle Tree bytes32 public immutable TREE_ROOT; /// @dev Id of the bond curve to be assigned for the EA members uint256 public immutable CURVE_ID; /// @dev Address of the Staking Module using Early Adoption contract address public immutable MODULE; mapping(address => bool) internal _consumedAddresses; event Consumed(address indexed member); error InvalidProof(); error AlreadyConsumed(); error InvalidTreeRoot(); error InvalidCurveId(); error ZeroModuleAddress(); error SenderIsNotModule(); constructor(bytes32 treeRoot, uint256 curveId, address module) { if (treeRoot == bytes32(0)) revert InvalidTreeRoot(); if (curveId == 0) revert InvalidCurveId(); if (module == address(0)) revert ZeroModuleAddress(); TREE_ROOT = treeRoot; CURVE_ID = curveId; MODULE = module; } /// @notice Validate EA eligibility proof and mark it as consumed /// @dev Called only by the module /// @param member Address to be verified alongside the proof /// @param proof Merkle proof of EA eligibility function consume(address member, bytes32[] calldata proof) external { if (msg.sender != MODULE) revert SenderIsNotModule(); if (_consumedAddresses[member]) revert AlreadyConsumed(); if (!verifyProof(member, proof)) revert InvalidProof(); _consumedAddresses[member] = true; emit Consumed(member); } /// @notice Check if the address has already consumed EA access /// @param member Address to check /// @return Consumed flag function isConsumed(address member) external view returns (bool) { return _consumedAddresses[member]; } /// @notice Check is the address is eligible to consume EA access /// @param member Address to check /// @param proof Merkle proof of EA eligibility /// @return Boolean flag if the proof is valid or not function verifyProof( address member, bytes32[] calldata proof ) public view returns (bool) { return MerkleProof.verifyCalldata(proof, TREE_ROOT, hashLeaf(member)); } /// @notice Get a hash of a leaf in EA Merkle tree /// @param member EA member address /// @return Hash of the leaf /// @dev Double hash the leaf to prevent second preimage attacks function hashLeaf(address member) public pure returns (bytes32) { return keccak256(bytes.concat(keccak256(abi.encode(member)))); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.20; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the Merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates Merkle trees that are safe * against this attack out of the box. */ library MerkleProof { /** *@dev The multiproof provided is not valid. */ error MerkleProofInvalidMultiproof(); /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} */ function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. if (leavesLen + proofLen != totalHashes + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { if (proofPos != proofLen) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. if (leavesLen + proofLen != totalHashes + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { if (proofPos != proofLen) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Sorts the pair (a, b) and hashes the result. */ function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } /** * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory. */ function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-FileCopyrightText: 2024 Lido <[email protected]> // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.24; interface ICSEarlyAdoption { function CURVE_ID() external view returns (uint256); function TREE_ROOT() external view returns (bytes32); function verifyProof( address addr, bytes32[] calldata proof ) external view returns (bool); function consume(address sender, bytes32[] calldata proof) external; function isConsumed(address sender) external view returns (bool); }
{ "remappings": [ "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/", "@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/", "forge-std/=node_modules/forge-std/src/", "ds-test/=node_modules/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "openzeppelin-contracts-v4.4/=lib/openzeppelin-contracts-v4.4/contracts/", "openzeppelin-contracts/=lib/openzeppelin-contracts/" ], "optimizer": { "enabled": true, "runs": 250 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "none", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "evmVersion": "cancun", "viaIR": false, "libraries": { "src/lib/AssetRecovererLib.sol": { "AssetRecovererLib": "0xA0513a7e28dAc4C31b5cCbF9A5F474B759257985" }, "src/lib/NOAddresses.sol": { "NOAddresses": "0x479244Bac2ae1D64841753307a0552183642c121" }, "src/lib/QueueLib.sol": { "QueueLib": "0x6FB7aF5aDDB044182caa27db35e394Ed3451A4da" } } }
Contract ABI
API[{"inputs":[{"internalType":"bytes32","name":"treeRoot","type":"bytes32"},{"internalType":"uint256","name":"curveId","type":"uint256"},{"internalType":"address","name":"module","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyConsumed","type":"error"},{"inputs":[],"name":"InvalidCurveId","type":"error"},{"inputs":[],"name":"InvalidProof","type":"error"},{"inputs":[],"name":"InvalidTreeRoot","type":"error"},{"inputs":[],"name":"SenderIsNotModule","type":"error"},{"inputs":[],"name":"ZeroModuleAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"member","type":"address"}],"name":"Consumed","type":"event"},{"inputs":[],"name":"CURVE_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MODULE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TREE_ROOT","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"member","type":"address"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"consume","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"member","type":"address"}],"name":"hashLeaf","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"member","type":"address"}],"name":"isConsumed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"member","type":"address"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"verifyProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60e060405234801561000f575f80fd5b5060405161059838038061059883398101604081905261002e916100ad565b8261004c576040516357e86a3360e01b815260040160405180910390fd5b815f0361006c5760405163fb3eeb4f60e01b815260040160405180910390fd5b6001600160a01b038116610093576040516378bc317d60e01b815260040160405180910390fd5b60809290925260a0526001600160a01b031660c0526100ef565b5f805f606084860312156100bf575f80fd5b83516020850151604086015191945092506001600160a01b03811681146100e4575f80fd5b809150509250925092565b60805160a05160c0516104736101255f395f81816083015261019f01525f61012401525f818160fd01526102e301526104735ff3fe608060405234801561000f575f80fd5b506004361061007a575f3560e01c806351c3b5c81161005857806351c3b5c8146100f85780638c96d81a1461011f578063d6baa28714610146578063e348643414610181575f80fd5b8063094d3a341461007e5780631d848ecc146100c257806325e49541146100d7575b5f80fd5b6100a57f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6100d56100d03660046103ba565b610194565b005b6100ea6100e5366004610439565b61028b565b6040519081526020016100b9565b6100ea7f000000000000000000000000000000000000000000000000000000000000000081565b6100ea7f000000000000000000000000000000000000000000000000000000000000000081565b610171610154366004610439565b6001600160a01b03165f9081526020819052604090205460ff1690565b60405190151581526020016100b9565b61017161018f3660046103ba565b6102db565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146101dd576040516303f249a160e51b815260040160405180910390fd5b6001600160a01b0383165f9081526020819052604090205460ff161561021657604051636f47ab5f60e01b815260040160405180910390fd5b6102218383836102db565b61023e576040516309bde33960e01b815260040160405180910390fd5b6001600160a01b0383165f81815260208190526040808220805460ff19166001179055517f7b0d6a375ac31729c196b98ec3eb011734456e0e9d75e50892b9e50e0053b0a49190a2505050565b604080516001600160a01b03831660208201525f910160408051601f1981840301815282825280516020918201209083015201604051602081830303815290604052805190602001209050919050565b5f61031083837f000000000000000000000000000000000000000000000000000000000000000061030b8861028b565b610318565b949350505050565b5f8261032586868561032f565b1495945050505050565b5f81815b848110156103675761035d8287878481811061035157610351610452565b90506020020135610370565b9150600101610333565b50949350505050565b5f81831061038a575f828152602084905260409020610398565b5f8381526020839052604090205b9392505050565b80356001600160a01b03811681146103b5575f80fd5b919050565b5f805f604084860312156103cc575f80fd5b6103d58461039f565b9250602084013567ffffffffffffffff808211156103f1575f80fd5b818601915086601f830112610404575f80fd5b813581811115610412575f80fd5b8760208260051b8501011115610426575f80fd5b6020830194508093505050509250925092565b5f60208284031215610449575f80fd5b6103988261039f565b634e487b7160e01b5f52603260045260245ffdfea164736f6c6343000818000a359e02c5c065c682839661c9bdfaf38db472629bf5f7a7e8f0261b31dc9332c2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000079cef36d84743222f37765204bec41e92a93e59d
Deployed Bytecode
0x608060405234801561000f575f80fd5b506004361061007a575f3560e01c806351c3b5c81161005857806351c3b5c8146100f85780638c96d81a1461011f578063d6baa28714610146578063e348643414610181575f80fd5b8063094d3a341461007e5780631d848ecc146100c257806325e49541146100d7575b5f80fd5b6100a57f00000000000000000000000079cef36d84743222f37765204bec41e92a93e59d81565b6040516001600160a01b0390911681526020015b60405180910390f35b6100d56100d03660046103ba565b610194565b005b6100ea6100e5366004610439565b61028b565b6040519081526020016100b9565b6100ea7f359e02c5c065c682839661c9bdfaf38db472629bf5f7a7e8f0261b31dc9332c281565b6100ea7f000000000000000000000000000000000000000000000000000000000000000181565b610171610154366004610439565b6001600160a01b03165f9081526020819052604090205460ff1690565b60405190151581526020016100b9565b61017161018f3660046103ba565b6102db565b336001600160a01b037f00000000000000000000000079cef36d84743222f37765204bec41e92a93e59d16146101dd576040516303f249a160e51b815260040160405180910390fd5b6001600160a01b0383165f9081526020819052604090205460ff161561021657604051636f47ab5f60e01b815260040160405180910390fd5b6102218383836102db565b61023e576040516309bde33960e01b815260040160405180910390fd5b6001600160a01b0383165f81815260208190526040808220805460ff19166001179055517f7b0d6a375ac31729c196b98ec3eb011734456e0e9d75e50892b9e50e0053b0a49190a2505050565b604080516001600160a01b03831660208201525f910160408051601f1981840301815282825280516020918201209083015201604051602081830303815290604052805190602001209050919050565b5f61031083837f359e02c5c065c682839661c9bdfaf38db472629bf5f7a7e8f0261b31dc9332c261030b8861028b565b610318565b949350505050565b5f8261032586868561032f565b1495945050505050565b5f81815b848110156103675761035d8287878481811061035157610351610452565b90506020020135610370565b9150600101610333565b50949350505050565b5f81831061038a575f828152602084905260409020610398565b5f8381526020839052604090205b9392505050565b80356001600160a01b03811681146103b5575f80fd5b919050565b5f805f604084860312156103cc575f80fd5b6103d58461039f565b9250602084013567ffffffffffffffff808211156103f1575f80fd5b818601915086601f830112610404575f80fd5b813581811115610412575f80fd5b8760208260051b8501011115610426575f80fd5b6020830194508093505050509250925092565b5f60208284031215610449575f80fd5b6103988261039f565b634e487b7160e01b5f52603260045260245ffdfea164736f6c6343000818000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
359e02c5c065c682839661c9bdfaf38db472629bf5f7a7e8f0261b31dc9332c2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000079cef36d84743222f37765204bec41e92a93e59d
-----Decoded View---------------
Arg [0] : treeRoot (bytes32): 0x359e02c5c065c682839661c9bdfaf38db472629bf5f7a7e8f0261b31dc9332c2
Arg [1] : curveId (uint256): 1
Arg [2] : module (address): 0x79CEf36D84743222f37765204Bec41E92a93E59d
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 359e02c5c065c682839661c9bdfaf38db472629bf5f7a7e8f0261b31dc9332c2
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [2] : 00000000000000000000000079cef36d84743222f37765204bec41e92a93e59d
Deployed Bytecode Sourcemap
275:2566:1:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;594:31;;;;;;;;-1:-1:-1;;;;;178:55:3;;;160:74;;148:2;133:18;594:31:1;;;;;;;;1472:341;;;;;;:::i;:::-;;:::i;:::-;;2697:142;;;;;;:::i;:::-;;:::i;:::-;;;1477:25:3;;;1465:2;1450:18;2697:142:1;1331:177:3;374:34:1;;;;;482:33;;;;;1956:115;;;;;;:::i;:::-;-1:-1:-1;;;;;2038:26:1;2015:4;2038:26;;;;;;;;;;;;;;1956:115;;;;1860:14:3;;1853:22;1835:41;;1823:2;1808:18;1956:115:1;1695:187:3;2296:198:1;;;;;;:::i;:::-;;:::i;1472:341::-;1554:10;-1:-1:-1;;;;;1568:6:1;1554:20;;1550:52;;1583:19;;-1:-1:-1;;;1583:19:1;;;;;;;;;;;1550:52;-1:-1:-1;;;;;1616:26:1;;:18;:26;;;;;;;;;;;;;1612:56;;;1651:17;;-1:-1:-1;;;1651:17:1;;;;;;;;;;;1612:56;1683:26;1695:6;1703:5;;1683:11;:26::i;:::-;1678:54;;1718:14;;-1:-1:-1;;;1718:14:1;;;;;;;;;;;1678:54;-1:-1:-1;;;;;1742:26:1;;:18;:26;;;;;;;;;;;:33;;-1:-1:-1;;1742:33:1;1771:4;1742:33;;;1790:16;;;1742:18;1790:16;1472:341;;;:::o;2697:142::-;2811:18;;;-1:-1:-1;;;;;178:55:3;;2811:18:1;;;160:74:3;2752:7:1;;133:18:3;2811::1;;;-1:-1:-1;;2811:18:1;;;;;;;;;2801:29;;2811:18;2801:29;;;;2788:43;;;2016:19:3;2051:12;2788:43:1;;;;;;;;;;;;2778:54;;;;;;2771:61;;2697:142;;;:::o;2296:198::-;2402:4;2425:62;2452:5;;2459:9;2470:16;2479:6;2470:8;:16::i;:::-;2425:26;:62::i;:::-;2418:69;2296:198;-1:-1:-1;;;;2296:198:1:o;1482:172:0:-;1583:4;1643;1606:33;1627:5;;1634:4;1606:20;:33::i;:::-;:41;;1482:172;-1:-1:-1;;;;;1482:172:0:o;2326:300::-;2419:7;2461:4;2419:7;2475:116;2495:16;;;2475:116;;;2547:33;2557:12;2571:5;;2577:1;2571:8;;;;;;;:::i;:::-;;;;;;;2547:9;:33::i;:::-;2532:48;-1:-1:-1;2513:3:0;;2475:116;;;-1:-1:-1;2607:12:0;2326:300;-1:-1:-1;;;;2326:300:0:o;9229:147::-;9292:7;9322:1;9318;:5;:51;;9564:13;9655:15;;;9690:4;9683:15;;;9736:4;9720:21;;9318:51;;;9564:13;9655:15;;;9690:4;9683:15;;;9736:4;9720:21;;9326:20;9311:58;9229:147;-1:-1:-1;;;9229:147:0:o;245:196:3:-;313:20;;-1:-1:-1;;;;;362:54:3;;352:65;;342:93;;431:1;428;421:12;342:93;245:196;;;:::o;446:689::-;541:6;549;557;610:2;598:9;589:7;585:23;581:32;578:52;;;626:1;623;616:12;578:52;649:29;668:9;649:29;:::i;:::-;639:39;;729:2;718:9;714:18;701:32;752:18;793:2;785:6;782:14;779:34;;;809:1;806;799:12;779:34;847:6;836:9;832:22;822:32;;892:7;885:4;881:2;877:13;873:27;863:55;;914:1;911;904:12;863:55;954:2;941:16;980:2;972:6;969:14;966:34;;;996:1;993;986:12;966:34;1049:7;1044:2;1034:6;1031:1;1027:14;1023:2;1019:23;1015:32;1012:45;1009:65;;;1070:1;1067;1060:12;1009:65;1101:2;1097;1093:11;1083:21;;1123:6;1113:16;;;;;446:689;;;;;:::o;1140:186::-;1199:6;1252:2;1240:9;1231:7;1227:23;1223:32;1220:52;;;1268:1;1265;1258:12;1220:52;1291:29;1310:9;1291:29;:::i;2074:127::-;2135:10;2130:3;2126:20;2123:1;2116:31;2166:4;2163:1;2156:15;2190:4;2187:1;2180:15
Swarm Source
none
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.