Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
BalanceLogicLibrary
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity)
/** *Submitted for verification at basescan.org on 2023-08-28 */ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; // 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 (AERO) 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); } /// @title SafeCast Library /// @author velodrome.finance /// @notice Safely convert unsigned and signed integers without overflow / underflow library SafeCastLibrary { error SafeCastOverflow(); error SafeCastUnderflow(); /// @dev Safely convert uint256 to int128 function toInt128(uint256 value) internal pure returns (int128) { if (value > uint128(type(int128).max)) revert SafeCastOverflow(); return int128(uint128(value)); } /// @dev Safely convert int128 to uint256 function toUint256(int128 value) internal pure returns (uint256) { if (value < 0) revert SafeCastUnderflow(); return uint256(int256(value)); } } library BalanceLogicLibrary { using SafeCastLibrary for uint256; using SafeCastLibrary for int128; uint256 internal constant WEEK = 1 weeks; /// @notice Binary search to get the user point index for a token id at or prior to a given timestamp /// @dev If a user point does not exist prior to the timestamp, this will return 0. /// @param _userPointEpoch State of all user point epochs /// @param _userPointHistory State of all user point history /// @param _tokenId . /// @param _timestamp . /// @return User point index function getPastUserPointIndex( mapping(uint256 => uint256) storage _userPointEpoch, mapping(uint256 => IVotingEscrow.UserPoint[1000000000]) storage _userPointHistory, uint256 _tokenId, uint256 _timestamp ) internal view returns (uint256) { uint256 _userEpoch = _userPointEpoch[_tokenId]; if (_userEpoch == 0) return 0; // First check most recent balance if (_userPointHistory[_tokenId][_userEpoch].ts <= _timestamp) return (_userEpoch); // Next check implicit zero balance if (_userPointHistory[_tokenId][1].ts > _timestamp) return 0; uint256 lower = 0; uint256 upper = _userEpoch; while (upper > lower) { uint256 center = upper - (upper - lower) / 2; // ceil, avoiding overflow IVotingEscrow.UserPoint storage userPoint = _userPointHistory[_tokenId][center]; if (userPoint.ts == _timestamp) { return center; } else if (userPoint.ts < _timestamp) { lower = center; } else { upper = center - 1; } } return lower; } /// @notice Binary search to get the global point index at or prior to a given timestamp /// @dev If a checkpoint does not exist prior to the timestamp, this will return 0. /// @param _epoch Current global point epoch /// @param _pointHistory State of all global point history /// @param _timestamp . /// @return Global point index function getPastGlobalPointIndex( uint256 _epoch, mapping(uint256 => IVotingEscrow.GlobalPoint) storage _pointHistory, uint256 _timestamp ) internal view returns (uint256) { if (_epoch == 0) return 0; // First check most recent balance if (_pointHistory[_epoch].ts <= _timestamp) return (_epoch); // Next check implicit zero balance if (_pointHistory[1].ts > _timestamp) return 0; uint256 lower = 0; uint256 upper = _epoch; while (upper > lower) { uint256 center = upper - (upper - lower) / 2; // ceil, avoiding overflow IVotingEscrow.GlobalPoint storage globalPoint = _pointHistory[center]; if (globalPoint.ts == _timestamp) { return center; } else if (globalPoint.ts < _timestamp) { lower = center; } else { upper = center - 1; } } return lower; } /// @notice Get the current voting power for `_tokenId` /// @dev Adheres to the ERC20 `balanceOf` interface for Aragon compatibility /// Fetches last user point prior to a certain timestamp, then walks forward to timestamp. /// @param _userPointEpoch State of all user point epochs /// @param _userPointHistory State of all user point history /// @param _tokenId NFT for lock /// @param _t Epoch time to return voting power at /// @return User voting power function balanceOfNFTAt( mapping(uint256 => uint256) storage _userPointEpoch, mapping(uint256 => IVotingEscrow.UserPoint[1000000000]) storage _userPointHistory, uint256 _tokenId, uint256 _t ) external view returns (uint256) { uint256 _epoch = getPastUserPointIndex(_userPointEpoch, _userPointHistory, _tokenId, _t); // epoch 0 is an empty point if (_epoch == 0) return 0; IVotingEscrow.UserPoint memory lastPoint = _userPointHistory[_tokenId][_epoch]; if (lastPoint.permanent != 0) { return lastPoint.permanent; } else { lastPoint.bias -= lastPoint.slope * (_t - lastPoint.ts).toInt128(); if (lastPoint.bias < 0) { lastPoint.bias = 0; } return lastPoint.bias.toUint256(); } } /// @notice Calculate total voting power at some point in the past /// @param _slopeChanges State of all slopeChanges /// @param _pointHistory State of all global point history /// @param _epoch The epoch to start search from /// @param _t Time to calculate the total voting power at /// @return Total voting power at that time function supplyAt( mapping(uint256 => int128) storage _slopeChanges, mapping(uint256 => IVotingEscrow.GlobalPoint) storage _pointHistory, uint256 _epoch, uint256 _t ) external view returns (uint256) { uint256 epoch_ = getPastGlobalPointIndex(_epoch, _pointHistory, _t); // epoch 0 is an empty point if (epoch_ == 0) return 0; IVotingEscrow.GlobalPoint memory _point = _pointHistory[epoch_]; int128 bias = _point.bias; int128 slope = _point.slope; uint256 ts = _point.ts; uint256 t_i = (ts / WEEK) * WEEK; for (uint256 i = 0; i < 255; ++i) { t_i += WEEK; int128 dSlope = 0; if (t_i > _t) { t_i = _t; } else { dSlope = _slopeChanges[t_i]; } bias -= slope * (t_i - ts).toInt128(); if (t_i == _t) { break; } slope += dSlope; ts = t_i; } if (bias < 0) { bias = 0; } return bias.toUint256() + _point.permanentLockBalance; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"SafeCastOverflow","type":"error"},{"inputs":[],"name":"SafeCastUnderflow","type":"error"}]
Contract Creation Code
6106da61003a600b82828239805160001a60731461002d57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600436106100405760003560e01c80637259b019146100455780637b29b3d11461006a575b600080fd5b610058610053366004610547565b61007d565b60405190815260200160405180910390f35b610058610078366004610547565b6101e4565b60008061008b8486856102f0565b90508060000361009f5760009150506101dc565b600081815260208681526040808320815160a0810183528154600f81810b808452600160801b909204900b9482018590526001830154938201849052600283015460608301526003909201546080820152939092919062093a80610103818461058f565b61010d91906105b1565b905060005b60ff8110156101a65761012862093a80836105ce565b915060008983111561013c57899250610150565b50600082815260208d90526040902054600f0b5b61016261015d85856105e1565b6103cd565b61016c90866105f4565b610176908761061b565b955089830361018557506101a6565b61018f8186610648565b9450829350508061019f90610675565b9050610112565b50600084600f0b12156101b857600093505b84608001516101c985600f0b6103fb565b6101d391906105ce565b96505050505050505b949350505050565b6000806101f386868686610427565b9050806000036102075760009150506101dc565b600084815260208690526040812082633b9aca0081106102295761022961068e565b6040805160a081018252600492909202929092018054600f81810b8452600160801b909104900b602083015260018101549282019290925260028201546060820152600390910154608082018190529091501561028d576080015191506101dc9050565b6102a081604001518561015d91906105e1565b81602001516102af91906105f4565b815182906102be90839061061b565b600f90810b90915282516000910b121590506102d957600081525b80516102e790600f0b6103fb565b925050506101dc565b600083600003610302575060006103c6565b60008481526020849052604090206001015482106103215750826103c6565b600160008181526020859052604090200154821015610342575060006103c6565b6000845b818111156103c2576000600261035c84846105e1565b610366919061058f565b61037090836105e1565b6000818152602088905260409020600181015491925090869003610399575092506103c6915050565b85816001015410156103ad578193506103bb565b6103b86001836105e1565b92505b5050610346565b5090505b9392505050565b600060016001607f1b038211156103f7576040516393dafdf160e01b815260040160405180910390fd5b5090565b60008082600f0b12156104205760405162406f5d60e21b815260040160405180910390fd5b50600f0b90565b6000828152602085905260408120548082036104475760009150506101dc565b6000848152602086905260409020839082633b9aca00811061046b5761046b61068e565b60040201600101541161047f5790506101dc565b6000848152602086905260409020600501548310156104a25760009150506101dc565b6000815b8181111561053c57600060026104bc84846105e1565b6104c6919061058f565b6104d090836105e1565b600088815260208a9052604081209192509082633b9aca0081106104f6576104f661068e565b60040201905086816001015403610513575093506101dc92505050565b868160010154101561052757819350610535565b6105326001836105e1565b92505b50506104a6565b509695505050505050565b6000806000806080858703121561055d57600080fd5b5050823594602084013594506040840135936060013592509050565b634e487b7160e01b600052601160045260246000fd5b6000826105ac57634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176105c8576105c8610579565b92915050565b808201808211156105c8576105c8610579565b818103818111156105c8576105c8610579565b600082600f0b82600f0b0280600f0b915080821461061457610614610579565b5092915050565b600f82810b9082900b0360016001607f1b0319811260016001607f1b03821317156105c8576105c8610579565b600f81810b9083900b0160016001607f1b03811360016001607f1b0319821217156105c8576105c8610579565b60006001820161068757610687610579565b5060010190565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220d421286315f2b6598afbd59f7923992ee2750d3e071f24c6ceea15f961a13ebb64736f6c63430008130033
Deployed Bytecode
0x738e634181dafb102213fad46b71ba1a4b6153b64830146080604052600436106100405760003560e01c80637259b019146100455780637b29b3d11461006a575b600080fd5b610058610053366004610547565b61007d565b60405190815260200160405180910390f35b610058610078366004610547565b6101e4565b60008061008b8486856102f0565b90508060000361009f5760009150506101dc565b600081815260208681526040808320815160a0810183528154600f81810b808452600160801b909204900b9482018590526001830154938201849052600283015460608301526003909201546080820152939092919062093a80610103818461058f565b61010d91906105b1565b905060005b60ff8110156101a65761012862093a80836105ce565b915060008983111561013c57899250610150565b50600082815260208d90526040902054600f0b5b61016261015d85856105e1565b6103cd565b61016c90866105f4565b610176908761061b565b955089830361018557506101a6565b61018f8186610648565b9450829350508061019f90610675565b9050610112565b50600084600f0b12156101b857600093505b84608001516101c985600f0b6103fb565b6101d391906105ce565b96505050505050505b949350505050565b6000806101f386868686610427565b9050806000036102075760009150506101dc565b600084815260208690526040812082633b9aca0081106102295761022961068e565b6040805160a081018252600492909202929092018054600f81810b8452600160801b909104900b602083015260018101549282019290925260028201546060820152600390910154608082018190529091501561028d576080015191506101dc9050565b6102a081604001518561015d91906105e1565b81602001516102af91906105f4565b815182906102be90839061061b565b600f90810b90915282516000910b121590506102d957600081525b80516102e790600f0b6103fb565b925050506101dc565b600083600003610302575060006103c6565b60008481526020849052604090206001015482106103215750826103c6565b600160008181526020859052604090200154821015610342575060006103c6565b6000845b818111156103c2576000600261035c84846105e1565b610366919061058f565b61037090836105e1565b6000818152602088905260409020600181015491925090869003610399575092506103c6915050565b85816001015410156103ad578193506103bb565b6103b86001836105e1565b92505b5050610346565b5090505b9392505050565b600060016001607f1b038211156103f7576040516393dafdf160e01b815260040160405180910390fd5b5090565b60008082600f0b12156104205760405162406f5d60e21b815260040160405180910390fd5b50600f0b90565b6000828152602085905260408120548082036104475760009150506101dc565b6000848152602086905260409020839082633b9aca00811061046b5761046b61068e565b60040201600101541161047f5790506101dc565b6000848152602086905260409020600501548310156104a25760009150506101dc565b6000815b8181111561053c57600060026104bc84846105e1565b6104c6919061058f565b6104d090836105e1565b600088815260208a9052604081209192509082633b9aca0081106104f6576104f661068e565b60040201905086816001015403610513575093506101dc92505050565b868160010154101561052757819350610535565b6105326001836105e1565b92505b50506104a6565b509695505050505050565b6000806000806080858703121561055d57600080fd5b5050823594602084013594506040840135936060013592509050565b634e487b7160e01b600052601160045260246000fd5b6000826105ac57634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176105c8576105c8610579565b92915050565b808201808211156105c8576105c8610579565b818103818111156105c8576105c8610579565b600082600f0b82600f0b0280600f0b915080821461061457610614610579565b5092915050565b600f82810b9082900b0360016001607f1b0319811260016001607f1b03821317156105c8576105c8610579565b600f81810b9083900b0160016001607f1b03811360016001607f1b0319821217156105c8576105c8610579565b60006001820161068757610687610579565b5060010190565b634e487b7160e01b600052603260045260246000fdfea2646970667358221220d421286315f2b6598afbd59f7923992ee2750d3e071f24c6ceea15f961a13ebb64736f6c63430008130033
Deployed Bytecode Sourcemap
32335:6068:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37224:1176;;;;;;:::i;:::-;;:::i;:::-;;;632:25:1;;;620:2;605:18;37224:1176:0;;;;;;;35992:866;;;;;;:::i;:::-;;:::i;37224:1176::-;37455:7;37475:14;37492:50;37516:6;37524:13;37539:2;37492:23;:50::i;:::-;37475:67;;37595:6;37605:1;37595:11;37591:25;;37615:1;37608:8;;;;;37591:25;37627:39;37669:21;;;;;;;;;;;37627:63;;;;;;;;;;;;;;;;-1:-1:-1;;;37627:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32484:7;37823:9;32484:7;37627:63;37823:9;:::i;:::-;37822:18;;;;:::i;:::-;37808:32;;37856:9;37851:417;37875:3;37871:1;:7;37851:417;;;37900:11;32484:7;37900:11;;:::i;:::-;;;37926:13;37968:2;37962:3;:8;37958:125;;;37997:2;37991:8;;37958:125;;;-1:-1:-1;38049:18:0;;;;;;;;;;;;;;37958:125;38113:21;38114:8;38120:2;38114:3;:8;:::i;:::-;38113:19;:21::i;:::-;38105:29;;:5;:29;:::i;:::-;38097:37;;;;:::i;:::-;;;38160:2;38153:3;:9;38149:55;;38183:5;;;38149:55;38218:15;38227:6;38218:15;;:::i;:::-;;;38253:3;38248:8;;37885:383;37880:3;;;;:::i;:::-;;;37851:417;;;;38291:1;38284:4;:8;;;38280:49;;;38316:1;38309:8;;38280:49;38365:6;:27;;;38346:16;:4;:14;;;:16::i;:::-;:46;;;;:::i;:::-;38339:53;;;;;;;;37224:1176;;;;;;;:::o;35992:866::-;36248:7;36268:14;36285:71;36307:15;36324:17;36343:8;36353:2;36285:21;:71::i;:::-;36268:88;;36409:6;36419:1;36409:11;36405:25;;36429:1;36422:8;;;;;36405:25;36441:40;36484:27;;;;;;;;;;36512:6;36484:35;;;;;;;:::i;:::-;36441:78;;;;;;;;36484:35;;;;;;;;;36441:78;;;;;;;;-1:-1:-1;;;36441:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36534:24:0;36530:321;;36582:19;;;;-1:-1:-1;36575:26:0;;-1:-1:-1;36575:26:0;36530:321;36670:30;36676:9;:12;;;36671:2;:17;;;;:::i;36670:30::-;36652:9;:15;;;:48;;;;:::i;:::-;36634:66;;:9;;:66;;;;;:::i;:::-;;;;;;;;36719:14;;36736:1;36719:18;;;36715:77;;-1:-1:-1;36715:77:0;;36775:1;36758:18;;36715:77;36813:14;;:26;;:24;;;:26::i;:::-;36806:33;;;;;;34475:1007;34670:7;34694:6;34704:1;34694:11;34690:25;;-1:-1:-1;34714:1:0;34707:8;;34690:25;34774:21;;;;;;;;;;;:24;;;:38;-1:-1:-1;34770:59:0;;-1:-1:-1;34822:6:0;34814:15;;34770:59;34903:1;34889:16;;;;;;;;;;;:19;;:32;-1:-1:-1;34885:46:0;;;-1:-1:-1;34930:1:0;34923:8;;34885:46;34944:13;34988:6;35005:447;35020:5;35012;:13;35005:447;;;35042:14;35085:1;35068:13;35076:5;35068;:13;:::i;:::-;35067:19;;;;:::i;:::-;35059:27;;:5;:27;:::i;:::-;35128:45;35176:21;;;;;;;;;;35216:14;;;;35042:44;;-1:-1:-1;35176:21:0;35216:28;;;35212:229;;-1:-1:-1;35272:6:0;-1:-1:-1;35265:13:0;;-1:-1:-1;;35265:13:0;35212:229;35321:10;35304:11;:14;;;:27;35300:141;;;35360:6;35352:14;;35300:141;;;35415:10;35424:1;35415:6;:10;:::i;:::-;35407:18;;35300:141;35027:425;;35005:447;;;-1:-1:-1;35469:5:0;-1:-1:-1;34475:1007:0;;;;;;:::o;31921:187::-;31977:6;-1:-1:-1;;;;;32000:33:0;;31996:64;;;32042:18;;-1:-1:-1;;;32042:18:0;;;;;;;;;;;31996:64;-1:-1:-1;32093:5:0;31921:187::o;32163:165::-;32219:7;32251:1;32243:5;:9;;;32239:41;;;32261:19;;-1:-1:-1;;;32261:19:0;;;;;;;;;;;32239:41;-1:-1:-1;32306:13:0;;;32163:165::o;32915:1190::-;33186:7;33227:25;;;;;;;;;;;33267:15;;;33263:29;;33291:1;33284:8;;;;;33263:29;33351:27;;;;;;;;;;;33397:10;;33379;33351:39;;;;;;;:::i;:::-;;;;:42;;;:56;33347:81;;33417:10;-1:-1:-1;33409:19:0;;33347:81;33488:27;;;;;;;;;;;:33;;;:46;-1:-1:-1;33484:60:0;;;33543:1;33536:8;;;;;33484:60;33557:13;33601:10;33622:453;33637:5;33629;:13;33622:453;;;33659:14;33702:1;33685:13;33693:5;33685;:13;:::i;:::-;33684:19;;;;:::i;:::-;33676:27;;:5;:27;:::i;:::-;33745:41;33789:27;;;;;;;;;;33659:44;;-1:-1:-1;33745:41:0;33659:44;33789:35;;;;;;;:::i;:::-;;;;33745:79;;33859:10;33843:9;:12;;;:26;33839:225;;-1:-1:-1;33897:6:0;-1:-1:-1;33890:13:0;;-1:-1:-1;;;33890:13:0;33839:225;33944:10;33929:9;:12;;;:25;33925:139;;;33983:6;33975:14;;33925:139;;;34038:10;34047:1;34038:6;:10;:::i;:::-;34030:18;;33925:139;33644:431;;33622:453;;;-1:-1:-1;34092:5:0;32915:1190;-1:-1:-1;;;;;;32915:1190:0:o;14:459:1:-;174:6;182;190;198;251:3;239:9;230:7;226:23;222:33;219:53;;;268:1;265;258:12;219:53;-1:-1:-1;;291:23:1;;;361:2;346:18;;333:32;;-1:-1:-1;412:2:1;397:18;;384:32;;463:2;448:18;435:32;;-1:-1:-1;14:459:1;-1:-1:-1;14:459:1:o;1160:127::-;1221:10;1216:3;1212:20;1209:1;1202:31;1252:4;1249:1;1242:15;1276:4;1273:1;1266:15;1292:217;1332:1;1358;1348:132;;1402:10;1397:3;1393:20;1390:1;1383:31;1437:4;1434:1;1427:15;1465:4;1462:1;1455:15;1348:132;-1:-1:-1;1494:9:1;;1292:217::o;1514:168::-;1587:9;;;1618;;1635:15;;;1629:22;;1615:37;1605:71;;1656:18;;:::i;:::-;1514:168;;;;:::o;1687:125::-;1752:9;;;1773:10;;;1770:36;;;1786:18;;:::i;1817:128::-;1884:9;;;1905:11;;;1902:37;;;1919:18;;:::i;1950:241::-;1989:7;2068:1;2064:2;2053:17;2049:1;2045:2;2034:17;2030:41;2106:11;2102:2;2091:27;2080:38;;2149:11;2140:7;2137:24;2127:58;;2165:18;;:::i;:::-;2127:58;1950:241;;;;:::o;2196:249::-;2296:2;2285:17;;;2266;;;;2262:41;-1:-1:-1;;;;;;2318:50:1;;-1:-1:-1;;;;;2370:45:1;;2315:101;2312:127;;;2419:18;;:::i;2450:245::-;2548:2;2518:17;;;2537;;;;2514:41;-1:-1:-1;;;;;2570:44:1;;-1:-1:-1;;;;;;2616:49:1;;2567:99;2564:125;;;2669:18;;:::i;2700:135::-;2739:3;2760:17;;;2757:43;;2780:18;;:::i;:::-;-1:-1:-1;2827:1:1;2816:13;;2700:135::o;2840:127::-;2901:10;2896:3;2892:20;2889:1;2882:31;2932:4;2929:1;2922:15;2956:4;2953:1;2946:15
Swarm Source
ipfs://d421286315f2b6598afbd59f7923992ee2750d3e071f24c6ceea15f961a13ebb
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
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.