Amplify
Launch AppGithub
  • Introduction
    • Amplify Overview
    • Concepts
      • Networks
      • DApps
      • Network Investors
      • LPs & Traders
    • Getting Started
      • Networks
      • DApps
      • Investors
  • Developers
    • Smart Contracts
      • VoteEscrowDistribution
      • Voter
      • VoteEscrow
      • Factories
        • Factory
        • IncentivesManagerFactory
        • VoterFactories
        • VoteEscrowFactory
        • GaugeFactory
          • BaseGaugeFactory
        • BribeFactory
          • BaseBribeFactory
      • Bribe
      • Gauge
      • IncentivesManager
    • Deployments
      • Arbitrum Sepolia
  • Resources
    • Brand Assets
    • Bug Bounty
    • Security & Audits
    • Whitelisting
  • Terms of Service
    • Privacy Policy
    • Terms of Use
Powered by GitBook
On this page
  • Description:
  • Constructor
  • supportsInterface
  • get_last_user_slope
  • user_point_history__ts
  • locked__end
  • balanceOf (ERC721)
  • ownerOf
  • getApproved
  • isApprovedForAll
  • tokenOfOwnerByIndex
  • isApprovedOrOwner
  • transferFrom
  • safeTransferFrom (without data)
  • safeTransferFrom (with data)
  • approve
  • setApprovalForAll
  • setIncentivesManager
  • setVoter
  • voting
  • abstain
  • attach
  • detach
  • merge
  • block_number
  • checkpoint
  • deposit_for
  • create_lock_for
  • create_lock
  • increase_amount
  • increase_unlock_time
  • withdraw
  • Input Parameters:
  • calculateExcessLockedTokens
  • tokenURI
  • balanceOfNFT
  • balanceOfNFTAt
  • balanceOfAtNFT
  • totalSupplyAtT
  • totalSupply
  • totalSupplyAt
  1. Developers
  2. Smart Contracts

VoteEscrow

Description:

This contract implements the core logic for a Voting Escrow system, based on the original Curve Finance design. Users lock an underlying ERC20 token (token) for a specified duration (up to 4 years) to receive a non-fungible token (NFT, veNFT) representing their lock. The voting power associated with the NFT is time-weighted, decreasing linearly towards zero as the lock expiration approaches. This contract manages the creation, modification (increasing amount or duration), merging, and withdrawal of locks. It calculates and provides historical voting power for individual NFTs and the total supply. It conforms to ERC721 and ERC165 standards and includes metadata generation for the NFTs. It interacts with a Voter contract to track voting status and attachments, an optional IIncentivesManager for potential features like early unlock conditions, and a IUserRegistry to record minting events.


Constructor

constructor(address token_addr, address user_registry)

Description:

Initializes the VoteEscrow contract upon deployment. Sets the underlying ERC20 token address (token_addr), the address of the UserRegistry contract (user_registry), and sets the deployer (msg.sender) as the initial voter address (which typically controls voting/attachment status updates). It also initializes the first global checkpoint (epoch 0) and sets up support for ERC165/ERC721 interfaces.

Input Parameters:

Name
Type
Description

token_addr

address

The address of the underlying ERC20 token to be locked.

user_registry

address

The address of the IUserRegistry contract for mint tracking.


supportsInterface

function supportsInterface(bytes4 _interfaceID) external view returns (bool)

Description:

Standard ERC165 function to check if the contract implements a specific interface ID. Returns true for ERC165 (0x01ffc9a7), ERC721 (0x80ac58cd), and ERC721Metadata (0x5b5e139f).

Input Parameters:

Name
Type
Description

_interfaceID

bytes4

The interface identifier to check for.

Return Value:

Type
Description

bool

true if the interface is supported, false otherwise.


get_last_user_slope

function get_last_user_slope(uint _tokenId) external view returns (int128)

Description:

Retrieves the most recently recorded rate of voting power decay (slope) for a specific veNFT (_tokenId). The slope represents how much voting power the lock loses per second.

Input Parameters:

Name
Type
Description

_tokenId

uint

The ID of the veNFT lock to query.

Return Value:

Type
Description

int128

