scaSUI Liquid Staking
Stake SUI into scaSUI (Scallop Staked SUI), Scallop's own liquid staking token, and redeem it back to SUI.
Overview
scaSUI is a SpringSui LST. That single fact determines everything else in this skill:
- Minting and redeeming scaSUI are SpringSui calls, not Scallop lending calls. They do not touch
the Scallop market, obligations, or the Scallop protocol package. Neither the TypeScript nor the
Python Scallop SDK wraps them — you build the
moveCallyourself. - Using scaSUI inside Scallop (supplying it, or depositing it as collateral) is an ordinary Scallop lending call, and works through the normal SDK path like any other coin.
Keep those two halves separate; most mistakes here come from expecting the Scallop SDK to mint.
SUI ──SpringSui liquid_staking::mint──> scaSUI ──Scallop supply/deposit_collateral──> yield
<─SpringSui liquid_staking::redeem──
Addresses
| Item | Value |
|---|---|
| SpringSui package | 0xb0575765166030556a6eafd3b1b970eba8183ff748860680245b9edd41c716e7 |
LiquidStakingInfo<scaSUI> (shared) |
0x259ea1d466d04323b806593fce4ec47c29f8e53d0a0802903e98c0f9829edf0f |
WeightHook<scaSUI> (shared) |
0x360950cd6cf172d709e29aac8f2e5873bd4325967d33a52141281f1df99ed43a |
| SuiSystemState | 0x5 (mutable shared) |
| scaSUI coin type | 0xda008a552a2d6a9566fa6204255d55ab32ce00f23e307145dec2644cf83336b2::sca_sui::SCA_SUI |
| scaSUI decimals | 9 |
scaSUI CoinMetadata |
0x71dd901768abcd6e83c4bca76dc7b45fe1ef038c554eba4b1fd76a4c5d91703d |
sCoin (sscaSUI) type |
0xa3b4ce56e020cb8086b38fb042b763ccfa1518a43715fb21673a7d814f6e2dac::scallop_sca_sui::SCALLOP_SCA_SUI |
| sCoin treasury | 0x85733627f015ac4f76b198235670f274a44241911623b7c695c784e95afc39bc |
| Price feed | Pyth SUI/USD 0x23d7315113f5b1d3ba7a83604c44b94d79f4fd69af77f804fc7f920a6dc65744 |
Both shared objects have
initialSharedVersion872044508.The Scallop Addresses API entry for
scasuistill has emptycoinType/decimals/symbolfields. Resolve scaSUI from on-chainCoinMetadata(or the table above), not from the API snapshot. See supported-coins.md.
Move Signatures
Verified against the on-chain module. Argument order differs between mint and redeem —
the system state is the 2nd argument when minting and the 3rd when redeeming:
// T = 0xda00...::sca_sui::SCA_SUI
public fun mint<T>(
&mut LiquidStakingInfo<T>,
&mut SuiSystemState, // 0x5
Coin<SUI>,
&mut TxContext,
): Coin<T>
public fun redeem<T>(
&mut LiquidStakingInfo<T>,
Coin<T>,
&mut SuiSystemState, // 0x5
&mut TxContext,
): Coin<SUI>
public fun rebalance<T>(
&mut WeightHook<T>,
&mut SuiSystemState, // 0x5
&mut LiquidStakingInfo<T>,
&mut TxContext,
)
All three are public fun, not entry — they must be called from a PTB, and mint/redeem
return a Coin you are responsible for transferring or consuming.
Stake: SUI → scaSUI
import { Transaction } from '@mysten/sui/transactions';
const SPRINGSUI = '0xb0575765166030556a6eafd3b1b970eba8183ff748860680245b9edd41c716e7';
const LST_INFO = '0x259ea1d466d04323b806593fce4ec47c29f8e53d0a0802903e98c0f9829edf0f';
const WEIGHT_HOOK = '0x360950cd6cf172d709e29aac8f2e5873bd4325967d33a52141281f1df99ed43a';
const SCASUI = '0xda008a552a2d6a9566fa6204255d55ab32ce00f23e307145dec2644cf83336b2::sca_sui::SCA_SUI';
const tx = new Transaction();
// 1 SUI (9 decimals). Split from the gas coin.
const [suiIn] = tx.splitCoins(tx.gas, [tx.pure.u64(1_000_000_000n)]);
const scasui = tx.moveCall({
target: `${SPRINGSUI}::liquid_staking::mint`,
typeArguments: [SCASUI],
arguments: [tx.object(LST_INFO), tx.object('0x5'), suiIn],
});
// Keep the minted scaSUI — mint returns a Coin, it does not transfer for you.
tx.transferObjects([scasui], sender);
// Redistribute the new stake across validators by configured weights.
tx.moveCall({
target: `${SPRINGSUI}::weight::rebalance`,
typeArguments: [SCASUI],
arguments: [tx.object(WEIGHT_HOOK), tx.object('0x5'), tx.object(LST_INFO)],
});
const result = await suiClient.signAndExecuteTransaction({ transaction: tx, signer: keypair });
TxContext is supplied by the runtime — never pass it as an argument.
On rebalance
rebalance is a maintenance call, not part of mint/redeem settlement: it moves SUI between
validators to match the weights configured on the WeightHook. Your mint succeeds without it. Bundle
it when you want the stake placed immediately; skip it for cheaper gas and let the next caller
rebalance. It takes no AdminCap, so anyone may call it.
Unstake: scaSUI → SUI
const tx = new Transaction();
// Merge your scaSUI coins first if the balance is split across several objects.
const [scasuiIn] = tx.splitCoins(tx.object(scasuiCoinId), [tx.pure.u64(1_000_000_000n)]);
const suiOut = tx.moveCall({
target: `${SPRINGSUI}::liquid_staking::redeem`,
typeArguments: [SCASUI],
arguments: [tx.object(LST_INFO), scasuiIn, tx.object('0x5')], // note the argument order
});
tx.transferObjects([suiOut], sender);
Redemption is served from the LST's liquid SUI pool. A redemption larger than the pool forces an unstake from validators, which can only settle at an epoch boundary — size large exits accordingly, and dry-run before submitting (see advanced-transactions).
Stake and Deposit as Collateral
The two halves compose in a single PTB: mint with SpringSui, then hand the resulting Coin<scaSUI>
straight to Scallop without it ever hitting your wallet.
const builder = await scallop.createScallopBuilder();
const tx = builder.createTxBlock();
// ScallopBuilder's txBlock is SuiKit-based — use its splitSUIFromGas helper here,
// not the raw @mysten/sui splitCoins(tx.gas, ...) form used above.
const [suiIn] = tx.splitSUIFromGas([10_000_000_000]); // 10 SUI
const scasui = tx.moveCall({
target: `${SPRINGSUI}::liquid_staking::mint`,
typeArguments: [SCASUI],
arguments: [tx.object(LST_INFO), tx.object('0x5'), suiIn],
});
// Deposit the freshly minted coin as collateral on an existing obligation.
// Signature: depositCollateral(obligation, coin, collateralCoinName)
tx.depositCollateral(obligationId, scasui, 'scasui');
const result = await builder.signAndSendTxBlock(tx);
To supply it to the lending pool for interest instead of pledging it as collateral, use
tx.supply(scasui, 'scasui') — signature supply(coin, poolCoinName), which returns the market
coin. See the terminology note in lend-integration.
Pass the coin argument, not an amount: the
*Quickhelpers (depositCollateralQuick,supplyQuick) select coins from your wallet by amount, which defeats the point of chaining — the minted coin is a PTB result and is not in your wallet yet.
Exchange Rate and Yield
scaSUI is a rate-appreciating LST: your balance never grows, its SUI value does. One scaSUI is worth strictly more than one SUI, and the gap widens each epoch as staking rewards accrue.
Read it from the LiquidStakingInfo object:
| Source | Meaning |
|---|---|
lst_treasury_cap.total_supply.value |
scaSUI in circulation (mist) |
storage.total_sui_supply |
SUI backing it, including staked principal + rewards (mist) |
accrued_spread_fees |
protocol's cut, owed out of the above |
storage.last_refresh_epoch |
epoch the figures were last refreshed |
rate ≈ (storage.total_sui_supply - accrued_spread_fees) / lst_treasury_cap.total_supply.value
The module also exposes total_sui_supply<T>() and total_lst_supply<T>() accessors; prefer those
via devInspect when you need an authoritative figure, since the field arithmetic above is a
reconstruction and the stored values are only as fresh as last_refresh_epoch (refresh updates
them).
Pricing caveat. Scallop prices scaSUI off the SUI/USD feed, so the protocol values it at 1:1 with SUI — a deliberate conservative lower bound, the same treatment afSUI / haSUI / vSUI get. Your collateral is therefore valued slightly below its redeemable worth. Do not build a strategy that assumes Scallop credits the LST premium. See oracle-integration.md.
Using scaSUI Elsewhere in Scallop
Once minted, scaSUI is an ordinary Scallop asset under the SDK name scasui:
- Supply / withdraw — lend-integration
- Collateral and borrowing — obligation-manager
- Mint
sscaSUIfrom its market coin — scoin - Caps and isolation flags — market-limits
Common Errors
| Symptom | Cause |
|---|---|
| Function not found | Called the Scallop protocol package instead of the SpringSui package |
| Type argument mismatch | typeArguments must be the scaSUI type, not 0x2::sui::SUI |
Argument type error on redeem |
Passed 0x5 as the 2nd argument — for redeem the coin is 2nd, 0x5 is 3rd |
| Unused value without drop | mint / redeem return a Coin that must be transferred or consumed |
| Redemption reverts on a large exit | Exceeds the liquid SUI pool; needs a validator unstake at an epoch boundary |
References
- supported-coins.md — scaSUI coin type and decimals
- scoin-types.md —
sscaSUItype and treasury - oracle-integration.md — LST pricing rules
- SpringSui — the LST framework scaSUI is built on