# Scallop Scasui Staking

> Stake SUI into scaSUI (Scallop Staked SUI) and unstake it again via SpringSui. Use when user says "scaSUI", "sca_sui", "Scallop LST", "liquid staking on Scallop", "stake SUI for scaSUI", "unstake scaSUI", "SpringSui", "mint scaSUI", "redeem scaSUI", or asks about Scallop's own liquid staking token or using it as collateral.

- Skill: `scallop-io/scallop-scasui-staking` (Agent Skill)
- Install (CLI): `npx skillmds@latest add scallop-io/scallop-scasui-staking`
- Raw SKILL.md: https://api.skillmd.com/api/skills/scallop-io/scallop-scasui-staking/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: scallop-io (https://skillmd.com/u/scallop-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/scallop-io/scallop-scasui-staking

---


# 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 `moveCall` yourself.
- **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 `initialSharedVersion` **872044508**.
>
> The Scallop Addresses API entry for `scasui` still has empty `coinType` / `decimals` / `symbol`
> fields. Resolve scaSUI from on-chain `CoinMetadata` (or the table above), not from the API
> snapshot. See [supported-coins.md](../../references/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:

```move
// 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

```typescript
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

```typescript
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](../scallop-advanced-transactions/SKILL.md)).

## 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.

```typescript
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](../scallop-lend-integration/SKILL.md).

> Pass the **coin argument**, not an amount: the `*Quick` helpers (`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](../../references/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](../scallop-lend-integration/SKILL.md)
- **Collateral and borrowing** — [obligation-manager](../scallop-obligation-manager/SKILL.md)
- **Mint `sscaSUI`** from its market coin — [scoin](../scallop-scoin/SKILL.md)
- **Caps and isolation flags** — [market-limits](../scallop-market-limits/SKILL.md)

## 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](../../references/supported-coins.md) — scaSUI coin type and decimals
- [scoin-types.md](../../references/scoin-types.md) — `sscaSUI` type and treasury
- [oracle-integration.md](../../references/oracle-integration.md) — LST pricing rules
- [SpringSui](https://github.com/solendprotocol/springsui) — the LST framework scaSUI is built on