The last recorded slope (rate of decay) for the specified NFT lock.


user_point_history__ts

function user_point_history__ts(uint _tokenId, uint _idx) external view returns (uint)

Description:

Retrieves the timestamp (ts) of a specific historical checkpoint (_idx) for a given user's veNFT lock (_tokenId).

Input Parameters:

Name
Type
Description

_tokenId

uint

The ID of the veNFT lock to query.

_idx

uint

The index of the user's checkpoint history.

Return Value:

Type
Description

uint

The Unix timestamp of the specified user checkpoint.


locked__end

function locked__end(uint _tokenId) external view returns (uint)

Description:

Retrieves the Unix timestamp when the lock for the specified veNFT (_tokenId) expires.

Input Parameters:

Name
Type
Description

_tokenId

uint

The ID of the veNFT lock to query.

Return Value:

Type
Description

uint

The timestamp when the lock expires.


balanceOf (ERC721)

function balanceOf(address _owner) external view returns (uint)

Description:

Standard ERC721 function. Returns the number of veNFTs owned by a specific address (_owner).

Input Parameters:

Name
Type
Description

_owner

address

The address to query the balance for.

Return Value:

Type
Description

uint

The number of veNFTs owned by _owner.


ownerOf

function ownerOf(uint _tokenId) public view returns (address)

Description:

Standard ERC721 function. Returns the owner address of the specified veNFT (_tokenId).

Input Parameters:

Name
Type
Description

_tokenId

uint

The ID of the veNFT to query.

Return Value:

Type
Description

address

The owner address of the _tokenId.


getApproved

function getApproved(uint _tokenId) external view returns (address)

Description:

Standard ERC721 function. Returns the address that is approved to manage the specified veNFT (_tokenId), or the zero address if none is set.

Input Parameters:

Name
Type
Description

_tokenId

uint

The ID of the veNFT to query approval for.

Return Value:

Type
Description

address

The approved address for the _tokenId.


isApprovedForAll

function isApprovedForAll(address _owner, address _operator) external view returns (bool)

Description:

Standard ERC721 function. Checks if an _operator address is approved to manage all veNFTs owned by _owner.

Input Parameters:

Name
Type
Description

_owner

address

The address of the NFT owner.

_operator

address

The address of the potential operator.

Return Value:

Type
Description

bool

true if _operator is approved for all of _owner's NFTs.


tokenOfOwnerByIndex

function tokenOfOwnerByIndex(address _owner, uint _tokenIndex) external view returns (uint)

Description:

Optional ERC721Enumerable function. Returns the token ID of the veNFT at a specific index (_tokenIndex) within the list of NFTs owned by _owner.

Input Parameters:

Name
Type
Description

_owner

address

The address of the NFT owner.

_tokenIndex

uint

The index of the token in the owner's list (0-based).

Return Value:

Type
Description

uint

The token ID at the specified index for the owner.


isApprovedOrOwner

function isApprovedOrOwner(address _spender, uint _tokenId) external view returns (bool)

Description:

Helper function to check if an address (_spender) is either the owner of, approved for, or an approved operator for the owner of a specific veNFT (_tokenId).

Input Parameters:

Name
Type
Description

_spender

address

The address to check permissions for.

_tokenId

uint

The ID of the veNFT.

Return Value:

Type
Description

bool

true if _spender has control permissions over the _tokenId.


transferFrom

function transferFrom(address _from, address _to, uint _tokenId) external

Description:

Standard ERC721 function. Transfers ownership of a veNFT (_tokenId) from _from to _to. Requires the caller (msg.sender) to be the owner, approved, or an operator. The NFT cannot be transferred if it is attached or marked as voted (attachments[_tokenId] != 0 || voted[_tokenId]).

Input Parameters:

Name
Type
Description

_from

address

The current owner's address.

_to

address

The recipient's address.

_tokenId

uint

The ID of the veNFT to transfer.

Events Emitted:

Transfer(address indexed from, address indexed to, uint indexed tokenId)


safeTransferFrom (without data)

function safeTransferFrom(address _from, address _to, uint _tokenId) external

Description:

