Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Contract Source Code Verified (Exact Match)
Contract Name:
RecurringGrantDrop
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 10000 runs
Other Settings:
default evmVersion
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"; import {ByteHasher} from "world-id-contracts/libraries/ByteHasher.sol"; /// @title RecurringGrantDrop /// @author Worldcoin contract RecurringGrantDrop { using ByteHasher for bytes; /////////////////////////////////////////////////////////////////////////////// /// 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 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 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( groupId, root, abi.encodePacked(receiver).hashToField(), 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), from) // Append the "from" argument. mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. 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), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. 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), to) // Append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. 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; /// @title WorldID Interface /// @author Worldcoin /// @notice The interface to the proof verification for WorldID. interface IWorldID { /// @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; /// @title WorldID Interface with Groups /// @author Worldcoin /// @notice The interface to the proof verification for WorldID. interface IWorldIDGroups { /// @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 groupId, uint256 root, uint256 signalHash, uint256 nullifierHash, uint256 externalNullifierHash, uint256[8] calldata proof ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; library ByteHasher { /// @dev Creates a keccak256 hash of a bytestring. /// @param value The bytestring to hash /// @return The hash of the specified value /// @dev `>> 8` makes sure that the result is included in our field function hashToField(bytes memory value) internal pure returns (uint256) { return uint256(keccak256(abi.encodePacked(value))) >> 8; } }
{ "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/", "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": { "bytecodeHash": "none", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"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
610120604052336101005234801561001657600080fd5b50604051610b6e380380610b6e83398101604081905261003591610086565b6001600160a01b0394851660805260a09390935290831660c052821660e052600080546001600160a01b031916919092161790556100f1565b6001600160a01b038116811461008357600080fd5b50565b600080600080600060a0868803121561009e57600080fd5b85516100a98161006e565b6020870151604088015191965094506100c18161006e565b60608701519093506100d28161006e565b60808701519092506100e38161006e565b809150509295509295909350565b60805160a05160c05160e05161010051610a166101586000396000818161010b015281816101df015281816102c7015261038501526000818161017e01526106e80152600081816101a501526106c601526000610531015260006104f50152610a166000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80639546f95e11610076578063a41e6ceb1161005b578063a41e6ceb14610166578063e534155d14610179578063fc0c546a146101a057600080fd5b80639546f95e1461014057806398359fd11461015357600080fd5b806330c3eaa8146100a85780633e450d71146100f1578063481c6a7514610106578063613a7b481461012d575b600080fd5b6000546100c89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6101046100ff366004610909565b6101c7565b005b6100c87f000000000000000000000000000000000000000000000000000000000000000081565b61010461013b366004610909565b6102af565b61010461014e366004610909565b61036d565b61010461016136600461092d565b610428565b61010461017436600461092d565b610601565b6100c87f000000000000000000000000000000000000000000000000000000000000000081565b6100c87f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610236576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f7f877502ebf2038c3656d0c4c3a24f370b4bc208246c5138817a9babdb433c2a9060200160405180910390a150565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461031e576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260026020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146103dc576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260026020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60008281526001602052604090205460ff1615610471576040517f5d904cb200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000546040517f77153fd00000000000000000000000000000000000000000000000000000000081526004810187905273ffffffffffffffffffffffffffffffffffffffff909116906377153fd09060240160006040518083038186803b1580156104db57600080fd5b505afa1580156104ef573d6000803e3d6000fd5b505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633bc778e37f0000000000000000000000000000000000000000000000000000000000000000856105a488604051602001610590919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b6040516020818303038152906040526107c7565b868a876040518763ffffffff1660e01b81526004016105c896959493929190610989565b600060405180830381600087803b1580156105e257600080fd5b505af11580156105f6573d6000803e3d6000fd5b505050505050505050565b3360009081526002602052604090205460ff1661064a576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106578585858585610428565b600082815260016020819052604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909217909155905490517f9980ec8600000000000000000000000000000000000000000000000000000000815260048101879052610772917f0000000000000000000000000000000000000000000000000000000000000000917f000000000000000000000000000000000000000000000000000000000000000091889173ffffffffffffffffffffffffffffffffffffffff90911690639980ec8690602401602060405180830381865afa158015610749573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076d91906109c1565b61081a565b6040805186815273ffffffffffffffffffffffffffffffffffffffff861660208201527fcb745ef40e04fcff0b474c186c7befb757851b212a93baa6c1665c7ae52e3a7a910160405180910390a15050505050565b60006008826040516020016107dc91906109da565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120901c92915050565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081528460048201528360248201528260448201526020600060648360008a5af13d15601f3d11600160005114161716915050806108dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c4544000000000000000000000000604482015260640160405180910390fd5b5050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461090657600080fd5b50565b60006020828403121561091b57600080fd5b8135610926816108e4565b9392505050565b600080600080600061018080878903121561094757600080fd5b863595506020870135610959816108e4565b9450604087013593506060870135925080870188101561097857600080fd5b506080860190509295509295909350565b60006101a0820190508782528660208301528560408301528460608301528360808301526101008360a0840137979650505050505050565b6000602082840312156109d357600080fd5b5051919050565b6000825160005b818110156109fb57602081860181015185830152016109e1565b50600092019182525091905056fea164736f6c6343000813000a000000000000000000000000f7134ce138832c1456f2a91d64621ee90c2bddea00000000000000000000000000000000000000000000000000000000000000010000000000000000000000008acecfa353f46c6afe235b2b838154426612cdd800000000000000000000000080dc00811e7c4a03c1f1599d3dc8febaad87bf87000000000000000000000000d7243020c24895e669773868ffbff4b581d8cd6d
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000f7134ce138832c1456f2a91d64621ee90c2bddea00000000000000000000000000000000000000000000000000000000000000010000000000000000000000008acecfa353f46c6afe235b2b838154426612cdd800000000000000000000000080dc00811e7c4a03c1f1599d3dc8febaad87bf87000000000000000000000000d7243020c24895e669773868ffbff4b581d8cd6d
-----Decoded View---------------
Arg [0] : _worldIdRouter (address): 0xf7134ce138832c1456f2a91d64621ee90c2bddea
Arg [1] : _groupId (uint256): 1
Arg [2] : _token (address): 0x8acecfa353f46c6afe235b2b838154426612cdd8
Arg [3] : _holder (address): 0x80dc00811e7c4a03c1f1599d3dc8febaad87bf87
Arg [4] : _grant (address): 0xd7243020c24895e669773868ffbff4b581d8cd6d
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000f7134ce138832c1456f2a91d64621ee90c2bddea
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [2] : 0000000000000000000000008acecfa353f46c6afe235b2b838154426612cdd8
Arg [3] : 00000000000000000000000080dc00811e7c4a03c1f1599d3dc8febaad87bf87
Arg [4] : 000000000000000000000000d7243020c24895e669773868ffbff4b581d8cd6d
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.