API
Stargate.sol interface
Stargate.sol interfaceStaking
stake(_levelId)
stake(_levelId)Hard stakes VET and mints an NFT.
When calling this function, the ID of the desired level must be passed as a parameter and the exact amount of VET must be sent as a value of the transaction.
A maturity period will be applied to the NFTs minted through this function.
unstake(_tokenId)
unstake(_tokenId)Burns the NFT and returns the staked VET to the user. If there are any claimable rewards, those will be automatically claimed and sent to the owner.
Unstaking is possible only when the NFT does not have any active delegation.
Delegation
delegate(_tokenId, _validator)
delegate(_tokenId, _validator)Delegates the token to the validator to increase its probability of being selected as a validator and accumulate rewards for each mined block.
The delegation is not active until the start of the next period of the validator. In the meantime, the user can change the validator by calling this function again, cancel the delegation or unstaking the token.
The validator must be in an ACTIVE or QUEUED state, and must not have requested to exit prior to this.
If the NFT has any claimable rewards, those will be automatically claimed.
When such action is done, a delegation, with its own ID, will be assigned and linked to the NFT. The delegation will be initially in PENDING state and become ACTIVE when the validator enters the next period or becomes active. If, in the meantime, the validator decides to exit, the delegation will be cancelled.
stakeAndDelegate(_levelId, _validator)
stakeAndDelegate(_levelId, _validator)Stakes VET and mints an NFT, boosts the NFT maturity period by paying the VTHO fee, and initiates a delegation for the specified validator.
Validator must be in an active or queued state.
Apart from sending the exact amount of VET as value of the transaction, developers need also to call the VTHO contract and approve the StargateNFT contract address to transfer enough VTHO tokens to cover the boosting price.
Even if we are interacting with the Stargate.sol contract, VTHO approval must be allowed to the StargateNFT.sol contract, which is the one actually burning the VTHO.
migrateAndDelegate(_tokenId, _validator)
migrateAndDelegate(_tokenId, _validator) Migrates a token from the legacy nodes contract to StargateNFT, and delegates it to the specified validator.
Validator must be in an active or queued state.
VET must be sent as value of the transaction. The legacy NFT will be burned and a new one, with the same level, will be minted in the StargateNFT contract.
No maturity period is applied to migrated tokens.
requestDelegationExit(_tokenId)
requestDelegationExit(_tokenId)Requests a delegation exit by signalling the exit to the protocol staking contract.
If the delegation is active, the user will need to wait for then end of the period to actually exit, if instead the delegation is pending the user will exit immediately.
Once the request to exit is signalled, the user cannot undo it and cannot request to exit again.
getDelegationDetails(_tokenId)
getDelegationDetails(_tokenId)Returns the details of the delegation of a token. If the token does not have any delegation, it will return a set of default values.
The returned details are:
delegationId: the latest delegation id for the token (can be pending, active, or exited)validator: the validator addressstake: the amount of VET delegated to the validator (that is the same as the price of the NFT)probabilityMultiplier: a multiplier used to multiply the stake of the user when calculating the weight of the delegation (scaled by 100)startPeriod: the period when the delegation became activeendPeriod: the period when the delegation ended (if exited);uint32.maxif still activeisLocked: the delegation is locked while active, and it means that the VET cannot be withdrawn and user needs to request to exitstatus: The status of a delegation
"Probability multiplier" is different from the "Rewards Multiplier". The first one is used by the protocol to handle validator's stakes, the second one is used by StarGate to calculate the effective stake and the share of rewards.
getDelegationStatus(_tokenId)
getDelegationStatus(_tokenId)Possible statuses of a delegation:
NONE: the delegation id is not valid, or user never delegatedPENDING: the user has selected a validator and staked the VET, but is waiting for the next period to start or for the validator to be become activeACTIVE: the user is accumulating rewards; if the user requests to exit the delegation the status remainsACTIVEEXITED: the user has exited the delegation or the validator exited and forced the user to exit or the user exited a pending delegation and the stake is now 0
There is no status to indicate if a delegation requested to exit. The ways to know that is by checking the endPeriod (if is uint32.max then it's active) or by calling Stargate.hasRequestedExit(_tokenId).
Rewards
lockedRewards(_tokenId)
lockedRewards(_tokenId)Returns the VTHO accrued in the current ongoing period for an ACTIVE delegation. These rewards are not yet claimable, and will become claimable at the end of the current period.
Returns 0 if the delegation is not ACTIVE (NONE, PENDING, or EXITED).
claimableRewards(_tokenId)
claimableRewards(_tokenId)Returns the total VTHO currently claimable for all completed periods since the last claim.
claimRewards(_tokenId)
claimRewards(_tokenId)Transfers all currently claimable VTHO to the NFT owner and advances lastClaimedPeriod to the last claimed period in that call.
Anyone can call this; funds are always sent to the current NFT owner.
Automatically executed by unstake(_tokenId) and during delegate(_tokenId, _validator) when moving from a prior delegation, but these actions will revert if the unclaimed window exceeds the cap (see below).
claimableDelegationPeriods(_tokenId)
claimableDelegationPeriods(_tokenId)Returns the range of periods that the token has available to claim.
Rewards - Edge Cases
To avoid out-of-gas with long period ranges, the contract enforces a claim window cap via maxClaimablePeriods (default: 832, equal to around 16 years of unclaimed rewards for periods of 7 days).
In mainnet and testnet such limits will hardly be reached, but when testing locally or in an ad-hoc created environment where validators have way lower periods (for example 3 minutes) devs will easily encounter such edge case.
For such edge case, we advise using the following procedure:
Call
claimableDelegationPeriods(_tokenId)to obtain the range of claimable periodsCall the
getMaxClaimablePeriods()to know the enforced limit of periods that can be claimable in one batchDetermine how many batches you will need (eg:
ceil((lastClaimablePeriod-firstClaimablePeriod)/maxClaimablePeriods))Call
claimableRewards(tokenId, batch), where batch is 0-based, to know exactly the amount of total claimable rewards of a tokenWhen claiming rewards, create a multiclause transaction with a
claimRewards(_tokenId)clause per batch
In such scenario unstake(_tokenId) and delegate(_tokenId, _validator) will revert with MaxClaimablePeriodsExceeded() to prevent accidental loss; claim the rewards with a multiclause transaction before executing those 2 functions to avoid errors.
StargateNFT.sol interface
StargateNFT.sol interfaceBoosting and Maturity
boost(_tokenId)
boost(_tokenId)Skips the remaining maturity blocks immediately by burning VTHO; token becomes usable for delegation right away.
VTHO must be approved to the StargateNFT contract; the contract transfers VTHO from caller and burns it (sends to address(0)).
Reverts if maturity already ended, with MaturityPeriodEnded(_tokenId), or on insufficient VTHO balance or allowance.
boostAmount(_tokenId)
boostAmount(_tokenId)Useful getter to pre-calculate the fee to boost the maturity period of a token.
When showing on the frontend, keep in mind that this may not be an accurate value, because the fee goes down as blocks are minted. So it may happen that you show/approve an amount, but you end up spending less (never more).
boostPricePerBlock(_levelId)
boostPricePerBlock(_levelId)This function will return the amount of VTHO that needs to be paid for each block of the maturity period that needs to be boosted for a specific level.
boostAmountOfLevel(_levelId)
boostAmountOfLevel(_levelId)Retrieve the total boost price required for a specific level, which can assist in determining the fee for boosting the maturity period of a token at that level during the stakeAndDelegate flow when the tokenId is still uknown.
Boost Price = boostPricePerBlock * StargateNFT.getLevel().maturityBlocksmaturityPeriodEndBlock(_tokenId)
maturityPeriodEndBlock(_tokenId)End block is tracked per token; migrated tokens have no maturity (end block set to the current block).
Levels and Token Details
getLevel(_levelId)
getLevel(_levelId)Returns the immutable level spec: name, isX, id, maturityBlocks, scaledRewardFactor, vetAmountRequiredToStake.
scaledRewardFactor is scaled by REWARD_MULTIPLIER_SCALING_FACTOR (100) and is used by Stargate.sol to compute effective stake for rewards.
Caps and circulating supply are enforced at mint; X-level caps auto-adjust on migrate/burn.
getToken(_tokenId)
getToken(_tokenId)Returns token metadata: tokenId, levelId, mintedAtBlock, vetAmountStaked, and a deprecated last-VTHO timestamp.
vetAmountStaked equals the level’s vetAmountRequiredToStake at mint/migration time.
For token URI, the contract uses a level-based base URI with a “locked” suffix when delegation is active.
isX(_tokenId)
isX(_tokenId)Returns if a token is of category "X" or not.
Ownership and Manager System
idsOwnedBy(_owner)
idsOwnedBy(_owner)Returns all token IDs owned by _owner using ERC721Enumerable indexing.
tokensOwnedBy(_owner)
tokensOwnedBy(_owner)Returns a full array of typed Token for the owner.
idsManagedBy(_user)
idsManagedBy(_user)Consider the following scenario to understand how the functions operate:
Dan minted NFTs with ID 1 and 2
Victor minted NFT with ID 3
Dan adds Victor as a manager for NFT ID 2
Victor adds Dan as a manager for NFT ID 3
Based on this setup:
idsManagedBy(dan)will return IDs: 1 and 3idsManagedBy(victor)will return ID 2
This means the function returns all NFTs owned by the user and not managed by someone else, along with all the NFTs that the user is managing on behalf of someone else. Note that the owner is always a potential manager, but if the owner assigns a different manager, they are no longer considered the manager.
tokensManagedBy(_user)
tokensManagedBy(_user)Same as idsManagedBy(_user) but returning the Token datatype.
Returns the list of:
Tokens managed by the user
Tokens owned by the user and not managed by someone else
tokensOverview(_user)
tokensOverview(_user)The tokensOverview function returns an array of TokenOverview structures for the specified _user. Each TokenOverview includes the token ID, the owner’s address, the manager’s address and the level ID.
getTokenManager(_tokenId)
getTokenManager(_tokenId)Returns the manager of the token; If it's not set it will return the owner address, otherwise the manager added by the owner. Returns address(0) if the token does not exist.
addTokenManager(_manager, _tokenId)
addTokenManager(_manager, _tokenId)Let owners assign a separate “manager” that can use the token for off-chain integrations (e.g., governance) without ownership rights. A token can have only 1 manager.
If no manager is added, then the owner is considered the manager of the token.
Adding a new manager replaces any existing one (emits removal for previous).
Manager is automatically removed on token transfer.
removeTokenManager(_tokenId)
removeTokenManager(_tokenId)Callable by the current manager or the token owner, and reverts if there is no manager already set.
Transfer Behaviour
transferFrom/safeTransferFrom(...)
transferFrom/safeTransferFrom(...)ERC721 implementation of transferability. The token remains fully transferable at all times. Only the owner can transfer tokens.
Last updated
Was this helpful?

