Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
Minter
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 (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; } // 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; } 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); } interface IEpochGovernor { enum ProposalState { Pending, Active, Canceled, Defeated, Succeeded, Queued, Expired, Executed } /// @dev Stores most recent voting result. Will be either Defeated, Succeeded or Expired. /// Any contracts that wish to use this governor must read from this to determine results. function result() external returns (ProposalState); } // 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 Minter /// @author velodrome.finance, @figs999, @pegahcarter /// @notice Controls minting of emissions and rebases for the Protocol contract Minter is IMinter { using SafeERC20 for IHydro; /// @inheritdoc IMinter IHydro public immutable hydro; /// @inheritdoc IMinter IVoter public immutable voter; /// @inheritdoc IMinter IVotingEscrow public immutable ve; /// @inheritdoc IMinter IRewardsDistributor public immutable rewardsDistributor; /// @inheritdoc IMinter uint256 public constant WEEK = 1 weeks; /// @inheritdoc IMinter uint256 public constant WEEKLY_DECAY = 9_900; /// @inheritdoc IMinter uint256 public constant WEEKLY_GROWTH = 10_300; /// @inheritdoc IMinter uint256 public constant MAXIMUM_TAIL_RATE = 100; /// @inheritdoc IMinter uint256 public constant MINIMUM_TAIL_RATE = 1; /// @inheritdoc IMinter uint256 public constant MAX_BPS = 10_000; /// @inheritdoc IMinter uint256 public constant NUDGE = 1; /// @inheritdoc IMinter uint256 public constant TAIL_START = 8_969_150 * 1e18; /// @inheritdoc IMinter uint256 public tailEmissionRate = 67; /// @inheritdoc IMinter uint256 public constant MAXIMUM_TEAM_RATE = 500; /// @inheritdoc IMinter uint256 public teamRate = 500; // team emissions start at 5% /// @inheritdoc IMinter uint256 public weekly = 10_000_000 * 1e18; /// @inheritdoc IMinter uint256 public activePeriod; /// @inheritdoc IMinter uint256 public epochCount; /// @inheritdoc IMinter mapping(uint256 => bool) public proposals; /// @inheritdoc IMinter address public team; /// @inheritdoc IMinter address public pendingTeam; /// @inheritdoc IMinter bool public initialized; constructor( address _voter, // the voting & distribution system address _ve, // the ve(3,3) system that will be locked into address _rewardsDistributor // the distribution system that ensures users aren't diluted ) { hydro = IHydro(IVotingEscrow(_ve).token()); voter = IVoter(_voter); ve = IVotingEscrow(_ve); team = msg.sender; rewardsDistributor = IRewardsDistributor(_rewardsDistributor); activePeriod = ((block.timestamp) / WEEK) * WEEK; // allow emissions this coming epoch } /// @inheritdoc IMinter function initialize(AirdropParams memory params) external { if (initialized) revert AlreadyInitialized(); if (msg.sender != team) revert NotTeam(); if ( (params.liquidWallets.length != params.liquidAmounts.length) || (params.lockedWallets.length != params.lockedAmounts.length) ) revert InvalidParams(); initialized = true; // Liquid Token Mint uint256 _len = params.liquidWallets.length; for (uint256 i = 0; i < _len; i++) { hydro.mint(params.liquidWallets[i], params.liquidAmounts[i]); emit DistributeLiquid(params.liquidWallets[i], params.liquidAmounts[i]); } // Locked NFT mint _len = params.lockedWallets.length; uint256 _sum; for (uint256 i = 0; i < _len; i++) { _sum += params.lockedAmounts[i]; } uint256 _tokenId; hydro.mint(address(this), _sum); hydro.safeApprove(address(ve), _sum); for (uint256 i = 0; i < _len; i++) { _tokenId = ve.createLock(params.lockedAmounts[i], WEEK); ve.lockPermanent(_tokenId); ve.safeTransferFrom(address(this), params.lockedWallets[i], _tokenId); emit DistributeLocked(params.lockedWallets[i], params.lockedAmounts[i], _tokenId); } hydro.safeApprove(address(ve), 0); } /// @inheritdoc IMinter function setTeam(address _team) external { if (msg.sender != team) revert NotTeam(); if (_team == address(0)) revert ZeroAddress(); pendingTeam = _team; } /// @inheritdoc IMinter function acceptTeam() external { if (msg.sender != pendingTeam) revert NotPendingTeam(); team = pendingTeam; delete pendingTeam; emit AcceptTeam(team); } /// @inheritdoc IMinter function setTeamRate(uint256 _rate) external { if (msg.sender != team) revert NotTeam(); if (_rate > MAXIMUM_TEAM_RATE) revert RateTooHigh(); teamRate = _rate; } /// @inheritdoc IMinter function calculateGrowth(uint256 _minted) public view returns (uint256 _growth) { uint256 _veTotal = ve.totalSupplyAt(activePeriod - 1); uint256 _hydroTotal = hydro.totalSupply(); return (((_minted * (_hydroTotal - _veTotal)) / _hydroTotal) * (_hydroTotal - _veTotal)) / _hydroTotal / 2; } /// @inheritdoc IMinter function nudge() external { address _epochGovernor = voter.epochGovernor(); if (msg.sender != _epochGovernor) revert NotEpochGovernor(); IEpochGovernor.ProposalState _state = IEpochGovernor(_epochGovernor).result(); if (weekly >= TAIL_START) revert TailEmissionsInactive(); uint256 _period = activePeriod; if (proposals[_period]) revert AlreadyNudged(); uint256 _newRate = tailEmissionRate; uint256 _oldRate = _newRate; if (_state != IEpochGovernor.ProposalState.Expired) { if (_state == IEpochGovernor.ProposalState.Succeeded) { _newRate = _oldRate + NUDGE > MAXIMUM_TAIL_RATE ? MAXIMUM_TAIL_RATE : _oldRate + NUDGE; } else { _newRate = _oldRate - NUDGE < MINIMUM_TAIL_RATE ? MINIMUM_TAIL_RATE : _oldRate - NUDGE; } tailEmissionRate = _newRate; } proposals[_period] = true; emit Nudge(_period, _oldRate, _newRate); } /// @inheritdoc IMinter function updatePeriod() external returns (uint256 _period) { _period = activePeriod; if (block.timestamp >= _period + WEEK) { epochCount++; _period = (block.timestamp / WEEK) * WEEK; activePeriod = _period; uint256 _weekly = weekly; uint256 _emission; uint256 _totalSupply = hydro.totalSupply(); bool _tail = _weekly < TAIL_START; if (_tail) { _emission = (_totalSupply * tailEmissionRate) / MAX_BPS; } else { _emission = _weekly; if (epochCount < 15) { _weekly = (_weekly * WEEKLY_GROWTH) / MAX_BPS; } else { _weekly = (_weekly * WEEKLY_DECAY) / MAX_BPS; } weekly = _weekly; } uint256 _growth = calculateGrowth(_emission); uint256 _rate = teamRate; uint256 _teamEmissions = (_rate * (_growth + _weekly)) / (MAX_BPS - _rate); uint256 _required = _growth + _emission + _teamEmissions; uint256 _balanceOf = hydro.balanceOf(address(this)); if (_balanceOf < _required) { hydro.mint(address(this), _required - _balanceOf); } hydro.safeTransfer(address(team), _teamEmissions); hydro.safeTransfer(address(rewardsDistributor), _growth); rewardsDistributor.checkpointToken(); // checkpoint token balance that was just minted in rewards distributor hydro.safeApprove(address(voter), _emission); voter.notifyRewardAmount(_emission); emit Mint(msg.sender, _emission, hydro.totalSupply(), _tail); } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_voter","type":"address"},{"internalType":"address","name":"_ve","type":"address"},{"internalType":"address","name":"_rewardsDistributor","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"AlreadyNudged","type":"error"},{"inputs":[],"name":"InvalidParams","type":"error"},{"inputs":[],"name":"NotEpochGovernor","type":"error"},{"inputs":[],"name":"NotPendingTeam","type":"error"},{"inputs":[],"name":"NotTeam","type":"error"},{"inputs":[],"name":"RateTooHigh","type":"error"},{"inputs":[],"name":"TailEmissionsInactive","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_newTeam","type":"address"}],"name":"AcceptTeam","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_destination","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"DistributeLiquid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_destination","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"DistributeLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_weekly","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_circulating_supply","type":"uint256"},{"indexed":true,"internalType":"bool","name":"_tail","type":"bool"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_period","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_oldRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newRate","type":"uint256"}],"name":"Nudge","type":"event"},{"inputs":[],"name":"MAXIMUM_TAIL_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAXIMUM_TEAM_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINIMUM_TAIL_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NUDGE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TAIL_START","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WEEK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WEEKLY_DECAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WEEKLY_GROWTH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptTeam","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"activePeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minted","type":"uint256"}],"name":"calculateGrowth","outputs":[{"internalType":"uint256","name":"_growth","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"epochCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hydro","outputs":[{"internalType":"contract IHydro","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address[]","name":"liquidWallets","type":"address[]"},{"internalType":"uint256[]","name":"liquidAmounts","type":"uint256[]"},{"internalType":"address[]","name":"lockedWallets","type":"address[]"},{"internalType":"uint256[]","name":"lockedAmounts","type":"uint256[]"}],"internalType":"struct IMinter.AirdropParams","name":"params","type":"tuple"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nudge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pendingTeam","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"proposals","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsDistributor","outputs":[{"internalType":"contract IRewardsDistributor","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_team","type":"address"}],"name":"setTeam","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rate","type":"uint256"}],"name":"setTeamRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tailEmissionRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"team","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"teamRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"updatePeriod","outputs":[{"internalType":"uint256","name":"_period","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ve","outputs":[{"internalType":"contract IVotingEscrow","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"voter","outputs":[{"internalType":"contract IVoter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weekly","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
61010060405260436000556101f46001556a084595161401484a0000006002553480156200002c57600080fd5b5060405162001faf38038062001faf8339810160408190526200004f916200012b565b816001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200008e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000b4919062000175565b6001600160a01b0390811660805283811660a05282811660c052600680546001600160a01b03191633179055811660e05262093a80620000f581426200019a565b620001019190620001bd565b60035550620001e9915050565b80516001600160a01b03811681146200012657600080fd5b919050565b6000806000606084860312156200014157600080fd5b6200014c846200010e565b92506200015c602085016200010e565b91506200016c604085016200010e565b90509250925092565b6000602082840312156200018857600080fd5b62000193826200010e565b9392505050565b600082620001b857634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417620001e357634e487b7160e01b600052601160045260246000fd5b92915050565b60805160a05160c05160e051611ceb620002c4600039600081816102e401528181610a800152610aa701526000818161029901528181611074015281816110a601528181611177015281816111dd0152818161135b015261138c01526000818161030b015281816104b601528181610b490152610b8401526000818161025101528181610776015281816108f70152818161097601528181610a2801528181610a5e01528181610b2501528181610c1901528181610df301528181610fcf0152818161105201528181611339015261142d0152611ceb6000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c8063817ad59511610104578063ac68da44116100a2578063ea64743d11610071578063ea64743d146103bd578063ef74b74c146103c6578063f4359ce5146103d8578063fd967f47146103e257600080fd5b8063ac68da441461037f578063b5cc143a1461038f578063dc03d0c114610397578063e4a091da146103aa57600080fd5b80639008a642116100de5780639008a6421461036e5780639ba6f976146103765780639fa8cbf11461037f578063a83627de1461038757600080fd5b8063817ad59514610349578063829965cc1461035257806385f2aef21461035b57600080fd5b806326cfc17b116101715780633f2a55401161014b5780633f2a5540146102df57806346c96aac1461030657806359d46ffc1461032d57806378ef7f021461034057600080fd5b806326cfc17b146102bb5780632e8f7b1f146102c45780633a6d93a4146102d757600080fd5b8063158ef93e116101ad578063158ef93e1461023857806315a75bae1461024c578063172a0a601461028b5780631f8507161461029457600080fd5b8063013cf08b146101d4578063095cf5c61461020c5780630a441f7b14610221575b600080fd5b6101f76101e2366004611878565b60056020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b61021f61021a3660046118a9565b6103eb565b005b61022a60035481565b604051908152602001610203565b6007546101f790600160a01b900460ff1681565b6102737f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610203565b61022a61283c81565b6102737f000000000000000000000000000000000000000000000000000000000000000081565b61022a60025481565b61021f6102d2366004611878565b61045f565b61022a606481565b6102737f000000000000000000000000000000000000000000000000000000000000000081565b6102737f000000000000000000000000000000000000000000000000000000000000000081565b600754610273906001600160a01b031681565b61022a60015481565b61022a6101f481565b61022a60045481565b600654610273906001600160a01b031681565b61021f6104b2565b61022a60005481565b61022a600181565b61022a61071d565b61021f610cbe565b61021f6103a5366004611a30565b610d3d565b61022a6103b8366004611878565b611387565b61022a6126ac81565b61022a6a076b4a988436a8c838000081565b61022a62093a8081565b61022a61271081565b6006546001600160a01b0316331461041657604051633a7cfa5d60e21b815260040160405180910390fd5b6001600160a01b03811661043d5760405163d92e233d60e01b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b0392909216919091179055565b6006546001600160a01b0316331461048a57604051633a7cfa5d60e21b815260040160405180910390fd5b6101f48111156104ad576040516347765d3b60e11b815260040160405180910390fd5b600155565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633aae971f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610512573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105369190611b09565b9050336001600160a01b03821614610561576040516349bb6a7d60e11b815260040160405180910390fd5b6000816001600160a01b031663653721476040518163ffffffff1660e01b81526004016020604051808303816000875af11580156105a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c79190611b26565b90506a076b4a988436a8c8380000600254106105f6576040516360d6b4d960e01b815260040160405180910390fd5b60035460008181526005602052604090205460ff16156106295760405163b292ec6560e01b815260040160405180910390fd5b60005480600684600781111561064157610641611b47565b146106b857600484600781111561065a5761065a611b47565b0361068b57606461066c600183611b73565b116106815761067c600182611b73565b610684565b60645b91506106b2565b60016106978183611b8c565b106106ac576106a7600182611b8c565b6106af565b60015b91505b60008290555b60008381526005602052604090819020805460ff191660011790555183907f89f7f67bc867b6d7eefd5bd92b0df77051c2507700c7994efc25cfc679a0c5269061070e9084908690918252602082015260400190565b60405180910390a25050505050565b60035461072d62093a8082611b73565b4210610cbb576004805490600061074383611b9f565b9091555062093a8090506107578142611bb8565b6107619190611bda565b905080600381905550600060025490506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f69190611bf1565b90506a076b4a988436a8c83800008310801561082e576127106000548361081d9190611bda565b6108279190611bb8565b925061087e565b839250600f600454101561085c5761271061084b61283c86611bda565b6108559190611bb8565b9350610878565b61271061086b6126ac86611bda565b6108759190611bb8565b93505b60028490555b600061088984611387565b600154909150600061089d82612710611b8c565b6108a78885611b73565b6108b19084611bda565b6108bb9190611bb8565b90506000816108ca8886611b73565b6108d49190611b73565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa15801561093e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109629190611bf1565b905081811015610a17576001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166340c10f19306109a68486611b8c565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af11580156109f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a159190611c0a565b505b600654610a51906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911685611501565b610aa56001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000087611501565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663bee5dc326040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610b0057600080fd5b505af1158015610b14573d6000803e3d6000fd5b50610b6e9250506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690507f00000000000000000000000000000000000000000000000000000000000000008a611569565b604051633c6b16ab60e01b8152600481018990527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690633c6b16ab90602401600060405180830381600087803b158015610bd057600080fd5b505af1158015610be4573d6000803e3d6000fd5b50505050851515336001600160a01b03167fcd2127828092f586df56003faf212897e901bb47f89a227e1acd3a0738f1fe5f8a7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c999190611bf1565b6040805192835260208301919091520160405180910390a35050505050505050505b90565b6007546001600160a01b03163314610ce95760405163071110c760e51b815260040160405180910390fd5b60078054600680546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fe25466fe8250322bee73bc230e10775fe0da57be723ebdabfdc8b62b4ba0d10c90600090a2565b600754600160a01b900460ff1615610d675760405162dc149f60e41b815260040160405180910390fd5b6006546001600160a01b03163314610d9257604051633a7cfa5d60e21b815260040160405180910390fd5b602081015151815151141580610db2575080606001515181604001515114155b15610dd057604051635435b28960e11b815260040160405180910390fd5b6007805460ff60a01b1916600160a01b17905580515160005b81811015610f5e577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166340c10f1984600001518381518110610e3657610e36611c2c565b602002602001015185602001518481518110610e5457610e54611c2c565b60200260200101516040518363ffffffff1660e01b8152600401610e8d9291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af1158015610eac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ed09190611c0a565b508251805182908110610ee557610ee5611c2c565b60200260200101516001600160a01b03167fad55b70c3adab3ed0dbd5a6924908c58a5c6f7ef36086ea57a46ecbea914bf9284602001518381518110610f2d57610f2d611c2c565b6020026020010151604051610f4491815260200190565b60405180910390a280610f5681611b9f565b915050610de9565b50506040810151516000805b82811015610faf5783606001518181518110610f8857610f88611c2c565b602002602001015182610f9b9190611b73565b915080610fa781611b9f565b915050610f6a565b506040516340c10f1960e01b8152306004820152602481018290526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906340c10f19906044016020604051808303816000875af1158015611020573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110449190611c0a565b506110996001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000084611569565b60005b8381101561132b577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663b52c05fe866060015183815181106110e9576110e9611c2c565b602002602001015162093a806040518363ffffffff1660e01b815260040161111b929190918252602082015260400190565b6020604051808303816000875af115801561113a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115e9190611bf1565b6040516373ad8e1760e11b8152600481018290529092507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e75b1c2e90602401600060405180830381600087803b1580156111c357600080fd5b505af11580156111d7573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166342842e0e308760400151848151811061122157611221611c2c565b60209081029190910101516040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260448101859052606401600060405180830381600087803b15801561127b57600080fd5b505af115801561128f573d6000803e3d6000fd5b50505050846040015181815181106112a9576112a9611c2c565b60200260200101516001600160a01b03167feaf2fed4f7f20988cb8090e5cb6ca6867a5e85be3d3a2b70691e8329ae96d618866060015183815181106112f1576112f1611c2c565b602002602001015184604051611311929190918252602082015260400190565b60405180910390a28061132381611b9f565b91505061109c565b506113816001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f00000000000000000000000000000000000000000000000000000000000000006000611569565b50505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663981b24d060016003546113c89190611b8c565b6040518263ffffffff1660e01b81526004016113e691815260200190565b602060405180830381865afa158015611403573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114279190611bf1565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611489573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ad9190611bf1565b90506002816114bc8482611b8c565b836114c78682611b8c565b6114d19089611bda565b6114db9190611bb8565b6114e59190611bda565b6114ef9190611bb8565b6114f99190611bb8565b949350505050565b6040516001600160a01b03831660248201526044810182905261156490849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611683565b505050565b8015806115e35750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa1580156115bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e19190611bf1565b155b6116535760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084015b60405180910390fd5b6040516001600160a01b03831660248201526044810182905261156490849063095ea7b360e01b9060640161152d565b60006116d8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166117559092919063ffffffff16565b80519091501561156457808060200190518101906116f69190611c0a565b6115645760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161164a565b60606114f9848460008585600080866001600160a01b0316858760405161177c9190611c66565b60006040518083038185875af1925050503d80600081146117b9576040519150601f19603f3d011682016040523d82523d6000602084013e6117be565b606091505b50915091506117cf878383876117da565b979650505050505050565b60608315611849578251600003611842576001600160a01b0385163b6118425760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161164a565b50816114f9565b6114f9838381511561185e5781518083602001fd5b8060405162461bcd60e51b815260040161164a9190611c82565b60006020828403121561188a57600080fd5b5035919050565b6001600160a01b03811681146118a657600080fd5b50565b6000602082840312156118bb57600080fd5b81356118c681611891565b9392505050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715611906576119066118cd565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611935576119356118cd565b604052919050565b600067ffffffffffffffff821115611957576119576118cd565b5060051b60200190565b600082601f83011261197257600080fd5b813560206119876119828361193d565b61190c565b82815260059290921b840181019181810190868411156119a657600080fd5b8286015b848110156119ca5780356119bd81611891565b83529183019183016119aa565b509695505050505050565b600082601f8301126119e657600080fd5b813560206119f66119828361193d565b82815260059290921b84018101918181019086841115611a1557600080fd5b8286015b848110156119ca5780358352918301918301611a19565b600060208284031215611a4257600080fd5b813567ffffffffffffffff80821115611a5a57600080fd5b9083019060808286031215611a6e57600080fd5b611a766118e3565b823582811115611a8557600080fd5b611a9187828601611961565b825250602083013582811115611aa657600080fd5b611ab2878286016119d5565b602083015250604083013582811115611aca57600080fd5b611ad687828601611961565b604083015250606083013582811115611aee57600080fd5b611afa878286016119d5565b60608301525095945050505050565b600060208284031215611b1b57600080fd5b81516118c681611891565b600060208284031215611b3857600080fd5b8151600881106118c657600080fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115611b8657611b86611b5d565b92915050565b81810381811115611b8657611b86611b5d565b600060018201611bb157611bb1611b5d565b5060010190565b600082611bd557634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417611b8657611b86611b5d565b600060208284031215611c0357600080fd5b5051919050565b600060208284031215611c1c57600080fd5b815180151581146118c657600080fd5b634e487b7160e01b600052603260045260246000fd5b60005b83811015611c5d578181015183820152602001611c45565b50506000910152565b60008251611c78818460208701611c42565b9190910192915050565b6020815260008251806020840152611ca1816040850160208701611c42565b601f01601f1916919091016040019291505056fea26469706673582212208618bb4aa27703361745a9acaa0973cb2671f65e6c79b91e237c5e66ccd9694f64736f6c6343000813003300000000000000000000000050a459fc0069843750091d6382afc960d0b22b6d000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f11000000000000000000000000233d9d30a07fef1dc84f137410613cd21cbba464
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101cf5760003560e01c8063817ad59511610104578063ac68da44116100a2578063ea64743d11610071578063ea64743d146103bd578063ef74b74c146103c6578063f4359ce5146103d8578063fd967f47146103e257600080fd5b8063ac68da441461037f578063b5cc143a1461038f578063dc03d0c114610397578063e4a091da146103aa57600080fd5b80639008a642116100de5780639008a6421461036e5780639ba6f976146103765780639fa8cbf11461037f578063a83627de1461038757600080fd5b8063817ad59514610349578063829965cc1461035257806385f2aef21461035b57600080fd5b806326cfc17b116101715780633f2a55401161014b5780633f2a5540146102df57806346c96aac1461030657806359d46ffc1461032d57806378ef7f021461034057600080fd5b806326cfc17b146102bb5780632e8f7b1f146102c45780633a6d93a4146102d757600080fd5b8063158ef93e116101ad578063158ef93e1461023857806315a75bae1461024c578063172a0a601461028b5780631f8507161461029457600080fd5b8063013cf08b146101d4578063095cf5c61461020c5780630a441f7b14610221575b600080fd5b6101f76101e2366004611878565b60056020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b61021f61021a3660046118a9565b6103eb565b005b61022a60035481565b604051908152602001610203565b6007546101f790600160a01b900460ff1681565b6102737f00000000000000000000000095f0c274bda9159dcd69fd0c778776bce265cc0a81565b6040516001600160a01b039091168152602001610203565b61022a61283c81565b6102737f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f1181565b61022a60025481565b61021f6102d2366004611878565b61045f565b61022a606481565b6102737f000000000000000000000000233d9d30a07fef1dc84f137410613cd21cbba46481565b6102737f00000000000000000000000050a459fc0069843750091d6382afc960d0b22b6d81565b600754610273906001600160a01b031681565b61022a60015481565b61022a6101f481565b61022a60045481565b600654610273906001600160a01b031681565b61021f6104b2565b61022a60005481565b61022a600181565b61022a61071d565b61021f610cbe565b61021f6103a5366004611a30565b610d3d565b61022a6103b8366004611878565b611387565b61022a6126ac81565b61022a6a076b4a988436a8c838000081565b61022a62093a8081565b61022a61271081565b6006546001600160a01b0316331461041657604051633a7cfa5d60e21b815260040160405180910390fd5b6001600160a01b03811661043d5760405163d92e233d60e01b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b0392909216919091179055565b6006546001600160a01b0316331461048a57604051633a7cfa5d60e21b815260040160405180910390fd5b6101f48111156104ad576040516347765d3b60e11b815260040160405180910390fd5b600155565b60007f00000000000000000000000050a459fc0069843750091d6382afc960d0b22b6d6001600160a01b0316633aae971f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610512573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105369190611b09565b9050336001600160a01b03821614610561576040516349bb6a7d60e11b815260040160405180910390fd5b6000816001600160a01b031663653721476040518163ffffffff1660e01b81526004016020604051808303816000875af11580156105a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c79190611b26565b90506a076b4a988436a8c8380000600254106105f6576040516360d6b4d960e01b815260040160405180910390fd5b60035460008181526005602052604090205460ff16156106295760405163b292ec6560e01b815260040160405180910390fd5b60005480600684600781111561064157610641611b47565b146106b857600484600781111561065a5761065a611b47565b0361068b57606461066c600183611b73565b116106815761067c600182611b73565b610684565b60645b91506106b2565b60016106978183611b8c565b106106ac576106a7600182611b8c565b6106af565b60015b91505b60008290555b60008381526005602052604090819020805460ff191660011790555183907f89f7f67bc867b6d7eefd5bd92b0df77051c2507700c7994efc25cfc679a0c5269061070e9084908690918252602082015260400190565b60405180910390a25050505050565b60035461072d62093a8082611b73565b4210610cbb576004805490600061074383611b9f565b9091555062093a8090506107578142611bb8565b6107619190611bda565b905080600381905550600060025490506000807f00000000000000000000000095f0c274bda9159dcd69fd0c778776bce265cc0a6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f69190611bf1565b90506a076b4a988436a8c83800008310801561082e576127106000548361081d9190611bda565b6108279190611bb8565b925061087e565b839250600f600454101561085c5761271061084b61283c86611bda565b6108559190611bb8565b9350610878565b61271061086b6126ac86611bda565b6108759190611bb8565b93505b60028490555b600061088984611387565b600154909150600061089d82612710611b8c565b6108a78885611b73565b6108b19084611bda565b6108bb9190611bb8565b90506000816108ca8886611b73565b6108d49190611b73565b6040516370a0823160e01b81523060048201529091506000906001600160a01b037f00000000000000000000000095f0c274bda9159dcd69fd0c778776bce265cc0a16906370a0823190602401602060405180830381865afa15801561093e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109629190611bf1565b905081811015610a17576001600160a01b037f00000000000000000000000095f0c274bda9159dcd69fd0c778776bce265cc0a166340c10f19306109a68486611b8c565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af11580156109f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a159190611c0a565b505b600654610a51906001600160a01b037f00000000000000000000000095f0c274bda9159dcd69fd0c778776bce265cc0a8116911685611501565b610aa56001600160a01b037f00000000000000000000000095f0c274bda9159dcd69fd0c778776bce265cc0a167f000000000000000000000000233d9d30a07fef1dc84f137410613cd21cbba46487611501565b7f000000000000000000000000233d9d30a07fef1dc84f137410613cd21cbba4646001600160a01b031663bee5dc326040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610b0057600080fd5b505af1158015610b14573d6000803e3d6000fd5b50610b6e9250506001600160a01b037f00000000000000000000000095f0c274bda9159dcd69fd0c778776bce265cc0a1690507f00000000000000000000000050a459fc0069843750091d6382afc960d0b22b6d8a611569565b604051633c6b16ab60e01b8152600481018990527f00000000000000000000000050a459fc0069843750091d6382afc960d0b22b6d6001600160a01b031690633c6b16ab90602401600060405180830381600087803b158015610bd057600080fd5b505af1158015610be4573d6000803e3d6000fd5b50505050851515336001600160a01b03167fcd2127828092f586df56003faf212897e901bb47f89a227e1acd3a0738f1fe5f8a7f00000000000000000000000095f0c274bda9159dcd69fd0c778776bce265cc0a6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c999190611bf1565b6040805192835260208301919091520160405180910390a35050505050505050505b90565b6007546001600160a01b03163314610ce95760405163071110c760e51b815260040160405180910390fd5b60078054600680546001600160a01b0383166001600160a01b031991821681179092559091169091556040517fe25466fe8250322bee73bc230e10775fe0da57be723ebdabfdc8b62b4ba0d10c90600090a2565b600754600160a01b900460ff1615610d675760405162dc149f60e41b815260040160405180910390fd5b6006546001600160a01b03163314610d9257604051633a7cfa5d60e21b815260040160405180910390fd5b602081015151815151141580610db2575080606001515181604001515114155b15610dd057604051635435b28960e11b815260040160405180910390fd5b6007805460ff60a01b1916600160a01b17905580515160005b81811015610f5e577f00000000000000000000000095f0c274bda9159dcd69fd0c778776bce265cc0a6001600160a01b03166340c10f1984600001518381518110610e3657610e36611c2c565b602002602001015185602001518481518110610e5457610e54611c2c565b60200260200101516040518363ffffffff1660e01b8152600401610e8d9291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af1158015610eac573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ed09190611c0a565b508251805182908110610ee557610ee5611c2c565b60200260200101516001600160a01b03167fad55b70c3adab3ed0dbd5a6924908c58a5c6f7ef36086ea57a46ecbea914bf9284602001518381518110610f2d57610f2d611c2c565b6020026020010151604051610f4491815260200190565b60405180910390a280610f5681611b9f565b915050610de9565b50506040810151516000805b82811015610faf5783606001518181518110610f8857610f88611c2c565b602002602001015182610f9b9190611b73565b915080610fa781611b9f565b915050610f6a565b506040516340c10f1960e01b8152306004820152602481018290526000907f00000000000000000000000095f0c274bda9159dcd69fd0c778776bce265cc0a6001600160a01b0316906340c10f19906044016020604051808303816000875af1158015611020573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110449190611c0a565b506110996001600160a01b037f00000000000000000000000095f0c274bda9159dcd69fd0c778776bce265cc0a167f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f1184611569565b60005b8381101561132b577f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b031663b52c05fe866060015183815181106110e9576110e9611c2c565b602002602001015162093a806040518363ffffffff1660e01b815260040161111b929190918252602082015260400190565b6020604051808303816000875af115801561113a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061115e9190611bf1565b6040516373ad8e1760e11b8152600481018290529092507f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b03169063e75b1c2e90602401600060405180830381600087803b1580156111c357600080fd5b505af11580156111d7573d6000803e3d6000fd5b505050507f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b03166342842e0e308760400151848151811061122157611221611c2c565b60209081029190910101516040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260448101859052606401600060405180830381600087803b15801561127b57600080fd5b505af115801561128f573d6000803e3d6000fd5b50505050846040015181815181106112a9576112a9611c2c565b60200260200101516001600160a01b03167feaf2fed4f7f20988cb8090e5cb6ca6867a5e85be3d3a2b70691e8329ae96d618866060015183815181106112f1576112f1611c2c565b602002602001015184604051611311929190918252602082015260400190565b60405180910390a28061132381611b9f565b91505061109c565b506113816001600160a01b037f00000000000000000000000095f0c274bda9159dcd69fd0c778776bce265cc0a167f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116000611569565b50505050565b6000807f000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f116001600160a01b031663981b24d060016003546113c89190611b8c565b6040518263ffffffff1660e01b81526004016113e691815260200190565b602060405180830381865afa158015611403573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114279190611bf1565b905060007f00000000000000000000000095f0c274bda9159dcd69fd0c778776bce265cc0a6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611489573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ad9190611bf1565b90506002816114bc8482611b8c565b836114c78682611b8c565b6114d19089611bda565b6114db9190611bb8565b6114e59190611bda565b6114ef9190611bb8565b6114f99190611bb8565b949350505050565b6040516001600160a01b03831660248201526044810182905261156490849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611683565b505050565b8015806115e35750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa1580156115bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e19190611bf1565b155b6116535760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084015b60405180910390fd5b6040516001600160a01b03831660248201526044810182905261156490849063095ea7b360e01b9060640161152d565b60006116d8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166117559092919063ffffffff16565b80519091501561156457808060200190518101906116f69190611c0a565b6115645760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161164a565b60606114f9848460008585600080866001600160a01b0316858760405161177c9190611c66565b60006040518083038185875af1925050503d80600081146117b9576040519150601f19603f3d011682016040523d82523d6000602084013e6117be565b606091505b50915091506117cf878383876117da565b979650505050505050565b60608315611849578251600003611842576001600160a01b0385163b6118425760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161164a565b50816114f9565b6114f9838381511561185e5781518083602001fd5b8060405162461bcd60e51b815260040161164a9190611c82565b60006020828403121561188a57600080fd5b5035919050565b6001600160a01b03811681146118a657600080fd5b50565b6000602082840312156118bb57600080fd5b81356118c681611891565b9392505050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715611906576119066118cd565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611935576119356118cd565b604052919050565b600067ffffffffffffffff821115611957576119576118cd565b5060051b60200190565b600082601f83011261197257600080fd5b813560206119876119828361193d565b61190c565b82815260059290921b840181019181810190868411156119a657600080fd5b8286015b848110156119ca5780356119bd81611891565b83529183019183016119aa565b509695505050505050565b600082601f8301126119e657600080fd5b813560206119f66119828361193d565b82815260059290921b84018101918181019086841115611a1557600080fd5b8286015b848110156119ca5780358352918301918301611a19565b600060208284031215611a4257600080fd5b813567ffffffffffffffff80821115611a5a57600080fd5b9083019060808286031215611a6e57600080fd5b611a766118e3565b823582811115611a8557600080fd5b611a9187828601611961565b825250602083013582811115611aa657600080fd5b611ab2878286016119d5565b602083015250604083013582811115611aca57600080fd5b611ad687828601611961565b604083015250606083013582811115611aee57600080fd5b611afa878286016119d5565b60608301525095945050505050565b600060208284031215611b1b57600080fd5b81516118c681611891565b600060208284031215611b3857600080fd5b8151600881106118c657600080fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115611b8657611b86611b5d565b92915050565b81810381811115611b8657611b86611b5d565b600060018201611bb157611bb1611b5d565b5060010190565b600082611bd557634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417611b8657611b86611b5d565b600060208284031215611c0357600080fd5b5051919050565b600060208284031215611c1c57600080fd5b815180151581146118c657600080fd5b634e487b7160e01b600052603260045260246000fd5b60005b83811015611c5d578181015183820152602001611c45565b50506000910152565b60008251611c78818460208701611c42565b9190910192915050565b6020815260008251806020840152611ca1816040850160208701611c42565b601f01601f1916919091016040019291505056fea26469706673582212208618bb4aa27703361745a9acaa0973cb2671f65e6c79b91e237c5e66ccd9694f64736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000050a459fc0069843750091d6382afc960d0b22b6d000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f11000000000000000000000000233d9d30a07fef1dc84f137410613cd21cbba464
-----Decoded View---------------
Arg [0] : _voter (address): 0x50a459FC0069843750091D6382aFC960d0b22b6d
Arg [1] : _ve (address): 0xe0d35cf2ab00f3C11F10535DB27807F3DE139F11
Arg [2] : _rewardsDistributor (address): 0x233d9D30A07FeF1dC84f137410613CD21Cbba464
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000050a459fc0069843750091d6382afc960d0b22b6d
Arg [1] : 000000000000000000000000e0d35cf2ab00f3c11f10535db27807f3de139f11
Arg [2] : 000000000000000000000000233d9d30a07fef1dc84f137410613cd21cbba464
Deployed Bytecode Sourcemap
84943:7653:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86416:41;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;364:14:1;;357:22;339:41;;327:2;312:18;86416:41:0;;;;;;;;88701:186;;;;;;:::i;:::-;;:::i;:::-;;86292:27;;;;;;;;;925:25:1;;;913:2;898:18;86292:27:0;779:177:1;86610:23:0;;;;;-1:-1:-1;;;86610:23:0;;;;;;85039:29;;;;;;;;-1:-1:-1;;;;;1139:32:1;;;1121:51;;1109:2;1094:18;85039:29:0;961:217:1;85485:46:0;;85525:6;85485:46;;85169:33;;;;;86215:41;;;;;;89155:193;;;;;;:::i;:::-;;:::i;85567:47::-;;85611:3;85567:47;;85238:55;;;;;85104:29;;;;;86548:26;;;;;-1:-1:-1;;;;;86548:26:0;;;86120:29;;;;;;86037:47;;86081:3;86037:47;;86355:25;;;;;;86493:19;;;;;-1:-1:-1;;;;;86493:19:0;;;89745:1018;;;:::i;85965:36::-;;;;;;85650:45;;85694:1;85650:45;;90800:1793;;;:::i;88924:194::-;;;:::i;87251:1413::-;;;;;;:::i;:::-;;:::i;89385:323::-;;;;;;:::i;:::-;;:::i;85405:44::-;;85444:5;85405:44;;85876:53;;85913:16;85876:53;;85331:38;;85362:7;85331:38;;85731:40;;85765:6;85731:40;;88701:186;88771:4;;-1:-1:-1;;;;;88771:4:0;88757:10;:18;88753:40;;88784:9;;-1:-1:-1;;;88784:9:0;;;;;;;;;;;88753:40;-1:-1:-1;;;;;88808:19:0;;88804:45;;88836:13;;-1:-1:-1;;;88836:13:0;;;;;;;;;;;88804:45;88860:11;:19;;-1:-1:-1;;;;;;88860:19:0;-1:-1:-1;;;;;88860:19:0;;;;;;;;;;88701:186::o;89155:193::-;89229:4;;-1:-1:-1;;;;;89229:4:0;89215:10;:18;89211:40;;89242:9;;-1:-1:-1;;;89242:9:0;;;;;;;;;;;89211:40;86081:3;89266:5;:25;89262:51;;;89300:13;;-1:-1:-1;;;89300:13:0;;;;;;;;;;;89262:51;89324:8;:16;89155:193::o;89745:1018::-;89782:22;89807:5;-1:-1:-1;;;;;89807:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;89782:46;-1:-1:-1;89843:10:0;-1:-1:-1;;;;;89843:28:0;;;89839:59;;89880:18;;-1:-1:-1;;;89880:18:0;;;;;;;;;;;89839:59;89909:35;89962:14;-1:-1:-1;;;;;89947:37:0;;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;89909:77;;85913:16;90001:6;;:20;89997:56;;90030:23;;-1:-1:-1;;;90030:23:0;;;;;;;;;;;89997:56;90082:12;;90064:15;90109:18;;;:9;:18;;;;;;;;90105:46;;;90136:15;;-1:-1:-1;;;90136:15:0;;;;;;;;;;;90105:46;90162:16;90181;;90262:36;90252:6;:46;;;;;;;;:::i;:::-;;90248:422;;90329:38;90319:6;:48;;;;;;;;:::i;:::-;;90315:302;;85611:3;90399:16;85839:1;90399:8;:16;:::i;:::-;:36;:75;;90458:16;85839:1;90458:8;:16;:::i;:::-;90399:75;;;85611:3;90399:75;90388:86;;90315:302;;;85694:1;90526:16;85694:1;90526:8;:16;:::i;:::-;:36;:75;;90585:16;85839:1;90585:8;:16;:::i;:::-;90526:75;;;85694:1;90526:75;90515:86;;90315:302;90631:16;:27;;;90248:422;90680:18;;;;:9;:18;;;;;;;:25;;-1:-1:-1;;90680:25:0;90701:4;90680:25;;;90721:34;90690:7;;90721:34;;;;90736:8;;90746;;6770:25:1;;;6826:2;6811:18;;6804:34;6758:2;6743:18;;6596:248;90721:34:0;;;;;;;;89771:992;;;;;89745:1018::o;90800:1793::-;90880:12;;90926:14;85362:7;90880:12;90926:14;:::i;:::-;90907:15;:33;90903:1683;;90957:10;:12;;;:10;:12;;;:::i;:::-;;;;-1:-1:-1;85362:7:0;;-1:-1:-1;90995:22:0;85362:7;90995:15;:22;:::i;:::-;90994:31;;;;:::i;:::-;90984:41;;91055:7;91040:12;:22;;;;91077:15;91095:6;;91077:24;;91116:17;91148:20;91171:5;-1:-1:-1;;;;;91171:17:0;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91148:42;-1:-1:-1;85913:16:0;91218:20;;91255:416;;;;85765:6;91313:16;;91298:12;:31;;;;:::i;:::-;91297:43;;;;:::i;:::-;91285:55;;91255:416;;;91393:7;91381:19;;91436:2;91423:10;;:15;91419:202;;;85765:6;91474:23;85525:6;91474:7;:23;:::i;:::-;91473:35;;;;:::i;:::-;91463:45;;91419:202;;;85765:6;91568:22;85444:5;91568:7;:22;:::i;:::-;91567:34;;;;:::i;:::-;91557:44;;91419:202;91639:6;:16;;;91255:416;91687:15;91705:26;91721:9;91705:15;:26::i;:::-;91764:8;;91687:44;;-1:-1:-1;91748:13:0;91845:15;91764:8;85765:6;91845:15;:::i;:::-;91822:17;91832:7;91822;:17;:::i;:::-;91813:27;;:5;:27;:::i;:::-;91812:49;;;;:::i;:::-;91787:74;-1:-1:-1;91878:17:0;91787:74;91898:19;91908:9;91898:7;:19;:::i;:::-;:36;;;;:::i;:::-;91970:30;;-1:-1:-1;;;91970:30:0;;91994:4;91970:30;;;1121:51:1;91878:56:0;;-1:-1:-1;91949:18:0;;-1:-1:-1;;;;;91970:5:0;:15;;;;1094:18:1;;91970:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;91949:51;;92032:9;92019:10;:22;92015:112;;;-1:-1:-1;;;;;92062:5:0;:10;;92081:4;92088:22;92100:10;92088:9;:22;:::i;:::-;92062:49;;-1:-1:-1;;;;;;92062:49:0;;;;;;;-1:-1:-1;;;;;7765:32:1;;;92062:49:0;;;7747:51:1;7814:18;;;7807:34;7720:18;;92062:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;92015:112;92170:4;;92143:49;;-1:-1:-1;;;;;92143:5:0;:18;;;92170:4;92177:14;92143:18;:49::i;:::-;92207:56;-1:-1:-1;;;;;92207:5:0;:18;92234;92255:7;92207:18;:56::i;:::-;92278:18;-1:-1:-1;;;;;92278:34:0;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;92403:44:0;;-1:-1:-1;;;;;;;92403:5:0;:17;;-1:-1:-1;92429:5:0;92437:9;92403:17;:44::i;:::-;92462:35;;-1:-1:-1;;;92462:35:0;;;;;925:25:1;;;92462:5:0;-1:-1:-1;;;;;92462:24:0;;;;898:18:1;;92462:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92568:5;92519:55;;92524:10;-1:-1:-1;;;;;92519:55:0;;92536:9;92547:5;-1:-1:-1;;;;;92547:17:0;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;92519:55;;;6770:25:1;;;6826:2;6811:18;;6804:34;;;;6743:18;92519:55:0;;;;;;;90942:1644;;;;;;;;;90903:1683;90800:1793;:::o;88924:194::-;88984:11;;-1:-1:-1;;;;;88984:11:0;88970:10;:25;88966:54;;89004:16;;-1:-1:-1;;;89004:16:0;;;;;;;;;;;88966:54;89038:11;;;89031:4;:18;;-1:-1:-1;;;;;89038:11:0;;-1:-1:-1;;;;;;89031:18:0;;;;;;;;89060;;;;;;89094:16;;;;-1:-1:-1;;89094:16:0;88924:194::o;87251:1413::-;87324:11;;-1:-1:-1;;;87324:11:0;;;;87320:44;;;87344:20;;-1:-1:-1;;;87344:20:0;;;;;;;;;;;87320:44;87393:4;;-1:-1:-1;;;;;87393:4:0;87379:10;:18;87375:40;;87406:9;;-1:-1:-1;;;87406:9:0;;;;;;;;;;;87375:40;87476:20;;;;:27;87445:20;;:27;:58;;;87444:137;;;87553:6;:20;;;:27;87522:6;:20;;;:27;:58;;87444:137;87426:189;;;87600:15;;-1:-1:-1;;;87600:15:0;;;;;;;;;;;87426:189;87626:11;:18;;-1:-1:-1;;;;87626:18:0;-1:-1:-1;;;87626:18:0;;;87702:20;;:27;87626:18;87740:208;87764:4;87760:1;:8;87740:208;;;87790:5;-1:-1:-1;;;;;87790:10:0;;87801:6;:20;;;87822:1;87801:23;;;;;;;;:::i;:::-;;;;;;;87826:6;:20;;;87847:1;87826:23;;;;;;;;:::i;:::-;;;;;;;87790:60;;;;;;;;;;;;;;;-1:-1:-1;;;;;7765:32:1;;;;7747:51;;7829:2;7814:18;;7807:34;7735:2;7720:18;;7573:274;87790:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;87887:20:0;;:23;;87908:1;;87887:23;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;87870:66:0;;87912:6;:20;;;87933:1;87912:23;;;;;;;;:::i;:::-;;;;;;;87870:66;;;;925:25:1;;913:2;898:18;;779:177;87870:66:0;;;;;;;;87770:3;;;;:::i;:::-;;;;87740:208;;;-1:-1:-1;;87995:20:0;;;;:27;88033:12;;88056:93;88080:4;88076:1;:8;88056:93;;;88114:6;:20;;;88135:1;88114:23;;;;;;;;:::i;:::-;;;;;;;88106:31;;;;;:::i;:::-;;-1:-1:-1;88086:3:0;;;;:::i;:::-;;;;88056:93;;;-1:-1:-1;88186:31:0;;-1:-1:-1;;;88186:31:0;;88205:4;88186:31;;;7747:51:1;7814:18;;;7807:34;;;88159:16:0;;88186:5;-1:-1:-1;;;;;88186:10:0;;;;7720:18:1;;88186:31:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;88228:36:0;-1:-1:-1;;;;;88228:5:0;:17;88254:2;88259:4;88228:17;:36::i;:::-;88280:9;88275:338;88299:4;88295:1;:8;88275:338;;;88336:2;-1:-1:-1;;;;;88336:13:0;;88350:6;:20;;;88371:1;88350:23;;;;;;;;:::i;:::-;;;;;;;85362:7;88336:44;;;;;;;;;;;;;;;6770:25:1;;;6826:2;6811:18;;6804:34;6758:2;6743:18;;6596:248;88336:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;88395:26;;-1:-1:-1;;;88395:26:0;;;;;925:25:1;;;88325:55:0;;-1:-1:-1;88395:2:0;-1:-1:-1;;;;;88395:16:0;;;;898:18:1;;88395:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88436:2;-1:-1:-1;;;;;88436:19:0;;88464:4;88471:6;:20;;;88492:1;88471:23;;;;;;;;:::i;:::-;;;;;;;;;;;88436:69;;-1:-1:-1;;;;;;88436:69:0;;;;;;;-1:-1:-1;;;;;8524:15:1;;;88436:69:0;;;8506:34:1;8576:15;;8556:18;;;8549:43;8608:18;;;8601:34;;;8441:18;;88436:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88542:6;:20;;;88563:1;88542:23;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;88525:76:0;;88567:6;:20;;;88588:1;88567:23;;;;;;;;:::i;:::-;;;;;;;88592:8;88525:76;;;;;;6770:25:1;;;6826:2;6811:18;;6804:34;6758:2;6743:18;;6596:248;88525:76:0;;;;;;;;88305:3;;;;:::i;:::-;;;;88275:338;;;-1:-1:-1;88623:33:0;-1:-1:-1;;;;;88623:5:0;:17;88649:2;88654:1;88623:17;:33::i;:::-;87309:1355;;;87251:1413;:::o;89385:323::-;89448:15;89476:16;89495:2;-1:-1:-1;;;;;89495:16:0;;89527:1;89512:12;;:16;;;;:::i;:::-;89495:34;;;;;;;;;;;;;925:25:1;;913:2;898:18;;779:177;89495:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;89476:53;;89540:19;89562:5;-1:-1:-1;;;;;89562:17:0;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;89540:41;-1:-1:-1;89699:1:0;89540:41;89658:22;89672:8;89540:41;89658:22;:::i;:::-;89642:11;89615:22;89629:8;89642:11;89615:22;:::i;:::-;89604:34;;:7;:34;:::i;:::-;89603:50;;;;:::i;:::-;89602:79;;;;:::i;:::-;89601:95;;;;:::i;:::-;:99;;;;:::i;:::-;89594:106;89385:323;-1:-1:-1;;;;89385:323:0:o;81186:177::-;81296:58;;-1:-1:-1;;;;;7765:32:1;;81296:58:0;;;7747:51:1;7814:18;;;7807:34;;;81269:86:0;;81289:5;;-1:-1:-1;;;81319:23:0;7720:18:1;;81296:58:0;;;;-1:-1:-1;;81296:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;81296:58:0;-1:-1:-1;;;;;;81296:58:0;;;;;;;;;;81269:19;:86::i;:::-;81186:177;;;:::o;81845:582::-;82175:10;;;82174:62;;-1:-1:-1;82191:39:0;;-1:-1:-1;;;82191:39:0;;82215:4;82191:39;;;8858:34:1;-1:-1:-1;;;;;8928:15:1;;;8908:18;;;8901:43;82191:15:0;;;;;8793:18:1;;82191:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;82174:62;82152:166;;;;-1:-1:-1;;;82152:166:0;;9157:2:1;82152:166:0;;;9139:21:1;9196:2;9176:18;;;9169:30;9235:34;9215:18;;;9208:62;-1:-1:-1;;;9286:18:1;;;9279:52;9348:19;;82152:166:0;;;;;;;;;82356:62;;-1:-1:-1;;;;;7765:32:1;;82356:62:0;;;7747:51:1;7814:18;;;7807:34;;;82329:90:0;;82349:5;;-1:-1:-1;;;82379:22:0;7720:18:1;;82356:62:0;7573:274:1;84074:716:0;84498:23;84524:69;84552:4;84524:69;;;;;;;;;;;;;;;;;84532:5;-1:-1:-1;;;;;84524:27:0;;;:69;;;;;:::i;:::-;84608:17;;84498:95;;-1:-1:-1;84608:21:0;84604:179;;84705:10;84694:30;;;;;;;;;;;;:::i;:::-;84686:85;;;;-1:-1:-1;;;84686:85:0;;9580:2:1;84686:85:0;;;9562:21:1;9619:2;9599:18;;;9592:30;9658:34;9638:18;;;9631:62;-1:-1:-1;;;9709:18:1;;;9702:40;9759:19;;84686:85:0;9378:406:1;75256:229:0;75393:12;75425:52;75447:6;75455:4;75461:1;75464:12;75393;76630;76644:23;76671:6;-1:-1:-1;;;;;76671:11:0;76690:5;76697:4;76671:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76629:73;;;;76720:69;76747:6;76755:7;76764:10;76776:12;76720:26;:69::i;:::-;76713:76;76342:455;-1:-1:-1;;;;;;;76342:455:0:o;78915:644::-;79100:12;79129:7;79125:427;;;79157:10;:17;79178:1;79157:22;79153:290;;-1:-1:-1;;;;;72795:19:0;;;79367:60;;;;-1:-1:-1;;;79367:60:0;;10945:2:1;79367:60:0;;;10927:21:1;10984:2;10964:18;;;10957:30;11023:31;11003:18;;;10996:59;11072:18;;79367:60:0;10743:353:1;79367:60:0;-1:-1:-1;79464:10:0;79457:17;;79125:427;79507:33;79515:10;79527:12;80262:17;;:21;80258:388;;80494:10;80488:17;80551:15;80538:10;80534:2;80530:19;80523:44;80258:388;80621:12;80614:20;;-1:-1:-1;;;80614:20:0;;;;;;;;:::i;14:180:1:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:1;;14:180;-1:-1:-1;14:180:1:o;391:131::-;-1:-1:-1;;;;;466:31:1;;456:42;;446:70;;512:1;509;502:12;446:70;391:131;:::o;527:247::-;586:6;639:2;627:9;618:7;614:23;610:32;607:52;;;655:1;652;645:12;607:52;694:9;681:23;713:31;738:5;713:31;:::i;:::-;763:5;527:247;-1:-1:-1;;;527:247:1:o;2080:127::-;2141:10;2136:3;2132:20;2129:1;2122:31;2172:4;2169:1;2162:15;2196:4;2193:1;2186:15;2212:253;2284:2;2278:9;2326:4;2314:17;;2361:18;2346:34;;2382:22;;;2343:62;2340:88;;;2408:18;;:::i;:::-;2444:2;2437:22;2212:253;:::o;2470:275::-;2541:2;2535:9;2606:2;2587:13;;-1:-1:-1;;2583:27:1;2571:40;;2641:18;2626:34;;2662:22;;;2623:62;2620:88;;;2688:18;;:::i;:::-;2724:2;2717:22;2470:275;;-1:-1:-1;2470:275:1:o;2750:183::-;2810:4;2843:18;2835:6;2832:30;2829:56;;;2865:18;;:::i;:::-;-1:-1:-1;2910:1:1;2906:14;2922:4;2902:25;;2750:183::o;2938:737::-;2992:5;3045:3;3038:4;3030:6;3026:17;3022:27;3012:55;;3063:1;3060;3053:12;3012:55;3099:6;3086:20;3125:4;3149:60;3165:43;3205:2;3165:43;:::i;:::-;3149:60;:::i;:::-;3243:15;;;3329:1;3325:10;;;;3313:23;;3309:32;;;3274:12;;;;3353:15;;;3350:35;;;3381:1;3378;3371:12;3350:35;3417:2;3409:6;3405:15;3429:217;3445:6;3440:3;3437:15;3429:217;;;3525:3;3512:17;3542:31;3567:5;3542:31;:::i;:::-;3586:18;;3624:12;;;;3462;;3429:217;;;-1:-1:-1;3664:5:1;2938:737;-1:-1:-1;;;;;;2938:737:1:o;3680:662::-;3734:5;3787:3;3780:4;3772:6;3768:17;3764:27;3754:55;;3805:1;3802;3795:12;3754:55;3841:6;3828:20;3867:4;3891:60;3907:43;3947:2;3907:43;:::i;3891:60::-;3985:15;;;4071:1;4067:10;;;;4055:23;;4051:32;;;4016:12;;;;4095:15;;;4092:35;;;4123:1;4120;4113:12;4092:35;4159:2;4151:6;4147:15;4171:142;4187:6;4182:3;4179:15;4171:142;;;4253:17;;4241:30;;4291:12;;;;4204;;4171:142;;4347:1178;4437:6;4490:2;4478:9;4469:7;4465:23;4461:32;4458:52;;;4506:1;4503;4496:12;4458:52;4546:9;4533:23;4575:18;4616:2;4608:6;4605:14;4602:34;;;4632:1;4629;4622:12;4602:34;4655:22;;;;4711:4;4693:16;;;4689:27;4686:47;;;4729:1;4726;4719:12;4686:47;4755:22;;:::i;:::-;4815:2;4802:16;4843:2;4833:8;4830:16;4827:36;;;4859:1;4856;4849:12;4827:36;4886:56;4934:7;4923:8;4919:2;4915:17;4886:56;:::i;:::-;4879:5;4872:71;;4989:2;4985;4981:11;4968:25;5018:2;5008:8;5005:16;5002:36;;;5034:1;5031;5024:12;5002:36;5070:56;5118:7;5107:8;5103:2;5099:17;5070:56;:::i;:::-;5065:2;5058:5;5054:14;5047:80;;5173:2;5169;5165:11;5152:25;5202:2;5192:8;5189:16;5186:36;;;5218:1;5215;5208:12;5186:36;5254:56;5302:7;5291:8;5287:2;5283:17;5254:56;:::i;:::-;5249:2;5242:5;5238:14;5231:80;;5357:2;5353;5349:11;5336:25;5386:2;5376:8;5373:16;5370:36;;;5402:1;5399;5392:12;5370:36;5438:56;5486:7;5475:8;5471:2;5467:17;5438:56;:::i;:::-;5433:2;5422:14;;5415:80;-1:-1:-1;5426:5:1;4347:1178;-1:-1:-1;;;;;4347:1178:1:o;5530:251::-;5600:6;5653:2;5641:9;5632:7;5628:23;5624:32;5621:52;;;5669:1;5666;5659:12;5621:52;5701:9;5695:16;5720:31;5745:5;5720:31;:::i;5786:278::-;5874:6;5927:2;5915:9;5906:7;5902:23;5898:32;5895:52;;;5943:1;5940;5933:12;5895:52;5975:9;5969:16;6014:1;6007:5;6004:12;5994:40;;6030:1;6027;6020:12;6069:127;6130:10;6125:3;6121:20;6118:1;6111:31;6161:4;6158:1;6151:15;6185:4;6182:1;6175:15;6201:127;6262:10;6257:3;6253:20;6250:1;6243:31;6293:4;6290:1;6283:15;6317:4;6314:1;6307:15;6333:125;6398:9;;;6419:10;;;6416:36;;;6432:18;;:::i;:::-;6333:125;;;;:::o;6463:128::-;6530:9;;;6551:11;;;6548:37;;;6565:18;;:::i;6849:135::-;6888:3;6909:17;;;6906:43;;6929:18;;:::i;:::-;-1:-1:-1;6976:1:1;6965:13;;6849:135::o;6989:217::-;7029:1;7055;7045:132;;7099:10;7094:3;7090:20;7087:1;7080:31;7134:4;7131:1;7124:15;7162:4;7159:1;7152:15;7045:132;-1:-1:-1;7191:9:1;;6989:217::o;7211:168::-;7284:9;;;7315;;7332:15;;;7326:22;;7312:37;7302:71;;7353:18;;:::i;7384:184::-;7454:6;7507:2;7495:9;7486:7;7482:23;7478:32;7475:52;;;7523:1;7520;7513:12;7475:52;-1:-1:-1;7546:16:1;;7384:184;-1:-1:-1;7384:184:1:o;7852:277::-;7919:6;7972:2;7960:9;7951:7;7947:23;7943:32;7940:52;;;7988:1;7985;7978:12;7940:52;8020:9;8014:16;8073:5;8066:13;8059:21;8052:5;8049:32;8039:60;;8095:1;8092;8085:12;8134:127;8195:10;8190:3;8186:20;8183:1;8176:31;8226:4;8223:1;8216:15;8250:4;8247:1;8240:15;10196:250;10281:1;10291:113;10305:6;10302:1;10299:13;10291:113;;;10381:11;;;10375:18;10362:11;;;10355:39;10327:2;10320:10;10291:113;;;-1:-1:-1;;10438:1:1;10420:16;;10413:27;10196:250::o;10451:287::-;10580:3;10618:6;10612:13;10634:66;10693:6;10688:3;10681:4;10673:6;10669:17;10634:66;:::i;:::-;10716:16;;;;;10451:287;-1:-1:-1;;10451:287:1:o;11101:396::-;11250:2;11239:9;11232:21;11213:4;11282:6;11276:13;11325:6;11320:2;11309:9;11305:18;11298:34;11341:79;11413:6;11408:2;11397:9;11393:18;11388:2;11380:6;11376:15;11341:79;:::i;:::-;11481:2;11460:15;-1:-1:-1;;11456:29:1;11441:45;;;;11488:2;11437:54;;11101:396;-1:-1:-1;;11101:396:1:o
Swarm Source
ipfs://8618bb4aa27703361745a9acaa0973cb2671f65e6c79b91e237c5e66ccd9694f
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 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.