Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/reserve-protocol/reserve-index-dtf/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The StakingVault contract is a transferrable ERC4626 vault that enables staking of an underlying token to earn voting power and multi-token rewards. It implements the full ERC20Votes interface for governance participation and supports configurable unstaking delays for security.

Key Features

  • ERC4626 Standard: Full compatibility with vault standards
  • ERC20Votes: Voting power delegation for governance
  • Multi-Token Rewards: Support for unlimited reward tokens with drip distribution
  • Unstaking Delay: Configurable delay for withdrawals
  • Exponential Reward Decay: Smooth reward distribution using half-life model
  • Slashing Mechanism: Ability to burn shares for punitive actions

Architecture

StakingVault extends:
  • ERC4626Upgradeable (vault functionality)
  • ERC20PermitUpgradeable (gasless approvals)
  • ERC20VotesUpgradeable (governance)
  • OwnableUpgradeable (access control)
  • UUPSUpgradeable (upgradeability)

Staking Functions

Deposit and Delegate

Deposit tokens and automatically self-delegate voting power.
assets
uint256
Amount of underlying tokens to deposit
StakingVault.sol
function depositAndDelegate(uint256 assets) external returns (uint256 shares)
This convenience function combines deposit() and delegate() into a single transaction, automatically delegating voting power to yourself.

Burn (Slashing)

Burn shares and redistribute underlying tokens to remaining holders.
_shares
uint256
Amount of shares to burn
StakingVault.sol
function burn(uint256 _shares) external
This is a slashing function. Burned shares reduce the caller’s balance and automatically distribute the underlying assets to all remaining stakers as native rewards.

Unstaking Configuration

Set Unstaking Delay

Configure the delay before withdrawn tokens become claimable.
_delay
uint256
New unstaking delay in seconds (max 4 weeks)
StakingVault.sol
function setUnstakingDelay(uint256 _delay) external onlyOwner
MAX_UNSTAKING_DELAY
uint256
default:"4 weeks"
Maximum allowed unstaking delay

Reward Management

Add Reward Token

Add a new reward token to the vault.
_rewardToken
address
Address of the reward token to add
StakingVault.sol
function addRewardToken(address _rewardToken) external onlyOwner
Reward tokens cannot be the vault’s share token or underlying asset. The contract tracks the token’s balance and distributes new tokens using an exponential decay curve.

Remove Reward Token

Remove a reward token from future distributions.
_rewardToken
address
Address of the reward token to remove
StakingVault.sol
function removeRewardToken(address _rewardToken) external onlyOwner
Users can still claim accrued rewards for removed tokens. This only stops new rewards from accumulating.

Claim Rewards

Claim accumulated rewards for specified tokens.
_rewardTokens
address[]
Array of reward token addresses to claim
StakingVault.sol
function claimRewards(
    address[] calldata _rewardTokens
) external returns (uint256[] memory claimableRewards)

Set Reward Ratio

Configure the reward distribution rate via half-life.
rewardHalfLife
uint256
Half-life for reward handout in seconds (1 day to 2 weeks)
StakingVault.sol
function setRewardRatio(uint256 rewardHalfLife) external onlyOwner
MAX_REWARD_HALF_LIFE
uint256
default:"2 weeks"
Maximum reward half-life
MIN_REWARD_HALF_LIFE
uint256
default:"1 day"
Minimum reward half-life

View Functions

Get All Reward Tokens

Retrieve all currently registered reward tokens.
StakingVault.sol
function getAllRewardTokens() external view returns (address[] memory)

Total Assets

Get total underlying assets including accrued native rewards.
StakingVault.sol
function totalAssets() public view override returns (uint256)

Poke

Manually trigger reward accrual for the caller.
StakingVault.sol
function poke() external
This function is useful for updating your reward balances without performing a deposit or withdrawal.

Reward Tracking Structures

RewardInfo

payoutLastPaid
uint256
Timestamp of last reward calculation
rewardIndex
uint256
Cumulative reward per share (D18+decimals)
balanceAccounted
uint256
Amount of rewards already distributed to index
balanceLastKnown
uint256
Last known total balance of reward token
totalClaimed
uint256
Total amount claimed by all users

UserRewardInfo

lastRewardIndex
uint256
User’s last checkpoint reward index
accruedRewards
uint256
Unclaimed rewards for this user

Events

UnstakingDelaySet
event
Emitted when unstaking delay is updatedParameters:
  • delay - New unstaking delay in seconds
RewardTokenAdded
event
Emitted when a reward token is registeredParameters:
  • rewardToken - Address of the added reward token
RewardTokenRemoved
event
Emitted when a reward token is removedParameters:
  • rewardToken - Address of the removed reward token
RewardsClaimed
event
Emitted when a user claims rewardsParameters:
  • user - Address claiming rewards
  • rewardToken - Token being claimed
  • amount - Amount claimed
RewardRatioSet
event
Emitted when reward distribution rate changesParameters:
  • rewardRatio - New reward ratio (per-second rate)
  • halfLife - Corresponding half-life in seconds

Unstaking Manager

When unstaking delay is non-zero, withdrawals are managed by a separate UnstakingManager contract:
unstakingManager
UnstakingManager
Automatically deployed contract that holds tokens during unstaking period
Users receive a lock ID when unstaking and must wait for the delay period before calling claimLock() on the UnstakingManager.

Usage Example

// Deposit and start earning rewards
uint256 shares = vault.depositAndDelegate(1000e18);

// Wait for rewards to accumulate
// ...

// Claim rewards
address[] memory tokens = vault.getAllRewardTokens();
uint256[] memory claimed = vault.claimRewards(tokens);

// Initiate withdrawal (creates lock if delay > 0)
vault.withdraw(shares, receiver, owner);

// After delay, claim from UnstakingManager
vault.unstakingManager().claimLock(lockId);

Constants

SCALAR
uint256
default:"1e18"
Scaling factor for reward calculations
LN_2
uint256
default:"0.693147180559945309e18"
Natural logarithm of 2 (for exponential decay)

Build docs developers (and LLMs) love