Latest 25 from a total of 25,928 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Update Root | 13790987 | 388 days ago | IN | 0 ETH | 0.0000002 | ||||
| Withdraw Unclaim... | 13790985 | 388 days ago | IN | 0 ETH | 0.00000025 | ||||
| Claim Ve Token | 13790705 | 388 days ago | IN | 0 ETH | 0.00000156 | ||||
| Claim | 13785549 | 388 days ago | IN | 0 ETH | 0.00000204 | ||||
| Claim | 13785481 | 388 days ago | IN | 0 ETH | 0.00000309 | ||||
| Claim | 13785453 | 388 days ago | IN | 0 ETH | 0.00000309 | ||||
| Claim | 13785403 | 388 days ago | IN | 0 ETH | 0.00000348 | ||||
| Claim | 13785348 | 388 days ago | IN | 0 ETH | 0.0000051 | ||||
| Claim | 13785323 | 388 days ago | IN | 0 ETH | 0.00000598 | ||||
| Claim | 13785294 | 388 days ago | IN | 0 ETH | 0.000007 | ||||
| Claim | 13785238 | 388 days ago | IN | 0 ETH | 0.0000103 | ||||
| Claim | 13785155 | 388 days ago | IN | 0 ETH | 0.00000532 | ||||
| Claim | 13785111 | 388 days ago | IN | 0 ETH | 0.00000391 | ||||
| Claim | 13784721 | 388 days ago | IN | 0 ETH | 0.00000377 | ||||
| Claim | 13784692 | 388 days ago | IN | 0 ETH | 0.00000322 | ||||
| Claim | 13784664 | 388 days ago | IN | 0 ETH | 0.00000267 | ||||
| Claim | 13784589 | 388 days ago | IN | 0 ETH | 0.00000299 | ||||
| Claim | 13784551 | 388 days ago | IN | 0 ETH | 0.00000336 | ||||
| Claim | 13784521 | 388 days ago | IN | 0 ETH | 0.00000267 | ||||
| Claim | 13784487 | 388 days ago | IN | 0 ETH | 0.00000349 | ||||
| Claim | 13784440 | 388 days ago | IN | 0 ETH | 0.00000423 | ||||
| Claim | 13784407 | 388 days ago | IN | 0 ETH | 0.00000457 | ||||
| Claim | 13784389 | 388 days ago | IN | 0 ETH | 0.00000393 | ||||
| Claim Ve Token | 13784372 | 388 days ago | IN | 0 ETH | 0.00000351 | ||||
| Claim | 13784314 | 388 days ago | IN | 0 ETH | 0.00000392 |
Latest 25 internal transactions (View All)
| Parent Transaction Hash | Block | From | To | ||||
|---|---|---|---|---|---|---|---|
| 13790985 | 388 days ago | 0 ETH | |||||
| 13790985 | 388 days ago | 0 ETH | |||||
| 13790705 | 388 days ago | 0 ETH | |||||
| 13790705 | 388 days ago | 0 ETH | |||||
| 13785549 | 388 days ago | 0 ETH | |||||
| 13785481 | 388 days ago | 0 ETH | |||||
| 13785453 | 388 days ago | 0 ETH | |||||
| 13785403 | 388 days ago | 0 ETH | |||||
| 13785348 | 388 days ago | 0 ETH | |||||
| 13785323 | 388 days ago | 0 ETH | |||||
| 13785294 | 388 days ago | 0 ETH | |||||
| 13785238 | 388 days ago | 0 ETH | |||||
| 13785155 | 388 days ago | 0 ETH | |||||
| 13785111 | 388 days ago | 0 ETH | |||||
| 13784721 | 388 days ago | 0 ETH | |||||
| 13784692 | 388 days ago | 0 ETH | |||||
| 13784664 | 388 days ago | 0 ETH | |||||
| 13784589 | 388 days ago | 0 ETH | |||||
| 13784551 | 388 days ago | 0 ETH | |||||
| 13784521 | 388 days ago | 0 ETH | |||||
| 13784487 | 388 days ago | 0 ETH | |||||
| 13784440 | 388 days ago | 0 ETH | |||||
| 13784407 | 388 days ago | 0 ETH | |||||
| 13784389 | 388 days ago | 0 ETH | |||||
| 13784372 | 388 days ago | 0 ETH |
Cross-Chain Transactions
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./interface/IVotingEscrow.sol";
import "./interface/IBlast.sol";
contract TokenDistributor is Ownable {
event Claimed(address indexed claimer, uint256 amount);
event VeClaimed(address indexed claimer, uint256 amount);
uint256 public constant MIN_LOCK = 12 * 7 days; // 12 weeks
address public token;
address public veToken;
bytes32 public root; // Same root used for both claims, because equal amount of THRUST is distributed for both claims
mapping(address => bool) public claimed;
mapping(address => bool) public claimedVeToken;
IBlast public constant BLAST =
IBlast(0x4300000000000000000000000000000000000002);
/**
* @dev Constructor for the TokenDistributor contract.
* @param owner_ - The owner of the contract
* @param root_ - The root of the merkle tree
* @param token_ - The address of the token contract
*/
constructor(
address owner_,
bytes32 root_,
address token_,
address veToken_
) Ownable(owner_) {
root = root_;
token = token_;
veToken = veToken_;
IERC20(token).approve(veToken, type(uint256).max); // Approve veToken to transfer token
BLAST.configureClaimableGas();
}
/**
* @dev Allows claiming by an external address if it exists in the tree. Only callable once per owner, requires merkle tree to be constructed correctly.
* @param amount_ - The amount of tokens to claim
* @param proof_ - The merkle proof to verify the claim
*/
function claim(uint256 amount_, bytes32[] calldata proof_) external {
bytes32 node = keccak256(abi.encodePacked(msg.sender, amount_));
require(
MerkleProof.verify(proof_, root, node),
"TokenDistributor: Invalid proof"
);
require(!claimed[msg.sender], "TokenDistributor: Already claimed");
claimed[msg.sender] = true;
IERC20(token).transfer(msg.sender, amount_);
emit Claimed(msg.sender, amount_);
}
/**
* @dev Claims the token and automatically deposits it into the user's veToken position, if the user has a lock >= MIN_LOCK.
* Only callable once per owner, requires merkle tree to be constructed correctly.
* @param amount_ - The amount of token to claim and deposit into veToken
* @param proof_ - The merkle proof to verify the claim
*/
function claimVeToken(uint256 amount_, bytes32[] calldata proof_) external {
bytes32 node = keccak256(abi.encodePacked(msg.sender, amount_));
require(
MerkleProof.verify(proof_, root, node),
"TokenDistributor: Invalid proof"
);
require(
!claimedVeToken[msg.sender],
"TokenDistributor: Already claimed"
);
require(
IVotingEscrow(veToken).locked(msg.sender).end >=
block.timestamp + MIN_LOCK,
"TokenDistributor: VeToken not locked long enough"
);
claimedVeToken[msg.sender] = true;
IVotingEscrow(veToken).deposit_for(msg.sender, amount_);
emit VeClaimed(msg.sender, amount_);
}
/**
* @dev Deposits tokens to distribute into the contract.
* @param _amount - The amount of tokens to deposit
*/
function depositToken(uint256 _amount) external onlyOwner {
IERC20(token).transferFrom(msg.sender, address(this), _amount);
}
/**
* @dev Withdraws all unclaimed tokens to the specified address.
* @param _receiver The address to send the unclaimed tokens to
*/
function withdrawUnclaimed(address _receiver) external onlyOwner {
IERC20(token).transfer(
_receiver,
IERC20(token).balanceOf(address(this))
);
}
/**
*
* @param _root - The new root of the merkle tree
*/
function updateRoot(bytes32 _root) external onlyOwner {
root = _root;
}
function claimGas(address _receiver) external onlyOwner {
BLAST.claimMaxGas(address(this), _receiver);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MerkleProof.sol)
pragma solidity ^0.8.20;
/**
* @dev These functions deal with verification of Merkle Tree proofs.
*
* The tree and the proofs can be generated using our
* https://github.com/OpenZeppelin/merkle-tree[JavaScript library].
* You will find a quickstart guide in the readme.
*
* WARNING: You should avoid using leaf values that are 64 bytes long prior to
* hashing, or use a hash function other than keccak256 for hashing leaves.
* This is because the concatenation of a sorted pair of internal nodes in
* the Merkle tree could be reinterpreted as a leaf value.
* OpenZeppelin's JavaScript library generates Merkle trees that are safe
* against this attack out of the box.
*/
library MerkleProof {
/**
*@dev The multiproof provided is not valid.
*/
error MerkleProofInvalidMultiproof();
/**
* @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
* defined by `root`. For this, a `proof` must be provided, containing
* sibling hashes on the branch from the leaf to the root of the tree. Each
* pair of leaves and each pair of pre-images are assumed to be sorted.
*/
function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
return processProof(proof, leaf) == root;
}
/**
* @dev Calldata version of {verify}
*/
function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
return processProofCalldata(proof, leaf) == root;
}
/**
* @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
* from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
* hash matches the root of the tree. When processing the proof, the pairs
* of leafs & pre-images are assumed to be sorted.
*/
function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
/**
* @dev Calldata version of {processProof}
*/
function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
computedHash = _hashPair(computedHash, proof[i]);
}
return computedHash;
}
/**
* @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by
* `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.
*
* CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.
*/
function multiProofVerify(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProof(proof, proofFlags, leaves) == root;
}
/**
* @dev Calldata version of {multiProofVerify}
*
* CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.
*/
function multiProofVerifyCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32 root,
bytes32[] memory leaves
) internal pure returns (bool) {
return processMultiProofCalldata(proof, proofFlags, leaves) == root;
}
/**
* @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction
* proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another
* leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false
* respectively.
*
* CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree
* is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the
* tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
*/
function processMultiProof(
bytes32[] memory proof,
bool[] memory proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
// This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
// consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
// `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
// the Merkle tree.
uint256 leavesLen = leaves.length;
uint256 proofLen = proof.length;
uint256 totalHashes = proofFlags.length;
// Check proof validity.
if (leavesLen + proofLen != totalHashes + 1) {
revert MerkleProofInvalidMultiproof();
}
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
// `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
// At each step, we compute the next hash using two values:
// - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
// get the next hash.
// - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
// `proof` array.
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i]
? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
: proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
if (proofPos != proofLen) {
revert MerkleProofInvalidMultiproof();
}
unchecked {
return hashes[totalHashes - 1];
}
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
/**
* @dev Calldata version of {processMultiProof}.
*
* CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.
*/
function processMultiProofCalldata(
bytes32[] calldata proof,
bool[] calldata proofFlags,
bytes32[] memory leaves
) internal pure returns (bytes32 merkleRoot) {
// This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by
// consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the
// `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of
// the Merkle tree.
uint256 leavesLen = leaves.length;
uint256 proofLen = proof.length;
uint256 totalHashes = proofFlags.length;
// Check proof validity.
if (leavesLen + proofLen != totalHashes + 1) {
revert MerkleProofInvalidMultiproof();
}
// The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using
// `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop".
bytes32[] memory hashes = new bytes32[](totalHashes);
uint256 leafPos = 0;
uint256 hashPos = 0;
uint256 proofPos = 0;
// At each step, we compute the next hash using two values:
// - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we
// get the next hash.
// - depending on the flag, either another value from the "main queue" (merging branches) or an element from the
// `proof` array.
for (uint256 i = 0; i < totalHashes; i++) {
bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];
bytes32 b = proofFlags[i]
? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])
: proof[proofPos++];
hashes[i] = _hashPair(a, b);
}
if (totalHashes > 0) {
if (proofPos != proofLen) {
revert MerkleProofInvalidMultiproof();
}
unchecked {
return hashes[totalHashes - 1];
}
} else if (leavesLen > 0) {
return leaves[0];
} else {
return proof[0];
}
}
/**
* @dev Sorts the pair (a, b) and hashes the result.
*/
function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) {
return a < b ? _efficientHash(a, b) : _efficientHash(b, a);
}
/**
* @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory.
*/
function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
/// @solidity memory-safe-assembly
assembly {
mstore(0x00, a)
mstore(0x20, b)
value := keccak256(0x00, 0x40)
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) 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 a `value` amount of tokens 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 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
interface IVotingEscrow {
/**
* @dev amount - The amount of tokens locked
* @dev end - The timestamp when the lock ends
*/
struct LockedBalance {
int128 amount;
uint256 end;
}
/**
* @dev Returns the amount and end week of the owner's lock position
* @param owner The address of the account that has locked tokens
*/
function locked(address owner) external view returns (LockedBalance memory lock);
/**
* @dev Deposits tokens into the escrow contract on behalf of another user
* @param owner - The address of the account that is depositing tokens
* @param value - The amount of tokens to deposit
*/
function deposit_for(address owner, uint256 value) external;
/**
* @dev Creates a new lock position for the owner
* @param value - The amount of tokens to lock
* @param unlockTime - The timestamp when the lock expires
*/
function create_lock(uint256 value, uint256 unlockTime) external;
/**
* @dev Increases the amount of tokens locked, must have an existing lock
* @param value - The amount of tokens to increase the lock by
*/
function increase_amount(uint256 value) external;
/**
* @dev Increases the unlock time of the lock, must have an existing lock
* @param unlockTime - The new unlock time
*/
function increase_unlock_time(uint256 unlockTime) external;
/**
* @dev Withdraws tokens from the escrow contract, only when the lock has expired
*/
function withdraw() external;
/**
* @dev Gets the current voting power of the owner
* @param owner - The address of the account to check the balance of
*/
function balanceOf(address owner) external view returns (uint256);
/**
* @dev Returns the total voting power (total veToken supply)
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the total number of locked tokens
*/
function supply() external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
interface IBlast {
function configureClaimableGas() external;
function claimMaxGas(address contractAddress, address recipient) external returns (uint256);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}{
"remappings": [
"@openzeppelin/=lib/openzeppelin-contracts/",
"forge-std/=lib/forge-std/src/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"bytes32","name":"root_","type":"bytes32"},{"internalType":"address","name":"token_","type":"address"},{"internalType":"address","name":"veToken_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"VeClaimed","type":"event"},{"inputs":[],"name":"BLAST","outputs":[{"internalType":"contract IBlast","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_LOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"bytes32[]","name":"proof_","type":"bytes32[]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"}],"name":"claimGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"bytes32[]","name":"proof_","type":"bytes32[]"}],"name":"claimVeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimedVeToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"updateRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"veToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"}],"name":"withdrawUnclaimed","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b5060405162000e8638038062000e868339810160408190526200003491620001f2565b836001600160a01b0381166200006457604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200006f8162000185565b506003839055600180546001600160a01b038481166001600160a01b031992831681179093556002805491851691909216811790915560405163095ea7b360e01b81526004810191909152600019602482015263095ea7b3906044016020604051808303816000875af1158015620000eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000111919062000246565b507343000000000000000000000000000000000000026001600160a01b0316634e606c476040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156200016257600080fd5b505af115801562000177573d6000803e3d6000fd5b505050505050505062000271565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b0381168114620001ed57600080fd5b919050565b600080600080608085870312156200020957600080fd5b6200021485620001d5565b9350602085015192506200022b60408601620001d5565b91506200023b60608601620001d5565b905092959194509250565b6000602082840312156200025957600080fd5b815180151581146200026a57600080fd5b9392505050565b610c0580620002816000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c806397d7577611610097578063ebf0c71711610066578063ebf0c71714610226578063f2fde38b1461023d578063f8764cec14610250578063fc0c546a1461025a57600080fd5b806397d75776146101af578063a0d3abbd146101bd578063b633fcba146101f0578063c884ef831461020357600080fd5b80636215be77116100d35780636215be7714610170578063715018a6146101835780637552509d1461018b5780638da5cb5b1461019e57600080fd5b80630fadea301461010557806321ff99701461011a5780632f52ebb71461012d5780633b92eb2314610140575b600080fd5b6101186101133660046109ee565b61026d565b005b610118610128366004610a17565b61035f565b61011861013b366004610a30565b61036c565b600254610153906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61011861017e366004610a17565b61053d565b610118610582565b610118610199366004610a30565b610596565b6000546001600160a01b0316610153565b6101536002604360981b0181565b6101e06101cb3660046109ee565b60056020526000908152604090205460ff1681565b6040519015158152602001610167565b6101186101fe3660046109ee565b610827565b6101e06102113660046109ee565b60046020526000908152604090205460ff1681565b61022f60035481565b604051908152602001610167565b61011861024b3660046109ee565b6108a6565b61022f626ebe0081565b600154610153906001600160a01b031681565b6102756108e4565b6001546040516370a0823160e01b81523060048201526001600160a01b039091169063a9059cbb90839083906370a0823190602401602060405180830381865afa1580156102c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102eb9190610aaf565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044015b6020604051808303816000875af1158015610337573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035b9190610ac8565b5050565b6103676108e4565b600355565b6040516bffffffffffffffffffffffff193360601b166020820152603481018490526000906054016040516020818303038152906040528051906020012090506103ed838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506003549150849050610911565b61043e5760405162461bcd60e51b815260206004820152601f60248201527f546f6b656e4469737472696275746f723a20496e76616c69642070726f6f660060448201526064015b60405180910390fd5b3360009081526004602052604090205460ff161561046e5760405162461bcd60e51b815260040161043590610aea565b33600081815260046020819052604091829020805460ff1916600190811790915554915163a9059cbb60e01b815290810192909252602482018690526001600160a01b03169063a9059cbb906044016020604051808303816000875af11580156104dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105009190610ac8565b5060405184815233907fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a906020015b60405180910390a250505050565b6105456108e4565b6001546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd90606401610318565b61058a6108e4565b6105946000610927565b565b6040516bffffffffffffffffffffffff193360601b16602082015260348101849052600090605401604051602081830303815290604052805190602001209050610617838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506003549150849050610911565b6106635760405162461bcd60e51b815260206004820152601f60248201527f546f6b656e4469737472696275746f723a20496e76616c69642070726f6f66006044820152606401610435565b3360009081526005602052604090205460ff16156106935760405162461bcd60e51b815260040161043590610aea565b6106a0626ebe0042610b2b565b60025460405163cbf9fe5f60e01b81523360048201526001600160a01b039091169063cbf9fe5f906024016040805180830381865afa1580156106e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061070b9190610b4c565b6020015110156107765760405162461bcd60e51b815260206004820152603060248201527f546f6b656e4469737472696275746f723a205665546f6b656e206e6f74206c6f60448201526f0c6d6cac840d8dedcce40cadcdeeaced60831b6064820152608401610435565b3360008181526005602052604090819020805460ff191660011790556002549051631d23139f60e11b81526004810192909252602482018690526001600160a01b031690633a46273e90604401600060405180830381600087803b1580156107dd57600080fd5b505af11580156107f1573d6000803e3d6000fd5b50506040518681523392507fd79f60cf9f73f4678745aa292b4eebd54a728a9ca814743675cc81c8043f143c915060200161052f565b61082f6108e4565b60405163662aa11d60e01b81523060048201526001600160a01b03821660248201526002604360981b019063662aa11d906044016020604051808303816000875af1158015610882573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035b9190610aaf565b6108ae6108e4565b6001600160a01b0381166108d857604051631e4fbdf760e01b815260006004820152602401610435565b6108e181610927565b50565b6000546001600160a01b031633146105945760405163118cdaa760e01b8152336004820152602401610435565b60008261091e8584610977565b14949350505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600081815b84518110156109b2576109a88286838151811061099b5761099b610bb9565b60200260200101516109bc565b915060010161097c565b5090505b92915050565b60008183106109d85760008281526020849052604090206109e7565b60008381526020839052604090205b9392505050565b600060208284031215610a0057600080fd5b81356001600160a01b03811681146109e757600080fd5b600060208284031215610a2957600080fd5b5035919050565b600080600060408486031215610a4557600080fd5b83359250602084013567ffffffffffffffff80821115610a6457600080fd5b818601915086601f830112610a7857600080fd5b813581811115610a8757600080fd5b8760208260051b8501011115610a9c57600080fd5b6020830194508093505050509250925092565b600060208284031215610ac157600080fd5b5051919050565b600060208284031215610ada57600080fd5b815180151581146109e757600080fd5b60208082526021908201527f546f6b656e4469737472696275746f723a20416c726561647920636c61696d656040820152601960fa1b606082015260800190565b808201808211156109b657634e487b7160e01b600052601160045260246000fd5b600060408284031215610b5e57600080fd5b6040516040810181811067ffffffffffffffff82111715610b8f57634e487b7160e01b600052604160045260246000fd5b6040528251600f81900b8114610ba457600080fd5b81526020928301519281019290925250919050565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220da0e8cd706600cb8caff755600382c3659eefb47e9d256d4a5ff1c84e69573f664736f6c63430008180033000000000000000000000000695decfb76b1c22deb0a4de3f8816bd03dfaf423a813034cd5717f3fa42bdd5908fcefe933b66094904619d155767ea083352376000000000000000000000000e36072dd051ce26261bf50cd966311cab62c596e000000000000000000000000c6de1f30415352941f7ce784a67b2df1552386a4
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101005760003560e01c806397d7577611610097578063ebf0c71711610066578063ebf0c71714610226578063f2fde38b1461023d578063f8764cec14610250578063fc0c546a1461025a57600080fd5b806397d75776146101af578063a0d3abbd146101bd578063b633fcba146101f0578063c884ef831461020357600080fd5b80636215be77116100d35780636215be7714610170578063715018a6146101835780637552509d1461018b5780638da5cb5b1461019e57600080fd5b80630fadea301461010557806321ff99701461011a5780632f52ebb71461012d5780633b92eb2314610140575b600080fd5b6101186101133660046109ee565b61026d565b005b610118610128366004610a17565b61035f565b61011861013b366004610a30565b61036c565b600254610153906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61011861017e366004610a17565b61053d565b610118610582565b610118610199366004610a30565b610596565b6000546001600160a01b0316610153565b6101536002604360981b0181565b6101e06101cb3660046109ee565b60056020526000908152604090205460ff1681565b6040519015158152602001610167565b6101186101fe3660046109ee565b610827565b6101e06102113660046109ee565b60046020526000908152604090205460ff1681565b61022f60035481565b604051908152602001610167565b61011861024b3660046109ee565b6108a6565b61022f626ebe0081565b600154610153906001600160a01b031681565b6102756108e4565b6001546040516370a0823160e01b81523060048201526001600160a01b039091169063a9059cbb90839083906370a0823190602401602060405180830381865afa1580156102c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102eb9190610aaf565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044015b6020604051808303816000875af1158015610337573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035b9190610ac8565b5050565b6103676108e4565b600355565b6040516bffffffffffffffffffffffff193360601b166020820152603481018490526000906054016040516020818303038152906040528051906020012090506103ed838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506003549150849050610911565b61043e5760405162461bcd60e51b815260206004820152601f60248201527f546f6b656e4469737472696275746f723a20496e76616c69642070726f6f660060448201526064015b60405180910390fd5b3360009081526004602052604090205460ff161561046e5760405162461bcd60e51b815260040161043590610aea565b33600081815260046020819052604091829020805460ff1916600190811790915554915163a9059cbb60e01b815290810192909252602482018690526001600160a01b03169063a9059cbb906044016020604051808303816000875af11580156104dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105009190610ac8565b5060405184815233907fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a906020015b60405180910390a250505050565b6105456108e4565b6001546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd90606401610318565b61058a6108e4565b6105946000610927565b565b6040516bffffffffffffffffffffffff193360601b16602082015260348101849052600090605401604051602081830303815290604052805190602001209050610617838380806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506003549150849050610911565b6106635760405162461bcd60e51b815260206004820152601f60248201527f546f6b656e4469737472696275746f723a20496e76616c69642070726f6f66006044820152606401610435565b3360009081526005602052604090205460ff16156106935760405162461bcd60e51b815260040161043590610aea565b6106a0626ebe0042610b2b565b60025460405163cbf9fe5f60e01b81523360048201526001600160a01b039091169063cbf9fe5f906024016040805180830381865afa1580156106e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061070b9190610b4c565b6020015110156107765760405162461bcd60e51b815260206004820152603060248201527f546f6b656e4469737472696275746f723a205665546f6b656e206e6f74206c6f60448201526f0c6d6cac840d8dedcce40cadcdeeaced60831b6064820152608401610435565b3360008181526005602052604090819020805460ff191660011790556002549051631d23139f60e11b81526004810192909252602482018690526001600160a01b031690633a46273e90604401600060405180830381600087803b1580156107dd57600080fd5b505af11580156107f1573d6000803e3d6000fd5b50506040518681523392507fd79f60cf9f73f4678745aa292b4eebd54a728a9ca814743675cc81c8043f143c915060200161052f565b61082f6108e4565b60405163662aa11d60e01b81523060048201526001600160a01b03821660248201526002604360981b019063662aa11d906044016020604051808303816000875af1158015610882573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061035b9190610aaf565b6108ae6108e4565b6001600160a01b0381166108d857604051631e4fbdf760e01b815260006004820152602401610435565b6108e181610927565b50565b6000546001600160a01b031633146105945760405163118cdaa760e01b8152336004820152602401610435565b60008261091e8584610977565b14949350505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600081815b84518110156109b2576109a88286838151811061099b5761099b610bb9565b60200260200101516109bc565b915060010161097c565b5090505b92915050565b60008183106109d85760008281526020849052604090206109e7565b60008381526020839052604090205b9392505050565b600060208284031215610a0057600080fd5b81356001600160a01b03811681146109e757600080fd5b600060208284031215610a2957600080fd5b5035919050565b600080600060408486031215610a4557600080fd5b83359250602084013567ffffffffffffffff80821115610a6457600080fd5b818601915086601f830112610a7857600080fd5b813581811115610a8757600080fd5b8760208260051b8501011115610a9c57600080fd5b6020830194508093505050509250925092565b600060208284031215610ac157600080fd5b5051919050565b600060208284031215610ada57600080fd5b815180151581146109e757600080fd5b60208082526021908201527f546f6b656e4469737472696275746f723a20416c726561647920636c61696d656040820152601960fa1b606082015260800190565b808201808211156109b657634e487b7160e01b600052601160045260246000fd5b600060408284031215610b5e57600080fd5b6040516040810181811067ffffffffffffffff82111715610b8f57634e487b7160e01b600052604160045260246000fd5b6040528251600f81900b8114610ba457600080fd5b81526020928301519281019290925250919050565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220da0e8cd706600cb8caff755600382c3659eefb47e9d256d4a5ff1c84e69573f664736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000695decfb76b1c22deb0a4de3f8816bd03dfaf423a813034cd5717f3fa42bdd5908fcefe933b66094904619d155767ea083352376000000000000000000000000e36072dd051ce26261bf50cd966311cab62c596e000000000000000000000000c6de1f30415352941f7ce784a67b2df1552386a4
-----Decoded View---------------
Arg [0] : owner_ (address): 0x695decFB76b1c22dEB0A4dE3F8816bd03dfAf423
Arg [1] : root_ (bytes32): 0xa813034cd5717f3fa42bdd5908fcefe933b66094904619d155767ea083352376
Arg [2] : token_ (address): 0xE36072DD051Ce26261BF50CD966311cab62C596e
Arg [3] : veToken_ (address): 0xc6de1f30415352941f7ce784A67B2Df1552386a4
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000695decfb76b1c22deb0a4de3f8816bd03dfaf423
Arg [1] : a813034cd5717f3fa42bdd5908fcefe933b66094904619d155767ea083352376
Arg [2] : 000000000000000000000000e36072dd051ce26261bf50cd966311cab62c596e
Arg [3] : 000000000000000000000000c6de1f30415352941f7ce784a67b2df1552386a4
Net Worth in USD
Net Worth in ETH
Multichain Portfolio | 35 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.