sCoin (Scallop Synthetic Coins)
Mint and manage interest-bearing synthetic coins backed by Scallop market coins.
Overview
sCoins are synthetic tokens that:
- Backed 1:1 by market coins
- Interest-bearing: Value increases over time
- Composable: Use in other DeFi protocols
- Transferable: Easy to move yield positions
Note: sCoin uses
supply()to supply assets to the lending pool and receive market coins, which are then converted to sCoins.
sCoin Types
| Market Coin | sCoin | Use Case |
|---|---|---|
| SUI Market Coin | sSUI | Yield-bearing SUI |
| USDC Market Coin | sUSDC | Yield-bearing stablecoin |
| wUSDC Market Coin | swUSDC | Yield-bearing wrapped USDC |
| wETH Market Coin | swETH | Yield-bearing wrapped ETH |
| afSUI Market Coin | safSUI | Yield-bearing liquid staked SUI |
| haSUI Market Coin | shaSUI | Yield-bearing liquid staked SUI |
Mint sCoin
From Market Coins
tx = builder.create_tx_block()
# Mint sCoin from existing market coins
scoin_idx = tx.mint_scoin(
market_coin_idx=market_coin, # Index of market coin (Input or Result)
coin_name="sui",
coin_is_result=True, # True if market_coin_idx is a Result index
)
tx.transfer_objects([scoin_idx], wallet_address)
result = builder.sign_and_send_tx_block(tx)
Deposit and Mint in One Step
tx = builder.create_tx_block()
# Deposit underlying and get sCoin directly
market_coin = tx.supply_quick(1_000_000_000, "sui", wallet_address)
scoin = tx.mint_scoin(market_coin, "sui")
tx.transfer_objects([scoin], wallet_address)
result = builder.sign_and_send_tx_block(tx)
// TypeScript - Mint sCoin from market coins
const tx = builder.createTxBlock();
const marketCoin = await tx.supplyQuick(1_000_000_000, 'sui');
const sCoin = tx.mintSCoin('sui', marketCoin);
tx.transferObjects([sCoin], sender);
await builder.signAndSendTxBlock(tx);
// Or use quick method
const tx2 = builder.createTxBlock();
const sCoin = await tx2.mintSCoinQuick('sui', 1_000_000_000);
tx2.transferObjects([sCoin], sender);
await builder.signAndSendTxBlock(tx2);
Burn sCoin
Convert sCoin back to market coins:
tx = builder.create_tx_block()
# Burn sCoin to get market coin
market_coin = tx.burn_scoin(
scoin_idx=scoin, # Index of sCoin (Input or Result)
coin_name="sui",
coin_is_result=True, # True if scoin_idx is a Result index
)
# Option 1: Keep market coin
// TypeScript - Burn sCoin
const tx = builder.createTxBlock();
const marketCoin = tx.burnSCoin('sui', sCoinObject);
tx.transferObjects([marketCoin], sender);
await builder.signAndSendTxBlock(tx);
// Or use quick method
const tx2 = builder.createTxBlock();
const marketCoin = await tx2.burnSCoinQuick('sui', 1_000_000_000);
tx2.transferObjects([marketCoin], sender);
await builder.signAndSendTxBlock(tx2);
# Option 1: Keep market coin
tx.transfer_objects([market_coin], wallet_address)
# Option 2: Withdraw to underlying
underlying = tx.withdraw(market_coin, "sui", coin_is_result=True)
tx.transfer_objects([underlying], wallet_address)
result = builder.sign_and_send_tx_block(tx)
Complete sCoin Flow
from sui_scallop_sdk import ScallopClient
client = ScallopClient(secret_key="...", network="mainnet")
builder = client.create_builder()
# Step 1: Deposit and mint sCoin
tx1 = builder.create_tx_block()
market_coin = tx1.supply_quick(10_000_000_000, "sui", client.wallet_address) # 10 SUI
scoin = tx1.mint_scoin(market_coin, "sui")
tx1.transfer_objects([scoin], client.wallet_address)
result1 = builder.sign_and_send_tx_block(tx1)
print("Minted sSUI from 10 SUI deposit")
# Step 2: Use sCoin in DeFi (transfer, LP, etc.)
# sCoin can be freely transferred and used
# Step 3: Burn sCoin when ready to withdraw
tx2 = builder.create_tx_block()
market_coin = tx2.burn_scoin(scoin_object, "sui", coin_is_result=False)
underlying = tx2.withdraw(market_coin, "sui", coin_is_result=True)
tx2.transfer_objects([underlying], client.wallet_address)
result2 = builder.sign_and_send_tx_block(tx2)
print("Burned sSUI and withdrew SUI")
sCoin Value
sCoin value tracks market coin value (which appreciates with interest):
def calculate_scoin_value(scoin_amount, exchange_rate, underlying_price):
"""Calculate sCoin USD value."""
# Exchange rate increases as interest accrues
underlying_amount = scoin_amount * exchange_rate
value_usd = underlying_amount * underlying_price
return value_usd
# Example:
# 100 sSUI * 1.05 exchange rate * $1.50 SUI price = $157.50
Query sCoin Data
Note: The Python SDK (
sui-scallop-sdk>= 0.3.0a1) exposes sCoin reads onScallopQuery:get_scoin_total_supply(coin_name),get_scoin_amount(s)(underlying ↔ sCoin conversion), andget_scoin_swap_rate(from, to).
Use Cases
An sCoin is a transferable, standalone token that keeps earning — that single property drives every use:
- Yield-bearing stablecoin — idle USDC earns nothing; sUSDC earns the supply rate and stays spendable.
- Transfer a yield position — an ordinary coin transfer moves principal and accrued interest.
- DeFi composability — a plain coin type other Sui protocols can accept, unlike the generic market coin.
- Cold storage with yield — appreciation is via exchange rate, so the holding wallet never signs anything.
Worked examples, the multi-asset portfolio loop, and when not to mint: use-cases.md.
sCoin vs Market Coin
| Feature | Market Coin | sCoin |
|---|---|---|
| Interest-bearing | ✅ | ✅ |
| Stakeable in Spool | ✅ | ❌ |
| Usable as Collateral | ❌ | ❌ |
| Easy to Transfer | ⚠️ Complex type | ✅ Simple |
| DeFi Composability | ⚠️ Limited | ✅ Better |
Minting is a trade-off, not an upgrade: you gain a clean, composable coin type but forfeit spool staking. Only 9 of the 34 markets have a spool, so for most assets there is nothing to give up. See scoin-mechanics.md.
Error Handling
| Error | Cause | Solution |
|---|---|---|
InvalidMarketCoin |
Wrong coin type | Check market coin matches |
InvalidSCoin |
Wrong sCoin type | Check sCoin type matches |
InsufficientBalance |
Not enough sCoin | Check balance |
References
- sCoin Mechanics - How sCoin works
- Use Cases - sCoin applications
- sCoin Types - Type mappings