Volo Liquid Staking on Sui
Volo is a liquid staking protocol on Sui. Users deposit SUI and receive CERT (vSUI) -- a yield-bearing liquid staking token that accrues staking rewards over time. Volo distributes staked SUI across multiple validators with configurable weights.
Package IDs
| Package | ID | Description |
|---------|------------|-------------|
| Core | 0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55 | NativePool, StakePool, CERT token, validator management |
Source Files
Decompiled Move source:
packages/mainnet_most_used/0x68/d22cf8bdbcd11ecba1e094922873e4080d4d11133e2443fddda0bfd11dae20/decompiled_modules/
Architecture
Volo has two staking systems:
StakePool (v2, recommended)
- StakePool: Shared object managing staked SUI across validators with instant stake/unstake
- ValidatorPool: Internal pool distributing SUI across validators by weight
- FeeConfig: Configurable fee structure (stake, unstake, reward, redistribution fees in BPS)
- Supports boosted rewards via additional SUI deposits
NativePool (v1, legacy)
- NativePool: Original staking pool with delayed unstaking via tickets
- UnstakeTicket: NFT representing a pending withdrawal, unlocks after a certain epoch
CERT Token (vSUI)
- CERT: The liquid staking token (9 decimals), symbol "vSUI"
- Metadata<CERT>: Shared object tracking CERT total supply
- Exchange rate:
vSUI/SUI = total_lst_supply / total_sui_supply - Rate increases over time as staking rewards accrue
Key Modules
| Module | Purpose |
|--------|---------|
| stake_pool | v2 staking: stake, unstake, delegate_stake, ratio queries, rebalance |
| native_pool | v1 staking: stake, mint_ticket/burn_ticket, ratio queries |
| cert | CERT (vSUI) token type, supply tracking |
| unstake_ticket | Delayed unstake ticket for v1 (epoch-locked) |
| validator_pool | Validator set management, weight-based delegation |
| fee_config | Fee configuration (stake/unstake/reward fees in BPS) |
| ownership | OwnerCap, OperatorCap for admin operations |
| manage | Version gating, pause control |
| math | Ratio calculations, share conversions |
Common Integration Patterns
Stake SUI for vSUI (v2 - recommended)
// Programmable: returns Coin<CERT>
let vsui = stake_pool::stake(
stake_pool, cert_metadata, sui_system, sui_coin, ctx
);
// Entry: auto-transfers to sender
stake_pool::stake_entry(
stake_pool, cert_metadata, sui_system, sui_coin, ctx
);
// Delegate to specific validator (still returns from pool, not direct)
let vsui = stake_pool::delegate_stake(
stake_pool, cert_metadata, sui_system, sui_coin, validator_addr, ctx
);
Unstake vSUI for SUI (v2 - instant)
// Programmable: returns Coin<SUI>
let sui = stake_pool::unstake(
stake_pool, cert_metadata, sui_system, cert_coin, ctx
);
// Entry: auto-transfers to sender
stake_pool::unstake_entry(
stake_pool, cert_metadata, sui_system, cert_coin, ctx
);
Stake SUI for vSUI (v1 - legacy)
// Entry
native_pool::stake(pool, cert_metadata, sui_system, sui_coin, ctx);
// Programmable
let vsui = native_pool::stake_non_entry(pool, cert_metadata, sui_system, sui_coin, ctx);
Unstake vSUI (v1 - delayed via ticket)
// Step 1: Mint an unstake ticket (locks CERT, returns ticket with unlock_epoch)
native_pool::mint_ticket(pool, cert_metadata, cert_coin, ctx);
// Step 2: After unlock_epoch, burn ticket to receive SUI
native_pool::burn_ticket(pool, sui_system, ticket, ctx);
Query Exchange Rate
// v2: How many vSUI per 1 SUI (in 9-decimal units)
let ratio = stake_pool::get_ratio(stake_pool, cert_metadata); // vSUI per 1 SUI
// v2: How many SUI per 1 vSUI
let ratio_rev = stake_pool::get_ratio_reverse(stake_pool, cert_metadata);
// v2: Preview output amount (is_stake = true for SUI->vSUI, false for vSUI->SUI)
let amount_out = stake_pool::get_amount_out(stake_pool, cert_metadata, amount_in, is_stake);
// v2: Convert amounts
let lst_amount = stake_pool::sui_amount_to_lst_amount(stake_pool, cert_metadata, sui_amount);
let sui_amount = stake_pool::lst_amount_to_sui_amount(stake_pool, cert_metadata, lst_amount);
// v1: Ratio as u256 (scaled)
let ratio = native_pool::get_ratio(pool, cert_metadata);
Query Pool State
// v2
let total_sui = stake_pool::total_sui_supply(stake_pool);
let total_lst = stake_pool::total_lst_supply(cert_metadata);
let total_fees = stake_pool::total_fees(stake_pool);
// v1
let total_staked = native_pool::get_total_staked(pool);
let total_rewards = native_pool::get_total_rewards(pool);
let pending = native_pool::get_pending(pool);
UnstakeTicket Queries (v1)
let unlock_epoch = unstake_ticket::get_unlock_epoch(ticket);
let value = unstake_ticket::get_value(ticket);
let fee = unstake_ticket::get_unstake_fee(ticket);
let is_ready = unstake_ticket::is_unlocked(ticket, ctx);
Related Skills
haedal-- Alternative LST protocol on Sui (haSUI)blizzard-- Alternative LST protocol for Walrus (WAL)aftermath-- Aftermath Finance (afSUI staking)sui-framework-- SuiSystem staking primitives
Scan to join WeChat group