Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
AllowListGateKeeper
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;
import "./IGateKeeper.sol";
import "openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
/// @notice A gateKeeper that implements a simple allow list per gate.
contract AllowListGateKeeper is IGateKeeper {
uint96 private _lastId;
/// @notice Get the merkle root used by a gate identifyied by it's `id`.
mapping(uint96 => bytes32) public merkleRoots;
/// @inheritdoc IGateKeeper
function isAllowed(
address participant,
bytes12 id,
bytes memory userData
) external view returns (bool) {
bytes32[] memory proof = abi.decode(userData, (bytes32[]));
bytes32 leaf;
assembly {
mstore(0x00, participant)
leaf := keccak256(0x0C, 20)
}
return MerkleProof.verify(proof, merkleRoots[uint96(id)], leaf);
}
/// @notice Create a new gate using `merkleRoot` to implement the allowlist.
/// @param merkleRoot The merkle root to use for the allowlist.
/// @return id The ID of the new gate.
function createGate(bytes32 merkleRoot) external returns (bytes12 id) {
uint96 id_ = ++_lastId;
merkleRoots[id_] = merkleRoot;
id = bytes12(id_);
}
}// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;
// Interface for a gatekeeper contract used for private crowdfund instances.
interface IGateKeeper {
/// @notice Check if a participant is eligible to participate in a crowdfund.
/// @param participant The address of the participant.
/// @param id The ID of the gate to eligibility against.
/// @param userData The data used to check eligibility.
/// @return `true` if the participant is allowed to participate, `false` otherwise.
function isAllowed(
address participant,
bytes12 id,
bytes memory userData
) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/MerkleProof.sol)
pragma solidity ^0.8.0;
/**
* @dev These functions deal with verification of Merkle Tree proofs.
*
* The proofs can be generated using the JavaScript library
* https://github.com/miguelmota/merkletreejs[merkletreejs].
* Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
*
* See `test/utils/cryptography/MerkleProof.test.js` for some examples.
*
* 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.
*/
library MerkleProof {
/**
* @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}
*
* _Available since v4.7._
*/
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.
*
* _Available since v4.4._
*/
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}
*
* _Available since v4.7._
*/
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 proved to be a part of a Merkle tree defined by
* `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
*
* _Available since v4.7._
*/
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}
*
* _Available since v4.7._
*/
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 the sibling nodes in `proof`,
* consuming from one or the other at each step according to the instructions given by
* `proofFlags`.
*
* _Available since v4.7._
*/
function processMultiProof(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
// This function rebuild 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 totalHashes = proofFlags.length;
// Check proof validity.
require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");
// 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 for 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) {
return hashes[totalHashes - 1];
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
/**
* @dev Calldata version of {processMultiProof}
*
* _Available since v4.7._
*/
function processMultiProofCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
// This function rebuild 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 totalHashes = proofFlags.length;
// Check proof validity.
require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof");
// 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 for 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) {
return hashes[totalHashes - 1];
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
}
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)
}
}
}{
"remappings": [
"ds-test/=lib/solmate/lib/ds-test/src/",
"forge-std/=lib/forge-std/src/",
"openzeppelin/=lib/openzeppelin-contracts/",
"solmate/=lib/solmate/src/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"bytecodeHash": "ipfs"
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "london",
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"createGate","outputs":[{"internalType":"bytes12","name":"id","type":"bytes12"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"participant","type":"address"},{"internalType":"bytes12","name":"id","type":"bytes12"},{"internalType":"bytes","name":"userData","type":"bytes"}],"name":"isAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint96","name":"","type":"uint96"}],"name":"merkleRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b506104a4806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80636a61e4fb1461004657806399e8281414610077578063b889a18f1461009a575b600080fd5b610059610054366004610201565b6100c8565b6040516001600160a01b031990911681526020015b60405180910390f35b61008a610085366004610261565b61011f565b604051901515815260200161006e565b6100ba6100a8366004610334565b60016020526000908152604090205481565b60405190815260200161006e565b600080548190819081906100e4906001600160601b0316610373565b82546001600160601b038083166101009490940a84810291021990911617909255600090815260016020526040902093909355505060a01b90565b600080828060200190518101906101369190610399565b60008681526014600c2060a087901c82526001602052604090912054919250906101629083908361016c565b9695505050505050565b6000826101798584610182565b14949350505050565b600081815b84518110156101c7576101b3828683815181106101a6576101a661043f565b60200260200101516101cf565b9150806101bf81610455565b915050610187565b509392505050565b60008183106101eb5760008281526020849052604090206101fa565b60008381526020839052604090205b9392505050565b60006020828403121561021357600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156102595761025961021a565b604052919050565b60008060006060848603121561027657600080fd5b83356001600160a01b038116811461028d57600080fd5b92506020848101356001600160a01b0319811681146102ab57600080fd5b9250604085013567ffffffffffffffff808211156102c857600080fd5b818701915087601f8301126102dc57600080fd5b8135818111156102ee576102ee61021a565b610300601f8201601f19168501610230565b9150808252888482850101111561031657600080fd5b80848401858401376000848284010152508093505050509250925092565b60006020828403121561034657600080fd5b81356001600160601b03811681146101fa57600080fd5b634e487b7160e01b600052601160045260246000fd5b60006001600160601b0380831681810361038f5761038f61035d565b6001019392505050565b600060208083850312156103ac57600080fd5b825167ffffffffffffffff808211156103c457600080fd5b818501915085601f8301126103d857600080fd5b8151818111156103ea576103ea61021a565b8060051b91506103fb848301610230565b818152918301840191848101908884111561041557600080fd5b938501935b838510156104335784518252938501939085019061041a565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b6000600182016104675761046761035d565b506001019056fea26469706673582212205aa26e66bdd4a71aded1a4f6f61ad96097e70d197027a66306454c39a88e325964736f6c63430008110033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100415760003560e01c80636a61e4fb1461004657806399e8281414610077578063b889a18f1461009a575b600080fd5b610059610054366004610201565b6100c8565b6040516001600160a01b031990911681526020015b60405180910390f35b61008a610085366004610261565b61011f565b604051901515815260200161006e565b6100ba6100a8366004610334565b60016020526000908152604090205481565b60405190815260200161006e565b600080548190819081906100e4906001600160601b0316610373565b82546001600160601b038083166101009490940a84810291021990911617909255600090815260016020526040902093909355505060a01b90565b600080828060200190518101906101369190610399565b60008681526014600c2060a087901c82526001602052604090912054919250906101629083908361016c565b9695505050505050565b6000826101798584610182565b14949350505050565b600081815b84518110156101c7576101b3828683815181106101a6576101a661043f565b60200260200101516101cf565b9150806101bf81610455565b915050610187565b509392505050565b60008183106101eb5760008281526020849052604090206101fa565b60008381526020839052604090205b9392505050565b60006020828403121561021357600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156102595761025961021a565b604052919050565b60008060006060848603121561027657600080fd5b83356001600160a01b038116811461028d57600080fd5b92506020848101356001600160a01b0319811681146102ab57600080fd5b9250604085013567ffffffffffffffff808211156102c857600080fd5b818701915087601f8301126102dc57600080fd5b8135818111156102ee576102ee61021a565b610300601f8201601f19168501610230565b9150808252888482850101111561031657600080fd5b80848401858401376000848284010152508093505050509250925092565b60006020828403121561034657600080fd5b81356001600160601b03811681146101fa57600080fd5b634e487b7160e01b600052601160045260246000fd5b60006001600160601b0380831681810361038f5761038f61035d565b6001019392505050565b600060208083850312156103ac57600080fd5b825167ffffffffffffffff808211156103c457600080fd5b818501915085601f8301126103d857600080fd5b8151818111156103ea576103ea61021a565b8060051b91506103fb848301610230565b818152918301840191848101908884111561041557600080fd5b938501935b838510156104335784518252938501939085019061041a565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b6000600182016104675761046761035d565b506001019056fea26469706673582212205aa26e66bdd4a71aded1a4f6f61ad96097e70d197027a66306454c39a88e325964736f6c63430008110033
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.