Address Contract Verified
Address
0xe48F30cbff7966460B65Ce55D79b49FC05C6427E
Balance
0 ETH
Nonce
1
Code Size
3251 bytes
Creator
0xd125B79B...50c2 at tx 0x25970a97...09f75f
Indexed Transactions
0
Contract Bytecode
3251 bytes
0x608060405234801561001057600080fd5b50600436106101215760003560e01c806387c13943116100ad578063cdf76d5a11610071578063cdf76d5a1461028a578063cf9fccb2146102ae578063d6de5cf6146102b6578063e834a834146102be578063fc0c546a146102c657610121565b806387c13943146102395780638bc85b03146102415780638bdff16114610249578063910ada6b146102515780639e34070f1461025957610121565b806341c61383116100f457806341c6138314610211578063545e9233146102195780635b0a3843146102215780636261c662146102295780636cecaa2c1461023157610121565b806324f0808c146101265780632e7ba6ef146101405780632eb4a7ab146101ce5780634021f45f146101d6575b600080fd5b61012e6102ce565b60408051918252519081900360200190f35b6101cc6004803603608081101561015657600080fd5b8135916001600160a01b03602082013516916040820135919081019060808101606082013564010000000081111561018d57600080fd5b82018360208201111561019f57600080fd5b803590602001918460208302840111640100000000831117156101c157600080fd5b5090925090506102da565b005b61012e61059a565b6101f3600480360360208110156101ec57600080fd5b50356105be565b60408051938452602084019290925282820152519081900360600190f35b61012e610698565b61012e61069e565b6101cc6106a4565b61012e61080e565b61012e610814565b61012e61081a565b61012e610826565b61012e61082c565b61012e610881565b6102766004803603602081101561026f57600080fd5b5035610887565b604080519115158252519081900360200190f35b6102926108ac565b604080516001600160a01b039092168252519081900360200190f35b61012e6108bb565b61012e6108c1565b61012e6108c7565b6102926108cd565b670ddd2935029d800081565b6102e385610887565b1561031f5760405162461bcd60e51b8152600401808060200182810382526028815260200180610bf16028913960400191505060405180910390fd5b336001600160a01b03851614610373576040805162461bcd60e51b81526020600482015260146024820152734f6e6c79206f776e65722063616e20636c61696d60601b604482015290519081900360640190fd5b600085858560405160200180848152602001836001600160a01b031660601b8152601401828152602001935050505060405160208183030381529060405280519060200120905061041a8383808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152507fddf006569df6484ab7ab529ede30e7d96556298d570ecacb62ad6298a1cf142192508591506108f19050565b6104555760405162461bcd60e51b8152600401808060200182810382526021815260200180610c196021913960400191505060405180910390fd5b61045e8661099a565b6000610469856109c1565b90507f000000000000000000000000da0c94c73d127ee191955fb46bacd7ff999b2bcd6001600160a01b031663a9059cbb87836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156104e257600080fd5b505af11580156104f6573d6000803e3d6000fd5b505050506040513d602081101561050c57600080fd5b50516105495760405162461bcd60e51b8152600401808060200182810382526023815260200180610c3a6023913960400191505060405180910390fd5b604080518881526001600160a01b038816602082015280820183905290517f4ec90e965519d92681267467f775ada5bd214aa92c0dc93d90a5e880ce9ed0269181900360600190a150505050505050565b7fddf006569df6484ab7ab529ede30e7d96556298d570ecacb62ad6298a1cf142181565b600080600060015460055460010114156105ee576004546105e0908590610a70565b600080925092509250610691565b600061062f670de0b6b3a7640000610623600654610629600254610623670de0b6b3a76400008c610ad390919063ffffffff16565b90610b2c565b90610ad3565b9050610652670de0b6b3a764000061062360045484610ad390919063ffffffff16565b915060006106608684610a70565b9050610680670de0b6b3a764000061062361067961082c565b8490610ad3565b935061068c8185610b93565b945050505b9193909250565b60015481565b60065481565b60095442116106f0576040805162461bcd60e51b81526020600482015260136024820152721512535153d55517d393d517d1561412549151606a1b604482015290519081900360640190fd5b600a54604080516370a0823160e01b815230600482015290516001600160a01b037f000000000000000000000000da0c94c73d127ee191955fb46bacd7ff999b2bcd81169363a9059cbb9391169184916370a08231916024808301926020929190829003018186803b15801561076557600080fd5b505afa158015610779573d6000803e3d6000fd5b505050506040513d602081101561078f57600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b1580156107e057600080fd5b505af11580156107f4573d6000803e3d6000fd5b505050506040513d602081101561080a57600080fd5b5050565b60075481565b60045481565b670de0b6b3a764000081565b60085481565b600080600854421161084a576008546108459042610b93565b61084d565b60005b905061087b610869600754600854610b9390919063ffffffff16565b610623670ddd2935029d800084610ad3565b91505090565b60025481565b6101008104600090815260208190526040902054600160ff83161b908116145b919050565b600a546001600160a01b031681565b60095481565b60035481565b60055481565b7f000000000000000000000000da0c94c73d127ee191955fb46bacd7ff999b2bcd81565b600081815b855181101561098f57600086828151811061090d57fe5b602002602001015190508083116109545782816040516020018083815260200182815260200192505050604051602081830303815290604052805190602001209250610986565b808360405160200180838152602001828152602001925050506040516020818303038152906040528051906020012092505b506001016108f6565b509092149392505050565b610100810460009081526020819052604090208054600160ff9093169290921b9091179055565b6000806000806109d0856105be565b6005805460019081019182905554939650919450925014156109f7578293505050506108a7565b600354600090610a079087610b93565b9050610a42670de0b6b3a7640000610623610a3984610623670de0b6b3a7640000600354610ad390919063ffffffff16565b60065490610ad3565b6006556003819055600454610a63908490610a5d9085610b93565b90610a70565b6004555091949350505050565b600082820183811015610aca576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b600082610ae257506000610acd565b82820282848281610aef57fe5b0414610aca5760405162461bcd60e51b8152600401808060200182810382526021815260200180610c5d6021913960400191505060405180910390fd5b6000808211610b82576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381610b8b57fe5b049392505050565b600082821115610bea576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b5090039056fe4d65726b6c654469737472696275746f723a2044726f7020616c726561647920636c61696d65642e4d65726b6c654469737472696275746f723a20496e76616c69642070726f6f662e4d65726b6c654469737472696275746f723a205472616e73666572206661696c65642e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220dc5ab69273f810ab4db9cc2ba08f5d494e1f22d345709c1bc46c1f3f7b79b81b64736f6c63430007030033
Verified Source Code Full Match
Compiler: v0.7.3+commit.9bfce1f6
EVM: istanbul
Optimization: Yes (200 runs)
MerkleDistributor.sol 162 lines
//SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/cryptography/MerkleProof.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
import "./interfaces/IMerkleDistributor.sol";
contract MerkleDistributor is IMerkleDistributor {
using SafeMath for uint256;
address public immutable override token;
bytes32 public immutable override merkleRoot;
// This is a packed array of booleans.
mapping(uint256 => uint256) private claimedBitMap;
// Opium Bonus
uint256 public constant MAX_BONUS = 0.999e18;
uint256 public constant PERCENTAGE_BASE = 1e18;
uint256 public totalClaims;
uint256 public initialPoolSize;
uint256 public currentPoolSize;
uint256 public bonusSum;
uint256 public claimed;
uint256 public percentageIndex;
uint256 public bonusStart;
uint256 public bonusEnd;
uint256 public emergencyTimeout;
address public emergencyReceiver;
constructor(
address token_, // token to be airdropped
bytes32 merkleRoot_, // generated merkle root of airdrop recipients/amounts
uint256 _totalClaims, // number of accounts eligible for airdrop
uint256 _initialPoolSize, // sum of all airdrop amounts, in wei
uint256 _bonusStart, // timestamp at which bonus starts
uint256 _bonusEnd, // timestamp after which bonus is max
uint256 _emergencyTimeout, // time after which an emergency withdrawal can be made
address _emergencyReceiver // receiver of emergency withdrawal, after emergency timeout passes
) {
token = token_;
merkleRoot = merkleRoot_;
// Opium Bonus
totalClaims = _totalClaims;
initialPoolSize = _initialPoolSize;
currentPoolSize = _initialPoolSize;
percentageIndex = PERCENTAGE_BASE;
bonusStart = _bonusStart;
bonusEnd = _bonusEnd;
emergencyTimeout = _emergencyTimeout;
emergencyReceiver = _emergencyReceiver;
require(bonusStart < bonusEnd, "WRONG_BONUS_TIME");
require(emergencyTimeout > bonusEnd, "WRONG_EMERGENCY_TIMEOUT");
}
function isClaimed(uint256 index) public view override returns (bool) {
uint256 claimedWordIndex = index / 256;
uint256 claimedBitIndex = index % 256;
uint256 claimedWord = claimedBitMap[claimedWordIndex];
uint256 mask = (1 << claimedBitIndex);
return claimedWord & mask == mask;
}
function _setClaimed(uint256 index) private {
uint256 claimedWordIndex = index / 256;
uint256 claimedBitIndex = index % 256;
claimedBitMap[claimedWordIndex] =
claimedBitMap[claimedWordIndex] |
(1 << claimedBitIndex);
}
function claim(
uint256 index,
address account,
uint256 amount,
bytes32[] calldata merkleProof
) external override {
require(!isClaimed(index), "MerkleDistributor: Drop already claimed.");
require(msg.sender == account, "Only owner can claim");
// Verify the merkle proof.
bytes32 node = keccak256(abi.encodePacked(index, account, amount));
require(
MerkleProof.verify(merkleProof, merkleRoot, node),
"MerkleDistributor: Invalid proof."
);
// Mark it claimed and send the token.
_setClaimed(index);
uint256 adjustedAmount = _applyAdjustment(amount);
require(
IERC20(token).transfer(account, adjustedAmount),
"MerkleDistributor: Transfer failed."
);
emit Claimed(index, account, adjustedAmount);
}
function getBonus() public view returns (uint256) {
// timeRemaining = bonusEnd - now, or 0 if bonus ended
uint256 timeRemaining =
block.timestamp > bonusEnd ? 0 : bonusEnd.sub(block.timestamp);
// bonus = maxBonus * timeRemaining / (bonusEnd - bonusStart)
return MAX_BONUS.mul(timeRemaining).div(bonusEnd.sub(bonusStart));
}
function calculateAdjustedAmount(uint256 amount)
public
view
returns (
uint256 adjustedAmount,
uint256 bonus,
uint256 bonusPart
)
{
// If last claims, return full amount + full bonus
if (claimed + 1 == totalClaims) {
return (amount.add(bonusSum), 0, 0);
}
// adjustedPercentage = amount / initialPoolSize * percentageIndex
uint256 adjustedPercentage =
amount.mul(PERCENTAGE_BASE).div(initialPoolSize).mul(percentageIndex).div(
PERCENTAGE_BASE
);
// bonusPart = adjustedPercentage * bonusSum
bonusPart = adjustedPercentage.mul(bonusSum).div(PERCENTAGE_BASE);
// totalToClaim = amount + bonusPart
uint256 totalToClaim = amount.add(bonusPart);
// bonus = totalToClaim * getBonus()
bonus = totalToClaim.mul(getBonus()).div(PERCENTAGE_BASE);
// adjustedAmount = totalToClaim - bonus
adjustedAmount = totalToClaim.sub(bonus);
}
function _applyAdjustment(uint256 amount) private returns (uint256) {
(uint256 adjustedAmount, uint256 bonus, uint256 bonusPart) =
calculateAdjustedAmount(amount);
// Increment claim index
claimed += 1;
// If last claims, return full amount, don't update anything
if (claimed == totalClaims) {
return adjustedAmount;
}
// newPoolSize = currentPoolSize - amount
uint256 newPoolSize = currentPoolSize.sub(amount);
// percentageIndex = percentageIndex * currentPoolSize / newPoolSize
percentageIndex = percentageIndex
.mul(currentPoolSize.mul(PERCENTAGE_BASE).div(newPoolSize))
.div(PERCENTAGE_BASE);
// currentPoolSize = newPoolSize
currentPoolSize = newPoolSize;
// bonusSum = bonusSum - bonusPart + bonus
bonusSum = bonusSum.sub(bonusPart).add(bonus);
return adjustedAmount;
}
function emergencyWithdrawal() public {
require(block.timestamp > emergencyTimeout, "TIMEOUT_NOT_EXPIRED");
IERC20(token).transfer(
emergencyReceiver,
IERC20(token).balanceOf(address(this))
);
}
}
SafeMath.sol 214 lines
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
/**
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a / b);
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryDiv}.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}
IMerkleDistributor.sol 25 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
// Allows anyone to claim a token if they exist in a merkle root.
interface IMerkleDistributor {
// Returns the address of the token distributed by this contract.
function token() external view returns (address);
// Returns the merkle root of the merkle tree containing account balances available to claim.
function merkleRoot() external view returns (bytes32);
// Returns true if the index has been marked claimed.
function isClaimed(uint256 index) external view returns (bool);
// Claim the given amount of the token to the given address. Reverts if the inputs are invalid.
function claim(
uint256 index,
address account,
uint256 amount,
bytes32[] calldata merkleProof
) external;
// This event is triggered whenever a call to #claim succeeds.
event Claimed(uint256 index, address account, uint256 amount);
}
IERC20.sol 77 lines
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
MerkleProof.sol 33 lines
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev These functions deal with verification of Merkle trees (hash trees),
*/
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) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
bytes32 proofElement = proof[i];
if (computedHash <= proofElement) {
// Hash(current computed hash + current element of the proof)
computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
} else {
// Hash(current element of the proof + current computed hash)
computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
}
}
// Check if the computed hash (root) is equal to the provided root
return computedHash == root;
}
}
Read Contract
MAX_BONUS 0x24f0808c → uint256
PERCENTAGE_BASE 0x87c13943 → uint256
bonusEnd 0x8bc85b03 → uint256
bonusStart 0x6261c662 → uint256
bonusSum 0x6cecaa2c → uint256
calculateAdjustedAmount 0x4021f45f → uint256, uint256, uint256
claimed 0xe834a834 → uint256
currentPoolSize 0xd6de5cf6 → uint256
emergencyReceiver 0xcdf76d5a → address
emergencyTimeout 0xcf9fccb2 → uint256
getBonus 0x8bdff161 → uint256
initialPoolSize 0x910ada6b → uint256
isClaimed 0x9e34070f → bool
merkleRoot 0x2eb4a7ab → bytes32
percentageIndex 0x545e9233 → uint256
token 0xfc0c546a → address
totalClaims 0x41c61383 → uint256
Write Contract 2 functions
These functions modify contract state and require a wallet transaction to execute.
claim 0x2e7ba6ef
uint256 index
address account
uint256 amount
bytes32[] merkleProof
emergencyWithdrawal 0x5b0a3843
No parameters
Recent Transactions
No transactions found for this address