Standard ERC721 safe transfer function. Transfers ownership of a veNFT (_tokenId) from _from to _to. Performs the same checks as transferFrom and additionally checks if _to is a contract; if so, it requires _to to implement onERC721Received. The NFT cannot be transferred if it is attached or marked as voted.

Input Parameters:

Name
Type
Description

_from

address

The current owner's address.

_to

address

The recipient's address.

_tokenId

uint

The ID of the veNFT to transfer.

Events Emitted:

Transfer(address indexed from, address indexed to, uint indexed tokenId)


safeTransferFrom (with data)

function safeTransferFrom(address _from, address _to, uint _tokenId, bytes memory _data) public

Description:

Standard ERC721 safe transfer function with additional data. Transfers ownership of a veNFT (_tokenId) from _from to _to, passing _data to the recipient if it is a contract implementing onERC721Received. Performs the same checks as the other transfer functions. The NFT cannot be transferred if it is attached or marked as voted.

Input Parameters:

Name
Type
Description

_from

address

The current owner's address.

_to

address

The recipient's address.

_tokenId

uint

The ID of the veNFT to transfer.

_data

bytes

Additional data to send to the recipient.

Events Emitted:

Transfer(address indexed from, address indexed to, uint indexed tokenId)


approve

function approve(address _approved, uint _tokenId) public

Description:

Standard ERC721 function. Grants approval to another address (_approved) to manage a specific veNFT (_tokenId). Requires the caller (msg.sender) to be the owner or an approved operator for the owner. Setting _approved to the zero address removes approval.

Input Parameters:

Name
Type
Description

_approved

address

The address to grant approval to.

_tokenId

uint

The ID of the veNFT to approve.

Events Emitted:

Approval(address indexed owner, address indexed approved, uint indexed tokenId)


setApprovalForAll

function setApprovalForAll(address _operator, bool _approved) external

Description:

Standard ERC721 function. Grants or revokes approval for an _operator address to manage all veNFTs owned by the caller (msg.sender).

Input Parameters:

Name
Type
Description

_operator

address

The address to set as an operator.

_approved

bool

true to grant approval, false to revoke it.

Events Emitted:

ApprovalForAll(address indexed owner, address indexed operator, bool approved)


setIncentivesManager

function setIncentivesManager(address incentivesManager) external

Description:

Allows the current voter address to set or update the _incentivesManager address.

Input Parameters:

Name
Type
Description

incentivesManager

address

The address of the IIncentivesManager contract.


setVoter

function setVoter(address _voter) external

Description:

Allows the current voter address to transfer the voter role to a new address (_voter). The voter address is responsible for calling functions like voting, abstain, attach, detach.

Input Parameters:

Name
Type
Description

_voter

address

The address of the new voter contract.


voting

function voting(uint _tokenId) external

Description:

Marks a specific veNFT (_tokenId) as having participated in voting. This is typically called by the Voter contract when a user casts votes. Prevents the NFT from being transferred, merged, or withdrawn while marked as voted.

Input Parameters:

Name
Type
Description

_tokenId

uint

The ID of the veNFT that has voted.


abstain

function abstain(uint _tokenId) external

Description:

Removes the 'voted' status from a specific veNFT (_tokenId). This is typically called by the Voter contract when votes are reset or changed. Allows the NFT to be transferred, merged, or withdrawn again (if not attached).

Input Parameters:

Name
Type
Description

_tokenId

uint

The ID of the veNFT that is abstaining.


attach

function attach(uint _tokenId) external

Description:

Increments the attachment counter for a veNFT (_tokenId). Prevents transfer, merge, and withdrawal while attached (attachments > 0).

Input Parameters:

Name
Type
Description

_tokenId

uint

The ID of the veNFT being attached.


detach

function detach(uint _tokenId) external

Description:

Decrements the attachment counter for a veNFT (_tokenId). Called when the NFT is unstaked or no longer needs to be attached. Allows transfer, merge, or withdrawal once the counter reaches zero (and voted is false).

Input Parameters:

Name
Type
Description

_tokenId

uint

The ID of the veNFT being detached.


merge

function merge(uint _from, uint _to) external

Description:

