Overview
ETH Balance
0 ETH
Eth Value
$0.00Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 959 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Update Rewards M... | 21485257 | 2 days ago | IN | 0 ETH | 0.00031911 | ||||
Deposit Reward | 21484674 | 3 days ago | IN | 0 ETH | 0.00028875 | ||||
Update Rewards M... | 21470952 | 4 days ago | IN | 0 ETH | 0.00030243 | ||||
Deposit Reward | 21470367 | 5 days ago | IN | 0 ETH | 0.00027886 | ||||
Join | 21439991 | 9 days ago | IN | 0 ETH | 0.00064195 | ||||
Update Rewards M... | 21435188 | 9 days ago | IN | 0 ETH | 0.00052028 | ||||
Deposit Reward | 21434643 | 10 days ago | IN | 0 ETH | 0.00052852 | ||||
Deposit Reward | 21434623 | 10 days ago | IN | 0 ETH | 0.00059746 | ||||
Deposit Reward | 21434603 | 10 days ago | IN | 0 ETH | 0.00054359 | ||||
Leave | 21426415 | 11 days ago | IN | 0 ETH | 0.0002398 | ||||
Join | 21426399 | 11 days ago | IN | 0 ETH | 0.00052413 | ||||
Join | 21386103 | 16 days ago | IN | 0 ETH | 0.00082481 | ||||
Update Rewards M... | 21385044 | 16 days ago | IN | 0 ETH | 0.00077939 | ||||
Deposit Reward | 21384497 | 17 days ago | IN | 0 ETH | 0.00077222 | ||||
Deposit Reward | 21384477 | 17 days ago | IN | 0 ETH | 0.0006822 | ||||
Deposit Reward | 21384457 | 17 days ago | IN | 0 ETH | 0.00072763 | ||||
Join | 21378816 | 17 days ago | IN | 0 ETH | 0.00058998 | ||||
Update Rewards M... | 21370725 | 18 days ago | IN | 0 ETH | 0.00060748 | ||||
Deposit Reward | 21370177 | 19 days ago | IN | 0 ETH | 0.00068917 | ||||
Deposit Reward | 21370139 | 19 days ago | IN | 0 ETH | 0.00066627 | ||||
Update Rewards M... | 21334914 | 23 days ago | IN | 0 ETH | 0.00088981 | ||||
Deposit Reward | 21334348 | 24 days ago | IN | 0 ETH | 0.00090351 | ||||
Deposit Reward | 21334328 | 24 days ago | IN | 0 ETH | 0.00085536 | ||||
Update Rewards M... | 21284818 | 30 days ago | IN | 0 ETH | 0.00047038 | ||||
Deposit Reward | 21284251 | 31 days ago | IN | 0 ETH | 0.00054724 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
RewardHarvester
Compiler Version
v0.8.12+commit.f00d7308
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.12; import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import {Errors} from "./libraries/Errors.sol"; import {Common} from "./libraries/Common.sol"; contract RewardHarvester is Ownable2Step { using SafeERC20 for IERC20; struct Reward { bytes32 merkleRoot; bytes32 hashedData; uint256 activeAt; } uint256 public constant FEE_BASIS = 1_000_000; uint256 public constant MAX_FEE = 100_000; uint256 public constant MINIMUM_ACTIVE_TIMER = 3 hours; // Maps members mapping(address => bool) public isMember; // Maps fees collected for each token mapping(address => uint256) public feesCollected; // Maps each of the identifier to its reward metadata mapping(address => Reward) public rewards; // Tracks the amount of claimed reward for the specified token and account mapping(address => mapping(address => uint256)) public claimed; // Harvest default token address public defaultToken; // Operator address address public operator; // Claimer address address public claimer; // Reward swapper address address public rewardSwapper; // Used for calculating the timestamp on which rewards can be claimed after an update uint256 public activeTimerDuration; //-----------------------// // Events // //-----------------------// event MemberJoined(address member); event MemberLeft(address member); event FeesCollected(address indexed token, uint256 amount); event BribeTransferred(address indexed token, uint256 totalAmount); event RewardClaimed( address indexed token, address indexed account, uint256 amount, uint256 postFeeAmount, address receiver ); event RewardMetadataUpdated( address indexed token, bytes32 merkleRoot, bytes32 proof, uint256 activeAt ); event DefaultTokenUpdated(address indexed token); event SetOperator(address indexed operator); event SetClaimer(address indexed claimer); event SetRewardSwapper(address indexed rewardSwapper); event SetActiveTimerDuration(uint256 duration); //-----------------------// // Modifiers // //-----------------------// /** * @notice Modifier to check caller is operator */ modifier onlyOperatorOrOwner() { if (msg.sender != operator && msg.sender != owner()) revert Errors.NotAuthorized(); _; } /** * @notice Modifier to check caller is operator or reward swapper */ modifier onlyOperatorOrRewardSwapper() { if (msg.sender != operator && msg.sender != rewardSwapper) revert Errors.NotAuthorized(); _; } //-----------------------// // Constructor // //-----------------------// constructor( address _rewardSwapper, address _operator, address _defaultToken ) { _setDefaultToken(_defaultToken); _setOperator(_operator); _setRewardSwapper(_rewardSwapper); _setActiveTimerDuration(MINIMUM_ACTIVE_TIMER); } //-----------------------// // External Functions // //-----------------------// /** @notice Join the harvester to enable claiming rewards in default token */ function join() external { isMember[msg.sender] = true; emit MemberJoined(msg.sender); } /** @notice Leave harvester */ function leave() external { isMember[msg.sender] = false; emit MemberLeft(msg.sender); } /** @notice Claim rewards based on the specified metadata @dev Can only be called by the claimer contract @param _token address Token to claim rewards @param _account address Account to claim rewards @param _amount uint256 Amount of rewards to claim @param _merkleProof bytes32[] Merkle proof of the claim @param _fee uint256 Claim fee @param _receiver address Receiver of the rewards */ function claim( address _token, address _account, uint256 _amount, bytes32[] calldata _merkleProof, uint256 _fee, address _receiver ) external { if (msg.sender != claimer) revert Errors.NotAuthorized(); if (_account == address(0)) revert Errors.InvalidClaim(); if (_amount == 0) revert Errors.InvalidAmount(); if (_fee > MAX_FEE) revert Errors.InvalidFee(); // Calculate amount after any fees uint256 feeAmount = (_amount * _fee) / FEE_BASIS; uint256 postFeeAmount = _amount - feeAmount; feesCollected[_token] += feeAmount; Reward memory reward = rewards[_token]; uint256 lifeTimeAmount = claimed[_token][_account] + _amount; if (reward.merkleRoot == 0) revert Errors.InvalidDistribution(); if (reward.activeAt > block.timestamp) revert Errors.RewardInactive(); // Verify the merkle proof if ( !MerkleProof.verifyCalldata( _merkleProof, reward.merkleRoot, keccak256(abi.encodePacked(_account, lifeTimeAmount)) ) ) revert Errors.InvalidProof(); // Update the claimed amount to the current total claimed[_token][_account] = lifeTimeAmount; IERC20(_token).safeTransfer(_receiver, postFeeAmount); emit RewardClaimed(_token, _account, _amount, postFeeAmount, _receiver); } /** @notice Deposit `defaultToken` to this contract @param _amount uint256 Amount of `defaultToken` to deposit */ function depositReward( uint256 _amount ) external onlyOperatorOrRewardSwapper { if (_amount == 0) revert Errors.InvalidAmount(); IERC20 token = IERC20(defaultToken); uint256 initialAmount = token.balanceOf(address(this)); token.safeTransferFrom(msg.sender, address(this), _amount); emit BribeTransferred( defaultToken, token.balanceOf(address(this)) - initialAmount ); } /** @notice Update rewards metadata @param _token address Token to update rewards metadata @param _merkleRoot bytes32 Merkle root of the rewards @param _hashedData bytes32 Hashed data of the rewards */ function updateRewardsMetadata( address _token, bytes32 _merkleRoot, bytes32 _hashedData ) external onlyOperatorOrOwner { if (_token == address(0)) revert Errors.InvalidToken(); if (_merkleRoot == 0) revert Errors.InvalidMerkleRoot(); // Update the metadata and start the timer until the rewards will be active/claimable uint256 activeAt = block.timestamp + activeTimerDuration; Reward storage reward = rewards[_token]; reward.merkleRoot = _merkleRoot; reward.hashedData = _hashedData; reward.activeAt = activeAt; emit RewardMetadataUpdated(_token, _merkleRoot, _hashedData, activeAt); } /** @notice Collect fees @param _token address Token to collect fees */ function collectFees(address _token) external onlyOwner { uint256 amount = feesCollected[_token]; if (amount == 0) revert Errors.InvalidAmount(); feesCollected[_token] = 0; IERC20(_token).safeTransfer(msg.sender, amount); emit FeesCollected(_token, amount); } /** @notice Change the operator @param _operator address New operator address */ function changeOperator(address _operator) external onlyOwner { _setOperator(_operator); } /** @notice Change the `defaultToken` @param _newToken address New default token address */ function changeDefaultToken(address _newToken) external onlyOwner { _setDefaultToken(_newToken); } /** @notice Change the RewardSwapper contract @param _newSwapper address New reward swapper address */ function changeRewardSwapper(address _newSwapper) external onlyOwner { _setRewardSwapper(_newSwapper); } /** @notice Change claimer address @param _claimer address New claimer address */ function changeClaimer(address _claimer) external onlyOwner { if (_claimer == address(0)) revert Errors.InvalidAddress(); claimer = _claimer; emit SetClaimer(_claimer); } /** @notice Set the active timer duration @param _duration uint256 Timer duration */ function changeActiveTimerDuration(uint256 _duration) external onlyOwner { _setActiveTimerDuration(_duration); } //-----------------------// // Internal Functions // //-----------------------// /** @dev Internal to set the default token @param _newToken address Token address */ function _setDefaultToken(address _newToken) internal { if (_newToken == address(0)) revert Errors.InvalidToken(); defaultToken = _newToken; emit DefaultTokenUpdated(_newToken); } /** @dev Internal to set the RewardSwapper contract @param _newSwapper address RewardSwapper address */ function _setRewardSwapper(address _newSwapper) internal { if (_newSwapper == address(0)) revert Errors.InvalidAddress(); rewardSwapper = _newSwapper; emit SetRewardSwapper(_newSwapper); } /** @dev Internal to set the operator @param _operator address Token address */ function _setOperator(address _operator) internal { if (_operator == address(0)) revert Errors.InvalidOperator(); operator = _operator; emit SetOperator(_operator); } /** @dev Internal to set the active timer duration @param _duration uint256 Timer duration */ function _setActiveTimerDuration(uint256 _duration) internal { if (_duration < MINIMUM_ACTIVE_TIMER) revert Errors.InvalidTimerDuration(); activeTimerDuration = _duration; emit SetActiveTimerDuration(_duration); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../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. * * By default, the owner account will be the one that deploys the contract. 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; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @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 { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @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 { require(newOwner != address(0), "Ownable: new owner is the zero address"); _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 v4.9.0) (access/Ownable2Step.sol) pragma solidity ^0.8.0; import "./Ownable.sol"; /** * @dev Contract module which provides access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership} and {acceptOwnership}. * * This module is used through inheritance. It will make available all functions * from parent (Ownable). */ abstract contract Ownable2Step is Ownable { address private _pendingOwner; event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() public virtual { address sender = _msgSender(); require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner"); _transferOwnership(sender); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @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 amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to * 0 before setting it to a non-zero value. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @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 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} * * _Available since v4.7._ */ 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. * * _Available since v4.4._ */ 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} * * _Available since v4.7._ */ 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. * * _Available since v4.7._ */ 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. * * _Available since v4.7._ */ 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). * * _Available since v4.7._ */ 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 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // 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) { 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. * * _Available since v4.7._ */ 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 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proof.length - 1 == totalHashes, "MerkleProof: invalid multiproof"); // 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) { unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } 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 pragma solidity 0.8.12; library Common { /** * @param identifier bytes32 Identifier of the distribution * @param token address Address of the token to distribute * @param merkleRoot bytes32 Merkle root of the distribution * @param proof bytes32 Proof of the distribution */ struct Distribution { bytes32 identifier; address token; bytes32 merkleRoot; bytes32 proof; } /** * @param proposal bytes32 Proposal to bribe * @param token address Token to bribe with * @param briber address Address of the briber * @param amount uint256 Amount of tokens to bribe with * @param maxTokensPerVote uint256 Maximum amount of tokens to use per vote * @param periods uint256 Number of periods to bribe for * @param periodDuration uint256 Duration of each period * @param proposalDeadline uint256 Deadline for the proposal * @param permitDeadline uint256 Deadline for the permit2 signature * @param signature bytes Permit2 signature */ struct DepositBribeParams { bytes32 proposal; address token; address briber; uint256 amount; uint256 maxTokensPerVote; uint256 periods; uint256 periodDuration; uint256 proposalDeadline; uint256 permitDeadline; bytes signature; } /** * @param rwIdentifier bytes32 Identifier for claiming reward * @param fromToken address Address of token to swap from * @param toToken address Address of token to swap to * @param fromAmount uint256 Amount of fromToken to swap * @param toAmount uint256 Amount of toToken to receive * @param deadline uint256 Timestamp until which swap may be fulfilled * @param callees address[] Array of addresses to call (DEX addresses) * @param callLengths uint256[] Index of the beginning of each call in exchangeData * @param values uint256[] Array of encoded values for each call in exchangeData * @param exchangeData bytes Calldata to execute on callees * @param rwMerkleProof bytes32[] Merkle proof for the reward claim */ struct ClaimAndSwapData { bytes32 rwIdentifier; address fromToken; address toToken; uint256 fromAmount; uint256 toAmount; uint256 deadline; address[] callees; uint256[] callLengths; uint256[] values; bytes exchangeData; bytes32[] rwMerkleProof; } /** * @param identifier bytes32 Identifier for claiming reward * @param account address Address of the account to claim for * @param amount uint256 Amount of tokens to claim * @param merkleProof bytes32[] Merkle proof for the reward claim */ struct Claim { bytes32 identifier; address account; uint256 amount; bytes32[] merkleProof; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.12; library Errors { /** * @notice max period 0 or greater than MAX_PERIODS */ error InvalidMaxPeriod(); /** * @notice period duration 0 or greater than MAX_PERIOD_DURATION */ error InvalidPeriodDuration(); /** * @notice address provided is not a contract */ error NotAContract(); /** * @notice not authorized */ error NotAuthorized(); /** * @notice contract already initialized */ error AlreadyInitialized(); /** * @notice address(0) */ error InvalidAddress(); /** * @notice empty bytes identifier */ error InvalidIdentifier(); /** * @notice invalid protocol name */ error InvalidProtocol(); /** * @notice invalid number of choices */ error InvalidChoiceCount(); /** * @notice invalid input amount */ error InvalidAmount(); /** * @notice not team member */ error NotTeamMember(); /** * @notice cannot whitelist BRIBE_VAULT */ error NoWhitelistBribeVault(); /** * @notice token already whitelisted */ error TokenWhitelisted(); /** * @notice token not whitelisted */ error TokenNotWhitelisted(); /** * @notice voter already blacklisted */ error VoterBlacklisted(); /** * @notice voter not blacklisted */ error VoterNotBlacklisted(); /** * @notice deadline has passed */ error DeadlinePassed(); /** * @notice invalid period */ error InvalidPeriod(); /** * @notice invalid deadline */ error InvalidDeadline(); /** * @notice invalid max fee */ error InvalidMaxFee(); /** * @notice invalid fee */ error InvalidFee(); /** * @notice invalid fee recipient */ error InvalidFeeRecipient(); /** * @notice invalid distributor */ error InvalidDistributor(); /** * @notice invalid briber */ error InvalidBriber(); /** * @notice address does not have DEPOSITOR_ROLE */ error NotDepositor(); /** * @notice no array given */ error InvalidArray(); /** * @notice invalid reward identifier */ error InvalidRewardIdentifier(); /** * @notice bribe has already been transferred */ error BribeAlreadyTransferred(); /** * @notice distribution does not exist */ error InvalidDistribution(); /** * @notice invalid merkle root */ error InvalidMerkleRoot(); /** * @notice token is address(0) */ error InvalidToken(); /** * @notice claim does not exist */ error InvalidClaim(); /** * @notice reward is not yet active for claiming */ error RewardInactive(); /** * @notice timer duration is invalid */ error InvalidTimerDuration(); /** * @notice merkle proof is invalid */ error InvalidProof(); /** * @notice ETH transfer failed */ error ETHTransferFailed(); /** * @notice Invalid operator address */ error InvalidOperator(); /** * @notice call to TokenTransferProxy contract */ error TokenTransferProxyCall(); /** * @notice calling TransferFrom */ error TransferFromCall(); /** * @notice external call failed */ error ExternalCallFailure(); /** * @notice returned tokens too few */ error InsufficientReturn(); /** * @notice swapDeadline expired */ error DeadlineBreach(); /** * @notice expected tokens returned are 0 */ error ZeroExpectedReturns(); /** * @notice arrays in SwapData.exchangeData have wrong lengths */ error ExchangeDataArrayMismatch(); }
{ "optimizer": { "enabled": true, "runs": 200, "details": { "yulDetails": { "optimizerSteps": "u" } } }, "viaIR": true, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_rewardSwapper","type":"address"},{"internalType":"address","name":"_operator","type":"address"},{"internalType":"address","name":"_defaultToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidClaim","type":"error"},{"inputs":[],"name":"InvalidDistribution","type":"error"},{"inputs":[],"name":"InvalidFee","type":"error"},{"inputs":[],"name":"InvalidMerkleRoot","type":"error"},{"inputs":[],"name":"InvalidOperator","type":"error"},{"inputs":[],"name":"InvalidProof","type":"error"},{"inputs":[],"name":"InvalidTimerDuration","type":"error"},{"inputs":[],"name":"InvalidToken","type":"error"},{"inputs":[],"name":"NotAuthorized","type":"error"},{"inputs":[],"name":"RewardInactive","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"totalAmount","type":"uint256"}],"name":"BribeTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"}],"name":"DefaultTokenUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeesCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"member","type":"address"}],"name":"MemberJoined","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"member","type":"address"}],"name":"MemberLeft","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","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":"token","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"postFeeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"}],"name":"RewardClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"proof","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"activeAt","type":"uint256"}],"name":"RewardMetadataUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"SetActiveTimerDuration","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimer","type":"address"}],"name":"SetClaimer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"}],"name":"SetOperator","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"rewardSwapper","type":"address"}],"name":"SetRewardSwapper","type":"event"},{"inputs":[],"name":"FEE_BASIS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINIMUM_ACTIVE_TIMER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"activeTimerDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"changeActiveTimerDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_claimer","type":"address"}],"name":"changeClaimer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newToken","type":"address"}],"name":"changeDefaultToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"changeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newSwapper","type":"address"}],"name":"changeRewardSwapper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32[]","name":"_merkleProof","type":"bytes32[]"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"claimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"collectFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"defaultToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"feesCollected","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isMember","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"join","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"leave","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardSwapper","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"hashedData","type":"bytes32"},{"internalType":"uint256","name":"activeAt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"},{"internalType":"bytes32","name":"_hashedData","type":"bytes32"}],"name":"updateRewardsMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523462000032575b620000206200001962000122565b9162000167565b604051611dcf620004fe8239611dcf90f35b6200003c62000042565b6200000b565b50600080fd5b50634e487b7160e01b600052604160045260246000fd5b90601f01601f191681019081106001600160401b038211176200008157604052565b6200008b62000048565b604052565b90620000a76200009f60405190565b92836200005f565b565b6001600160a01b031690565b90565b6001600160a01b03811614156200004257565b90505190620000a782620000b8565b909160608284031262000112575b620000b5620000f88484620000cb565b93620001088160208601620000cb565b93604001620000cb565b6200011c62000042565b620000e8565b62000145620022cd80380380620001398162000090565b928339810190620000da565b909192565b620000b5620000b5620000b59290565b620000b5612a306200014a565b906200018c9062000186620001929462000180620001a6565b62000306565b620003f1565b62000384565b620000a7620001a06200015a565b62000485565b620000a780336200022d565b916001600160a01b0360089290920291821b911b5b9181191691161790565b620000b590620000a9906001600160a01b031682565b620000b590620001d1565b620000b590620001e7565b919062000212620000b56200021b93620001f2565b908354620001b2565b9055565b620000a791600091620001fd565b620000a79062000240600060016200021f565b62000289565b620000b590620000a9565b620000b5905462000246565b906001600160a01b0390620001c7565b9062000281620000b56200021b92620001f2565b82546200025d565b62000295600062000251565b90620002a38160006200026d565b620002da620002d37f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093620001f2565b91620001f2565b91620002e560405190565b600090a3565b620000a9620000b5620000b59290565b620000b590620002eb565b62000316620000a96000620002fb565b6001600160a01b038216146200037057620003338160066200026d565b6200035f7f2ffae89a4970d1ff9bf1a765b00d7eee23cd328cdaaab85b7ce9e5379c1ece3291620001f2565b906200036a60405190565b600090a2565b505060405163c1ab6dc160e01b8152600490fd5b62000394620000a96000620002fb565b6001600160a01b03821614620003dd57620003b18160096200026d565b6200035f7f5326c5ebddd2feafb723c3b63cc83fb32a9c8dd7d05476832b798d9782bad87891620001f2565b505060405163e6c4247b60e01b8152600490fd5b62000401620000a96000620002fb565b6001600160a01b038216146200044a576200041e8160076200026d565b6200035f7fdbebfba65bd6398fb722063efc10c99f624f9cd8ba657201056af918a676d5ee91620001f2565b505060405163ccea9e6f60e01b8152600490fd5b9060001990620001c7565b906200047d620000b56200021b926200014a565b82546200045e565b62000493620000b56200015a565b8110620004e957620004a781600a62000469565b620004e47f676dc704f22ddab12a141690a96616ef0128413803c63394aba7ffe658681a1691620004d760405190565b9182918290815260200190565b0390a1565b50506040516367e00a0760e01b8152600490fdfe60806040526004361015610018575b61001661061e565b005b60003560e01c806303aaf08b146105f757806306394c9b146105d05780630700037d146105965780630c9cbf0e1461056b5780630cc630c714610543578063101cef481461051c5780631e2720ff146104f557806333f642f6146104cb57806348a61ff51461049d5780635512b81114610473578063570ca735146104495780635b2478ea1461041f578063715018a6146103f857806374c13fda146103ce57806379ba5097146103a75780637fdba5f61461037d5780638686ebcc146103535780638da5cb5b146103295780638e3fb0d314610302578063960d264d146102db578063a230c5241461029f578063a480ca7914610278578063b688a36314610251578063bc063e1a14610216578063d379be23146101ec578063d66d9e19146101c5578063e30c3978146101805763f2fde38b146101565761000e565b34610173575b61001661016a366004610655565b610b3b565b0390f35b61017b61061e565b61015c565b50346101b8575b6101923660046107f0565b61016f61019d610a97565b6040515b918291826001600160a01b03909116815260200190565b6101c061061e565b610187565b50346101df575b6101d73660046107f0565b610016610cc4565b6101e761061e565b6101cc565b5034610209575b6101fe3660046107f0565b61016f61019d6109ab565b61021161061e565b6101f3565b5034610244575b6102283660046107f0565b61016f6102336109a3565b6040515b9182918290815260200190565b61024c61061e565b61021d565b503461026b575b6102633660046107f0565b610016610c7b565b61027361061e565b610258565b5034610292575b61001661028d366004610655565b611b10565b61029a61061e565b61027f565b50346102ce575b61016f6102bc6102b7366004610655565b610980565b60405191829182901515815260200190565b6102d661061e565b6102a6565b50346102f5575b6100166102f03660046107cf565b611c13565b6102fd61061e565b6102e2565b503461031c575b610016610317366004610655565b611b4c565b61032461061e565b610309565b5034610346575b61033b3660046107f0565b61016f61019d6109ca565b61034e61061e565b610330565b5034610370575b6103653660046107f0565b61016f61023361095f565b61037861061e565b61035a565b503461039a575b61038f3660046107f0565b61016f61023361094b565b6103a261061e565b610384565b50346103c1575b6103b93660046107f0565b610016610c34565b6103c961061e565b6103ae565b50346103eb575b6103e03660046107f0565b61016f61019d610927565b6103f361061e565b6103d5565b5034610412575b61040a3660046107f0565b610016610a0c565b61041a61061e565b6103ff565b503461043c575b61016f610233610437366004610655565b610915565b61044461061e565b610426565b5034610466575b61045b3660046107f0565b61016f61019d610909565b61046e61061e565b610450565b5034610490575b6104853660046107f0565b61016f61019d6108fd565b61049861061e565b61047a565b50346104be575b6100166104b236600461085b565b95949094939193610ecf565b6104c661061e565b6104a4565b50346104e8575b6104dd3660046107f0565b61016f610233610803565b6104f061061e565b6104d2565b503461050f575b61001661050a3660046107cf565b6118c0565b61051761061e565b6104fc565b5034610536575b610016610531366004610655565b611bf5565b61053e61061e565b610523565b503461055e575b610016610558366004610791565b91611a71565b61056661061e565b61054a565b5034610589575b61016f610233610583366004610718565b9061075f565b61059161061e565b610572565b50346105c3575b61016f6105b36105ae366004610655565b6106c5565b6040519193915b938493846106f6565b6105cb61061e565b61059d565b50346105ea575b6100166105e5366004610655565b611b2e565b6105f261061e565b6105d7565b5034610611575b61001661060c366004610655565b611b6a565b61061961061e565b6105fe565b50600080fd5b6001600160a01b031690565b90565b6001600160a01b0381165b141561061e57565b9050359061065382610633565b565b906106309160208183031261066957610646565b61067161061e565b610646565b61063090610624906001600160a01b031682565b61063090610676565b6106309061068a565b906106a690610693565b600052602052604060002090565b6106309081565b61063090546106b4565b6106d090600461069c565b6106d9816106bb565b9161063060026106eb600185016106bb565b93016106bb565b9052565b908152606081019392610653929091604091610714905b6020830152565b0152565b91906106309060408482031261073c575b6107338185610646565b93602001610646565b61074461061e565b610729565b610630916008021c81565b906106309154610749565b6107796106309261077460059360009461069c565b61069c565b610754565b8061063e565b905035906106538261077e565b90916060828403126107c2575b6106306107ab8484610646565b936107b98160208601610784565b93604001610784565b6107ca61061e565b61079e565b90610630916020818303126107e357610784565b6107eb61061e565b610784565b60009103126107fb57565b61065361061e565b6106306000600a610754565b909182601f8301121561084e575b602082359267ffffffffffffffff8411610841575b0192602083028401116107fb57565b61084961061e565b610832565b61085661061e565b61081d565b909160c0828403126108d8575b6108728383610646565b926106306108838260208601610646565b936108918360408301610784565b936108b284606084013567ffffffffffffffff81116108cb575b840161080f565b9390946108c28160808601610784565b9360a001610646565b6108d361061e565b6108ab565b6108e061061e565b610868565b610630916008021c610624565b9061063091546108e5565b610630600060096108f2565b610630600060076108f2565b6106309061077960039160009261069c565b610630600060066108f2565b6106306106306106309290565b610630612a30610933565b610630610940565b610630620f4240610933565b610630610953565b610630916008021c60ff1690565b906106309154610967565b6106309061099260029160009261069c565b610975565b610630620186a0610933565b610630610997565b610630600060086108f2565b61063090610624565b61063090546109b7565b61063060006109c0565b6109dc610a6d565b6106536109fa565b6106246106306106309290565b610630906109e4565b610653610a0760006109f1565b610b82565b6106536109d4565b0190565b15610a1f57565b5060405162461bcd60e51b815280610a69600482016020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b0390fd5b610653610a786109ca565b610a91610a8433610624565b916001600160a01b031690565b14610a18565b61063060016109c0565b61065390610aad610a6d565b610ae2565b906001600160a01b03905b9181191691161790565b90610ad7610630610ade92610693565b8254610ab2565b9055565b610aed816001610ac7565b610af56109ca565b90610b29610b237f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270093610693565b91610693565b91610b3360405190565b80805b0390a3565b61065390610aa1565b916001600160a01b0360089290920291821b911b610abd565b9190610b6e610630610ade93610693565b908354610b44565b61065391600091610b5d565b61065390610b9260006001610b76565b610b9c60006109c0565b90610ba8816000610ac7565b610b29610b237f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610693565b15610bdc57565b5060405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608490fd5b61065333610a07610c43610a97565b610c556001600160a01b038416610a84565b14610bd5565b9060ff90610abd565b90610c74610630610ade92151590565b8254610c5b565b33610c916001610c8c83600261069c565b610c64565b610cbf7f0abf3b3f643594d958297062a019458e27d7766629590ac621aa1000fa1298ab916101a160405190565b0390a1565b33610cd56000610c8c83600261069c565b610cbf7fbea911b50ccdd2233b28faa49766c3cbd0631608f32e5a724d7b83b32b681ad0916101a160405190565b50634e487b7160e01b600052601160045260246000fd5b90610d24565b9190565b908060001904821181151516610d38570290565b610d40610d03565b0290565b50634e487b7160e01b600052601260045260246000fd5b8115610d65570490565b610d6d610d44565b0490565b818110610d7c570390565b610d84610d03565b0390565b81198111610d94570190565b610a14610d03565b9060001990610abd565b90610db6610630610ade92610933565b8254610d9c565b601f01601f191690565b50634e487b7160e01b600052604160045260246000fd5b90601f01601f1916810190811067ffffffffffffffff821117610e0057604052565b610e08610dc7565b604052565b90610653610e1a60405190565b9283610dde565b6106306060610e0d565b90610653610e696002610e3c610e21565b94610e4d610e49826106bb565b8752565b610e63610e5c600183016106bb565b6020880152565b016106bb565b6040840152565b61063090610e2b565b6106f2906001600160a01b031660601b90565b601481610e9f610a149360209695610e79565b01918252565b908152606081019392610653929091604091610ec09061070d565b01906001600160a01b03169052565b93909433610ee3610a8461062460086109c0565b141561118157600091610ef8610624846109f1565b6001600160a01b0388161461116057610f1083610933565b841461113f57610f21610630610997565b821161111e57610f43610f35879386610d1a565b610f3d610953565b90610d5b565b94610f75610f518787610d71565b96610f6f610f6086600361069c565b91610f6a836106bb565b610d88565b90610da6565b600491610f8a610f85858561069c565b610e70565b94610fa787610f6a610fa28d61077460059a8b61069c565b6106bb565b9581810191610fc0610d20610fba855190565b92610933565b146110f2576040015142106110c7579161102391610fdf611027945190565b908b61100a610fed60405190565b8092610ffe8c602084019283610e8c565b90810382520382610dde565b61101c611015825190565b9160200190565b20926115bd565b1590565b61109f57509061103e86610774876110439561069c565b610da6565b611056828661105186610693565b6111e4565b610b3661108c6110867f70fec9c7f21f70099818a4619c69af3a4677031e67acea18286c0eca3a754bce95610693565b95610693565b9561109660405190565b93849384610ea5565b9650505050505050610a6991506110b560405190565b6309bde33960e01b8152918291820190565b5050509650505050505050610a6991506110e060405190565b630995309b60e01b8152918291820190565b505050509650505050505050610a69915061110c60405190565b630d16b83360e31b8152918291820190565b50505050505050505061113060405190565b6358d620b360e01b8152600490fd5b50505050505050505061115160405190565b63162908e360e11b8152600490fd5b50505050505050505061117260405190565b633b4f091f60e21b8152600490fd5b505050505050505061119260405190565b63ea8e4eb560e01b8152600490fd5b6111ba6111b46106309263ffffffff1690565b60e01b90565b6001600160e01b03191690565b6001600160a01b0390911681526040810192916106539160200152565b611227600492611218610653956111fe63a9059cbb6111a1565b9261120860405190565b96879460208601908152016111c7565b60208201810382520383610dde565b61133b565b610a1460209167ffffffffffffffff811161124b57601f01601f191690565b610dbd610dc7565b906112656112608361122c565b610e0d565b918252565b6112746020611253565b7f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564602082015290565b61063061126a565b80151561063e565b90505190610653826112a5565b90610630916020818303126112ce576112ad565b6112d661061e565b6112ad565b156112e257565b5060405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b6106539161134b61135a92610693565b9061135461129d565b91611398565b8051611369610d206000610933565b14908115611378575b506112db565b61139291506020611387825190565b8183010191016112ba565b38611372565b61063092916113a76000610933565b91611428565b156113b457565b5060405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608490fd5b3d15611423576114183d611253565b903d6000602084013e565b606090565b9060006106309493819261143a606090565b5061145161144730610693565b83903110156113ad565b60208101905191855af1611463611409565b916114b6565b1561147057565b5060405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b9192606091156114eb57505081516114d1610d206000610933565b146114da575090565b6114e6610630916114f8565b611469565b909392610653925061157a565b3b611506610d206000610933565b1190565b918091926000905b82821061152a575011611523575050565b6000910152565b91508060209183015181860152018291611512565b611560610dbd602093610a1493611554815190565b80835293849260200190565b9586910161150a565b60208082526106309291019061153f565b9150611584825190565b611591610d206000610933565b11156115a05750805190602001fd5b604051610a69925062461bcd60e51b815291829160048301611569565b6115dc9293610d20926115d8926115d2600090565b5061162e565b9290565b1490565b6001906000198114610d94570190565b50634e487b7160e01b600052603260045260246000fd5b9160209181101561161757020190565b61161f6115f0565b020190565b356106308161077e565b6116386000610933565b925b8284101561166e576116626116689161165c611657878787611607565b611624565b90611675565b936115e0565b9261163a565b9250505090565b81811015611690579061063091600052602052604060002090565b61063091600052602052604060002090565b336116b061062460076109c0565b6001600160a01b038216141590816116db575b506116d15761065390611730565b5050604051611192565b90506116ed610a8461062460096109c0565b1415386116c3565b905051906106538261077e565b9061063091602081830312611716576116f5565b61171e61061e565b6116f5565b506040513d6000823e3d90fd5b61173a6000610933565b81146118b65761181761175561175060066109c0565b610693565b61175e81610693565b926370a082319361176e30610693565b9161177860405190565b936117838760e01b90565b85526001600160a01b0384166004860152602085602481865afa9485156118a9575b60009561187f575b50916117c284926117fd9560209533906118ed565b6117e66117cf60066109c0565b976117d960405190565b9586948593849360e01b90565b83526001600160a01b031660048301526024820190565b03915afa908115611872575b600091611854575b50610d71565b9061184f6118457ff1fa0256e6ecba08316eb890d662830768e73136b5b0dbea4c9c8c16ca1747eb92610693565b9261023760405190565b0390a2565b61186c91506118633d82610dde565b3d810190611702565b38611811565b61187a611723565b611809565b60209391955084926117fd9561189c6117c2936118633d82610dde565b97939550509294506117ad565b6118b1611723565b6117a5565b5050604051611151565b610653906116a2565b6001600160a01b039182168152911660208201526060810192916106539160400152565b9061122790611218610653956004956119096323b872dd6111a1565b9361191360405190565b97889560208701908152016118c9565b91903361193361062460076109c0565b6001600160a01b03821614159081611961575b506119545761065392611987565b5050505061119260405190565b9050611971610a846106246109ca565b141538611946565b90610db6610630610ade9290565b9091600092611998610624856109f1565b6001600160a01b03841614611a54576119b084610933565b8114611a3757611a006002946119d0426119ca600a6106bb565b90610d88565b9586916119ed856119e56106308a600461069c565b928301611979565b6119fa8660018301611979565b01610da6565b61184f611a2d7f9ca93988e299d8264919a188c320f8d8efa97e1976a234f3c6c42315fc10b4e094610693565b946105ba60405190565b5050505050611a4560405190565b639dd854d360e01b8152600490fd5b5050505050611a6260405190565b63c1ab6dc160e01b8152600490fd5b906106539291611923565b61065390611a88610a6d565b600390611a98610fa2828461069c565b91600090611aa582610933565b8414611b025761103e83611abb611ac194610933565b9261069c565b611ad582611ace83610693565b33906111e4565b61184f6118457f9dc46f23cfb5ddcad0ae7ea2be38d47fec07bb9382ec7e564efc69e036dd66ce92610693565b505050505061115160405190565b61065390611a7c565b61065390611b25610a6d565b61065390611cc8565b61065390611b19565b61065390611b43610a6d565b61065390611c1c565b61065390611b37565b61065390611b61610a6d565b61065390611c77565b61065390611b55565b61065390611b7f610a6d565b611b8c61062460006109f1565b6001600160a01b03821614611be157611ba6816008610ac7565b611bd07fdfe91dcad2adcb1ecd18d2e830b469081211d6743c1e2dfa893836431fb7879491610693565b90611bda60405190565b808061184f565b505060405163e6c4247b60e01b8152600490fd5b61065390611b73565b61065390611c0a610a6d565b61065390611d2d565b61065390611bfe565b611c2961062460006109f1565b6001600160a01b03821614611c6d57611c43816006610ac7565b611bd07f2ffae89a4970d1ff9bf1a765b00d7eee23cd328cdaaab85b7ce9e5379c1ece3291610693565b5050604051611a62565b611c8461062460006109f1565b6001600160a01b03821614611be157611c9e816009610ac7565b611bd07f5326c5ebddd2feafb723c3b63cc83fb32a9c8dd7d05476832b798d9782bad87891610693565b611cd561062460006109f1565b6001600160a01b03821614611d1957611cef816007610ac7565b611bd07fdbebfba65bd6398fb722063efc10c99f624f9cd8ba657201056af918a676d5ee91610693565b505060405163ccea9e6f60e01b8152600490fd5b611d38610630610940565b8110611d7757611d4981600a610da6565b610cbf7f676dc704f22ddab12a141690a96616ef0128413803c63394aba7ffe658681a169161023760405190565b50506040516367e00a0760e01b8152600490fdfea364697066735822122048416a76561fc48128e8f000ff0712a4c8201c10df1cbc9e2d4fd939fbe4e8526c6578706572696d656e74616cf564736f6c634300080c00410000000000000000000000004177b6f4c38a2ee94606e10049691393643b80ae000000000000000000000000fcd2f5f382e4b3cd3b67a4e399ada0edf56d0383000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Deployed Bytecode
0x60806040526004361015610018575b61001661061e565b005b60003560e01c806303aaf08b146105f757806306394c9b146105d05780630700037d146105965780630c9cbf0e1461056b5780630cc630c714610543578063101cef481461051c5780631e2720ff146104f557806333f642f6146104cb57806348a61ff51461049d5780635512b81114610473578063570ca735146104495780635b2478ea1461041f578063715018a6146103f857806374c13fda146103ce57806379ba5097146103a75780637fdba5f61461037d5780638686ebcc146103535780638da5cb5b146103295780638e3fb0d314610302578063960d264d146102db578063a230c5241461029f578063a480ca7914610278578063b688a36314610251578063bc063e1a14610216578063d379be23146101ec578063d66d9e19146101c5578063e30c3978146101805763f2fde38b146101565761000e565b34610173575b61001661016a366004610655565b610b3b565b0390f35b61017b61061e565b61015c565b50346101b8575b6101923660046107f0565b61016f61019d610a97565b6040515b918291826001600160a01b03909116815260200190565b6101c061061e565b610187565b50346101df575b6101d73660046107f0565b610016610cc4565b6101e761061e565b6101cc565b5034610209575b6101fe3660046107f0565b61016f61019d6109ab565b61021161061e565b6101f3565b5034610244575b6102283660046107f0565b61016f6102336109a3565b6040515b9182918290815260200190565b61024c61061e565b61021d565b503461026b575b6102633660046107f0565b610016610c7b565b61027361061e565b610258565b5034610292575b61001661028d366004610655565b611b10565b61029a61061e565b61027f565b50346102ce575b61016f6102bc6102b7366004610655565b610980565b60405191829182901515815260200190565b6102d661061e565b6102a6565b50346102f5575b6100166102f03660046107cf565b611c13565b6102fd61061e565b6102e2565b503461031c575b610016610317366004610655565b611b4c565b61032461061e565b610309565b5034610346575b61033b3660046107f0565b61016f61019d6109ca565b61034e61061e565b610330565b5034610370575b6103653660046107f0565b61016f61023361095f565b61037861061e565b61035a565b503461039a575b61038f3660046107f0565b61016f61023361094b565b6103a261061e565b610384565b50346103c1575b6103b93660046107f0565b610016610c34565b6103c961061e565b6103ae565b50346103eb575b6103e03660046107f0565b61016f61019d610927565b6103f361061e565b6103d5565b5034610412575b61040a3660046107f0565b610016610a0c565b61041a61061e565b6103ff565b503461043c575b61016f610233610437366004610655565b610915565b61044461061e565b610426565b5034610466575b61045b3660046107f0565b61016f61019d610909565b61046e61061e565b610450565b5034610490575b6104853660046107f0565b61016f61019d6108fd565b61049861061e565b61047a565b50346104be575b6100166104b236600461085b565b95949094939193610ecf565b6104c661061e565b6104a4565b50346104e8575b6104dd3660046107f0565b61016f610233610803565b6104f061061e565b6104d2565b503461050f575b61001661050a3660046107cf565b6118c0565b61051761061e565b6104fc565b5034610536575b610016610531366004610655565b611bf5565b61053e61061e565b610523565b503461055e575b610016610558366004610791565b91611a71565b61056661061e565b61054a565b5034610589575b61016f610233610583366004610718565b9061075f565b61059161061e565b610572565b50346105c3575b61016f6105b36105ae366004610655565b6106c5565b6040519193915b938493846106f6565b6105cb61061e565b61059d565b50346105ea575b6100166105e5366004610655565b611b2e565b6105f261061e565b6105d7565b5034610611575b61001661060c366004610655565b611b6a565b61061961061e565b6105fe565b50600080fd5b6001600160a01b031690565b90565b6001600160a01b0381165b141561061e57565b9050359061065382610633565b565b906106309160208183031261066957610646565b61067161061e565b610646565b61063090610624906001600160a01b031682565b61063090610676565b6106309061068a565b906106a690610693565b600052602052604060002090565b6106309081565b61063090546106b4565b6106d090600461069c565b6106d9816106bb565b9161063060026106eb600185016106bb565b93016106bb565b9052565b908152606081019392610653929091604091610714905b6020830152565b0152565b91906106309060408482031261073c575b6107338185610646565b93602001610646565b61074461061e565b610729565b610630916008021c81565b906106309154610749565b6107796106309261077460059360009461069c565b61069c565b610754565b8061063e565b905035906106538261077e565b90916060828403126107c2575b6106306107ab8484610646565b936107b98160208601610784565b93604001610784565b6107ca61061e565b61079e565b90610630916020818303126107e357610784565b6107eb61061e565b610784565b60009103126107fb57565b61065361061e565b6106306000600a610754565b909182601f8301121561084e575b602082359267ffffffffffffffff8411610841575b0192602083028401116107fb57565b61084961061e565b610832565b61085661061e565b61081d565b909160c0828403126108d8575b6108728383610646565b926106306108838260208601610646565b936108918360408301610784565b936108b284606084013567ffffffffffffffff81116108cb575b840161080f565b9390946108c28160808601610784565b9360a001610646565b6108d361061e565b6108ab565b6108e061061e565b610868565b610630916008021c610624565b9061063091546108e5565b610630600060096108f2565b610630600060076108f2565b6106309061077960039160009261069c565b610630600060066108f2565b6106306106306106309290565b610630612a30610933565b610630610940565b610630620f4240610933565b610630610953565b610630916008021c60ff1690565b906106309154610967565b6106309061099260029160009261069c565b610975565b610630620186a0610933565b610630610997565b610630600060086108f2565b61063090610624565b61063090546109b7565b61063060006109c0565b6109dc610a6d565b6106536109fa565b6106246106306106309290565b610630906109e4565b610653610a0760006109f1565b610b82565b6106536109d4565b0190565b15610a1f57565b5060405162461bcd60e51b815280610a69600482016020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b0390fd5b610653610a786109ca565b610a91610a8433610624565b916001600160a01b031690565b14610a18565b61063060016109c0565b61065390610aad610a6d565b610ae2565b906001600160a01b03905b9181191691161790565b90610ad7610630610ade92610693565b8254610ab2565b9055565b610aed816001610ac7565b610af56109ca565b90610b29610b237f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270093610693565b91610693565b91610b3360405190565b80805b0390a3565b61065390610aa1565b916001600160a01b0360089290920291821b911b610abd565b9190610b6e610630610ade93610693565b908354610b44565b61065391600091610b5d565b61065390610b9260006001610b76565b610b9c60006109c0565b90610ba8816000610ac7565b610b29610b237f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610693565b15610bdc57565b5060405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608490fd5b61065333610a07610c43610a97565b610c556001600160a01b038416610a84565b14610bd5565b9060ff90610abd565b90610c74610630610ade92151590565b8254610c5b565b33610c916001610c8c83600261069c565b610c64565b610cbf7f0abf3b3f643594d958297062a019458e27d7766629590ac621aa1000fa1298ab916101a160405190565b0390a1565b33610cd56000610c8c83600261069c565b610cbf7fbea911b50ccdd2233b28faa49766c3cbd0631608f32e5a724d7b83b32b681ad0916101a160405190565b50634e487b7160e01b600052601160045260246000fd5b90610d24565b9190565b908060001904821181151516610d38570290565b610d40610d03565b0290565b50634e487b7160e01b600052601260045260246000fd5b8115610d65570490565b610d6d610d44565b0490565b818110610d7c570390565b610d84610d03565b0390565b81198111610d94570190565b610a14610d03565b9060001990610abd565b90610db6610630610ade92610933565b8254610d9c565b601f01601f191690565b50634e487b7160e01b600052604160045260246000fd5b90601f01601f1916810190811067ffffffffffffffff821117610e0057604052565b610e08610dc7565b604052565b90610653610e1a60405190565b9283610dde565b6106306060610e0d565b90610653610e696002610e3c610e21565b94610e4d610e49826106bb565b8752565b610e63610e5c600183016106bb565b6020880152565b016106bb565b6040840152565b61063090610e2b565b6106f2906001600160a01b031660601b90565b601481610e9f610a149360209695610e79565b01918252565b908152606081019392610653929091604091610ec09061070d565b01906001600160a01b03169052565b93909433610ee3610a8461062460086109c0565b141561118157600091610ef8610624846109f1565b6001600160a01b0388161461116057610f1083610933565b841461113f57610f21610630610997565b821161111e57610f43610f35879386610d1a565b610f3d610953565b90610d5b565b94610f75610f518787610d71565b96610f6f610f6086600361069c565b91610f6a836106bb565b610d88565b90610da6565b600491610f8a610f85858561069c565b610e70565b94610fa787610f6a610fa28d61077460059a8b61069c565b6106bb565b9581810191610fc0610d20610fba855190565b92610933565b146110f2576040015142106110c7579161102391610fdf611027945190565b908b61100a610fed60405190565b8092610ffe8c602084019283610e8c565b90810382520382610dde565b61101c611015825190565b9160200190565b20926115bd565b1590565b61109f57509061103e86610774876110439561069c565b610da6565b611056828661105186610693565b6111e4565b610b3661108c6110867f70fec9c7f21f70099818a4619c69af3a4677031e67acea18286c0eca3a754bce95610693565b95610693565b9561109660405190565b93849384610ea5565b9650505050505050610a6991506110b560405190565b6309bde33960e01b8152918291820190565b5050509650505050505050610a6991506110e060405190565b630995309b60e01b8152918291820190565b505050509650505050505050610a69915061110c60405190565b630d16b83360e31b8152918291820190565b50505050505050505061113060405190565b6358d620b360e01b8152600490fd5b50505050505050505061115160405190565b63162908e360e11b8152600490fd5b50505050505050505061117260405190565b633b4f091f60e21b8152600490fd5b505050505050505061119260405190565b63ea8e4eb560e01b8152600490fd5b6111ba6111b46106309263ffffffff1690565b60e01b90565b6001600160e01b03191690565b6001600160a01b0390911681526040810192916106539160200152565b611227600492611218610653956111fe63a9059cbb6111a1565b9261120860405190565b96879460208601908152016111c7565b60208201810382520383610dde565b61133b565b610a1460209167ffffffffffffffff811161124b57601f01601f191690565b610dbd610dc7565b906112656112608361122c565b610e0d565b918252565b6112746020611253565b7f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564602082015290565b61063061126a565b80151561063e565b90505190610653826112a5565b90610630916020818303126112ce576112ad565b6112d661061e565b6112ad565b156112e257565b5060405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b6106539161134b61135a92610693565b9061135461129d565b91611398565b8051611369610d206000610933565b14908115611378575b506112db565b61139291506020611387825190565b8183010191016112ba565b38611372565b61063092916113a76000610933565b91611428565b156113b457565b5060405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608490fd5b3d15611423576114183d611253565b903d6000602084013e565b606090565b9060006106309493819261143a606090565b5061145161144730610693565b83903110156113ad565b60208101905191855af1611463611409565b916114b6565b1561147057565b5060405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b9192606091156114eb57505081516114d1610d206000610933565b146114da575090565b6114e6610630916114f8565b611469565b909392610653925061157a565b3b611506610d206000610933565b1190565b918091926000905b82821061152a575011611523575050565b6000910152565b91508060209183015181860152018291611512565b611560610dbd602093610a1493611554815190565b80835293849260200190565b9586910161150a565b60208082526106309291019061153f565b9150611584825190565b611591610d206000610933565b11156115a05750805190602001fd5b604051610a69925062461bcd60e51b815291829160048301611569565b6115dc9293610d20926115d8926115d2600090565b5061162e565b9290565b1490565b6001906000198114610d94570190565b50634e487b7160e01b600052603260045260246000fd5b9160209181101561161757020190565b61161f6115f0565b020190565b356106308161077e565b6116386000610933565b925b8284101561166e576116626116689161165c611657878787611607565b611624565b90611675565b936115e0565b9261163a565b9250505090565b81811015611690579061063091600052602052604060002090565b61063091600052602052604060002090565b336116b061062460076109c0565b6001600160a01b038216141590816116db575b506116d15761065390611730565b5050604051611192565b90506116ed610a8461062460096109c0565b1415386116c3565b905051906106538261077e565b9061063091602081830312611716576116f5565b61171e61061e565b6116f5565b506040513d6000823e3d90fd5b61173a6000610933565b81146118b65761181761175561175060066109c0565b610693565b61175e81610693565b926370a082319361176e30610693565b9161177860405190565b936117838760e01b90565b85526001600160a01b0384166004860152602085602481865afa9485156118a9575b60009561187f575b50916117c284926117fd9560209533906118ed565b6117e66117cf60066109c0565b976117d960405190565b9586948593849360e01b90565b83526001600160a01b031660048301526024820190565b03915afa908115611872575b600091611854575b50610d71565b9061184f6118457ff1fa0256e6ecba08316eb890d662830768e73136b5b0dbea4c9c8c16ca1747eb92610693565b9261023760405190565b0390a2565b61186c91506118633d82610dde565b3d810190611702565b38611811565b61187a611723565b611809565b60209391955084926117fd9561189c6117c2936118633d82610dde565b97939550509294506117ad565b6118b1611723565b6117a5565b5050604051611151565b610653906116a2565b6001600160a01b039182168152911660208201526060810192916106539160400152565b9061122790611218610653956004956119096323b872dd6111a1565b9361191360405190565b97889560208701908152016118c9565b91903361193361062460076109c0565b6001600160a01b03821614159081611961575b506119545761065392611987565b5050505061119260405190565b9050611971610a846106246109ca565b141538611946565b90610db6610630610ade9290565b9091600092611998610624856109f1565b6001600160a01b03841614611a54576119b084610933565b8114611a3757611a006002946119d0426119ca600a6106bb565b90610d88565b9586916119ed856119e56106308a600461069c565b928301611979565b6119fa8660018301611979565b01610da6565b61184f611a2d7f9ca93988e299d8264919a188c320f8d8efa97e1976a234f3c6c42315fc10b4e094610693565b946105ba60405190565b5050505050611a4560405190565b639dd854d360e01b8152600490fd5b5050505050611a6260405190565b63c1ab6dc160e01b8152600490fd5b906106539291611923565b61065390611a88610a6d565b600390611a98610fa2828461069c565b91600090611aa582610933565b8414611b025761103e83611abb611ac194610933565b9261069c565b611ad582611ace83610693565b33906111e4565b61184f6118457f9dc46f23cfb5ddcad0ae7ea2be38d47fec07bb9382ec7e564efc69e036dd66ce92610693565b505050505061115160405190565b61065390611a7c565b61065390611b25610a6d565b61065390611cc8565b61065390611b19565b61065390611b43610a6d565b61065390611c1c565b61065390611b37565b61065390611b61610a6d565b61065390611c77565b61065390611b55565b61065390611b7f610a6d565b611b8c61062460006109f1565b6001600160a01b03821614611be157611ba6816008610ac7565b611bd07fdfe91dcad2adcb1ecd18d2e830b469081211d6743c1e2dfa893836431fb7879491610693565b90611bda60405190565b808061184f565b505060405163e6c4247b60e01b8152600490fd5b61065390611b73565b61065390611c0a610a6d565b61065390611d2d565b61065390611bfe565b611c2961062460006109f1565b6001600160a01b03821614611c6d57611c43816006610ac7565b611bd07f2ffae89a4970d1ff9bf1a765b00d7eee23cd328cdaaab85b7ce9e5379c1ece3291610693565b5050604051611a62565b611c8461062460006109f1565b6001600160a01b03821614611be157611c9e816009610ac7565b611bd07f5326c5ebddd2feafb723c3b63cc83fb32a9c8dd7d05476832b798d9782bad87891610693565b611cd561062460006109f1565b6001600160a01b03821614611d1957611cef816007610ac7565b611bd07fdbebfba65bd6398fb722063efc10c99f624f9cd8ba657201056af918a676d5ee91610693565b505060405163ccea9e6f60e01b8152600490fd5b611d38610630610940565b8110611d7757611d4981600a610da6565b610cbf7f676dc704f22ddab12a141690a96616ef0128413803c63394aba7ffe658681a169161023760405190565b50506040516367e00a0760e01b8152600490fdfea364697066735822122048416a76561fc48128e8f000ff0712a4c8201c10df1cbc9e2d4fd939fbe4e8526c6578706572696d656e74616cf564736f6c634300080c0041
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004177b6f4c38a2ee94606e10049691393643b80ae000000000000000000000000fcd2f5f382e4b3cd3b67a4e399ada0edf56d0383000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
-----Decoded View---------------
Arg [0] : _rewardSwapper (address): 0x4177b6f4C38A2ee94606e10049691393643b80ae
Arg [1] : _operator (address): 0xfCD2F5F382E4b3cD3b67A4e399AdA0EDF56d0383
Arg [2] : _defaultToken (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000004177b6f4c38a2ee94606e10049691393643b80ae
Arg [1] : 000000000000000000000000fcd2f5f382e4b3cd3b67a4e399ada0edf56d0383
Arg [2] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $3,396.5 | 43.2316 | $146,835.92 |
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.