Overview
ETH Balance
ETH Value
$0.00Latest 25 from a total of 23,743 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Claim | 107270112 | 956 days ago | IN | 0 ETH | 0.000192022825 | ||||
| Claim | 107270093 | 956 days ago | IN | 0 ETH | 0.000192196131 | ||||
| Claim | 107270087 | 956 days ago | IN | 0 ETH | 0.000195143633 | ||||
| Claim | 107270084 | 956 days ago | IN | 0 ETH | 0.000196126799 | ||||
| Claim | 107270063 | 956 days ago | IN | 0 ETH | 0.000175759354 | ||||
| Claim | 107270051 | 956 days ago | IN | 0 ETH | 0.00016209039 | ||||
| Claim | 107270047 | 956 days ago | IN | 0 ETH | 0.000170680673 | ||||
| Claim | 107270044 | 956 days ago | IN | 0 ETH | 0.000171313091 | ||||
| Claim | 107270033 | 956 days ago | IN | 0 ETH | 0.000171559829 | ||||
| Claim | 107270011 | 956 days ago | IN | 0 ETH | 0.000169914874 | ||||
| Claim | 107269980 | 956 days ago | IN | 0 ETH | 0.000178586432 | ||||
| Claim | 107269970 | 956 days ago | IN | 0 ETH | 0.000176965894 | ||||
| Claim | 107269957 | 956 days ago | IN | 0 ETH | 0.000176797931 | ||||
| Claim | 107269939 | 956 days ago | IN | 0 ETH | 0.000178791876 | ||||
| Claim | 107269933 | 956 days ago | IN | 0 ETH | 0.000185872932 | ||||
| Claim | 107269918 | 956 days ago | IN | 0 ETH | 0.000176167518 | ||||
| Claim | 107269914 | 956 days ago | IN | 0 ETH | 0.000180937991 | ||||
| Claim | 107269907 | 956 days ago | IN | 0 ETH | 0.000187672034 | ||||
| Claim | 107269896 | 956 days ago | IN | 0 ETH | 0.000182112822 | ||||
| Claim | 107269885 | 956 days ago | IN | 0 ETH | 0.000178844834 | ||||
| Claim | 107269882 | 956 days ago | IN | 0 ETH | 0.000179068738 | ||||
| Claim | 107269854 | 956 days ago | IN | 0 ETH | 0.000168243758 | ||||
| Claim | 107269850 | 956 days ago | IN | 0 ETH | 0.000167975907 | ||||
| Claim | 107269827 | 956 days ago | IN | 0 ETH | 0.000174391673 | ||||
| Claim | 107269816 | 956 days ago | IN | 0 ETH | 0.000176753368 |
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 107270112 | 956 days ago | 0 ETH | ||||
| 107270112 | 956 days ago | 0 ETH | ||||
| 107270112 | 956 days ago | 0 ETH | ||||
| 107270112 | 956 days ago | 0 ETH | ||||
| 107270093 | 956 days ago | 0 ETH | ||||
| 107270093 | 956 days ago | 0 ETH | ||||
| 107270093 | 956 days ago | 0 ETH | ||||
| 107270093 | 956 days ago | 0 ETH | ||||
| 107270087 | 956 days ago | 0 ETH | ||||
| 107270087 | 956 days ago | 0 ETH | ||||
| 107270087 | 956 days ago | 0 ETH | ||||
| 107270087 | 956 days ago | 0 ETH | ||||
| 107270084 | 956 days ago | 0 ETH | ||||
| 107270084 | 956 days ago | 0 ETH | ||||
| 107270084 | 956 days ago | 0 ETH | ||||
| 107270084 | 956 days ago | 0 ETH | ||||
| 107270063 | 956 days ago | 0 ETH | ||||
| 107270063 | 956 days ago | 0 ETH | ||||
| 107270063 | 956 days ago | 0 ETH | ||||
| 107270063 | 956 days ago | 0 ETH | ||||
| 107270051 | 956 days ago | 0 ETH | ||||
| 107270051 | 956 days ago | 0 ETH | ||||
| 107270051 | 956 days ago | 0 ETH | ||||
| 107270051 | 956 days ago | 0 ETH | ||||
| 107270047 | 956 days ago | 0 ETH |
Cross-Chain Transactions
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x7D8ee529...A64FaEb0A The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import {ERC20} from "solmate/tokens/ERC20.sol";
import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol";
import { IGrant } from './IGrant.sol';
import {IWorldID} from "world-id-contracts/interfaces/IWorldID.sol";
import {IWorldIDGroups} from "world-id-contracts/interfaces/IWorldIDGroups.sol";
/// @title RecurringGrantDrop
/// @author Worldcoin
contract RecurringGrantDrop {
///////////////////////////////////////////////////////////////////////////////
/// ERRORS ///
//////////////////////////////////////////////////////////////////////////////
/// @notice Thrown when restricted functions are called by not allowed addresses
error Unauthorized();
/// @notice Thrown when attempting to reuse a nullifier
error InvalidNullifier();
///////////////////////////////////////////////////////////////////////////////
/// EVENTS ///
//////////////////////////////////////////////////////////////////////////////
/// @notice Emitted when a grant is successfully claimed
/// @param receiver The address that received the tokens
event GrantClaimed(uint256 grantId, address receiver);
/// @notice Emitted when the grant is changed
/// @param grant The new grant instance
event GrantUpdated(IGrant grant);
///////////////////////////////////////////////////////////////////////////////
/// CONFIG STORAGE ///
//////////////////////////////////////////////////////////////////////////////
/// @dev The WorldID router instance that will be used for managing groups and verifying proofs
IWorldIDGroups internal immutable worldIdRouter;
/// @dev The World ID group whose participants can claim this airdrop
uint256 internal immutable groupId;
/// @notice The ERC20 token airdropped
ERC20 public immutable token;
/// @notice The address that holds the tokens that are being airdropped
/// @dev Make sure the holder has approved spending for this contract!
address public immutable holder;
/// @notice The address that manages this airdrop
address public immutable manager = msg.sender;
/// @notice The grant instance used
IGrant public grant;
/// @dev Whether a nullifier hash has been used already. Used to prevent double-signaling
mapping(uint256 => bool) internal nullifierHashes;
/// @dev Allowed addresses to call `claim`
mapping(address => bool) internal allowedCallers;
///////////////////////////////////////////////////////////////////////////////
/// CONSTRUCTOR ///
//////////////////////////////////////////////////////////////////////////////
/// @notice Deploys a WorldIDAirdrop instance
/// @param _worldIdRouter The WorldID router that will manage groups and verify proofs
/// @param _groupId The group ID of the World ID
/// @param _token The ERC20 token that will be airdropped
/// @param _holder The address holding the tokens that will be airdropped
/// @param _grant The grant that contains the amounts and validity
constructor(
IWorldIDGroups _worldIdRouter,
uint256 _groupId,
ERC20 _token,
address _holder,
IGrant _grant
) {
worldIdRouter = _worldIdRouter;
groupId = _groupId;
token = _token;
holder = _holder;
grant = _grant;
}
///////////////////////////////////////////////////////////////////////////////
/// CLAIM LOGIC ///
//////////////////////////////////////////////////////////////////////////////
/// @notice Claim the airdrop
/// @param grantId The grant ID to claim
/// @param receiver The address that will receive the tokens (this is also the signal of the ZKP)
/// @param root The root of the Merkle tree (signup-sequencer or world-id-contracts provides this)
/// @param nullifierHash The nullifier for this proof, preventing double signaling
/// @param proof The zero knowledge proof that demonstrates the claimer has a verified World ID
/// @dev hashToField function docs are in lib/world-id-contracts/src/libraries/ByteHasher.sol
function claim(uint256 grantId, address receiver, uint256 root, uint256 nullifierHash, uint256[8] calldata proof)
public
{
if (!allowedCallers[msg.sender]) revert Unauthorized();
checkClaim(grantId, receiver, root, nullifierHash, proof);
nullifierHashes[nullifierHash] = true;
SafeTransferLib.safeTransferFrom(token, holder, receiver, grant.getAmount(grantId));
emit GrantClaimed(grantId, receiver);
}
/// @notice Check whether a claim is valid
/// @param grantId The grant ID to claim
/// @param receiver The address that will receive the tokens (this is also the signal of the ZKP)
/// @param root The root of the Merkle tree (signup-sequencer or world-id-contracts provides this)
/// @param nullifierHash The nullifier for this proof, preventing double signaling
/// @param proof The zero knowledge proof that demonstrates the claimer has a verified World ID
function checkClaim(uint256 grantId, address receiver, uint256 root, uint256 nullifierHash, uint256[8] calldata proof)
public
{
if (nullifierHashes[nullifierHash]) revert InvalidNullifier();
grant.checkValidity(grantId);
worldIdRouter.verifyProof(
root,
groupId,
uint256(keccak256(abi.encodePacked(receiver))) >> 8,
nullifierHash,
grantId,
proof
);
}
///////////////////////////////////////////////////////////////////////////////
/// CONFIG LOGIC ///
//////////////////////////////////////////////////////////////////////////////
/// @notice Add a caller to the list of allowed callers
/// @param _caller The address to add
function addAllowedCaller(address _caller) public {
if (msg.sender != manager) revert Unauthorized();
allowedCallers[_caller] = true;
}
/// @notice Remove a caller to the list of allowed callers
/// @param _caller The address to remove
function removeAllowedCaller(address _caller) public {
if (msg.sender != manager) revert Unauthorized();
allowedCallers[_caller] = false;
}
/// @notice Update the grant
/// @param _grant The new grant
function setGrant(IGrant _grant) public {
if (msg.sender != manager) revert Unauthorized();
grant = _grant;
emit GrantUpdated(_grant);
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
/*//////////////////////////////////////////////////////////////
METADATA STORAGE
//////////////////////////////////////////////////////////////*/
string public name;
string public symbol;
uint8 public immutable decimals;
/*//////////////////////////////////////////////////////////////
ERC20 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
/*//////////////////////////////////////////////////////////////
EIP-2612 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 internal immutable INITIAL_CHAIN_ID;
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public nonces;
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
}
/*//////////////////////////////////////////////////////////////
ERC20 LOGIC
//////////////////////////////////////////////////////////////*/
function approve(address spender, uint256 amount) public virtual returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
balanceOf[msg.sender] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
/*//////////////////////////////////////////////////////////////
EIP-2612 LOGIC
//////////////////////////////////////////////////////////////*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
// Unchecked because the only math done is incrementing
// the owner's nonce which cannot realistically overflow.
unchecked {
address recoveredAddress = ecrecover(
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
),
owner,
spender,
value,
nonces[owner]++,
deadline
)
)
)
),
v,
r,
s
);
require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
allowance[recoveredAddress][spender] = value;
}
emit Approval(owner, spender, value);
}
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
}
function computeDomainSeparator() internal view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256("1"),
block.chainid,
address(this)
)
);
}
/*//////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(address to, uint256 amount) internal virtual {
totalSupply += amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(address(0), to, amount);
}
function _burn(address from, uint256 amount) internal virtual {
balanceOf[from] -= amount;
// Cannot underflow because a user's balance
// will never be larger than the total supply.
unchecked {
totalSupply -= amount;
}
emit Transfer(from, address(0), amount);
}
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../tokens/ERC20.sol";
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
/*//////////////////////////////////////////////////////////////
ETH OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferETH(address to, uint256 amount) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Transfer the ETH and store if it succeeded or not.
success := call(gas(), to, amount, 0, 0, 0, 0)
}
require(success, "ETH_TRANSFER_FAILED");
}
/*//////////////////////////////////////////////////////////////
ERC20 OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferFrom(
ERC20 token,
address from,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument.
mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
)
}
require(success, "TRANSFER_FROM_FAILED");
}
function safeTransfer(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
}
require(success, "TRANSFER_FAILED");
}
function safeApprove(
ERC20 token,
address to,
uint256 amount
) internal {
bool success;
/// @solidity memory-safe-assembly
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata into memory, beginning with the function selector.
mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.
success := and(
// Set success to whether the call reverted, if not we check it either
// returned exactly 1 (can't just be non-zero data), or had no return data.
or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
// We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
// We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
// Counterintuitively, this call must be positioned second to the or() call in the
// surrounding and() call or else returndatasize() will be zero during the computation.
call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
)
}
require(success, "APPROVE_FAILED");
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
interface IGrant {
/// @notice Error in case the grant is invalid.
error InvalidGrant();
/// @notice Returns the current grant id.
function getCurrentId() external view returns (uint256);
/// @notice Returns the amount of tokens for a grant.
/// @notice This may contain more complicated logic and is therefore not just a member variable.
/// @param grantId The grant id to get the amount for.
function getAmount(uint256 grantId) external view returns (uint256);
/// @notice Checks whether a grant is valid.
/// @param grantId The grant id to check.
function checkValidity(uint256 grantId) external view;
}//SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import {IBaseWorldID} from "./IBaseWorldID.sol";
/// @title WorldID Interface
/// @author Worldcoin
/// @notice The interface to the proof verification for WorldID.
interface IWorldID is IBaseWorldID {
/// @notice Verifies a WorldID zero knowledge proof.
/// @dev Note that a double-signaling check is not included here, and should be carried by the
/// caller.
/// @dev It is highly recommended that the implementation is restricted to `view` if possible.
///
/// @param root The of the Merkle tree
/// @param signalHash A keccak256 hash of the Semaphore signal
/// @param nullifierHash The nullifier hash
/// @param externalNullifierHash A keccak256 hash of the external nullifier
/// @param proof The zero-knowledge proof
///
/// @custom:reverts string If the `proof` is invalid.
function verifyProof(
uint256 root,
uint256 signalHash,
uint256 nullifierHash,
uint256 externalNullifierHash,
uint256[8] calldata proof
) external;
}//SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import {IBaseWorldID} from "./IBaseWorldID.sol";
/// @title WorldID Interface with Groups
/// @author Worldcoin
/// @notice The interface to the proof verification for WorldID.
interface IWorldIDGroups is IBaseWorldID {
/// @notice Verifies a WorldID zero knowledge proof.
/// @dev Note that a double-signaling check is not included here, and should be carried by the
/// caller.
/// @dev It is highly recommended that the implementation is restricted to `view` if possible.
///
/// @param groupId The group identifier for the group to verify a proof for.
/// @param root The of the Merkle tree
/// @param signalHash A keccak256 hash of the Semaphore signal
/// @param nullifierHash The nullifier hash
/// @param externalNullifierHash A keccak256 hash of the external nullifier
/// @param proof The zero-knowledge proof
///
/// @custom:reverts string If the `proof` is invalid.
/// @custom:reverts NoSuchGroup If the provided `groupId` references a group that does not exist.
function verifyProof(
uint256 root,
uint256 groupId,
uint256 signalHash,
uint256 nullifierHash,
uint256 externalNullifierHash,
uint256[8] calldata proof
) external;
}//SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
/// @title Base WorldID interface
/// @author Worldcoin
/// @notice The interface providing basic types across various WorldID contracts.
interface IBaseWorldID {
///////////////////////////////////////////////////////////////////////////////
/// ERRORS ///
///////////////////////////////////////////////////////////////////////////////
/// @notice Thrown when attempting to validate a root that has expired.
error ExpiredRoot();
/// @notice Thrown when attempting to validate a root that has yet to be added to the root
/// history.
error NonExistentRoot();
}{
"remappings": [
"@openzeppelin/=lib/openzeppelin-contracts/",
"@prb/test/=lib/prb-test/src/",
"@zk-kit/=lib/zk-kit/packages/",
"contracts-upgradeable/=lib/world-id-contracts/lib/openzeppelin-contracts-upgradeable/contracts/",
"ds-test/=lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"openzeppelin-contracts-upgradeable/=lib/world-id-contracts/lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"openzeppelin/=lib/openzeppelin-contracts/contracts/",
"prb-test/=lib/prb-test/src/",
"semaphore/=lib/semaphore/",
"solmate/=lib/solmate/src/",
"src/=src/",
"world-id-contracts/=lib/world-id-contracts/src/",
"zk-kit/=lib/zk-kit/"
],
"optimizer": {
"enabled": true,
"runs": 10000,
"details": {
"peephole": true,
"inliner": true,
"deduplicate": true,
"cse": true,
"yul": true
}
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "none",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IWorldIDGroups","name":"_worldIdRouter","type":"address"},{"internalType":"uint256","name":"_groupId","type":"uint256"},{"internalType":"contract ERC20","name":"_token","type":"address"},{"internalType":"address","name":"_holder","type":"address"},{"internalType":"contract IGrant","name":"_grant","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidNullifier","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"grantId","type":"uint256"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"}],"name":"GrantClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IGrant","name":"grant","type":"address"}],"name":"GrantUpdated","type":"event"},{"inputs":[{"internalType":"address","name":"_caller","type":"address"}],"name":"addAllowedCaller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"grantId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"root","type":"uint256"},{"internalType":"uint256","name":"nullifierHash","type":"uint256"},{"internalType":"uint256[8]","name":"proof","type":"uint256[8]"}],"name":"checkClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"grantId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"root","type":"uint256"},{"internalType":"uint256","name":"nullifierHash","type":"uint256"},{"internalType":"uint256[8]","name":"proof","type":"uint256[8]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"grant","outputs":[{"internalType":"contract IGrant","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"holder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_caller","type":"address"}],"name":"removeAllowedCaller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IGrant","name":"_grant","type":"address"}],"name":"setGrant","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
0x610120604052336101005234801561001657600080fd5b50604051610b55380380610b5583398101604081905261003591610086565b6001600160a01b0394851660805260a09390935290831660c052821660e052600080546001600160a01b031916919092161790556100f1565b6001600160a01b038116811461008357600080fd5b50565b600080600080600060a0868803121561009e57600080fd5b85516100a98161006e565b6020870151604088015191965094506100c18161006e565b60608701519093506100d28161006e565b60808701519092506100e38161006e565b809150509295509295909350565b60805160a05160c05160e051610100516109fd6101586000396000818161010b015281816101df015281816102c7015261038501526000818161017e01526107250152600081816101a5015261070301526000610532015260006104f501526109fd6000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80639546f95e11610076578063a41e6ceb1161005b578063a41e6ceb14610166578063e534155d14610179578063fc0c546a146101a057600080fd5b80639546f95e1461014057806398359fd11461015357600080fd5b806330c3eaa8146100a85780633e450d71146100f1578063481c6a7514610106578063613a7b481461012d575b600080fd5b6000546100c89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6101046100ff36600461091f565b6101c7565b005b6100c87f000000000000000000000000000000000000000000000000000000000000000081565b61010461013b36600461091f565b6102af565b61010461014e36600461091f565b61036d565b610104610161366004610943565b610428565b610104610174366004610943565b61063e565b6100c87f000000000000000000000000000000000000000000000000000000000000000081565b6100c87f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610236576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f7f877502ebf2038c3656d0c4c3a24f370b4bc208246c5138817a9babdb433c2a9060200160405180910390a150565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461031e576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260026020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146103dc576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260026020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60008281526001602052604090205460ff1615610471576040517f5d904cb200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000546040517f77153fd00000000000000000000000000000000000000000000000000000000081526004810187905273ffffffffffffffffffffffffffffffffffffffff909116906377153fd09060240160006040518083038186803b1580156104db57600080fd5b505afa1580156104ef573d6000803e3d6000fd5b505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633bc778e3847f000000000000000000000000000000000000000000000000000000000000000060088860405160200161058f919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020909101207fffffffff0000000000000000000000000000000000000000000000000000000060e087901b1682526106059493921c9088908c90899060040161099f565b600060405180830381600087803b15801561061f57600080fd5b505af1158015610633573d6000803e3d6000fd5b505050505050505050565b3360009081526002602052604090205460ff16610687576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106948585858585610428565b600082815260016020819052604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909217909155905490517f9980ec86000000000000000000000000000000000000000000000000000000008152600481018790526107af917f0000000000000000000000000000000000000000000000000000000000000000917f000000000000000000000000000000000000000000000000000000000000000091889173ffffffffffffffffffffffffffffffffffffffff90911690639980ec8690602401602060405180830381865afa158015610786573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107aa91906109d7565b610804565b6040805186815273ffffffffffffffffffffffffffffffffffffffff861660208201527fcb745ef40e04fcff0b474c186c7befb757851b212a93baa6c1665c7ae52e3a7a910160405180910390a15050505050565b60006040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015273ffffffffffffffffffffffffffffffffffffffff841660248201528260448201526020600060648360008a5af13d15601f3d11600160005114161716915050806108f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c4544000000000000000000000000604482015260640160405180910390fd5b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461091c57600080fd5b50565b60006020828403121561093157600080fd5b813561093c816108fa565b9392505050565b600080600080600061018080878903121561095d57600080fd5b86359550602087013561096f816108fa565b9450604087013593506060870135925080870188101561098e57600080fd5b506080860190509295509295909350565b60006101a0820190508782528660208301528560408301528460608301528360808301526101008360a0840137979650505050505050565b6000602082840312156109e957600080fd5b505191905056fea164736f6c6343000813000a00000000000000000000000057f928158c3ee7cdad1e4d8642503c4d0201f61100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000346c32e5d7e98bd57100b6f7002a0ae1718804800000000000000000000000080dc00811e7c4a03c1f1599d3dc8febaad87bf87000000000000000000000000e89fa795611a1da4cf5e4c7ec908f4244f13aad1
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100a35760003560e01c80639546f95e11610076578063a41e6ceb1161005b578063a41e6ceb14610166578063e534155d14610179578063fc0c546a146101a057600080fd5b80639546f95e1461014057806398359fd11461015357600080fd5b806330c3eaa8146100a85780633e450d71146100f1578063481c6a7514610106578063613a7b481461012d575b600080fd5b6000546100c89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6101046100ff36600461091f565b6101c7565b005b6100c87f0000000000000000000000007d896339a80dd38bc3bbb04383894c62b2ef258581565b61010461013b36600461091f565b6102af565b61010461014e36600461091f565b61036d565b610104610161366004610943565b610428565b610104610174366004610943565b61063e565b6100c87f00000000000000000000000080dc00811e7c4a03c1f1599d3dc8febaad87bf8781565b6100c87f0000000000000000000000000346c32e5d7e98bd57100b6f7002a0ae1718804881565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007d896339a80dd38bc3bbb04383894c62b2ef25851614610236576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f7f877502ebf2038c3656d0c4c3a24f370b4bc208246c5138817a9babdb433c2a9060200160405180910390a150565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007d896339a80dd38bc3bbb04383894c62b2ef2585161461031e576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260026020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000007d896339a80dd38bc3bbb04383894c62b2ef258516146103dc576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260026020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60008281526001602052604090205460ff1615610471576040517f5d904cb200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000546040517f77153fd00000000000000000000000000000000000000000000000000000000081526004810187905273ffffffffffffffffffffffffffffffffffffffff909116906377153fd09060240160006040518083038186803b1580156104db57600080fd5b505afa1580156104ef573d6000803e3d6000fd5b505050507f00000000000000000000000057f928158c3ee7cdad1e4d8642503c4d0201f61173ffffffffffffffffffffffffffffffffffffffff16633bc778e3847f000000000000000000000000000000000000000000000000000000000000000160088860405160200161058f919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020909101207fffffffff0000000000000000000000000000000000000000000000000000000060e087901b1682526106059493921c9088908c90899060040161099f565b600060405180830381600087803b15801561061f57600080fd5b505af1158015610633573d6000803e3d6000fd5b505050505050505050565b3360009081526002602052604090205460ff16610687576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106948585858585610428565b600082815260016020819052604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909217909155905490517f9980ec86000000000000000000000000000000000000000000000000000000008152600481018790526107af917f0000000000000000000000000346c32e5d7e98bd57100b6f7002a0ae17188048917f00000000000000000000000080dc00811e7c4a03c1f1599d3dc8febaad87bf8791889173ffffffffffffffffffffffffffffffffffffffff90911690639980ec8690602401602060405180830381865afa158015610786573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107aa91906109d7565b610804565b6040805186815273ffffffffffffffffffffffffffffffffffffffff861660208201527fcb745ef40e04fcff0b474c186c7befb757851b212a93baa6c1665c7ae52e3a7a910160405180910390a15050505050565b60006040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015273ffffffffffffffffffffffffffffffffffffffff841660248201528260448201526020600060648360008a5af13d15601f3d11600160005114161716915050806108f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c4544000000000000000000000000604482015260640160405180910390fd5b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461091c57600080fd5b50565b60006020828403121561093157600080fd5b813561093c816108fa565b9392505050565b600080600080600061018080878903121561095d57600080fd5b86359550602087013561096f816108fa565b9450604087013593506060870135925080870188101561098e57600080fd5b506080860190509295509295909350565b60006101a0820190508782528660208301528560408301528460608301528360808301526101008360a0840137979650505050505050565b6000602082840312156109e957600080fd5b505191905056fea164736f6c6343000813000a
Net Worth in USD
Net Worth in ETH
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.