Merges the lock (amount and end time) from one veNFT (_from) into another (_to). The resulting lock in _to will have the combined amount and the later of the two end times. The _from NFT is burned. Requires the caller to own or be approved for both NFTs, and the _from NFT must not be attached or voted.

Input Parameters:

Name
Type
Description

_from

uint

The ID of the veNFT to merge from (will be burned).

_to

uint

The ID of the veNFT to merge into.

Events Emitted:

Deposit, Supply, Transfer (for burn).


block_number

function block_number() external view returns (uint)

Description:

Returns the current block number.

Return Value:

Type
Description

uint

The current block number.


checkpoint

function checkpoint() external

Description:

Triggers a global checkpoint, updating the global epoch and point history based on the current block time and any scheduled slope changes. Does not require or affect a specific user NFT.


deposit_for

function deposit_for(uint _tokenId, uint _value) external nonreentrant

Description:

Adds more underlying tokens (_value) to an existing, non-expired lock (_tokenId) without changing its unlock time. Can be called by anyone.

Input Parameters:

Name
Type
Description

_tokenId

uint

The ID of the veNFT lock to add to.

_value

uint

The amount of underlying token to add.

Events Emitted:

Deposit, Supply.


create_lock_for

function create_lock_for(uint _value, uint _lock_duration, address _to) external nonreentrant returns (uint)

Description:

Creates a new lock with the specified _value and _lock_duration for a designated recipient address _to. Mints a new veNFT and transfers the underlying tokens from the caller (msg.sender).

Input Parameters:

Name
Type
Description

_value

uint

The amount of underlying token to lock.

_lock_duration

uint

The duration in seconds for which to lock the tokens (max 4 years).

_to

address

The address that will own the new veNFT lock.

Return Value:

Type
Description

uint

The token ID of the newly created veNFT.

Events Emitted:

Transfer (mint), Deposit, Supply.


create_lock

function create_lock(uint _value, uint _lock_duration) external nonreentrant returns (uint)

Description:

Creates a new lock with the specified _value and _lock_duration for the caller (msg.sender). Mints a new veNFT owned by the caller and transfers the underlying tokens from the caller.

Input Parameters:

Name
Type
Description

_value

uint

The amount of underlying token to lock.

_lock_duration

uint

The duration in seconds for which to lock the tokens (max 4 years).

Return Value:

Type
Description

uint

The token ID of the newly created veNFT.

Events Emitted:

Transfer (mint), Deposit, Supply.


increase_amount

function increase_amount(uint _tokenId, uint _value) external nonreentrant

Description:

Adds more underlying tokens (_value) to an existing, non-expired lock (_tokenId) without changing its unlock time. Requires the caller (msg.sender) to be the owner or approved for the _tokenId.

Input Parameters:

Name
Type
Description

_tokenId

uint

The ID of the veNFT lock to add to.

_value

uint

The amount of underlying token to add.

Events Emitted:

Deposit, Supply.


increase_unlock_time

function increase_unlock_time(uint _tokenId, uint _lock_duration) external nonreentrant

Description:

Extends the unlock time of an existing, non-expired lock (_tokenId). The new unlock time is calculated based on the current block time plus _lock_duration (rounded down to the nearest week), up to the maximum lock time (4 years from now). Requires the caller (msg.sender) to be the owner or approved for the _tokenId.

Input Parameters:

Name
Type
Description

_tokenId

uint

The ID of the veNFT lock to extend.

_lock_duration

uint

The duration in seconds to extend the lock from the current time (max 4 years).

Events Emitted:

Deposit.


withdraw

function withdraw(uint _tokenId, uint _amount) external nonreentrant

Description:

Allows the owner or approved address to withdraw underlying tokens associated with a veNFT (_tokenId). Requires the NFT to not be attached or voted. Two scenarios:

  1. Expired Lock: If block.timestamp >= lock.end, the entire remaining locked.amount is withdrawn, and the veNFT is burned. _amount parameter is ignored in this case (implicitly withdraws all).

  2. Early Unlock: If the lock is active (block.timestamp < lock.end) AND early unlock conditions are met (current incentive rate from _incentivesManager is lower than the rate at which the user locked, and there's a global excess of locked tokens above the new cap), the user can withdraw up to _amount tokens, provided _amount does not exceed their share of the global excess or their total locked amount. The lock amount is reduced, but the NFT remains (unless _amount equals the total locked amount, in which case it's burned).

