Bluefin Protocol on Sui
Bluefin is a perpetual futures DEX on Sui. It uses off-chain order matching (sequencer/TEE) with on-chain settlement. Users deposit collateral to an AssetBank, and trades are executed via signed payloads verified on-chain. Supports both cross-margin and isolated-margin positions.
Package IDs
| Package | Original ID | Description |
|---------|------------|-------------|
| Perps v2 | 0xe74481697f432ddee8dd6f9bd13b9d0297a5b63d55f3db25c4d3b5d34dad85b7 | Perpetuals engine: accounts, positions, margining, exchange |
| Vault | 0xfadc2a695e4d92612a203f5bfc48e9f0a5be4d6bad9d08b1e8f06ce9be7a3f5a | Vault system for managed perpetual positions |
Source Files
Decompiled Move source:
- Perps v2 (latest):
packages/mainnet_most_used/0xe2/0ade8adca3df877664e6af96e39143ca32be4a3f74234aa628932fc0b31b82/decompiled_modules/ - Vault:
packages/mainnet_most_used/0xf6/83f21823e6dbbeca59759c2c5f703e3f7f40cfd488191de424e56b0bdb7fd1/decompiled_modules/
Architecture
- ExternalDataStore: Shared object for user-facing deposits. Contains AssetBank and perpetual configs pending sync.
- InternalDataStore: Owned by operator (TEE). Stores accounts, positions, perpetual state, filled orders, sequence hashes.
- Account: Per-user account with cross positions, isolated positions, deposited assets, and fee tiers.
- Position: Perpetual position with size, average_entry_price, is_long, leverage, margin, funding state.
- Perpetual: Market config (symbol, IMR/MMR, fees, tick/step size, price bounds, funding rate, oracle price).
- AssetBank: Multi-asset collateral bank. Deposits go here before being synced to InternalDataStore.
- Vault<T>: Managed vault where users deposit funds, receive shares, and an operator trades on their behalf.
Key Design: Sequencer/TEE Pattern
Most operations (trades, liquidations, funding, withdrawals) are NOT direct user calls. Instead:
- User signs an order off-chain
- Sequencer matches orders and creates signed payloads
- TEE or operator submits BCS-encoded + signed transactions on-chain
- On-chain contracts verify signatures and execute settlement
The only direct user entry point is deposit_to_asset_bank.
Constants
- Base unit: 1e9 (
protocol_decimals = 9) - Primary collateral: USDC
- IMR range: 2%-50% (20_000_000 - 500_000_000)
- MMR minimum: 1% (10_000_000)
- Max fee: 3% (30_000_000)
- Lifespan (tx validity): 90 days (7_776_000_000 ms)
Key Modules
| Module | Purpose |
|--------|---------|
| exchange | Entry points: deposit, trade settlement, liquidation, funding, ADL |
| data_store | ExternalDataStore + InternalDataStore, perpetual/account CRUD |
| account | Account struct, positions, assets, PnL computation, health checks |
| perpetual | Perpetual market config, funding rates, oracle prices |
| bank | AssetBank, multi-asset deposits/withdrawals, asset support |
| margining_engine | Trade math, PnL settlement, fee calculation, health verification |
| signed_number | Signed integer math (value + sign bool) for PnL calculations |
| constants | Action types, base units, payload types, operator roles |
| bluefin_vault | Vault deposit/withdraw/claim with share-based accounting |
Common Integration Patterns
Deposit to Asset Bank (only direct user entry point)
// Deposit collateral (e.g., USDC) to Bluefin for trading
exchange::deposit_to_asset_bank<USDC>(
external_data_store, // &mut ExternalDataStore
string::utf8(b"USDC"), // asset symbol
account_address, // destination account
amount, // amount in asset decimals
&mut coin, // coin to deposit from
ctx
);
Query Account Position
let position = account::get_account_position(account, symbol, is_isolated);
let (perpetual, size, avg_price, is_long, leverage, margin, is_isolated, pending_funding) =
account::get_position_values(&position);
Compute Position PnL
let pnl = account::compute_position_pnl(perpetual_table, &position);
// Returns signed_number::Number (value + sign)
Check Account Health
let (account_value, health) = account::get_account_value_and_health(
account, symbol, is_isolated, perpetual_table, asset_table, threshold
);
let is_liq = account::is_liquidateable(account, symbol, is_isolated, perpetual_table, asset_table);
Query Perpetual Config
let symbol = perpetual::get_symbol(perp);
let oracle_price = perpetual::get_oracle_price(perp);
let (maker_fee, taker_fee) = perpetual::get_fees(perp);
let imr = perpetual::get_imr(perp);
let mmr = perpetual::get_mmr(perp);
Vault: Deposit
bluefin_vault::deposit_to_vault<USDC>(
perpetual_v2, bank_v2, sequencer,
vault, &mut coin, amount, beneficiary, ctx
);
Vault: Withdraw (request shares burn)
bluefin_vault::withdraw_from_vault<USDC>(
perpetual_v2, bank_v2, vault, shares_amount, ctx
);
Vault: Claim Withdrawn Funds
bluefin_vault::claim_withdrawn_funds<USDC>(vault, recipient, amount, ctx);
Related Skills
sui-framework-- Core Sui types (Coin, Balance, Clock)pyth-- Oracle price feeds used by Bluefin
微信扫一扫