Overview
S Balance
0 S
S Value
-More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
RewardsDistributor
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity)
/** *Submitted for verification at SonicScan.org on 2024-12-18 */ // SPDX-License-Identifier: GPL-3.0-or-later // Hydrometer combines powerful liquidity incentives, low slippage, and a vote-locked governance model using $HYDRO and $veHYDRO tokens, ensuring an innovative and decentralized experience for all users. //https://x.com/Hydrometer_Fi pragma solidity 0.8.19; // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } } // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) /** * @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); } /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); } /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // OpenZeppelin Contracts (interfaces/IERC6372.sol) interface IERC6372 { /** * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting). */ function clock() external view returns (uint48); /** * @dev Description of the clock */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() external view returns (string memory); } // OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol) // OpenZeppelin Contracts v4.4.1 (interfaces/IERC721.sol) /// @title EIP-721 Metadata Update Extension interface IERC4906 is IERC165, IERC721 { /// @dev This event emits when the metadata of a token is changed. /// So that the third-party platforms such as NFT market could /// timely update the images and related attributes of the NFT. event MetadataUpdate(uint256 _tokenId); /// @dev This event emits when the metadata of a range of tokens is changed. /// So that the third-party platforms such as NFT market could /// timely update the images and related attributes of the NFTs. event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId); } /// Modified IVotes interface for tokenId based voting interface IVotes { /** * @dev Emitted when an account changes their delegate. */ event DelegateChanged(address indexed delegator, uint256 indexed fromDelegate, uint256 indexed toDelegate); /** * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes. */ event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance); /** * @dev Returns the amount of votes that `tokenId` had at a specific moment in the past. * If the account passed in is not the owner, returns 0. */ function getPastVotes(address account, uint256 tokenId, uint256 timepoint) external view returns (uint256); /** * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value the end of the corresponding block. * * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. * Votes that have not been delegated are still part of total supply, even though they would not participate in a * vote. */ function getPastTotalSupply(uint256 timepoint) external view returns (uint256); /** * @dev Returns the delegate that `tokenId` has chosen. Can never be equal to the delegator's `tokenId`. * Returns 0 if not delegated. */ function delegates(uint256 tokenId) external view returns (uint256); /** * @dev Delegates votes from the sender to `delegatee`. */ function delegate(uint256 delegator, uint256 delegatee) external; /** * @dev Delegates votes from `delegator` to `delegatee`. Signer must own `delegator`. */ function delegateBySig( uint256 delegator, uint256 delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external; } interface IVotingEscrow is IVotes, IERC4906, IERC6372, IERC721Metadata { struct LockedBalance { int128 amount; uint256 end; bool isPermanent; } struct UserPoint { int128 bias; int128 slope; // # -dweight / dt uint256 ts; uint256 blk; // block uint256 permanent; } struct GlobalPoint { int128 bias; int128 slope; // # -dweight / dt uint256 ts; uint256 blk; // block uint256 permanentLockBalance; } /// @notice A checkpoint for recorded delegated voting weights at a certain timestamp struct Checkpoint { uint256 fromTimestamp; address owner; uint256 delegatedBalance; uint256 delegatee; } enum DepositType { DEPOSIT_FOR_TYPE, CREATE_LOCK_TYPE, INCREASE_LOCK_AMOUNT, INCREASE_UNLOCK_TIME } /// @dev Different types of veNFTs: /// NORMAL - typical veNFT /// LOCKED - veNFT which is locked into a MANAGED veNFT /// MANAGED - veNFT which can accept the deposit of NORMAL veNFTs enum EscrowType { NORMAL, LOCKED, MANAGED } error AlreadyVoted(); error AmountTooBig(); error ERC721ReceiverRejectedTokens(); error ERC721TransferToNonERC721ReceiverImplementer(); error InvalidNonce(); error InvalidSignature(); error InvalidSignatureS(); error InvalidManagedNFTId(); error LockDurationNotInFuture(); error LockDurationTooLong(); error LockExpired(); error LockNotExpired(); error NoLockFound(); error NonExistentToken(); error NotApprovedOrOwner(); error NotDistributor(); error NotEmergencyCouncilOrGovernor(); error NotGovernor(); error NotGovernorOrManager(); error NotManagedNFT(); error NotManagedOrNormalNFT(); error NotLockedNFT(); error NotNormalNFT(); error NotPermanentLock(); error NotOwner(); error NotTeam(); error NotVoter(); error OwnershipChange(); error PermanentLock(); error SameAddress(); error SameNFT(); error SameState(); error SplitNoOwner(); error SplitNotAllowed(); error SignatureExpired(); error TooManyTokenIDs(); error ZeroAddress(); error ZeroAmount(); error ZeroBalance(); event Deposit( address indexed provider, uint256 indexed tokenId, DepositType indexed depositType, uint256 value, uint256 locktime, uint256 ts ); event Withdraw(address indexed provider, uint256 indexed tokenId, uint256 value, uint256 ts); event LockPermanent(address indexed _owner, uint256 indexed _tokenId, uint256 amount, uint256 _ts); event UnlockPermanent(address indexed _owner, uint256 indexed _tokenId, uint256 amount, uint256 _ts); event Supply(uint256 prevSupply, uint256 supply); event Merge( address indexed _sender, uint256 indexed _from, uint256 indexed _to, uint256 _amountFrom, uint256 _amountTo, uint256 _amountFinal, uint256 _locktime, uint256 _ts ); event Split( uint256 indexed _from, uint256 indexed _tokenId1, uint256 indexed _tokenId2, address _sender, uint256 _splitAmount1, uint256 _splitAmount2, uint256 _locktime, uint256 _ts ); event CreateManaged( address indexed _to, uint256 indexed _mTokenId, address indexed _from, address _lockedManagedReward, address _freeManagedReward ); event DepositManaged( address indexed _owner, uint256 indexed _tokenId, uint256 indexed _mTokenId, uint256 _weight, uint256 _ts ); event WithdrawManaged( address indexed _owner, uint256 indexed _tokenId, uint256 indexed _mTokenId, uint256 _weight, uint256 _ts ); event SetAllowedManager(address indexed _allowedManager); // State variables /// @notice Address of Meta-tx Forwarder function forwarder() external view returns (address); /// @notice Address of FactoryRegistry.sol function factoryRegistry() external view returns (address); /// @notice Address of token (HYDRO) used to create a veNFT function token() external view returns (address); /// @notice Address of RewardsDistributor.sol function distributor() external view returns (address); /// @notice Address of Voter.sol function voter() external view returns (address); /// @notice Address of Protocol Team multisig function team() external view returns (address); /// @notice Address of art proxy used for on-chain art generation function artProxy() external view returns (address); /// @dev address which can create managed NFTs function allowedManager() external view returns (address); /// @dev Current count of token function tokenId() external view returns (uint256); /*/////////////////////////////////////////////////////////////// MANAGED NFT STORAGE //////////////////////////////////////////////////////////////*/ /// @dev Mapping of token id to escrow type /// Takes advantage of the fact default value is EscrowType.NORMAL function escrowType(uint256 tokenId) external view returns (EscrowType); /// @dev Mapping of token id to managed id function idToManaged(uint256 tokenId) external view returns (uint256 managedTokenId); /// @dev Mapping of user token id to managed token id to weight of token id function weights(uint256 tokenId, uint256 managedTokenId) external view returns (uint256 weight); /// @dev Mapping of managed id to deactivated state function deactivated(uint256 tokenId) external view returns (bool inactive); /// @dev Mapping from managed nft id to locked managed rewards /// `token` denominated rewards (rebases/rewards) stored in locked managed rewards contract /// to prevent co-mingling of assets function managedToLocked(uint256 tokenId) external view returns (address); /// @dev Mapping from managed nft id to free managed rewards contract /// these rewards can be freely withdrawn by users function managedToFree(uint256 tokenId) external view returns (address); /*/////////////////////////////////////////////////////////////// MANAGED NFT LOGIC //////////////////////////////////////////////////////////////*/ /// @notice Create managed NFT (a permanent lock) for use within ecosystem. /// @dev Throws if address already owns a managed NFT. /// @return _mTokenId managed token id. function createManagedLockFor(address _to) external returns (uint256 _mTokenId); /// @notice Delegates balance to managed nft /// Note that NFTs deposited into a managed NFT will be re-locked /// to the maximum lock time on withdrawal. /// Permanent locks that are deposited will automatically unlock. /// @dev Managed nft will remain max-locked as long as there is at least one /// deposit or withdrawal per week. /// Throws if deposit nft is managed. /// Throws if recipient nft is not managed. /// Throws if deposit nft is already locked. /// Throws if not called by voter. /// @param _tokenId tokenId of NFT being deposited /// @param _mTokenId tokenId of managed NFT that will receive the deposit function depositManaged(uint256 _tokenId, uint256 _mTokenId) external; /// @notice Retrieves locked rewards and withdraws balance from managed nft. /// Note that the NFT withdrawn is re-locked to the maximum lock time. /// @dev Throws if NFT not locked. /// Throws if not called by voter. /// @param _tokenId tokenId of NFT being deposited. function withdrawManaged(uint256 _tokenId) external; /// @notice Permit one address to call createManagedLockFor() that is not Voter.governor() function setAllowedManager(address _allowedManager) external; /// @notice Set Managed NFT state. Inactive NFTs cannot be deposited into. /// @param _mTokenId managed nft state to set /// @param _state true => inactive, false => active function setManagedState(uint256 _mTokenId, bool _state) external; /*/////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ function name() external view returns (string memory); function symbol() external view returns (string memory); function version() external view returns (string memory); function decimals() external view returns (uint8); function setTeam(address _team) external; function setArtProxy(address _proxy) external; /// @inheritdoc IERC721Metadata function tokenURI(uint256 tokenId) external view returns (string memory); /*////////////////////////////////////////////////////////////// ERC721 BALANCE/OWNER STORAGE //////////////////////////////////////////////////////////////*/ /// @dev Mapping from owner address to mapping of index to tokenId function ownerToNFTokenIdList(address _owner, uint256 _index) external view returns (uint256 _tokenId); /// @inheritdoc IERC721 function ownerOf(uint256 tokenId) external view returns (address owner); /// @inheritdoc IERC721 function balanceOf(address owner) external view returns (uint256 balance); /*////////////////////////////////////////////////////////////// ERC721 APPROVAL STORAGE //////////////////////////////////////////////////////////////*/ /// @inheritdoc IERC721 function getApproved(uint256 _tokenId) external view returns (address operator); /// @inheritdoc IERC721 function isApprovedForAll(address owner, address operator) external view returns (bool); /// @notice Check whether spender is owner or an approved user for a given veNFT /// @param _spender . /// @param _tokenId . function isApprovedOrOwner(address _spender, uint256 _tokenId) external returns (bool); /*////////////////////////////////////////////////////////////// ERC721 LOGIC //////////////////////////////////////////////////////////////*/ /// @inheritdoc IERC721 function approve(address to, uint256 tokenId) external; /// @inheritdoc IERC721 function setApprovalForAll(address operator, bool approved) external; /// @inheritdoc IERC721 function transferFrom(address from, address to, uint256 tokenId) external; /// @inheritdoc IERC721 function safeTransferFrom(address from, address to, uint256 tokenId) external; /// @inheritdoc IERC721 function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /*////////////////////////////////////////////////////////////// ERC165 LOGIC //////////////////////////////////////////////////////////////*/ /// @inheritdoc IERC165 function supportsInterface(bytes4 _interfaceID) external view returns (bool); /*////////////////////////////////////////////////////////////// ESCROW STORAGE //////////////////////////////////////////////////////////////*/ /// @notice Total count of epochs witnessed since contract creation function epoch() external view returns (uint256); /// @notice Total amount of token() deposited function supply() external view returns (uint256); /// @notice Aggregate permanent locked balances function permanentLockBalance() external view returns (uint256); function userPointEpoch(uint256 _tokenId) external view returns (uint256 _epoch); /// @notice time -> signed slope change function slopeChanges(uint256 _timestamp) external view returns (int128); /// @notice account -> can split function canSplit(address _account) external view returns (bool); /// @notice Global point history at a given index function pointHistory(uint256 _loc) external view returns (GlobalPoint memory); /// @notice Get the LockedBalance (amount, end) of a _tokenId /// @param _tokenId . /// @return LockedBalance of _tokenId function locked(uint256 _tokenId) external view returns (LockedBalance memory); /// @notice User -> UserPoint[userEpoch] function userPointHistory(uint256 _tokenId, uint256 _loc) external view returns (UserPoint memory); /*////////////////////////////////////////////////////////////// ESCROW LOGIC //////////////////////////////////////////////////////////////*/ /// @notice Record global data to checkpoint function checkpoint() external; /// @notice Deposit `_value` tokens for `_tokenId` and add to the lock /// @dev Anyone (even a smart contract) can deposit for someone else, but /// cannot extend their locktime and deposit for a brand new user /// @param _tokenId lock NFT /// @param _value Amount to add to user's lock function depositFor(uint256 _tokenId, uint256 _value) external; /// @notice Deposit `_value` tokens for `msg.sender` and lock for `_lockDuration` /// @param _value Amount to deposit /// @param _lockDuration Number of seconds to lock tokens for (rounded down to nearest week) /// @return TokenId of created veNFT function createLock(uint256 _value, uint256 _lockDuration) external returns (uint256); /// @notice Deposit `_value` tokens for `_to` and lock for `_lockDuration` /// @param _value Amount to deposit /// @param _lockDuration Number of seconds to lock tokens for (rounded down to nearest week) /// @param _to Address to deposit /// @return TokenId of created veNFT function createLockFor(uint256 _value, uint256 _lockDuration, address _to) external returns (uint256); /// @notice Deposit `_value` additional tokens for `_tokenId` without modifying the unlock time /// @param _value Amount of tokens to deposit and add to the lock function increaseAmount(uint256 _tokenId, uint256 _value) external; /// @notice Extend the unlock time for `_tokenId` /// Cannot extend lock time of permanent locks /// @param _lockDuration New number of seconds until tokens unlock function increaseUnlockTime(uint256 _tokenId, uint256 _lockDuration) external; /// @notice Withdraw all tokens for `_tokenId` /// @dev Only possible if the lock is both expired and not permanent /// This will burn the veNFT. Any rebases or rewards that are unclaimed /// will no longer be claimable. Claim all rebases and rewards prior to calling this. function withdraw(uint256 _tokenId) external; /// @notice Merges `_from` into `_to`. /// @dev Cannot merge `_from` locks that are permanent or have already voted this epoch. /// Cannot merge `_to` locks that have already expired. /// This will burn the veNFT. Any rebases or rewards that are unclaimed /// will no longer be claimable. Claim all rebases and rewards prior to calling this. /// @param _from VeNFT to merge from. /// @param _to VeNFT to merge into. function merge(uint256 _from, uint256 _to) external; /// @notice Splits veNFT into two new veNFTS - one with oldLocked.amount - `_amount`, and the second with `_amount` /// @dev This burns the tokenId of the target veNFT /// Callable by approved or owner /// If this is called by approved, approved will not have permissions to manipulate the newly created veNFTs /// Returns the two new split veNFTs to owner /// If `from` is permanent, will automatically dedelegate. /// This will burn the veNFT. Any rebases or rewards that are unclaimed /// will no longer be claimable. Claim all rebases and rewards prior to calling this. /// @param _from VeNFT to split. /// @param _amount Amount to split from veNFT. /// @return _tokenId1 Return tokenId of veNFT with oldLocked.amount - `_amount`. /// @return _tokenId2 Return tokenId of veNFT with `_amount`. function split(uint256 _from, uint256 _amount) external returns (uint256 _tokenId1, uint256 _tokenId2); /// @notice Toggle split for a specific address. /// @dev Toggle split for address(0) to enable or disable for all. /// @param _account Address to toggle split permissions /// @param _bool True to allow, false to disallow function toggleSplit(address _account, bool _bool) external; /// @notice Permanently lock a veNFT. Voting power will be equal to /// `LockedBalance.amount` with no decay. Required to delegate. /// @dev Only callable by unlocked normal veNFTs. /// @param _tokenId tokenId to lock. function lockPermanent(uint256 _tokenId) external; /// @notice Unlock a permanently locked veNFT. Voting power will decay. /// Will automatically dedelegate if delegated. /// @dev Only callable by permanently locked veNFTs. /// Cannot unlock if already voted this epoch. /// @param _tokenId tokenId to unlock. function unlockPermanent(uint256 _tokenId) external; /*/////////////////////////////////////////////////////////////// GAUGE VOTING STORAGE //////////////////////////////////////////////////////////////*/ /// @notice Get the voting power for _tokenId at the current timestamp /// @dev Returns 0 if called in the same block as a transfer. /// @param _tokenId . /// @return Voting power function balanceOfNFT(uint256 _tokenId) external view returns (uint256); /// @notice Get the voting power for _tokenId at a given timestamp /// @param _tokenId . /// @param _t Timestamp to query voting power /// @return Voting power function balanceOfNFTAt(uint256 _tokenId, uint256 _t) external view returns (uint256); /// @notice Calculate total voting power at current timestamp /// @return Total voting power at current timestamp function totalSupply() external view returns (uint256); /// @notice Calculate total voting power at a given timestamp /// @param _t Timestamp to query total voting power /// @return Total voting power at given timestamp function totalSupplyAt(uint256 _t) external view returns (uint256); /*/////////////////////////////////////////////////////////////// GAUGE VOTING LOGIC //////////////////////////////////////////////////////////////*/ /// @notice See if a queried _tokenId has actively voted /// @param _tokenId . /// @return True if voted, else false function voted(uint256 _tokenId) external view returns (bool); /// @notice Set the global state voter and distributor /// @dev This is only called once, at setup function setVoterAndDistributor(address _voter, address _distributor) external; /// @notice Set `voted` for _tokenId to true or false /// @dev Only callable by voter /// @param _tokenId . /// @param _voted . function voting(uint256 _tokenId, bool _voted) external; /*/////////////////////////////////////////////////////////////// DAO VOTING STORAGE //////////////////////////////////////////////////////////////*/ /// @notice The number of checkpoints for each tokenId function numCheckpoints(uint256 tokenId) external view returns (uint48); /// @notice A record of states for signing / validating signatures function nonces(address account) external view returns (uint256); /// @inheritdoc IVotes function delegates(uint256 delegator) external view returns (uint256); /// @notice A record of delegated token checkpoints for each account, by index /// @param tokenId . /// @param index . /// @return Checkpoint function checkpoints(uint256 tokenId, uint48 index) external view returns (Checkpoint memory); /// @inheritdoc IVotes function getPastVotes(address account, uint256 tokenId, uint256 timestamp) external view returns (uint256); /// @inheritdoc IVotes function getPastTotalSupply(uint256 timestamp) external view returns (uint256); /*/////////////////////////////////////////////////////////////// DAO VOTING LOGIC //////////////////////////////////////////////////////////////*/ /// @inheritdoc IVotes function delegate(uint256 delegator, uint256 delegatee) external; /// @inheritdoc IVotes function delegateBySig( uint256 delegator, uint256 delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external; /*////////////////////////////////////////////////////////////// ERC6372 LOGIC //////////////////////////////////////////////////////////////*/ /// @inheritdoc IERC6372 function clock() external view returns (uint48); /// @inheritdoc IERC6372 function CLOCK_MODE() external view returns (string memory); } interface IRewardsDistributor { event CheckpointToken(uint256 time, uint256 tokens); event Claimed(uint256 indexed tokenId, uint256 indexed epochStart, uint256 indexed epochEnd, uint256 amount); error NotMinter(); error NotManagedOrNormalNFT(); error UpdatePeriod(); /// @notice 7 days in seconds function WEEK() external view returns (uint256); /// @notice Timestamp of contract creation function startTime() external view returns (uint256); /// @notice Timestamp of most recent claim of tokenId function timeCursorOf(uint256 tokenId) external view returns (uint256); /// @notice The last timestamp Minter has called checkpointToken() function lastTokenTime() external view returns (uint256); /// @notice Interface of VotingEscrow.sol function ve() external view returns (IVotingEscrow); /// @notice Address of token used for distributions (HYDRO) function token() external view returns (address); /// @notice Address of Minter.sol /// Authorized caller of checkpointToken() function minter() external view returns (address); /// @notice Amount of token in contract when checkpointToken() was last called function tokenLastBalance() external view returns (uint256); /// @notice Called by Minter to notify Distributor of rebases function checkpointToken() external; /// @notice Returns the amount of rebases claimable for a given token ID /// @dev Allows claiming of rebases up to 50 epochs old /// @param tokenId The token ID to check /// @return The amount of rebases claimable for the given token ID function claimable(uint256 tokenId) external view returns (uint256); /// @notice Claims rebases for a given token ID /// @dev Allows claiming of rebases up to 50 epochs old /// `Minter.updatePeriod()` must be called before claiming /// @param tokenId The token ID to claim for /// @return The amount of rebases claimed function claim(uint256 tokenId) external returns (uint256); /// @notice Claims rebases for a list of token IDs /// @dev `Minter.updatePeriod()` must be called before claiming /// @param tokenIds The token IDs to claim for /// @return Whether or not the claim succeeded function claimMany(uint256[] calldata tokenIds) external returns (bool); /// @notice Used to set minter once on initialization /// @dev Callable once by Minter only, Minter is immutable function setMinter(address _minter) external; } // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) /** * @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); } interface IHydro is IERC20 { error NotMinter(); error NotOwner(); /// @notice Mint an amount of tokens to an account /// Only callable by Minter.sol /// @return True if success function mint(address account, uint256 amount) external returns (bool); /// @notice Address of Minter.sol function minter() external view returns (address); } interface IVoter { error AlreadyVotedOrDeposited(); error DistributeWindow(); error FactoryPathNotApproved(); error GaugeAlreadyKilled(); error GaugeAlreadyRevived(); error GaugeExists(); error GaugeDoesNotExist(address _pool); error GaugeNotAlive(address _gauge); error InactiveManagedNFT(); error MaximumVotingNumberTooLow(); error NonZeroVotes(); error NotAPool(); error NotApprovedOrOwner(); error NotGovernor(); error NotEmergencyCouncil(); error NotMinter(); error NotWhitelistedNFT(); error NotWhitelistedToken(); error SameValue(); error SpecialVotingWindow(); error TooManyPools(); error UnequalLengths(); error ZeroBalance(); error ZeroAddress(); event GaugeCreated( address indexed poolFactory, address indexed votingRewardsFactory, address indexed gaugeFactory, address pool, address bribeVotingReward, address feeVotingReward, address gauge, address creator ); event GaugeKilled(address indexed gauge); event GaugeRevived(address indexed gauge); event Voted( address indexed voter, address indexed pool, uint256 indexed tokenId, uint256 weight, uint256 totalWeight, uint256 timestamp ); event Abstained( address indexed voter, address indexed pool, uint256 indexed tokenId, uint256 weight, uint256 totalWeight, uint256 timestamp ); event NotifyReward(address indexed sender, address indexed reward, uint256 amount); event DistributeReward(address indexed sender, address indexed gauge, uint256 amount); event WhitelistToken(address indexed whitelister, address indexed token, bool indexed _bool); event WhitelistNFT(address indexed whitelister, uint256 indexed tokenId, bool indexed _bool); /// @notice Store trusted forwarder address to pass into factories function forwarder() external view returns (address); /// @notice The ve token that governs these contracts function ve() external view returns (address); /// @notice Factory registry for valid pool / gauge / rewards factories function factoryRegistry() external view returns (address); /// @notice Address of Minter.sol function minter() external view returns (address); /// @notice Standard OZ IGovernor using ve for vote weights. function governor() external view returns (address); /// @notice Custom Epoch Governor using ve for vote weights. function epochGovernor() external view returns (address); /// @notice credibly neutral party similar to Curve's Emergency DAO function emergencyCouncil() external view returns (address); /// @dev Total Voting Weights function totalWeight() external view returns (uint256); /// @dev Most number of pools one voter can vote for at once function maxVotingNum() external view returns (uint256); // mappings /// @dev Pool => Gauge function gauges(address pool) external view returns (address); /// @dev Gauge => Pool function poolForGauge(address gauge) external view returns (address); /// @dev Gauge => Fees Voting Reward function gaugeToFees(address gauge) external view returns (address); /// @dev Gauge => Bribes Voting Reward function gaugeToBribe(address gauge) external view returns (address); /// @dev Pool => Weights function weights(address pool) external view returns (uint256); /// @dev NFT => Pool => Votes function votes(uint256 tokenId, address pool) external view returns (uint256); /// @dev NFT => Total voting weight of NFT function usedWeights(uint256 tokenId) external view returns (uint256); /// @dev Nft => Timestamp of last vote (ensures single vote per epoch) function lastVoted(uint256 tokenId) external view returns (uint256); /// @dev Address => Gauge function isGauge(address) external view returns (bool); /// @dev Token => Whitelisted status function isWhitelistedToken(address token) external view returns (bool); /// @dev TokenId => Whitelisted status function isWhitelistedNFT(uint256 tokenId) external view returns (bool); /// @dev Gauge => Liveness status function isAlive(address gauge) external view returns (bool); /// @dev Gauge => Amount claimable function claimable(address gauge) external view returns (uint256); /// @notice Number of pools with a Gauge function length() external view returns (uint256); /// @notice Called by Minter to distribute weekly emissions rewards for disbursement amongst gauges. /// @dev Assumes totalWeight != 0 (Will never be zero as long as users are voting). /// Throws if not called by minter. /// @param _amount Amount of rewards to distribute. function notifyRewardAmount(uint256 _amount) external; /// @dev Utility to distribute to gauges of pools in range _start to _finish. /// @param _start Starting index of gauges to distribute to. /// @param _finish Ending index of gauges to distribute to. function distribute(uint256 _start, uint256 _finish) external; /// @dev Utility to distribute to gauges of pools in array. /// @param _gauges Array of gauges to distribute to. function distribute(address[] memory _gauges) external; /// @notice Called by users to update voting balances in voting rewards contracts. /// @param _tokenId Id of veNFT whose balance you wish to update. function poke(uint256 _tokenId) external; /// @notice Called by users to vote for pools. Votes distributed proportionally based on weights. /// Can only vote or deposit into a managed NFT once per epoch. /// Can only vote for gauges that have not been killed. /// @dev Weights are distributed proportional to the sum of the weights in the array. /// Throws if length of _poolVote and _weights do not match. /// @param _tokenId Id of veNFT you are voting with. /// @param _poolVote Array of pools you are voting for. /// @param _weights Weights of pools. function vote(uint256 _tokenId, address[] calldata _poolVote, uint256[] calldata _weights) external; /// @notice Called by users to reset voting state. Required if you wish to make changes to /// veNFT state (e.g. merge, split, deposit into managed etc). /// Cannot reset in the same epoch that you voted in. /// Can vote or deposit into a managed NFT again after reset. /// @param _tokenId Id of veNFT you are reseting. function reset(uint256 _tokenId) external; /// @notice Called by users to deposit into a managed NFT. /// Can only vote or deposit into a managed NFT once per epoch. /// Note that NFTs deposited into a managed NFT will be re-locked /// to the maximum lock time on withdrawal. /// @dev Throws if not approved or owner. /// Throws if managed NFT is inactive. /// Throws if depositing within privileged window (one hour prior to epoch flip). function depositManaged(uint256 _tokenId, uint256 _mTokenId) external; /// @notice Called by users to withdraw from a managed NFT. /// Cannot do it in the same epoch that you deposited into a managed NFT. /// Can vote or deposit into a managed NFT again after withdrawing. /// Note that the NFT withdrawn is re-locked to the maximum lock time. function withdrawManaged(uint256 _tokenId) external; /// @notice Claim emissions from gauges. /// @param _gauges Array of gauges to collect emissions from. function claimRewards(address[] memory _gauges) external; /// @notice Claim bribes for a given NFT. /// @dev Utility to help batch bribe claims. /// @param _bribes Array of BribeVotingReward contracts to collect from. /// @param _tokens Array of tokens that are used as bribes. /// @param _tokenId Id of veNFT that you wish to claim bribes for. function claimBribes(address[] memory _bribes, address[][] memory _tokens, uint256 _tokenId) external; /// @notice Claim fees for a given NFT. /// @dev Utility to help batch fee claims. /// @param _fees Array of FeesVotingReward contracts to collect from. /// @param _tokens Array of tokens that are used as fees. /// @param _tokenId Id of veNFT that you wish to claim fees for. function claimFees(address[] memory _fees, address[][] memory _tokens, uint256 _tokenId) external; /// @notice Set new governor. /// @dev Throws if not called by governor. /// @param _governor . function setGovernor(address _governor) external; /// @notice Set new epoch based governor. /// @dev Throws if not called by governor. /// @param _epochGovernor . function setEpochGovernor(address _epochGovernor) external; /// @notice Set new emergency council. /// @dev Throws if not called by emergency council. /// @param _emergencyCouncil . function setEmergencyCouncil(address _emergencyCouncil) external; /// @notice Set maximum number of gauges that can be voted for. /// @dev Throws if not called by governor. /// Throws if _maxVotingNum is too low. /// Throws if the values are the same. /// @param _maxVotingNum . function setMaxVotingNum(uint256 _maxVotingNum) external; /// @notice Whitelist (or unwhitelist) token for use in bribes. /// @dev Throws if not called by governor. /// @param _token . /// @param _bool . function whitelistToken(address _token, bool _bool) external; /// @notice Whitelist (or unwhitelist) token id for voting in last hour prior to epoch flip. /// @dev Throws if not called by governor. /// Throws if already whitelisted. /// @param _tokenId . /// @param _bool . function whitelistNFT(uint256 _tokenId, bool _bool) external; /// @notice Create a new gauge (unpermissioned). /// @dev Governor can create a new gauge for a pool with any address. /// @param _poolFactory . /// @param _pool . function createGauge(address _poolFactory, address _pool) external returns (address); /// @notice Kills a gauge. The gauge will not receive any new emissions and cannot be deposited into. /// Can still withdraw from gauge. /// @dev Throws if not called by emergency council. /// Throws if gauge already killed. /// @param _gauge . function killGauge(address _gauge) external; /// @notice Revives a killed gauge. Gauge will can receive emissions and deposits again. /// @dev Throws if not called by emergency council. /// Throws if gauge is not killed. /// @param _gauge . function reviveGauge(address _gauge) external; /// @dev Update claims to emissions for an array of gauges. /// @param _gauges Array of gauges to update emissions for. function updateFor(address[] memory _gauges) external; /// @dev Update claims to emissions for gauges based on their pool id as stored in Voter. /// @param _start Starting index of pools. /// @param _end Ending index of pools. function updateFor(uint256 _start, uint256 _end) external; /// @dev Update claims to emissions for single gauge /// @param _gauge . function updateFor(address _gauge) external; } interface IMinter { struct AirdropParams { // List of addresses to receive Liquid Tokens from the airdrop address[] liquidWallets; // List of amounts of Liquid Tokens to be issued uint256[] liquidAmounts; // List of addresses to receive Locked NFTs from the airdrop address[] lockedWallets; // List of amounts of Locked NFTs to be issued uint256[] lockedAmounts; } error NotTeam(); error RateTooHigh(); error ZeroAddress(); error InvalidParams(); error AlreadyNudged(); error NotPendingTeam(); error NotEpochGovernor(); error AlreadyInitialized(); error TailEmissionsInactive(); event Mint(address indexed _sender, uint256 _weekly, uint256 _circulating_supply, bool indexed _tail); event DistributeLocked(address indexed _destination, uint256 _amount, uint256 _tokenId); event Nudge(uint256 indexed _period, uint256 _oldRate, uint256 _newRate); event DistributeLiquid(address indexed _destination, uint256 _amount); event AcceptTeam(address indexed _newTeam); /// @notice Interface of Hydro.sol function hydro() external view returns (IHydro); /// @notice Interface of Voter.sol function voter() external view returns (IVoter); /// @notice Interface of IVotingEscrow.sol function ve() external view returns (IVotingEscrow); /// @notice Interface of RewardsDistributor.sol function rewardsDistributor() external view returns (IRewardsDistributor); /// @notice Duration of epoch in seconds function WEEK() external view returns (uint256); /// @notice Decay rate of emissions as percentage of `MAX_BPS` function WEEKLY_DECAY() external view returns (uint256); /// @notice Growth rate of emissions as percentage of `MAX_BPS` in first 14 weeks function WEEKLY_GROWTH() external view returns (uint256); /// @notice Maximum tail emission rate in basis points. function MAXIMUM_TAIL_RATE() external view returns (uint256); /// @notice Minimum tail emission rate in basis points. function MINIMUM_TAIL_RATE() external view returns (uint256); /// @notice Denominator for emissions calculations (as basis points) function MAX_BPS() external view returns (uint256); /// @notice Rate change per proposal function NUDGE() external view returns (uint256); /// @notice When emissions fall below this amount, begin tail emissions function TAIL_START() external view returns (uint256); /// @notice Maximum team percentage in basis points function MAXIMUM_TEAM_RATE() external view returns (uint256); /// @notice Current team percentage in basis points function teamRate() external view returns (uint256); /// @notice Tail emissions rate in basis points function tailEmissionRate() external view returns (uint256); /// @notice Starting weekly emission of 10M HYDRO (HYDRO has 18 decimals) function weekly() external view returns (uint256); /// @notice Timestamp of start of epoch that updatePeriod was last called in function activePeriod() external view returns (uint256); /// @notice Number of epochs in which updatePeriod was called function epochCount() external view returns (uint256); /// @notice Boolean used to verify if contract has been initialized function initialized() external returns (bool); /// @dev activePeriod => proposal existing, used to enforce one proposal per epoch /// @param _activePeriod Timestamp of start of epoch /// @return True if proposal has been executed, else false function proposals(uint256 _activePeriod) external view returns (bool); /// @notice Current team address in charge of emissions function team() external view returns (address); /// @notice Possible team address pending approval of current team function pendingTeam() external view returns (address); /// @notice Mints liquid tokens and permanently locked NFTs to the provided accounts /// @param params Struct that stores the wallets and amounts for the Airdrops function initialize(AirdropParams memory params) external; /// @notice Creates a request to change the current team's address /// @param _team Address of the new team to be chosen function setTeam(address _team) external; /// @notice Accepts the request to replace the current team's address /// with the requested one, present on variable pendingTeam function acceptTeam() external; /// @notice Creates a request to change the current team's percentage /// @param _rate New team rate to be set in basis points function setTeamRate(uint256 _rate) external; /// @notice Allows epoch governor to modify the tail emission rate by at most 1 basis point /// per epoch to a maximum of 100 basis points or to a minimum of 1 basis point. /// Note: the very first nudge proposal must take place the week prior /// to the tail emission schedule starting. /// @dev Throws if not epoch governor. /// Throws if not currently in tail emission schedule. /// Throws if already nudged this epoch. /// Throws if nudging above maximum rate. /// Throws if nudging below minimum rate. /// This contract is coupled to EpochGovernor as it requires three option simple majority voting. function nudge() external; /// @notice Calculates rebases according to the formula /// weekly * ((hydro.totalsupply - ve.totalSupply) / hydro.totalsupply) ^ 2 / 2 /// Note that ve.totalSupply is the locked ve supply /// hydro.totalSupply is the total ve supply minted /// @param _minted Amount of HYDRO minted this epoch /// @return _growth Rebases function calculateGrowth(uint256 _minted) external view returns (uint256 _growth); /// @notice Processes emissions and rebases. Callable once per epoch (1 week). /// @return _period Start of current epoch. function updatePeriod() external returns (uint256 _period); } // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Permit.sol) /** * @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); } // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) /** * @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.5.11/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); } } } /** * @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; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } 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)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } 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"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } 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"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } /* * @title Curve Fee Distribution modified for ve(3,3) emissions * @author Curve Finance, andrecronje * @author velodrome.finance, @figs999, @pegahcarter * @license MIT */ contract RewardsDistributor is IRewardsDistributor { using SafeERC20 for IERC20; /// @inheritdoc IRewardsDistributor uint256 public constant WEEK = 7 * 86400; /// @inheritdoc IRewardsDistributor uint256 public startTime; /// @inheritdoc IRewardsDistributor mapping(uint256 => uint256) public timeCursorOf; /// @inheritdoc IRewardsDistributor uint256 public lastTokenTime; uint256[1000000000000000] public tokensPerWeek; /// @inheritdoc IRewardsDistributor IVotingEscrow public immutable ve; /// @inheritdoc IRewardsDistributor address public token; /// @inheritdoc IRewardsDistributor address public minter; /// @inheritdoc IRewardsDistributor uint256 public tokenLastBalance; constructor(address _ve) { uint256 _t = (block.timestamp / WEEK) * WEEK; startTime = _t; lastTokenTime = _t; ve = IVotingEscrow(_ve); address _token = ve.token(); token = _token; minter = msg.sender; IERC20(_token).safeApprove(_ve, type(uint256).max); } function _checkpointToken() internal { uint256 tokenBalance = IERC20(token).balanceOf(address(this)); uint256 toDistribute = tokenBalance - tokenLastBalance; tokenLastBalance = tokenBalance; uint256 t = lastTokenTime; uint256 sinceLast = block.timestamp - t; lastTokenTime = block.timestamp; uint256 thisWeek = (t / WEEK) * WEEK; uint256 nextWeek = 0; uint256 timestamp = block.timestamp; for (uint256 i = 0; i < 20; i++) { nextWeek = thisWeek + WEEK; if (timestamp < nextWeek) { if (sinceLast == 0 && timestamp == t) { tokensPerWeek[thisWeek] += toDistribute; } else { tokensPerWeek[thisWeek] += (toDistribute * (timestamp - t)) / sinceLast; } break; } else { if (sinceLast == 0 && nextWeek == t) { tokensPerWeek[thisWeek] += toDistribute; } else { tokensPerWeek[thisWeek] += (toDistribute * (nextWeek - t)) / sinceLast; } } t = nextWeek; thisWeek = nextWeek; } emit CheckpointToken(timestamp, toDistribute); } /// @inheritdoc IRewardsDistributor function checkpointToken() external { if (msg.sender != minter) revert NotMinter(); _checkpointToken(); } function _claim(uint256 _tokenId, uint256 _lastTokenTime) internal returns (uint256) { (uint256 toDistribute, uint256 epochStart, uint256 weekCursor) = _claimable(_tokenId, _lastTokenTime); timeCursorOf[_tokenId] = weekCursor; if (toDistribute == 0) return 0; emit Claimed(_tokenId, epochStart, weekCursor, toDistribute); return toDistribute; } function _claimable( uint256 _tokenId, uint256 _lastTokenTime ) internal view returns (uint256 toDistribute, uint256 weekCursorStart, uint256 weekCursor) { uint256 _startTime = startTime; weekCursor = timeCursorOf[_tokenId]; weekCursorStart = weekCursor; // case where token does not exist uint256 maxUserEpoch = ve.userPointEpoch(_tokenId); if (maxUserEpoch == 0) return (0, weekCursorStart, weekCursor); // case where token exists but has never been claimed if (weekCursor == 0) { IVotingEscrow.UserPoint memory userPoint = ve.userPointHistory(_tokenId, 1); weekCursor = (userPoint.ts / WEEK) * WEEK; weekCursorStart = weekCursor; } if (weekCursor >= _lastTokenTime) return (0, weekCursorStart, weekCursor); if (weekCursor < _startTime) weekCursor = _startTime; for (uint256 i = 0; i < 50; i++) { if (weekCursor >= _lastTokenTime) break; uint256 balance = ve.balanceOfNFTAt(_tokenId, weekCursor + WEEK - 1); uint256 supply = ve.totalSupplyAt(weekCursor + WEEK - 1); supply = supply == 0 ? 1 : supply; toDistribute += (balance * tokensPerWeek[weekCursor]) / supply; weekCursor += WEEK; } } /// @inheritdoc IRewardsDistributor function claimable(uint256 _tokenId) external view returns (uint256 claimable_) { uint256 _lastTokenTime = (lastTokenTime / WEEK) * WEEK; (claimable_, , ) = _claimable(_tokenId, _lastTokenTime); } /// @inheritdoc IRewardsDistributor function claim(uint256 _tokenId) external returns (uint256) { if (IMinter(minter).activePeriod() < ((block.timestamp / WEEK) * WEEK)) revert UpdatePeriod(); if (ve.escrowType(_tokenId) == IVotingEscrow.EscrowType.LOCKED) revert NotManagedOrNormalNFT(); uint256 _timestamp = block.timestamp; uint256 _lastTokenTime = lastTokenTime; _lastTokenTime = (_lastTokenTime / WEEK) * WEEK; uint256 amount = _claim(_tokenId, _lastTokenTime); if (amount != 0) { IVotingEscrow.LockedBalance memory _locked = ve.locked(_tokenId); if (_timestamp >= _locked.end && !_locked.isPermanent) { address _owner = ve.ownerOf(_tokenId); IERC20(token).safeTransfer(_owner, amount); } else { ve.depositFor(_tokenId, amount); } tokenLastBalance -= amount; } return amount; } /// @inheritdoc IRewardsDistributor function claimMany(uint256[] calldata _tokenIds) external returns (bool) { if (IMinter(minter).activePeriod() < ((block.timestamp / WEEK) * WEEK)) revert UpdatePeriod(); uint256 _timestamp = block.timestamp; uint256 _lastTokenTime = lastTokenTime; _lastTokenTime = (_lastTokenTime / WEEK) * WEEK; uint256 total = 0; uint256 _length = _tokenIds.length; for (uint256 i = 0; i < _length; i++) { uint256 _tokenId = _tokenIds[i]; if (ve.escrowType(_tokenId) == IVotingEscrow.EscrowType.LOCKED) revert NotManagedOrNormalNFT(); if (_tokenId == 0) break; uint256 amount = _claim(_tokenId, _lastTokenTime); if (amount != 0) { IVotingEscrow.LockedBalance memory _locked = ve.locked(_tokenId); if (_timestamp >= _locked.end && !_locked.isPermanent) { address _owner = ve.ownerOf(_tokenId); IERC20(token).safeTransfer(_owner, amount); } else { ve.depositFor(_tokenId, amount); } total += amount; } } if (total != 0) { tokenLastBalance -= total; } return true; } /// @inheritdoc IRewardsDistributor function setMinter(address _minter) external { if (msg.sender != minter) revert NotMinter(); minter = _minter; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_ve","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"NotManagedOrNormalNFT","type":"error"},{"inputs":[],"name":"NotMinter","type":"error"},{"inputs":[],"name":"UpdatePeriod","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"CheckpointToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"epochStart","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"epochEnd","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claimed","type":"event"},{"inputs":[],"name":"WEEK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkpointToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"claim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"claimMany","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"claimable","outputs":[{"internalType":"uint256","name":"claimable_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastTokenTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"setMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"timeCursorOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenLastBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokensPerWeek","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ve","outputs":[{"internalType":"contract IVotingEscrow","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b5060405162001ddd38038062001ddd8339810160408190526200003491620004ec565b600062093a806200004681426200051e565b62000052919062000541565b600081815560028290556001600160a01b038416608081905260408051637e062a3560e11b815290519394509192909163fc0c546a9160048083019260209291908290030181865afa158015620000ad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000d39190620004ec565b66038d7ea4c6800380546001600160a01b0383166001600160a01b0319918216811790925566038d7ea4c680048054909116331790559091506200011b908460001962000124565b50505062000624565b801580620001a25750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa1580156200017a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001a091906200056d565b155b6200021a5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e63650000000000000000000060648201526084015b60405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152620002729185916200027716565b505050565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090620002c6906001600160a01b03851690849062000348565b805190915015620002725780806020019051810190620002e7919062000587565b620002725760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000211565b606062000359848460008562000361565b949350505050565b606082471015620003c45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000211565b600080866001600160a01b03168587604051620003e29190620005d1565b60006040518083038185875af1925050503d806000811462000421576040519150601f19603f3d011682016040523d82523d6000602084013e62000426565b606091505b5090925090506200043a8783838762000445565b979650505050505050565b60608315620004b9578251600003620004b1576001600160a01b0385163b620004b15760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000211565b508162000359565b620003598383815115620004d05781518083602001fd5b8060405162461bcd60e51b8152600401620002119190620005ef565b600060208284031215620004ff57600080fd5b81516001600160a01b03811681146200051757600080fd5b9392505050565b6000826200053c57634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176200056757634e487b7160e01b600052601160045260246000fd5b92915050565b6000602082840312156200058057600080fd5b5051919050565b6000602082840312156200059a57600080fd5b815180151581146200051757600080fd5b60005b83811015620005c8578181015183820152602001620005ae565b50506000910152565b60008251620005e5818460208701620005ab565b9190910192915050565b602081526000825180602084015262000610816040850160208701620005ab565b601f01601f19169190910160400192915050565b608051611749620006946000396000818161012a01528181610303015281816103f10152818161049a0152818161055001528181610711015281816107ee015281816108970152818161094d01528181610e3701528181610ee701528181610fbf015261107101526117496000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063925489a81161008c578063d1d58b2511610066578063d1d58b25146101ee578063f4359ce514610201578063fc0c546a1461020b578063fca3b5aa1461022457600080fd5b8063925489a8146101b8578063939ea66b146101db578063bee5dc32146101e457600080fd5b80634607bf60116100c85780634607bf601461016d57806378e979251461018d578063899519be146101965780638ec8468a146101a957600080fd5b806307546172146100ef5780631f85071614610125578063379607f51461014c575b600080fd5b66038d7ea4c6800454610108906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101087f000000000000000000000000000000000000000000000000000000000000000081565b61015f61015a366004611386565b610237565b60405190815260200161011c565b61015f61017b366004611386565b60016020526000908152604090205481565b61015f60005481565b61015f6101a4366004611386565b6105dc565b61015f66038d7ea4c680055481565b6101cb6101c636600461139f565b6105f9565b604051901515815260200161011c565b61015f60025481565b6101ec610a09565b005b61015f6101fc366004611386565b610a44565b61015f62093a8081565b66038d7ea4c6800354610108906001600160a01b031681565b6101ec61023236600461142c565b610a79565b600062093a806102478142611466565b6102519190611488565b66038d7ea4c6800460009054906101000a90046001600160a01b03166001600160a01b0316630a441f7b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ce919061149f565b10156102ed5760405163465a1c3560e01b815260040160405180910390fd5b600160405161f8e560ef1b8152600481018490527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690637c72800090602401602060405180830381865afa158015610352573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061037691906114ce565b6002811115610387576103876114b8565b036103a557604051635eb32db160e11b815260040160405180910390fd5b600254429062093a806103b88183611466565b6103c29190611488565b905060006103d08583610ad2565b905080156105d457604051635a2d1e0760e11b8152600481018690526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063b45a3c0e90602401606060405180830381865afa158015610440573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104649190611516565b90508060200151841015801561047c57508060400151155b15610533576040516331a9108f60e11b8152600481018790526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa1580156104e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050d9190611589565b66038d7ea4c680035490915061052d906001600160a01b03168285610b54565b506105b5565b60405163076426ed60e11b815260048101879052602481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690630ec84dda90604401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b8166038d7ea4c6800560008282546105cd91906115a6565b9091555050505b949350505050565b60038166038d7ea4c6800081106105f257600080fd5b0154905081565b600062093a806106098142611466565b6106139190611488565b66038d7ea4c6800460009054906101000a90046001600160a01b03166001600160a01b0316630a441f7b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561066c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610690919061149f565b10156106af5760405163465a1c3560e01b815260040160405180910390fd5b600254429062093a806106c28183611466565b6106cc9190611488565b9050600084815b818110156109d55760008888838181106106ef576106ef6115b9565b602002919091013591506001905060405161f8e560ef1b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690637c72800090602401602060405180830381865afa158015610760573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061078491906114ce565b6002811115610795576107956114b8565b036107b357604051635eb32db160e11b815260040160405180910390fd5b806000036107c157506109d5565b60006107cd8287610ad2565b905080156109c057604051635a2d1e0760e11b8152600481018390526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063b45a3c0e90602401606060405180830381865afa15801561083d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108619190611516565b90508060200151881015801561087957508060400151155b15610930576040516331a9108f60e11b8152600481018490526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa1580156108e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090a9190611589565b66038d7ea4c680035490915061092a906001600160a01b03168285610b54565b506109b2565b60405163076426ed60e11b815260048101849052602481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690630ec84dda90604401600060405180830381600087803b15801561099957600080fd5b505af11580156109ad573d6000803e3d6000fd5b505050505b6109bc82876115cf565b9550505b505080806109cd906115e2565b9150506106d3565b5081156109fa578166038d7ea4c6800560008282546109f491906115a6565b90915550505b60019450505050505b92915050565b66038d7ea4c68004546001600160a01b03163314610a3a57604051633e34a41b60e21b815260040160405180910390fd5b610a42610bab565b565b60008062093a8080600254610a599190611466565b610a639190611488565b9050610a6f8382610e0a565b5090949350505050565b66038d7ea4c68004546001600160a01b03163314610aaa57604051633e34a41b60e21b815260040160405180910390fd5b66038d7ea4c6800480546001600160a01b0319166001600160a01b0392909216919091179055565b600080600080610ae28686610e0a565b60008981526001602052604081208290559295509093509150839003610b0e5760009350505050610a03565b8082877fcae2990aa9af8eb1c64713b7eddb3a80bf18e49a94a13fe0d0002b5d61d58f0086604051610b4291815260200190565b60405180910390a45090949350505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610ba690849061118c565b505050565b66038d7ea4c68003546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610bfa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1e919061149f565b9050600066038d7ea4c680055482610c3691906115a6565b66038d7ea4c680058390556002549091506000610c5382426115a6565b426002559050600062093a80610c698185611466565b610c739190611488565b9050600042815b6014811015610dc757610c9062093a80856115cf565b925082821015610d195784158015610ca757508582145b15610ce1578660038566038d7ea4c680008110610cc657610cc66115b9565b016000828254610cd691906115cf565b90915550610dc79050565b84610cec87846115a6565b610cf69089611488565b610d009190611466565b60038566038d7ea4c680008110610cc657610cc66115b9565b84158015610d2657508583145b15610d60578660038566038d7ea4c680008110610d4557610d456115b9565b016000828254610d5591906115cf565b90915550610dae9050565b84610d6b87856115a6565b610d759089611488565b610d7f9190611466565b60038566038d7ea4c680008110610d9857610d986115b9565b016000828254610da891906115cf565b90915550505b8295508293508080610dbf906115e2565b915050610c7a565b5060408051828152602081018890527fce749457b74e10f393f2c6b1ce4261b78791376db5a3f501477a809f03f500d6910160405180910390a150505050505050565b600080548382526001602052604080832054905163e58f594760e01b8152600481018690529091829184907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e58f594790602401602060405180830381865afa158015610e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eaa919061149f565b905080600003610ebf57600094505050611185565b82600003610f81576040516322565a1560e11b815260048101889052600160248201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906344acb42a9060440160a060405180830381865afa158015610f36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5a91906115fb565b905062093a80808260400151610f709190611466565b610f7a9190611488565b9350839450505b858310610f9357600094505050611185565b81831015610f9f578192505b60005b603281101561118157868410156111815760006001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663e0514aba8a6001610ff462093a808a6115cf565b610ffe91906115a6565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401602060405180830381865afa15801561103f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611063919061149f565b905060006001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663981b24d060016110a562093a808a6115cf565b6110af91906115a6565b6040518263ffffffff1660e01b81526004016110cd91815260200190565b602060405180830381865afa1580156110ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110e919061149f565b9050801561111c578061111f565b60015b90508060038766038d7ea4c68000811061113b5761113b6115b9565b01546111479084611488565b6111519190611466565b61115b90896115cf565b975061116a62093a80876115cf565b955050508080611179906115e2565b915050610fa2565b5050505b9250925092565b60006111e1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166112639092919063ffffffff16565b805190915015610ba657808060200190518101906111ff9190611685565b610ba65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b60606105d4848460008585600080866001600160a01b0316858760405161128a91906116c4565b60006040518083038185875af1925050503d80600081146112c7576040519150601f19603f3d011682016040523d82523d6000602084013e6112cc565b606091505b50915091506112dd878383876112e8565b979650505050505050565b60608315611357578251600003611350576001600160a01b0385163b6113505760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161125a565b50816105d4565b6105d4838381511561136c5781518083602001fd5b8060405162461bcd60e51b815260040161125a91906116e0565b60006020828403121561139857600080fd5b5035919050565b600080602083850312156113b257600080fd5b823567ffffffffffffffff808211156113ca57600080fd5b818501915085601f8301126113de57600080fd5b8135818111156113ed57600080fd5b8660208260051b850101111561140257600080fd5b60209290920196919550909350505050565b6001600160a01b038116811461142957600080fd5b50565b60006020828403121561143e57600080fd5b813561144981611414565b9392505050565b634e487b7160e01b600052601160045260246000fd5b60008261148357634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417610a0357610a03611450565b6000602082840312156114b157600080fd5b5051919050565b634e487b7160e01b600052602160045260246000fd5b6000602082840312156114e057600080fd5b81516003811061144957600080fd5b8051600f81900b811461150157600080fd5b919050565b8051801515811461150157600080fd5b60006060828403121561152857600080fd5b6040516060810181811067ffffffffffffffff8211171561155957634e487b7160e01b600052604160045260246000fd5b604052611565836114ef565b81526020830151602082015261157d60408401611506565b60408201529392505050565b60006020828403121561159b57600080fd5b815161144981611414565b81810381811115610a0357610a03611450565b634e487b7160e01b600052603260045260246000fd5b80820180821115610a0357610a03611450565b6000600182016115f4576115f4611450565b5060010190565b600060a0828403121561160d57600080fd5b60405160a0810181811067ffffffffffffffff8211171561163e57634e487b7160e01b600052604160045260246000fd5b60405261164a836114ef565b8152611658602084016114ef565b60208201526040830151604082015260608301516060820152608083015160808201528091505092915050565b60006020828403121561169757600080fd5b61144982611506565b60005b838110156116bb5781810151838201526020016116a3565b50506000910152565b600082516116d68184602087016116a0565b9190910192915050565b60208152600082518060208401526116ff8160408501602087016116a0565b601f01601f1916919091016040019291505056fea2646970667358221220d3893021dd899f8a8cb882b4a3b7893fac11545eaebb4b625e0efbafa3bfb3da64736f6c63430008130033000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f11
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063925489a81161008c578063d1d58b2511610066578063d1d58b25146101ee578063f4359ce514610201578063fc0c546a1461020b578063fca3b5aa1461022457600080fd5b8063925489a8146101b8578063939ea66b146101db578063bee5dc32146101e457600080fd5b80634607bf60116100c85780634607bf601461016d57806378e979251461018d578063899519be146101965780638ec8468a146101a957600080fd5b806307546172146100ef5780631f85071614610125578063379607f51461014c575b600080fd5b66038d7ea4c6800454610108906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6101087f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f1181565b61015f61015a366004611386565b610237565b60405190815260200161011c565b61015f61017b366004611386565b60016020526000908152604090205481565b61015f60005481565b61015f6101a4366004611386565b6105dc565b61015f66038d7ea4c680055481565b6101cb6101c636600461139f565b6105f9565b604051901515815260200161011c565b61015f60025481565b6101ec610a09565b005b61015f6101fc366004611386565b610a44565b61015f62093a8081565b66038d7ea4c6800354610108906001600160a01b031681565b6101ec61023236600461142c565b610a79565b600062093a806102478142611466565b6102519190611488565b66038d7ea4c6800460009054906101000a90046001600160a01b03166001600160a01b0316630a441f7b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156102aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ce919061149f565b10156102ed5760405163465a1c3560e01b815260040160405180910390fd5b600160405161f8e560ef1b8152600481018490527f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b031690637c72800090602401602060405180830381865afa158015610352573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061037691906114ce565b6002811115610387576103876114b8565b036103a557604051635eb32db160e11b815260040160405180910390fd5b600254429062093a806103b88183611466565b6103c29190611488565b905060006103d08583610ad2565b905080156105d457604051635a2d1e0760e11b8152600481018690526000907f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b03169063b45a3c0e90602401606060405180830381865afa158015610440573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104649190611516565b90508060200151841015801561047c57508060400151155b15610533576040516331a9108f60e11b8152600481018790526000907f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b031690636352211e90602401602060405180830381865afa1580156104e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050d9190611589565b66038d7ea4c680035490915061052d906001600160a01b03168285610b54565b506105b5565b60405163076426ed60e11b815260048101879052602481018390527f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b031690630ec84dda90604401600060405180830381600087803b15801561059c57600080fd5b505af11580156105b0573d6000803e3d6000fd5b505050505b8166038d7ea4c6800560008282546105cd91906115a6565b9091555050505b949350505050565b60038166038d7ea4c6800081106105f257600080fd5b0154905081565b600062093a806106098142611466565b6106139190611488565b66038d7ea4c6800460009054906101000a90046001600160a01b03166001600160a01b0316630a441f7b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561066c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610690919061149f565b10156106af5760405163465a1c3560e01b815260040160405180910390fd5b600254429062093a806106c28183611466565b6106cc9190611488565b9050600084815b818110156109d55760008888838181106106ef576106ef6115b9565b602002919091013591506001905060405161f8e560ef1b8152600481018390527f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b031690637c72800090602401602060405180830381865afa158015610760573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061078491906114ce565b6002811115610795576107956114b8565b036107b357604051635eb32db160e11b815260040160405180910390fd5b806000036107c157506109d5565b60006107cd8287610ad2565b905080156109c057604051635a2d1e0760e11b8152600481018390526000907f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b03169063b45a3c0e90602401606060405180830381865afa15801561083d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108619190611516565b90508060200151881015801561087957508060400151155b15610930576040516331a9108f60e11b8152600481018490526000907f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b031690636352211e90602401602060405180830381865afa1580156108e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090a9190611589565b66038d7ea4c680035490915061092a906001600160a01b03168285610b54565b506109b2565b60405163076426ed60e11b815260048101849052602481018390527f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b031690630ec84dda90604401600060405180830381600087803b15801561099957600080fd5b505af11580156109ad573d6000803e3d6000fd5b505050505b6109bc82876115cf565b9550505b505080806109cd906115e2565b9150506106d3565b5081156109fa578166038d7ea4c6800560008282546109f491906115a6565b90915550505b60019450505050505b92915050565b66038d7ea4c68004546001600160a01b03163314610a3a57604051633e34a41b60e21b815260040160405180910390fd5b610a42610bab565b565b60008062093a8080600254610a599190611466565b610a639190611488565b9050610a6f8382610e0a565b5090949350505050565b66038d7ea4c68004546001600160a01b03163314610aaa57604051633e34a41b60e21b815260040160405180910390fd5b66038d7ea4c6800480546001600160a01b0319166001600160a01b0392909216919091179055565b600080600080610ae28686610e0a565b60008981526001602052604081208290559295509093509150839003610b0e5760009350505050610a03565b8082877fcae2990aa9af8eb1c64713b7eddb3a80bf18e49a94a13fe0d0002b5d61d58f0086604051610b4291815260200190565b60405180910390a45090949350505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610ba690849061118c565b505050565b66038d7ea4c68003546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610bfa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1e919061149f565b9050600066038d7ea4c680055482610c3691906115a6565b66038d7ea4c680058390556002549091506000610c5382426115a6565b426002559050600062093a80610c698185611466565b610c739190611488565b9050600042815b6014811015610dc757610c9062093a80856115cf565b925082821015610d195784158015610ca757508582145b15610ce1578660038566038d7ea4c680008110610cc657610cc66115b9565b016000828254610cd691906115cf565b90915550610dc79050565b84610cec87846115a6565b610cf69089611488565b610d009190611466565b60038566038d7ea4c680008110610cc657610cc66115b9565b84158015610d2657508583145b15610d60578660038566038d7ea4c680008110610d4557610d456115b9565b016000828254610d5591906115cf565b90915550610dae9050565b84610d6b87856115a6565b610d759089611488565b610d7f9190611466565b60038566038d7ea4c680008110610d9857610d986115b9565b016000828254610da891906115cf565b90915550505b8295508293508080610dbf906115e2565b915050610c7a565b5060408051828152602081018890527fce749457b74e10f393f2c6b1ce4261b78791376db5a3f501477a809f03f500d6910160405180910390a150505050505050565b600080548382526001602052604080832054905163e58f594760e01b8152600481018690529091829184907f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b03169063e58f594790602401602060405180830381865afa158015610e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eaa919061149f565b905080600003610ebf57600094505050611185565b82600003610f81576040516322565a1560e11b815260048101889052600160248201526000907f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b0316906344acb42a9060440160a060405180830381865afa158015610f36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5a91906115fb565b905062093a80808260400151610f709190611466565b610f7a9190611488565b9350839450505b858310610f9357600094505050611185565b81831015610f9f578192505b60005b603281101561118157868410156111815760006001600160a01b037f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f111663e0514aba8a6001610ff462093a808a6115cf565b610ffe91906115a6565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401602060405180830381865afa15801561103f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611063919061149f565b905060006001600160a01b037f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f111663981b24d060016110a562093a808a6115cf565b6110af91906115a6565b6040518263ffffffff1660e01b81526004016110cd91815260200190565b602060405180830381865afa1580156110ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110e919061149f565b9050801561111c578061111f565b60015b90508060038766038d7ea4c68000811061113b5761113b6115b9565b01546111479084611488565b6111519190611466565b61115b90896115cf565b975061116a62093a80876115cf565b955050508080611179906115e2565b915050610fa2565b5050505b9250925092565b60006111e1826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166112639092919063ffffffff16565b805190915015610ba657808060200190518101906111ff9190611685565b610ba65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b60606105d4848460008585600080866001600160a01b0316858760405161128a91906116c4565b60006040518083038185875af1925050503d80600081146112c7576040519150601f19603f3d011682016040523d82523d6000602084013e6112cc565b606091505b50915091506112dd878383876112e8565b979650505050505050565b60608315611357578251600003611350576001600160a01b0385163b6113505760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161125a565b50816105d4565b6105d4838381511561136c5781518083602001fd5b8060405162461bcd60e51b815260040161125a91906116e0565b60006020828403121561139857600080fd5b5035919050565b600080602083850312156113b257600080fd5b823567ffffffffffffffff808211156113ca57600080fd5b818501915085601f8301126113de57600080fd5b8135818111156113ed57600080fd5b8660208260051b850101111561140257600080fd5b60209290920196919550909350505050565b6001600160a01b038116811461142957600080fd5b50565b60006020828403121561143e57600080fd5b813561144981611414565b9392505050565b634e487b7160e01b600052601160045260246000fd5b60008261148357634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417610a0357610a03611450565b6000602082840312156114b157600080fd5b5051919050565b634e487b7160e01b600052602160045260246000fd5b6000602082840312156114e057600080fd5b81516003811061144957600080fd5b8051600f81900b811461150157600080fd5b919050565b8051801515811461150157600080fd5b60006060828403121561152857600080fd5b6040516060810181811067ffffffffffffffff8211171561155957634e487b7160e01b600052604160045260246000fd5b604052611565836114ef565b81526020830151602082015261157d60408401611506565b60408201529392505050565b60006020828403121561159b57600080fd5b815161144981611414565b81810381811115610a0357610a03611450565b634e487b7160e01b600052603260045260246000fd5b80820180821115610a0357610a03611450565b6000600182016115f4576115f4611450565b5060010190565b600060a0828403121561160d57600080fd5b60405160a0810181811067ffffffffffffffff8211171561163e57634e487b7160e01b600052604160045260246000fd5b60405261164a836114ef565b8152611658602084016114ef565b60208201526040830151604082015260608301516060820152608083015160808201528091505092915050565b60006020828403121561169757600080fd5b61144982611506565b60005b838110156116bb5781810151838201526020016116a3565b50506000910152565b600082516116d68184602087016116a0565b9190910192915050565b60208152600082518060208401526116ff8160408501602087016116a0565b601f01601f1916919091016040019291505056fea2646970667358221220d3893021dd899f8a8cb882b4a3b7893fac11545eaebb4b625e0efbafa3bfb3da64736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f11
-----Decoded View---------------
Arg [0] : _ve (address): 0xe0d35cf2ab00f3C11F10535DB27807F3DE139F11
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f11
Deployed Bytecode Sourcemap
84514:7173:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85185:21;;;;;-1:-1:-1;;;;;85185:21:0;;;;;;-1:-1:-1;;;;;178:32:1;;;160:51;;148:2;133:18;85185:21:0;;;;;;;;85036:33;;;;;89207:948;;;;;;:::i;:::-;;:::i;:::-;;;783:25:1;;;771:2;756:18;89207:948:0;637:177:1;84808:47:0;;;;;;:::i;:::-;;;;;;;;;;;;;;84736:24;;;;;;84940:46;;;;;;:::i;:::-;;:::i;85254:31::-;;;;;;90204:1296;;;;;;:::i;:::-;;:::i;:::-;;;1604:14:1;;1597:22;1579:41;;1567:2;1552:18;90204:1296:0;1439:187:1;84905:28:0;;;;;;86990:128;;;:::i;:::-;;88939:219;;;;;;:::i;:::-;;:::i;84646:40::-;;84677:9;84646:40;;85117:20;;;;;-1:-1:-1;;;;;85117:20:0;;;91549:135;;;;;;:::i;:::-;;:::i;89207:948::-;89258:7;84677:9;89317:22;84677:9;89317:15;:22;:::i;:::-;89316:31;;;;:::i;:::-;89290:6;;;;;;;;;-1:-1:-1;;;;;89290:6:0;-1:-1:-1;;;;;89282:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:66;89278:93;;;89357:14;;-1:-1:-1;;;89357:14:0;;;;;;;;;;;89278:93;89413:31;89386:23;;-1:-1:-1;;;89386:23:0;;;;;783:25:1;;;89386:2:0;-1:-1:-1;;;;;89386:13:0;;;;756:18:1;;89386:23:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:58;;;;;;;;:::i;:::-;;89382:94;;89453:23;;-1:-1:-1;;;89453:23:0;;;;;;;;;;;89382:94;89559:13;;89508:15;;84677:9;89601:21;84677:9;89559:13;89601:21;:::i;:::-;89600:30;;;;:::i;:::-;89583:47;;89641:14;89658:32;89665:8;89675:14;89658:6;:32::i;:::-;89641:49;-1:-1:-1;89705:11:0;;89701:423;;89778:19;;-1:-1:-1;;;89778:19:0;;;;;783:25:1;;;89733:42:0;;89778:2;-1:-1:-1;;;;;89778:9:0;;;;756:18:1;;89778:19:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;89733:64;;89830:7;:11;;;89816:10;:25;;:49;;;;;89846:7;:19;;;89845:20;89816:49;89812:260;;;89903:20;;-1:-1:-1;;;89903:20:0;;;;;783:25:1;;;89886:14:0;;89903:2;-1:-1:-1;;;;;89903:10:0;;;;756:18:1;;89903:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;89949:5;;89886:37;;-1:-1:-1;89942:42:0;;-1:-1:-1;;;;;89949:5:0;89886:37;89977:6;89942:26;:42::i;:::-;89867:133;89812:260;;;90025:31;;-1:-1:-1;;;90025:31:0;;;;;4629:25:1;;;4670:18;;;4663:34;;;90025:2:0;-1:-1:-1;;;;;90025:13:0;;;;4602:18:1;;90025:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89812:260;90106:6;90086:16;;:26;;;;;;;:::i;:::-;;;;-1:-1:-1;;;89701:423:0;90141:6;89207:948;-1:-1:-1;;;;89207:948:0:o;84940:46::-;;;;;;;;;;;;;;;-1:-1:-1;84940:46:0;:::o;90204:1296::-;90271:4;84677:9;90327:22;84677:9;90327:15;:22;:::i;:::-;90326:31;;;;:::i;:::-;90300:6;;;;;;;;;-1:-1:-1;;;;;90300:6:0;-1:-1:-1;;;;;90292:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:66;90288:93;;;90367:14;;-1:-1:-1;;;90367:14:0;;;;;;;;;;;90288:93;90464:13;;90413:15;;84677:9;90506:21;84677:9;90464:13;90506:21;:::i;:::-;90505:30;;;;:::i;:::-;90488:47;-1:-1:-1;90546:13:0;90592:9;90546:13;90621:770;90645:7;90641:1;:11;90621:770;;;90674:16;90693:9;;90703:1;90693:12;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;90751:31:0;;-1:-1:-1;90724:23:0;;-1:-1:-1;;;90724:23:0;;;;;783:25:1;;;90724:2:0;-1:-1:-1;;;;;90724:13:0;;;;756:18:1;;90724:23:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:58;;;;;;;;:::i;:::-;;90720:94;;90791:23;;-1:-1:-1;;;90791:23:0;;;;;;;;;;;90720:94;90833:8;90845:1;90833:13;90829:24;;90848:5;;;90829:24;90868:14;90885:32;90892:8;90902:14;90885:6;:32::i;:::-;90868:49;-1:-1:-1;90936:11:0;;90932:448;;91013:19;;-1:-1:-1;;;91013:19:0;;;;;783:25:1;;;90968:42:0;;91013:2;-1:-1:-1;;;;;91013:9:0;;;;756:18:1;;91013:19:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90968:64;;91069:7;:11;;;91055:10;:25;;:49;;;;;91085:7;:19;;;91084:20;91055:49;91051:280;;;91146:20;;-1:-1:-1;;;91146:20:0;;;;;783:25:1;;;91129:14:0;;91146:2;-1:-1:-1;;;;;91146:10:0;;;;756:18:1;;91146:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91196:5;;91129:37;;-1:-1:-1;91189:42:0;;-1:-1:-1;;;;;91196:5:0;91129:37;91224:6;91189:26;:42::i;:::-;91106:145;91051:280;;;91280:31;;-1:-1:-1;;;91280:31:0;;;;;4629:25:1;;;4670:18;;;4663:34;;;91280:2:0;-1:-1:-1;;;;;91280:13:0;;;;4602:18:1;;91280:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91051:280;91349:15;91358:6;91349:15;;:::i;:::-;;;90949:431;90932:448;90659:732;;90654:3;;;;;:::i;:::-;;;;90621:770;;;-1:-1:-1;91405:10:0;;91401:68;;91452:5;91432:16;;:25;;;;;;;:::i;:::-;;;;-1:-1:-1;;91401:68:0;91488:4;91481:11;;;;;;90204:1296;;;;;:::o;86990:128::-;87055:6;;-1:-1:-1;;;;;87055:6:0;87041:10;:20;87037:44;;87070:11;;-1:-1:-1;;;87070:11:0;;;;;;;;;;;87037:44;87092:18;:16;:18::i;:::-;86990:128::o;88939:219::-;88999:18;89030:22;84677:9;;89056:13;;:20;;;;:::i;:::-;89055:29;;;;:::i;:::-;89030:54;;89114:36;89125:8;89135:14;89114:10;:36::i;:::-;-1:-1:-1;89095:55:0;;88939:219;-1:-1:-1;;;;88939:219:0:o;91549:135::-;91623:6;;-1:-1:-1;;;;;91623:6:0;91609:10;:20;91605:44;;91638:11;;-1:-1:-1;;;91638:11:0;;;;;;;;;;;91605:44;91660:6;:16;;-1:-1:-1;;;;;;91660:16:0;-1:-1:-1;;;;;91660:16:0;;;;;;;;;;91549:135::o;87126:396::-;87202:7;87223:20;87245:18;87265;87287:36;87298:8;87308:14;87287:10;:36::i;:::-;87334:22;;;;:12;:22;;;;;:35;;;87222:101;;-1:-1:-1;87222:101:0;;-1:-1:-1;87222:101:0;-1:-1:-1;87384:17:0;;;87380:31;;87410:1;87403:8;;;;;;;87380:31;87459:10;87447;87437:8;87429:55;87471:12;87429:55;;;;783:25:1;;771:2;756:18;;637:177;87429:55:0;;;;;;;;-1:-1:-1;87502:12:0;;87126:396;-1:-1:-1;;;;87126:396:0:o;80719:177::-;80829:58;;;-1:-1:-1;;;;;5435:32:1;;80829:58:0;;;5417:51:1;5484:18;;;;5477:34;;;80829:58:0;;;;;;;;;;5390:18:1;;;;80829:58:0;;;;;;;;-1:-1:-1;;;;;80829:58:0;-1:-1:-1;;;80829:58:0;;;80802:86;;80822:5;;80802:19;:86::i;:::-;80719:177;;;:::o;85632:1309::-;85710:5;;85703:38;;-1:-1:-1;;;85703:38:0;;85735:4;85703:38;;;160:51:1;85680:20:0;;-1:-1:-1;;;;;85710:5:0;;85703:23;;133:18:1;;85703:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;85680:61;;85752:20;85790:16;;85775:12;:31;;;;:::i;:::-;85817:16;:31;;;85873:13;;85752:54;;-1:-1:-1;85861:9:0;85917:19;85873:13;85917:15;:19;:::i;:::-;85963:15;85947:13;:31;85897:39;-1:-1:-1;85989:16:0;84677:9;86009:8;84677:9;86009:1;:8;:::i;:::-;86008:17;;;;:::i;:::-;85989:36;-1:-1:-1;86036:16:0;86087:15;86036:16;86115:763;86139:2;86135:1;:6;86115:763;;;86174:15;84677:9;86174:8;:15;:::i;:::-;86163:26;;86220:8;86208:9;:20;86204:602;;;86253:14;;:32;;;;;86284:1;86271:9;:14;86253:32;86249:240;;;86337:12;86310:13;86324:8;86310:23;;;;;;;:::i;:::-;;;:39;;;;;;;:::i;:::-;;;;-1:-1:-1;86507:5:0;;-1:-1:-1;86507:5:0;86249:240;86460:9;86442:13;86454:1;86442:9;:13;:::i;:::-;86426:30;;:12;:30;:::i;:::-;86425:44;;;;:::i;:::-;86398:13;86412:8;86398:23;;;;;;;:::i;86204:602::-;86557:14;;:31;;;;;86587:1;86575:8;:13;86557:31;86553:238;;;86640:12;86613:13;86627:8;86613:23;;;;;;;:::i;:::-;;;:39;;;;;;;:::i;:::-;;;;-1:-1:-1;86553:238:0;;-1:-1:-1;86553:238:0;;86762:9;86745:12;86756:1;86745:8;:12;:::i;:::-;86729:29;;:12;:29;:::i;:::-;86728:43;;;;:::i;:::-;86701:13;86715:8;86701:23;;;;;;;:::i;:::-;;;:70;;;;;;;:::i;:::-;;;;-1:-1:-1;;86553:238:0;86824:8;86820:12;;86858:8;86847:19;;86143:3;;;;;:::i;:::-;;;;86115:763;;;-1:-1:-1;86893:40:0;;;4629:25:1;;;4685:2;4670:18;;4663:34;;;86893:40:0;;4602:18:1;86893:40:0;;;;;;;85669:1272;;;;;;;85632:1309::o;87530:1360::-;87640:20;87739:9;;87772:22;;;:12;:22;;;;;;;87913:27;;-1:-1:-1;;;87913:27:0;;;;;783:25:1;;;87772:22:0;;;;87640:20;;87913:2;-1:-1:-1;;;;;87913:17:0;;;;756:18:1;;87913:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;87890:50;;87955:12;87971:1;87955:17;87951:62;;87982:1;87974:39;;;;;;87951:62;88093:10;88107:1;88093:15;88089:222;;88168:32;;-1:-1:-1;;;88168:32:0;;;;;4629:25:1;;;88198:1:0;4670:18:1;;;4663:34;88125:40:0;;88168:2;-1:-1:-1;;;;;88168:19:0;;;;4602:18:1;;88168:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;88125:75;;84677:9;;88229;:12;;;:19;;;;:::i;:::-;88228:28;;;;:::i;:::-;88215:41;;88289:10;88271:28;;88110:201;88089:222;88339:14;88325:10;:28;88321:73;;88363:1;88355:39;;;;;;88321:73;88422:10;88409;:23;88405:52;;;88447:10;88434:23;;88405:52;88475:9;88470:413;88494:2;88490:1;:6;88470:413;;;88536:14;88522:10;:28;88518:39;88552:5;88518:39;88574:15;-1:-1:-1;;;;;88592:2:0;:17;;88610:8;88640:1;88620:17;84677:9;88620:10;:17;:::i;:::-;:21;;;;:::i;:::-;88592:50;;-1:-1:-1;;;;;;88592:50:0;;;;;;;;;;4629:25:1;;;;4670:18;;;4663:34;4602:18;;88592:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;88574:68;-1:-1:-1;88657:14:0;-1:-1:-1;;;;;88674:2:0;:16;;88711:1;88691:17;84677:9;88691:10;:17;:::i;:::-;:21;;;;:::i;:::-;88674:39;;;;;;;;;;;;;783:25:1;;771:2;756:18;;637:177;88674:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;88657:56;-1:-1:-1;88737:11:0;;:24;;88755:6;88737:24;;;88751:1;88737:24;88728:33;;88832:6;88803:13;88817:10;88803:25;;;;;;;:::i;:::-;;;88793:35;;:7;:35;:::i;:::-;88792:46;;;;:::i;:::-;88776:62;;;;:::i;:::-;;-1:-1:-1;88853:18:0;84677:9;88853:18;;:::i;:::-;;;88503:380;;88498:3;;;;;:::i;:::-;;;;88470:413;;;;87707:1183;;87530:1360;;;;;;:::o;83607:716::-;84031:23;84057:69;84085:4;84057:69;;;;;;;;;;;;;;;;;84065:5;-1:-1:-1;;;;;84057:27:0;;;:69;;;;;:::i;:::-;84141:17;;84031:95;;-1:-1:-1;84141:21:0;84137:179;;84238:10;84227:30;;;;;;;;;;;;:::i;:::-;84219:85;;;;-1:-1:-1;;;84219:85:0;;7024:2:1;84219:85:0;;;7006:21:1;7063:2;7043:18;;;7036:30;7102:34;7082:18;;;7075:62;-1:-1:-1;;;7153:18:1;;;7146:40;7203:19;;84219:85:0;;;;;;;;74789:229;74926:12;74958:52;74980:6;74988:4;74994:1;74997:12;74926;76163;76177:23;76204:6;-1:-1:-1;;;;;76204:11:0;76223:5;76230:4;76204:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76162:73;;;;76253:69;76280:6;76288:7;76297:10;76309:12;76253:26;:69::i;:::-;76246:76;75875:455;-1:-1:-1;;;;;;;75875:455:0:o;78448:644::-;78633:12;78662:7;78658:427;;;78690:10;:17;78711:1;78690:22;78686:290;;-1:-1:-1;;;;;72328:19:0;;;78900:60;;;;-1:-1:-1;;;78900:60:0;;8389:2:1;78900:60:0;;;8371:21:1;8428:2;8408:18;;;8401:30;8467:31;8447:18;;;8440:59;8516:18;;78900:60:0;8187:353:1;78900:60:0;-1:-1:-1;78997:10:0;78990:17;;78658:427;79040:33;79048:10;79060:12;79795:17;;:21;79791:388;;80027:10;80021:17;80084:15;80071:10;80067:2;80063:19;80056:44;79791:388;80154:12;80147:20;;-1:-1:-1;;;80147:20:0;;;;;;;;:::i;452:180:1:-;511:6;564:2;552:9;543:7;539:23;535:32;532:52;;;580:1;577;570:12;532:52;-1:-1:-1;603:23:1;;452:180;-1:-1:-1;452:180:1:o;819:615::-;905:6;913;966:2;954:9;945:7;941:23;937:32;934:52;;;982:1;979;972:12;934:52;1022:9;1009:23;1051:18;1092:2;1084:6;1081:14;1078:34;;;1108:1;1105;1098:12;1078:34;1146:6;1135:9;1131:22;1121:32;;1191:7;1184:4;1180:2;1176:13;1172:27;1162:55;;1213:1;1210;1203:12;1162:55;1253:2;1240:16;1279:2;1271:6;1268:14;1265:34;;;1295:1;1292;1285:12;1265:34;1348:7;1343:2;1333:6;1330:1;1326:14;1322:2;1318:23;1314:32;1311:45;1308:65;;;1369:1;1366;1359:12;1308:65;1400:2;1392:11;;;;;1422:6;;-1:-1:-1;819:615:1;;-1:-1:-1;;;;819:615:1:o;1631:131::-;-1:-1:-1;;;;;1706:31:1;;1696:42;;1686:70;;1752:1;1749;1742:12;1686:70;1631:131;:::o;1767:247::-;1826:6;1879:2;1867:9;1858:7;1854:23;1850:32;1847:52;;;1895:1;1892;1885:12;1847:52;1934:9;1921:23;1953:31;1978:5;1953:31;:::i;:::-;2003:5;1767:247;-1:-1:-1;;;1767:247:1:o;2019:127::-;2080:10;2075:3;2071:20;2068:1;2061:31;2111:4;2108:1;2101:15;2135:4;2132:1;2125:15;2151:217;2191:1;2217;2207:132;;2261:10;2256:3;2252:20;2249:1;2242:31;2296:4;2293:1;2286:15;2324:4;2321:1;2314:15;2207:132;-1:-1:-1;2353:9:1;;2151:217::o;2373:168::-;2446:9;;;2477;;2494:15;;;2488:22;;2474:37;2464:71;;2515:18;;:::i;2546:184::-;2616:6;2669:2;2657:9;2648:7;2644:23;2640:32;2637:52;;;2685:1;2682;2675:12;2637:52;-1:-1:-1;2708:16:1;;2546:184;-1:-1:-1;2546:184:1:o;2735:127::-;2796:10;2791:3;2787:20;2784:1;2777:31;2827:4;2824:1;2817:15;2851:4;2848:1;2841:15;2867:275;2952:6;3005:2;2993:9;2984:7;2980:23;2976:32;2973:52;;;3021:1;3018;3011:12;2973:52;3053:9;3047:16;3092:1;3085:5;3082:12;3072:40;;3108:1;3105;3098:12;3147:166;3225:13;;3278:2;3267:21;;;3257:32;;3247:60;;3303:1;3300;3293:12;3247:60;3147:166;;;:::o;3318:164::-;3394:13;;3443;;3436:21;3426:32;;3416:60;;3472:1;3469;3462:12;3487:707;3588:6;3641:2;3629:9;3620:7;3616:23;3612:32;3609:52;;;3657:1;3654;3647:12;3609:52;3690:2;3684:9;3732:2;3724:6;3720:15;3801:6;3789:10;3786:22;3765:18;3753:10;3750:34;3747:62;3744:185;;;3851:10;3846:3;3842:20;3839:1;3832:31;3886:4;3883:1;3876:15;3914:4;3911:1;3904:15;3744:185;3945:2;3938:22;3984:39;4013:9;3984:39;:::i;:::-;3976:6;3969:55;4078:2;4067:9;4063:18;4057:25;4052:2;4044:6;4040:15;4033:50;4116:46;4158:2;4147:9;4143:18;4116:46;:::i;:::-;4111:2;4099:15;;4092:71;4103:6;3487:707;-1:-1:-1;;;3487:707:1:o;4199:251::-;4269:6;4322:2;4310:9;4301:7;4297:23;4293:32;4290:52;;;4338:1;4335;4328:12;4290:52;4370:9;4364:16;4389:31;4414:5;4389:31;:::i;4708:128::-;4775:9;;;4796:11;;;4793:37;;;4810:18;;:::i;4841:127::-;4902:10;4897:3;4893:20;4890:1;4883:31;4933:4;4930:1;4923:15;4957:4;4954:1;4947:15;4973:125;5038:9;;;5059:10;;;5056:36;;;5072:18;;:::i;5103:135::-;5142:3;5163:17;;;5160:43;;5183:18;;:::i;:::-;-1:-1:-1;5230:1:1;5219:13;;5103:135::o;5783:827::-;5880:6;5933:3;5921:9;5912:7;5908:23;5904:33;5901:53;;;5950:1;5947;5940:12;5901:53;5983:2;5977:9;6025:3;6017:6;6013:16;6095:6;6083:10;6080:22;6059:18;6047:10;6044:34;6041:62;6038:185;;;6145:10;6140:3;6136:20;6133:1;6126:31;6180:4;6177:1;6170:15;6208:4;6205:1;6198:15;6038:185;6239:2;6232:22;6278:39;6307:9;6278:39;:::i;:::-;6270:6;6263:55;6351:48;6395:2;6384:9;6380:18;6351:48;:::i;:::-;6346:2;6338:6;6334:15;6327:73;6454:2;6443:9;6439:18;6433:25;6428:2;6420:6;6416:15;6409:50;6513:2;6502:9;6498:18;6492:25;6487:2;6479:6;6475:15;6468:50;6573:3;6562:9;6558:19;6552:26;6546:3;6538:6;6534:16;6527:52;6598:6;6588:16;;;5783:827;;;;:::o;6615:202::-;6682:6;6735:2;6723:9;6714:7;6710:23;6706:32;6703:52;;;6751:1;6748;6741:12;6703:52;6774:37;6801:9;6774:37;:::i;7640:250::-;7725:1;7735:113;7749:6;7746:1;7743:13;7735:113;;;7825:11;;;7819:18;7806:11;;;7799:39;7771:2;7764:10;7735:113;;;-1:-1:-1;;7882:1:1;7864:16;;7857:27;7640:250::o;7895:287::-;8024:3;8062:6;8056:13;8078:66;8137:6;8132:3;8125:4;8117:6;8113:17;8078:66;:::i;:::-;8160:16;;;;;7895:287;-1:-1:-1;;7895:287:1:o;8545:396::-;8694:2;8683:9;8676:21;8657:4;8726:6;8720:13;8769:6;8764:2;8753:9;8749:18;8742:34;8785:79;8857:6;8852:2;8841:9;8837:18;8832:2;8824:6;8820:15;8785:79;:::i;:::-;8925:2;8904:15;-1:-1:-1;;8900:29:1;8885:45;;;;8932:2;8881:54;;8545:396;-1:-1:-1;;8545:396:1:o
Swarm Source
ipfs://d3893021dd899f8a8cb882b4a3b7893fac11545eaebb4b625e0efbafa3bfb3da
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.