Input Parameters:

Name
Type
Description

_tokenId

uint

The ID of the veNFT lock from which to withdraw.

_amount

uint

The amount to attempt to withdraw during an early unlock. Ignored if the lock has expired (full withdrawal occurs).

Events Emitted:

Withdraw, Supply, Transfer (burn, if applicable).


calculateExcessLockedTokens

function calculateExcessLockedTokens(uint256 LockInRate) public view returns (uint256 userExcess)

Description:

Calculates the global amount of tokens locked in the system that exceeds the dynamically calculated cap, based on a provided historical LockInRate (presumably the rate when a user initially locked) and the current rate/cap from the _incentivesManager. This value represents the total pool of tokens available for all eligible users to withdraw early. Returns 0 if the current rate is not lower than LockInRate or if the total locked supply is within the allowed cap.

Input Parameters:

Name
Type
Description

LockInRate

uint256

The incentive rate present when a specific lock was created/last updated.

Return Value:

Type
Description

uint256

The total amount of excess locked tokens currently available for early withdrawal globally.


tokenURI

function tokenURI(uint _tokenId) external view returns (string memory)

Description:

Standard ERC721Metadata function. Returns the Uniform Resource Identifier (URI) for a given veNFT (_tokenId). The URI contains JSON metadata including the NFT's name, description, and an embedded SVG image displaying its ID, current voting balance, lock end time, and original locked value.

Input Parameters:

Name
Type
Description

_tokenId

uint

The ID of the veNFT to get the URI for.

Return Value:

Type
Description

string

The data URI containing the JSON metadata.


balanceOfNFT

function balanceOfNFT(uint _tokenId) external view returns (uint)

Description:

Calculates the current voting power (ve balance) of a specific veNFT (_tokenId) at the current block timestamp. Returns 0 if the NFT was transferred in the current block (flash loan protection).

Input Parameters:

Name
Type
Description

_tokenId

uint

The ID of the veNFT lock to query.

Return Value:

Type
Description

uint

The current voting power of the _tokenId.


balanceOfNFTAt

function balanceOfNFTAt(uint _tokenId, uint _t) external view returns (uint)

Description:

Calculates the voting power (ve balance) of a specific veNFT (_tokenId) at a given past timestamp (_t).

Input Parameters:

Name
Type
Description

_tokenId

uint

The ID of the veNFT lock to query.

_t

uint

The past timestamp to calculate balance at.

Return Value:

Type
Description

uint

The voting power of the _tokenId at time _t.


balanceOfAtNFT

function balanceOfAtNFT(uint _tokenId, uint _block) external view returns (uint)

Description:

Calculates the voting power (ve balance) of a specific veNFT (_tokenId) at a given past block number (_block). It estimates the timestamp corresponding to the block number using historical checkpoints.

Input Parameters:

Name
Type
Description

_tokenId

uint

The ID of the veNFT lock to query.

_block

uint

The past block number to calculate balance at.

Return Value:

Type
Description

uint

The voting power of the _tokenId at block _block.


totalSupplyAtT

function totalSupplyAtT(uint t) public view returns (uint)

Description:

Calculates the total voting power (total ve supply) across all locks in the contract at a specific timestamp t.

Input Parameters:

Name
Type
Description

t

uint

The timestamp to calculate supply at.

Return Value:

Type
Description

uint

The total voting power at time t.


totalSupply

function totalSupply() external view returns (uint)

Description:

Calculates the current total voting power (total ve supply) across all locks at the current block timestamp.

Return Value:

Type
Description

uint

The current total voting power.


totalSupplyAt

function totalSupplyAt(uint _block) external view returns (uint)

Description:

Calculates the total voting power (total ve supply) across all locks at a specific past block number (_block). Estimates the timestamp corresponding to the block number.

Input Parameters:

Name
Type
Description

_block

uint

The past block number to calculate supply at.

Return Value:

Type
Description

uint

The total voting power at block _block.

PreviousVoterNextFactories

Last updated 2 months ago