More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 84,789 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Unpause | 10114786 | 189 days ago | IN | 0 ETH | 0.00000009 | ||||
Update Reward Di... | 10114784 | 189 days ago | IN | 0 ETH | 0.00000022 | ||||
Pause | 10114768 | 189 days ago | IN | 0 ETH | 0.00000017 | ||||
Unpause | 10114186 | 189 days ago | IN | 0 ETH | 0.00000009 | ||||
Update Reward Di... | 10114184 | 189 days ago | IN | 0 ETH | 0.00000021 | ||||
Pause | 10114168 | 189 days ago | IN | 0 ETH | 0.00000017 | ||||
Unpause | 10113586 | 189 days ago | IN | 0 ETH | 0.00000008 | ||||
Update Reward Di... | 10113583 | 189 days ago | IN | 0 ETH | 0.00000019 | ||||
Pause | 10113567 | 189 days ago | IN | 0 ETH | 0.00000015 | ||||
Unpause | 10112986 | 189 days ago | IN | 0 ETH | 0.00000008 | ||||
Update Reward Di... | 10112984 | 189 days ago | IN | 0 ETH | 0.00000018 | ||||
Pause | 10112968 | 189 days ago | IN | 0 ETH | 0.00000015 | ||||
Unpause | 10112386 | 189 days ago | IN | 0 ETH | 0.00000008 | ||||
Update Reward Di... | 10112384 | 189 days ago | IN | 0 ETH | 0.00000019 | ||||
Pause | 10112368 | 189 days ago | IN | 0 ETH | 0.00000016 | ||||
Unpause | 10111788 | 189 days ago | IN | 0 ETH | 0.00000009 | ||||
Update Reward Di... | 10111785 | 189 days ago | IN | 0 ETH | 0.00000021 | ||||
Pause | 10111768 | 189 days ago | IN | 0 ETH | 0.00000018 | ||||
Unpause | 10111185 | 189 days ago | IN | 0 ETH | 0.0000001 | ||||
Update Reward Di... | 10111183 | 189 days ago | IN | 0 ETH | 0.00000023 | ||||
Pause | 10111167 | 189 days ago | IN | 0 ETH | 0.00000018 | ||||
Unpause | 10110586 | 189 days ago | IN | 0 ETH | 0.0000001 | ||||
Update Reward Di... | 10110584 | 189 days ago | IN | 0 ETH | 0.00000024 | ||||
Pause | 10110568 | 189 days ago | IN | 0 ETH | 0.00000019 | ||||
Unpause | 10109985 | 189 days ago | IN | 0 ETH | 0.00000011 |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
RewardDistributor
Compiler Version
v0.8.24+commit.e11b9ed9
Optimization Enabled:
Yes with 888888 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; import {LowLevelERC20Transfer} from "@looksrare/contracts-libs/contracts/lowLevelCallers/LowLevelERC20Transfer.sol"; import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol"; import {Pausable} from "@looksrare/contracts-libs/contracts/Pausable.sol"; import {ReentrancyGuard} from "@looksrare/contracts-libs/contracts/ReentrancyGuard.sol"; import {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import {IBlast, GasMode, YieldMode} from "./interfaces/IBlast.sol"; /** * @title RewardDistributor * @notice It distributes reward tokens with rolling Merkle airdrops. * @author YOLO Games Team */ contract RewardDistributor is Pausable, ReentrancyGuard, AccessControl, LowLevelERC20Transfer { bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE"); /** * @notice The reward token */ address public immutable REWARD_TOKEN; // Current round (users can only claim pending rewards for the current round) uint256 public currentRound; // Users can claim until this timestamp uint256 public canClaimUntil; // Max amount per user in current tree uint256 public maximumAmountPerUserInCurrentTree; // Total amount claimed by user (in reward token) mapping(address => uint256) public amountClaimedByUser; // Merkle root for a round mapping(uint256 => bytes32) public merkleRootOfRound; // Keeps track on whether user has claimed at a given round mapping(uint256 => mapping(address => bool)) public hasUserClaimedForRound; event RewardClaimed(address indexed user, uint256 indexed round, uint256 amount); event RewardDistributionUpdated(uint256 indexed round); event TokenWithdrawn(address currency, uint256 amount); event CanClaimUntilUpdated(uint256 timestamp); error AlreadyClaimed(); error AmountHigherThanMax(); error ClaimPeriodEnded(); error InvalidProof(); /** * @notice Constructor * @param _rewardToken address of the reward token * @param _owner address of the owner * @param _operator address of the operator * @param _blast address of the BLAST precompile */ constructor(address _rewardToken, address _owner, address _operator, address _blast) { REWARD_TOKEN = _rewardToken; _grantRole(DEFAULT_ADMIN_ROLE, _owner); _grantRole(OPERATOR_ROLE, _owner); _grantRole(OPERATOR_ROLE, _operator); IBlast(_blast).configure(YieldMode.CLAIMABLE, GasMode.CLAIMABLE, _owner); } /** * @notice Claim pending rewards * @param amount amount to claim * @param merkleProof array containing the merkle proof */ function claim(uint256 amount, bytes32[] calldata merkleProof) external whenNotPaused nonReentrant { // Verify the round is not claimed already if (hasUserClaimedForRound[currentRound][msg.sender]) { revert AlreadyClaimed(); } if (block.timestamp >= canClaimUntil) { revert ClaimPeriodEnded(); } (bool claimStatus, uint256 adjustedAmount) = _canClaim(msg.sender, amount, merkleProof); if (!claimStatus) { revert InvalidProof(); } if (amount > maximumAmountPerUserInCurrentTree) { revert AmountHigherThanMax(); } // Set mapping for user and round as true hasUserClaimedForRound[currentRound][msg.sender] = true; // Adjust amount claimed amountClaimedByUser[msg.sender] += adjustedAmount; // Transfer adjusted amount _executeERC20DirectTransfer({currency: REWARD_TOKEN, to: msg.sender, amount: adjustedAmount}); emit RewardClaimed(msg.sender, currentRound, adjustedAmount); } /** * @notice Update reward distribution with a new merkle root * @dev It automatically increments the currentRound * @param merkleRoot root of the computed merkle tree */ function updateRewardDistribution( bytes32 merkleRoot, uint256 newMaximumAmountPerUser ) external whenPaused onlyRole(OPERATOR_ROLE) { currentRound++; merkleRootOfRound[currentRound] = merkleRoot; maximumAmountPerUserInCurrentTree = newMaximumAmountPerUser; emit RewardDistributionUpdated(currentRound); } function updateCanClaimUntil(uint256 timestamp) external onlyRole(OPERATOR_ROLE) { canClaimUntil = timestamp; emit CanClaimUntilUpdated(timestamp); } /** * @notice Pause claim */ function pause() external onlyRole(OPERATOR_ROLE) whenNotPaused { _pause(); } /** * @notice Unpause claim */ function unpause() external onlyRole(OPERATOR_ROLE) whenPaused { _unpause(); } /** * @notice Transfer reward token back to owner * @dev It is for emergency purposes * @param currency currency to withdraw * @param amount amount to withdraw */ function withdrawToken(address currency, uint256 amount) external onlyRole(DEFAULT_ADMIN_ROLE) { _executeERC20DirectTransfer({currency: currency, to: msg.sender, amount: amount}); emit TokenWithdrawn(currency, amount); } /** * @notice Check whether it is possible to claim and how much based on previous distribution * @param user address of the user * @param amount amount to claim * @param merkleProof array with the merkle proof */ function canClaim( address user, uint256 amount, bytes32[] calldata merkleProof ) external view returns (bool, uint256) { if (block.timestamp >= canClaimUntil) { return (false, 0); } return _canClaim(user, amount, merkleProof); } /** * @notice Check whether it is possible to claim and how much based on previous distribution * @param user address of the user * @param amount amount to claim * @param merkleProof array with the merkle proof */ function _canClaim( address user, uint256 amount, bytes32[] calldata merkleProof ) internal view returns (bool, uint256) { // Compute the node and verify the merkle proof bytes32 node = keccak256(bytes.concat(keccak256(abi.encode(user, amount)))); bool canUserClaim = MerkleProof.verify(merkleProof, merkleRootOfRound[currentRound], node); if ((!canUserClaim) || (hasUserClaimedForRound[currentRound][user])) { return (false, 0); } else { return (true, amount - amountClaimedByUser[user]); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; /** * @notice It is emitted if the call recipient is not a contract. */ error NotAContract();
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; /** * @notice It is emitted if the ETH transfer fails. */ error ETHTransferFail(); /** * @notice It is emitted if the ERC20 approval fails. */ error ERC20ApprovalFail(); /** * @notice It is emitted if the ERC20 transfer fails. */ error ERC20TransferFail(); /** * @notice It is emitted if the ERC20 transferFrom fails. */ error ERC20TransferFromFail(); /** * @notice It is emitted if the ERC721 transferFrom fails. */ error ERC721TransferFromFail(); /** * @notice It is emitted if the ERC1155 safeTransferFrom fails. */ error ERC1155SafeTransferFromFail(); /** * @notice It is emitted if the ERC1155 safeBatchTransferFrom fails. */ error ERC1155SafeBatchTransferFromFail();
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; interface IERC20 { event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address to, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom(address from, address to, uint256 amount) external returns (bool); function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; /** * @title IReentrancyGuard * @author LooksRare protocol team (👀,💎) */ interface IReentrancyGuard { /** * @notice This is returned when there is a reentrant call. */ error ReentrancyFail(); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; // Interfaces import {IERC20} from "../interfaces/generic/IERC20.sol"; // Errors import {ERC20TransferFail, ERC20TransferFromFail} from "../errors/LowLevelErrors.sol"; import {NotAContract} from "../errors/GenericErrors.sol"; /** * @title LowLevelERC20Transfer * @notice This contract contains low-level calls to transfer ERC20 tokens. * @author LooksRare protocol team (👀,💎) */ contract LowLevelERC20Transfer { /** * @notice Execute ERC20 transferFrom * @param currency Currency address * @param from Sender address * @param to Recipient address * @param amount Amount to transfer */ function _executeERC20TransferFrom(address currency, address from, address to, uint256 amount) internal { if (currency.code.length == 0) { revert NotAContract(); } (bool status, bytes memory data) = currency.call(abi.encodeCall(IERC20.transferFrom, (from, to, amount))); if (!status) { revert ERC20TransferFromFail(); } if (data.length > 0) { if (!abi.decode(data, (bool))) { revert ERC20TransferFromFail(); } } } /** * @notice Execute ERC20 (direct) transfer * @param currency Currency address * @param to Recipient address * @param amount Amount to transfer */ function _executeERC20DirectTransfer(address currency, address to, uint256 amount) internal { if (currency.code.length == 0) { revert NotAContract(); } (bool status, bytes memory data) = currency.call(abi.encodeCall(IERC20.transfer, (to, amount))); if (!status) { revert ERC20TransferFail(); } if (data.length > 0) { if (!abi.decode(data, (bool))) { revert ERC20TransferFail(); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; /** * @title Pausable * @notice This contract makes it possible to pause the contract. * It is adjusted from OpenZeppelin. * @author LooksRare protocol team (👀,💎) */ abstract contract Pausable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); error IsPaused(); error NotPaused(); bool private _paused; /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { if (paused()) { revert IsPaused(); } } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { if (!paused()) { revert NotPaused(); } } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(msg.sender); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(msg.sender); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; // Interfaces import {IReentrancyGuard} from "./interfaces/IReentrancyGuard.sol"; /** * @title ReentrancyGuard * @notice This contract protects against reentrancy attacks. * It is adjusted from OpenZeppelin. * @author LooksRare protocol team (👀,💎) */ abstract contract ReentrancyGuard is IReentrancyGuard { uint256 private _status; /** * @notice Modifier to wrap functions to prevent reentrancy calls. */ modifier nonReentrant() { if (_status == 2) { revert ReentrancyFail(); } _status = 2; _; _status = 1; } constructor() { _status = 1; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol) pragma solidity ^0.8.20; import {IAccessControl} from "./IAccessControl.sol"; import {Context} from "../utils/Context.sol"; import {ERC165} from "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ```solidity * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ```solidity * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address account => bool) hasRole; bytes32 adminRole; } mapping(bytes32 role => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with an {AccessControlUnauthorizedAccount} error including the required role. */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual returns (bool) { return _roles[role].hasRole[account]; } /** * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()` * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier. */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account` * is missing `role`. */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert AccessControlUnauthorizedAccount(account, role); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `callerConfirmation`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address callerConfirmation) public virtual { if (callerConfirmation != _msgSender()) { revert AccessControlBadConfirmation(); } _revokeRole(role, callerConfirmation); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual returns (bool) { if (!hasRole(role, account)) { _roles[role].hasRole[account] = true; emit RoleGranted(role, account, _msgSender()); return true; } else { return false; } } /** * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual returns (bool) { if (hasRole(role, account)) { _roles[role].hasRole[account] = false; emit RoleRevoked(role, account, _msgSender()); return true; } else { return false; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol) pragma solidity ^0.8.20; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev The `account` is missing a role. */ error AccessControlUnauthorizedAccount(address account, bytes32 neededRole); /** * @dev The caller of a function is not the expected one. * * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}. */ error AccessControlBadConfirmation(); /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `callerConfirmation`. */ function renounceRole(bytes32 role, address callerConfirmation) external; }
// 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; } }
// 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) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; enum YieldMode { AUTOMATIC, VOID, CLAIMABLE } enum GasMode { VOID, CLAIMABLE } interface IBlast { // configure function configureContract(address contractAddress, YieldMode _yield, GasMode gasMode, address governor) external; function configure(YieldMode _yield, GasMode gasMode, address governor) external; // base configuration options function configureClaimableYield() external; function configureClaimableYieldOnBehalf(address contractAddress) external; function configureAutomaticYield() external; function configureAutomaticYieldOnBehalf(address contractAddress) external; function configureVoidYield() external; function configureVoidYieldOnBehalf(address contractAddress) external; function configureClaimableGas() external; function configureClaimableGasOnBehalf(address contractAddress) external; function configureVoidGas() external; function configureVoidGasOnBehalf(address contractAddress) external; function configureGovernor(address _governor) external; function configureGovernorOnBehalf(address _newGovernor, address contractAddress) external; // claim yield function claimYield(address contractAddress, address recipientOfYield, uint256 amount) external returns (uint256); function claimAllYield(address contractAddress, address recipientOfYield) external returns (uint256); // claim gas function claimAllGas(address contractAddress, address recipientOfGas) external returns (uint256); function claimGasAtMinClaimRate( address contractAddress, address recipientOfGas, uint256 minClaimRateBips ) external returns (uint256); function claimMaxGas(address contractAddress, address recipientOfGas) external returns (uint256); function claimGas( address contractAddress, address recipientOfGas, uint256 gasToClaim, uint256 gasSecondsToConsume ) external returns (uint256); // read functions function readClaimableYield(address contractAddress) external view returns (uint256); function readYieldConfiguration(address contractAddress) external view returns (uint8); function readGasParams( address contractAddress ) external view returns (uint256 etherSeconds, uint256 etherBalance, uint256 lastUpdated, GasMode); }
{ "viaIR": true, "optimizer": { "enabled": true, "runs": 888888 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_rewardToken","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_operator","type":"address"},{"internalType":"address","name":"_blast","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[],"name":"AlreadyClaimed","type":"error"},{"inputs":[],"name":"AmountHigherThanMax","type":"error"},{"inputs":[],"name":"ClaimPeriodEnded","type":"error"},{"inputs":[],"name":"ERC20TransferFail","type":"error"},{"inputs":[],"name":"InvalidProof","type":"error"},{"inputs":[],"name":"IsPaused","type":"error"},{"inputs":[],"name":"NotAContract","type":"error"},{"inputs":[],"name":"NotPaused","type":"error"},{"inputs":[],"name":"ReentrancyFail","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"CanClaimUntilUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"round","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"round","type":"uint256"}],"name":"RewardDistributionUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokenWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARD_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"amountClaimedByUser","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"canClaim","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canClaimUntil","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentRound","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"hasUserClaimedForRound","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maximumAmountPerUserInCurrentTree","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"merkleRootOfRound","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"updateCanClaimUntil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"uint256","name":"newMaximumAmountPerUser","type":"uint256"}],"name":"updateRewardDistribution","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"currency","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a0346200014757601f6200170238819003918201601f1916830192916001600160401b03918285118486101762000126578160809285926040978852833981010312620001475762000052826200014c565b91620000a762000065602083016200014c565b91620000816060620000798884016200014c565b92016200014c565b9460018055608052620000948362000161565b50620000a083620001e2565b50620001e2565b506001600160a01b0392831692833b1562000147576064600092838751968794859363c8992e6160e01b855260026004860152600160248601521660448401525af180156200013c5762000115575b825161145c90816200028682396080518181816104b70152610aa10152f35b8111620001265781523880620000f6565b634e487b7160e01b600052604160045260246000fd5b83513d6000823e3d90fd5b600080fd5b51906001600160a01b03821682036200014757565b6001600160a01b031660008181527fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b602052604081205490919060ff16620001de5781805260026020526040822081835260205260408220600160ff198254161790553391600080516020620016e28339815191528180a4600190565b5090565b6001600160a01b031660008181527f6bc781d8c7f9885ebbb3cefbc18932c491038e2ae5c5b56447891e0bd98ea16360205260408120549091907f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9299060ff16620002805780835260026020526040832082845260205260408320600160ff19825416179055600080516020620016e2833981519152339380a4600190565b50509056fe608060408181526004918236101561001657600080fd5b600092833560e01c91826301ffc9a714610c6057508163248a9ca314610c175781632f2ff15d14610bcf5781632f52ebb71461097c57816336568abe146108f25781633b66f49d146108905781633cfb81ab1461081f5781633f4ba83a14610785578163453dfc1e1461073f578163456dee17146106665781635c975abb146106265781638456cb59146105895781638a19c8bc1461054c57816391d14854146104db57816399248ea71461046c5781639c6b7744146104005781639e281a981461030b578163a217fddf146102d2578163ba1ef3d114610296578163d547741f14610234578163dc38bdb5146101b957508063f5b541a6146101615763ff0a4eb01461012257600080fd5b3461015d57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d576020906005549051908152f35b5080fd5b503461015d57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d57602090517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b8391503461015d5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d576101f3610d44565b916044359067ffffffffffffffff82116102315750610223929161021991369101610d67565b9160243590610d98565b825191151582526020820152f35b80fd5b9190503461029257807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102925761028e91356102896001610277610d1c565b93838752600260205286200154610e51565b61134c565b5080f35b8280fd5b90503461029257827ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102925760209250549051908152f35b50503461015d57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d5751908152602090f35b8391503461015d57827ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d57610344610d44565b60243591838052600260205284842033855260205260ff8585205416156103ca57506103c47fa2bd9fcfcdba69f52bcd9a520846ad4bd685b187483f53efc42d035b2ddebff093946103978433856111c3565b51928392836020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b0390a180f35b604490848651917fe2517d3f00000000000000000000000000000000000000000000000000000000835233908301526024820152fd5b919050346102925760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261029257816020917fa28b54f1a4f6871abf5beebe4e0c893515010a9235994016ddf53e259d7dbedf93358092610463610dbe565b5551908152a180f35b50503461015d57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b90503461029257817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610292578160209360ff9261051a610d1c565b903582526002865273ffffffffffffffffffffffffffffffffffffffff83832091168252855220541690519015158152f35b50503461015d57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d576020906003549051908152f35b50503461015d57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d5760207f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258916105e5610dbe565b6105ed610f23565b6105f5610f23565b60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0085541617845551338152a180f35b50503461015d57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d5760ff602092541690519015158152f35b90503461029257817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102925761069e6113ef565b6106a6610dbe565b6003547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461071357600101806003558352600760205235908220556024356005556003547f208da4b6ff8a3b509f5976dcb8183fe1f90fcc22f5a206cd045bb0ff3b4d26288280a280f35b6024846011847f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b9050346102925760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102925760209282913581526007845220549051908152f35b50503461015d57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d5760207f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa916107e1610dbe565b6107e96113ef565b6107f16113ef565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00845416845551338152a180f35b90503461029257817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610292578160209360ff9261085e610d1c565b903582526008865273ffffffffffffffffffffffffffffffffffffffff83832091168252855220541690519015158152f35b50503461015d5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d578060209273ffffffffffffffffffffffffffffffffffffffff6108e2610d44565b1681526006845220549051908152f35b83833461015d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d5761092a610d1c565b903373ffffffffffffffffffffffffffffffffffffffff831603610954575061028e91923561134c565b8390517f6697b232000000000000000000000000000000000000000000000000000000008152fd5b83833461015d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d57823560243567ffffffffffffffff8111610bcb576109cd9036908601610d67565b6109d5610f23565b600260015414610ba35760026001556003549081865260209260088452858720338852845260ff8688205416610b7b578754421015610b535790610a1a918533610fc9565b939015610b2b5760055410610b0357845260088152828420338552815282842060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541617905560068152828420805490838201809211610ad757557ff01da32686223933d8a18a391060918c7f11a3648639edd87ae013e2e273174390610ac583337f00000000000000000000000000000000000000000000000000000000000000006111c3565b60035493519283523392a36001805580f35b6024866011897f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b8584517fc3ebbdaf000000000000000000000000000000000000000000000000000000008152fd5b8685517f09bde339000000000000000000000000000000000000000000000000000000008152fd5b8786517fe3ea9849000000000000000000000000000000000000000000000000000000008152fd5b8786517f646cf558000000000000000000000000000000000000000000000000000000008152fd5b8584517f1bbee726000000000000000000000000000000000000000000000000000000008152fd5b8380fd5b9190503461029257807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102925761028e9135610c126001610277610d1c565b610e77565b9050346102925760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102925781602093600192358152600285522001549051908152f35b8491346102925760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261029257357fffffffff00000000000000000000000000000000000000000000000000000000811680910361029257602092507f7965db0b000000000000000000000000000000000000000000000000000000008114908115610cf2575b5015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501483610ceb565b6024359073ffffffffffffffffffffffffffffffffffffffff82168203610d3f57565b600080fd5b6004359073ffffffffffffffffffffffffffffffffffffffff82168203610d3f57565b9181601f84011215610d3f5782359167ffffffffffffffff8311610d3f576020808501948460051b010111610d3f57565b929190600454421015610db257610dae93610fc9565b9091565b50505050600090600090565b3360009081527f6bc781d8c7f9885ebbb3cefbc18932c491038e2ae5c5b56447891e0bd98ea16360205260409020547f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9299060ff1615610e1a5750565b604490604051907fe2517d3f0000000000000000000000000000000000000000000000000000000082523360048301526024820152fd5b80600052600260205260406000203360005260205260ff6040600020541615610e1a5750565b90600091808352600260205273ffffffffffffffffffffffffffffffffffffffff6040842092169182845260205260ff60408420541615600014610f1e578083526002602052604083208284526020526040832060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008254161790557f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d339380a4600190565b505090565b60ff60005416610f2f57565b60046040517f1309a563000000000000000000000000000000000000000000000000000000008152fd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610f9a57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805173ffffffffffffffffffffffffffffffffffffffff831660208083019182528284018690528383529697939692959491611008606082610f59565b519020928551918383019485528383528683019767ffffffffffffffff95848a10878b1117610f9a578989528451902060035490600098828a52600788528a8a2054988d116111965760059c808e1b979695949392919061106b8a8a018f610f59565b8d526060976060880190820191368311611192578a90915b83831061118257505050509789985b8c518a10156110cd57898e1b870188015190818110156110be578b52885260018b8b205b990198611092565b908b52885260018b8b206110b6565b949b5094509450949550969598501490811591611150575b50156110f357505050508190565b73ffffffffffffffffffffffffffffffffffffffff16855260069052832054810392908311611123575060019190565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526011600452fd5b8752506008825282862073ffffffffffffffffffffffffffffffffffffffff8216875282528286205460ff16386110e5565b82358152918101918b9101611083565b8c80fd5b60248a7f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b9190823b15611322576040517fa9059cbb000000000000000000000000000000000000000000000000000000006020820190815273ffffffffffffffffffffffffffffffffffffffff9290921660248201526044808201939093529182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09161124e606482610f59565b600093849283809351925af13d15611319573d67ffffffffffffffff81116112ec57611285602060405194601f8401160184610f59565b82523d83602084013e5b156112c2578051806112a057505050565b816020918101031261015d57602001519081159182150361023157506112c257565b60046040517ff1568f95000000000000000000000000000000000000000000000000000000008152fd5b6024847f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b6060915061128f565b60046040517f09ee12d5000000000000000000000000000000000000000000000000000000008152fd5b90600091808352600260205273ffffffffffffffffffffffffffffffffffffffff6040842092169182845260205260ff604084205416600014610f1e57808352600260205260408320828452602052604083207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a4600190565b60ff60005416156113fc57565b60046040517f6cd60201000000000000000000000000000000000000000000000000000000008152fdfea2646970667358221220a4acc0ce8f99f23096f8aa4b3ab6a08b0393a42d017bd629aa271a298b8916a264736f6c634300081800332f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d000000000000000000000000f77dd21c5ce38ac08786be35ef1d1dec1a6a15f3000000000000000000000000fb03340fdb69024c6579b35170f1b3c0d7d67242000000000000000000000000fa3914f0e6cb2c07acf84b66f362ac8d3278b9010000000000000000000000004300000000000000000000000000000000000002
Deployed Bytecode
0x608060408181526004918236101561001657600080fd5b600092833560e01c91826301ffc9a714610c6057508163248a9ca314610c175781632f2ff15d14610bcf5781632f52ebb71461097c57816336568abe146108f25781633b66f49d146108905781633cfb81ab1461081f5781633f4ba83a14610785578163453dfc1e1461073f578163456dee17146106665781635c975abb146106265781638456cb59146105895781638a19c8bc1461054c57816391d14854146104db57816399248ea71461046c5781639c6b7744146104005781639e281a981461030b578163a217fddf146102d2578163ba1ef3d114610296578163d547741f14610234578163dc38bdb5146101b957508063f5b541a6146101615763ff0a4eb01461012257600080fd5b3461015d57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d576020906005549051908152f35b5080fd5b503461015d57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d57602090517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b8391503461015d5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d576101f3610d44565b916044359067ffffffffffffffff82116102315750610223929161021991369101610d67565b9160243590610d98565b825191151582526020820152f35b80fd5b9190503461029257807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102925761028e91356102896001610277610d1c565b93838752600260205286200154610e51565b61134c565b5080f35b8280fd5b90503461029257827ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102925760209250549051908152f35b50503461015d57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d5751908152602090f35b8391503461015d57827ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d57610344610d44565b60243591838052600260205284842033855260205260ff8585205416156103ca57506103c47fa2bd9fcfcdba69f52bcd9a520846ad4bd685b187483f53efc42d035b2ddebff093946103978433856111c3565b51928392836020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b0390a180f35b604490848651917fe2517d3f00000000000000000000000000000000000000000000000000000000835233908301526024820152fd5b919050346102925760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261029257816020917fa28b54f1a4f6871abf5beebe4e0c893515010a9235994016ddf53e259d7dbedf93358092610463610dbe565b5551908152a180f35b50503461015d57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d576020905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000f77dd21c5ce38ac08786be35ef1d1dec1a6a15f3168152f35b90503461029257817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610292578160209360ff9261051a610d1c565b903582526002865273ffffffffffffffffffffffffffffffffffffffff83832091168252855220541690519015158152f35b50503461015d57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d576020906003549051908152f35b50503461015d57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d5760207f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258916105e5610dbe565b6105ed610f23565b6105f5610f23565b60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0085541617845551338152a180f35b50503461015d57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d5760ff602092541690519015158152f35b90503461029257817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102925761069e6113ef565b6106a6610dbe565b6003547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461071357600101806003558352600760205235908220556024356005556003547f208da4b6ff8a3b509f5976dcb8183fe1f90fcc22f5a206cd045bb0ff3b4d26288280a280f35b6024846011847f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b9050346102925760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102925760209282913581526007845220549051908152f35b50503461015d57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d5760207f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa916107e1610dbe565b6107e96113ef565b6107f16113ef565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00845416845551338152a180f35b90503461029257817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610292578160209360ff9261085e610d1c565b903582526008865273ffffffffffffffffffffffffffffffffffffffff83832091168252855220541690519015158152f35b50503461015d5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d578060209273ffffffffffffffffffffffffffffffffffffffff6108e2610d44565b1681526006845220549051908152f35b83833461015d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d5761092a610d1c565b903373ffffffffffffffffffffffffffffffffffffffff831603610954575061028e91923561134c565b8390517f6697b232000000000000000000000000000000000000000000000000000000008152fd5b83833461015d57807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261015d57823560243567ffffffffffffffff8111610bcb576109cd9036908601610d67565b6109d5610f23565b600260015414610ba35760026001556003549081865260209260088452858720338852845260ff8688205416610b7b578754421015610b535790610a1a918533610fc9565b939015610b2b5760055410610b0357845260088152828420338552815282842060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082541617905560068152828420805490838201809211610ad757557ff01da32686223933d8a18a391060918c7f11a3648639edd87ae013e2e273174390610ac583337f000000000000000000000000f77dd21c5ce38ac08786be35ef1d1dec1a6a15f36111c3565b60035493519283523392a36001805580f35b6024866011897f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b8584517fc3ebbdaf000000000000000000000000000000000000000000000000000000008152fd5b8685517f09bde339000000000000000000000000000000000000000000000000000000008152fd5b8786517fe3ea9849000000000000000000000000000000000000000000000000000000008152fd5b8786517f646cf558000000000000000000000000000000000000000000000000000000008152fd5b8584517f1bbee726000000000000000000000000000000000000000000000000000000008152fd5b8380fd5b9190503461029257807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102925761028e9135610c126001610277610d1c565b610e77565b9050346102925760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102925781602093600192358152600285522001549051908152f35b8491346102925760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261029257357fffffffff00000000000000000000000000000000000000000000000000000000811680910361029257602092507f7965db0b000000000000000000000000000000000000000000000000000000008114908115610cf2575b5015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501483610ceb565b6024359073ffffffffffffffffffffffffffffffffffffffff82168203610d3f57565b600080fd5b6004359073ffffffffffffffffffffffffffffffffffffffff82168203610d3f57565b9181601f84011215610d3f5782359167ffffffffffffffff8311610d3f576020808501948460051b010111610d3f57565b929190600454421015610db257610dae93610fc9565b9091565b50505050600090600090565b3360009081527f6bc781d8c7f9885ebbb3cefbc18932c491038e2ae5c5b56447891e0bd98ea16360205260409020547f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9299060ff1615610e1a5750565b604490604051907fe2517d3f0000000000000000000000000000000000000000000000000000000082523360048301526024820152fd5b80600052600260205260406000203360005260205260ff6040600020541615610e1a5750565b90600091808352600260205273ffffffffffffffffffffffffffffffffffffffff6040842092169182845260205260ff60408420541615600014610f1e578083526002602052604083208284526020526040832060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008254161790557f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d339380a4600190565b505090565b60ff60005416610f2f57565b60046040517f1309a563000000000000000000000000000000000000000000000000000000008152fd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117610f9a57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805173ffffffffffffffffffffffffffffffffffffffff831660208083019182528284018690528383529697939692959491611008606082610f59565b519020928551918383019485528383528683019767ffffffffffffffff95848a10878b1117610f9a578989528451902060035490600098828a52600788528a8a2054988d116111965760059c808e1b979695949392919061106b8a8a018f610f59565b8d526060976060880190820191368311611192578a90915b83831061118257505050509789985b8c518a10156110cd57898e1b870188015190818110156110be578b52885260018b8b205b990198611092565b908b52885260018b8b206110b6565b949b5094509450949550969598501490811591611150575b50156110f357505050508190565b73ffffffffffffffffffffffffffffffffffffffff16855260069052832054810392908311611123575060019190565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526011600452fd5b8752506008825282862073ffffffffffffffffffffffffffffffffffffffff8216875282528286205460ff16386110e5565b82358152918101918b9101611083565b8c80fd5b60248a7f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b9190823b15611322576040517fa9059cbb000000000000000000000000000000000000000000000000000000006020820190815273ffffffffffffffffffffffffffffffffffffffff9290921660248201526044808201939093529182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09161124e606482610f59565b600093849283809351925af13d15611319573d67ffffffffffffffff81116112ec57611285602060405194601f8401160184610f59565b82523d83602084013e5b156112c2578051806112a057505050565b816020918101031261015d57602001519081159182150361023157506112c257565b60046040517ff1568f95000000000000000000000000000000000000000000000000000000008152fd5b6024847f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b6060915061128f565b60046040517f09ee12d5000000000000000000000000000000000000000000000000000000008152fd5b90600091808352600260205273ffffffffffffffffffffffffffffffffffffffff6040842092169182845260205260ff604084205416600014610f1e57808352600260205260408320828452602052604083207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541690557ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b339380a4600190565b60ff60005416156113fc57565b60046040517f6cd60201000000000000000000000000000000000000000000000000000000008152fdfea2646970667358221220a4acc0ce8f99f23096f8aa4b3ab6a08b0393a42d017bd629aa271a298b8916a264736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000f77dd21c5ce38ac08786be35ef1d1dec1a6a15f3000000000000000000000000fb03340fdb69024c6579b35170f1b3c0d7d67242000000000000000000000000fa3914f0e6cb2c07acf84b66f362ac8d3278b9010000000000000000000000004300000000000000000000000000000000000002
-----Decoded View---------------
Arg [0] : _rewardToken (address): 0xf77dd21c5ce38ac08786BE35Ef1d1DeC1a6a15F3
Arg [1] : _owner (address): 0xFB03340fdB69024C6579b35170F1B3c0D7D67242
Arg [2] : _operator (address): 0xFA3914F0e6cb2c07AcF84B66f362ac8d3278b901
Arg [3] : _blast (address): 0x4300000000000000000000000000000000000002
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000f77dd21c5ce38ac08786be35ef1d1dec1a6a15f3
Arg [1] : 000000000000000000000000fb03340fdb69024c6579b35170f1b3c0d7d67242
Arg [2] : 000000000000000000000000fa3914f0e6cb2c07acf84b66f362ac8d3278b901
Arg [3] : 0000000000000000000000004300000000000000000000000000000000000002
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
BLAST | 100.00% | $0.000412 | 141,141,502.2209 | $58,161.59 |
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
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.