Sable Delta Neutral
The Delta Neutral vault earns yield by capturing the spread between USDC borrow cost and USDC yield.
Risk Level: 4 (Medium-High)
Strategy: Deposit WBTC → Borrow USDC → Supply USDC to Vesu PRIME → Earn spread
Strategy Overview
WBTC (Re7 xBTC Pool)
↓ Supply as collateral
Borrow USDC (50% LTV)
↓ Deploy to yield
Vesu PRIME USDC Pool
↓
Spread = USDC Supply APY - USDC Borrow APY + BTCFi STRK Rewards
Why “Delta Neutral”?
This strategy is BTC price neutral because:
- WBTC collateral value = $100
- USDC debt value = $50 (50% LTV)
- If BTC ↑2x: collateral = 200,debtstill50 → profit $100
- If BTC ↓0.5x: collateral = 50,debtstill50 → breakeven (no loss from BTC drop)
The vault earns from the interest rate differential, not BTC price movement.
Yield Sources
| Source | Type | Net Impact |
|---|
| Vesu PRIME USDC Supply APY | Revenue | +5-10% |
| Re7 xBTC USDC Borrow APY | Cost | -2-5% |
| BTCFi STRK Rewards | Revenue | +3-8% |
| Net Spread | Profit | +6-13% APY |
Risk Profile
- Liquidation risk: If BTC drops >50%, USDC debt could exceed collateral value
- Negative spread risk: If USDC borrow cost > supply yield, vault loses money
- Oracle risk: Uses Pragma Oracle for BTC/USD price (auto-deploy only)
- Dual Vesu pool risk: Exposure to both Re7 xBTC and PRIME USDC pools
Contract Architecture
File: delta_neutral.cairo (~800 LOC)
Deployed: 0x06c8779ee7ed14b35ac5c6eae5dc721cc3e8104a65ffef4b5252babc407a1012
Core Components
Dual Vesu Pools
Auto-Deploy Strategy
Flash Loan Unwind
Delta Neutral manages two separate Vesu positions:struct Storage {
// ...
vesu_singleton: ContractAddress,
wbtc_pool_id: felt252, // Re7 xBTC (collateral + debt)
usdc_pool_id: felt252, // PRIME USDC (yield)
debt_asset: ContractAddress, // USDC
// Strategy state
wbtc_collateral: u256,
usdc_debt: u256,
usdc_deployed: u256,
pragma_oracle: ContractAddress,
}
WBTC Pool (Re7 xBTC):
- Collateral: WBTC
- Debt: USDC
USDC Pool (PRIME):
- Collateral: USDC
- Debt: None (pure supply)
Deposits auto-execute the full strategy:fn _deploy_to_strategy(ref self: ContractState, amount: u256) {
// Step 1: Supply WBTC as collateral to Re7 xBTC pool
wbtc.approve(wbtc_pool_addr, amount);
vesu.modify_position(/* deposit WBTC collateral */);
// Step 2: Get BTC price from Pragma Oracle
let pragma = IPragmaOracleDispatcher { contract_address: oracle_addr };
let price_response = pragma.get_data_median(DataType::SpotEntry(0x4254432f555344));
let btc_price: u256 = price_response.price.into();
// Step 3: Borrow USDC at 50% LTV
// usdc_borrow = wbtc_sats * btc_price_8dec * 50 / 10^12
let usdc_borrow = (amount * btc_price * 50) / 1000000000000;
vesu.modify_position(/* borrow USDC */);
// Step 4: Supply ALL borrowed USDC to PRIME yield pool
usdc.approve(usdc_pool_addr, usdc_borrow);
usdc_pool.modify_position(/* deposit USDC collateral */);
}
From delta_neutral.cairo:740 Withdrawals use a flash loan to atomically unwind both positions:fn on_flash_loan(
ref self: ContractState,
sender: ContractAddress,
asset: ContractAddress, // USDC
amount: u256, // Full USDC debt
data: Span<felt252>,
) {
// Step 1: Repay ALL USDC debt + withdraw ALL WBTC collateral from Re7
usdc.approve(wbtc_pool_addr, max_u256);
vesu.modify_position(ModifyPositionParams {
collateral: Amount { /* withdraw ALL WBTC */ },
debt: Amount { /* repay ALL USDC debt */ },
});
// Step 2: Swap WBTC -> USDC via AVNU (Ekubo WBTC/USDC pool)
wbtc.approve(avnu_addr, wbtc_to_sell);
avnu.multi_route_swap(
wbtc_addr, wbtc_to_sell, usdc_addr,
0, min_usdc_out, this, 0, Zero::zero(), routes,
);
// Step 3: Approve USDC for flash loan repayment
usdc.approve(wbtc_pool_addr, amount);
// All positions closed, WBTC becomes idle
self.usdc_debt.write(0);
self.wbtc_collateral.write(0);
}
From delta_neutral.cairo:995
Key Functions
User Functions
Deposit WBTC and receive yvBTC-DN sharesParameters:
assets (u256): Amount of WBTC to deposit (8 decimals)
receiver (ContractAddress): Address to receive vault shares
Returns: u256 — Number of shares mintedAuto-deploys to:
- Supply WBTC to Re7 xBTC pool
- Query BTC price from Pragma Oracle
- Borrow USDC at 50% LTV
- Supply USDC to PRIME yield pool
Burn shares and withdraw WBTCParameters:
assets (u256): Amount of WBTC to withdraw
receiver (ContractAddress): Address to receive WBTC
owner (ContractAddress): Share owner
Returns: u256 — Number of shares burnedFlash Loan Unwind (if USDC debt exists):
- Withdraw ALL USDC from PRIME pool
- Flash loan USDC to cover gap
- Repay USDC debt + withdraw WBTC from Re7
- Swap ~5% WBTC → USDC to repay flash loan
- Send remaining WBTC to user
Curator Functions
Supply idle WBTC to Re7 xBTC pool as collateralParameters:
amount (u256): WBTC to supply
fn deploy_collateral(ref self: ContractState, amount: u256)
Implementation at delta_neutral.cairo:343
Borrow USDC against WBTC collateral, then deploy to PRIME poolParameters:
borrow_amount (u256): USDC to borrow (6 decimals)
fn borrow_and_deploy_usdc(ref self: ContractState, borrow_amount: u256)
Implementation at delta_neutral.cairo:373Two-step process:
- Borrow USDC from Re7 xBTC pool
- Supply USDC to PRIME pool (earns yield)
Withdraw USDC from PRIME, repay Re7 debtParameters:
amount (u256): USDC to unwind (6 decimals)
fn unwind_usdc(ref self: ContractState, amount: u256)
Implementation at delta_neutral.cairo:425Leaves 2 microUSDC buffer to avoid Vesu rounding errors on repayment.
Withdraw WBTC collateral from Re7 poolParameters:
amount (u256): WBTC to withdraw (8 decimals)
fn withdraw_collateral(ref self: ContractState, amount: u256)
Implementation at delta_neutral.cairo:492Can only withdraw if health factor remains safe (debt < 70% of collateral value).
Emergency full unwind via flash loanParameters:
wbtc_to_sell (u256): WBTC to swap for USDC repayment
min_usdc_out (u256): Minimum USDC from swap (slippage protection)
routes (Array<Route>): AVNU swap routes
fn flash_unwind(ref self: ContractState, wbtc_to_sell: u256, min_usdc_out: u256, routes: Array<Route>)
Implementation at delta_neutral.cairo:584
Integration with External Protocols
Vesu Re7 xBTC Pool (Collateral + Debt)
Pool ID: 0x03a8416bf20d036df5b1cf3447630a2e1cb04685f6b0c3a70ed7fb1473548ecf
Delta Neutral uses this pool for:
- Collateral: WBTC
- Debt: USDC borrowed at 50% LTV
vesu.modify_position(ModifyPositionParams {
collateral_asset: wbtc_addr,
debt_asset: usdc_addr,
user: vault_address,
collateral: Amount { /* WBTC amount */ },
debt: Amount { /* USDC amount, positive = borrow */ },
});
Vesu PRIME USDC Pool (Yield)
Pool ID: 0x03976cac265a12609934089004df458ea29c776d77da423c96dc761d09d24124
Delta Neutral supplies all borrowed USDC to this pool to earn yield:
usdc_pool.modify_position(ModifyPositionParams {
collateral_asset: usdc_addr,
debt_asset: usdc_pool_debt_asset, // Valid registered asset (no debt)
user: vault_address,
collateral: Amount { /* USDC amount */ },
debt: Amount { /* zero */ },
});
Pragma Oracle (Auto-Deploy Only)
Address: pragma_oracle (constructor parameter)
Delta Neutral uses Pragma to calculate 50% LTV borrow amount:
let pragma = IPragmaOracleDispatcher { contract_address: oracle_addr };
let price_response = pragma.get_data_median(DataType::SpotEntry(0x4254432f555344));
let btc_price: u256 = price_response.price.into(); // 8 decimals
// USDC to borrow = wbtc_sats * btc_price * 50 / 10^12
let usdc_borrow = (amount * btc_price * 50) / 1000000000000;
From delta_neutral.cairo:776
Data Type: SpotEntry(0x4254432f555344) = “BTC/USD” as felt252
AVNU WBTC/USDC Swap (Flash Unwind)
For flash loan repayment, Delta Neutral swaps WBTC → USDC via Ekubo (hardcoded route):
let swap_params: Array<felt252> = array![
token0, token1, // WBTC, USDC (sorted by address)
0x20c49ba5e353f80000000000000000, // fee 0.05%
0x3e8, // tick_spacing 1000
0x0, // extension
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, // sqrt_ratio_limit (max)
];
From delta_neutral.cairo:960
Example Usage
Depositing WBTC
import { Contract } from 'starknet'
const deltaNeutralVault = new Contract(deltaNeutralABI, deltaNeutralAddress, account)
const wbtc = new Contract(erc20ABI, wbtcAddress, account)
// Check minimum deposit
const minDeposit = await deltaNeutralVault.min_deposit()
console.log('Min deposit:', minDeposit / 1e8, 'WBTC')
// Deposit (auto-borrows + deploys USDC)
const amount = 10_000_000n // 0.1 WBTC
await wbtc.approve(deltaNeutralAddress, amount)
await deltaNeutralVault.deposit(amount, account.address)
// Check yvBTC-DN balance
const shares = await deltaNeutralVault.balance_of(account.address)
Checking Strategy State
// Strategy info: (wbtc_collateral, usdc_debt, 0, paused)
const [wbtcColl, usdcDebt, _, paused] = await deltaNeutralVault.get_strategy_info()
console.log('WBTC collateral:', wbtcColl / 1e8)
console.log('USDC debt:', usdcDebt / 1e6)
// USDC deployed to PRIME pool
const usdcDeployed = await deltaNeutralVault.get_usdc_deployed()
console.log('USDC in PRIME pool:', usdcDeployed / 1e6)
// Verify 50% LTV
const btcPrice = 95000 // Example: $95k/BTC
const collateralValue = (wbtcColl / 1e8) * btcPrice
const ltv = (usdcDebt / 1e6) / collateralValue
console.log('LTV:', (ltv * 100).toFixed(2) + '%') // Should be ~50%
Monitoring Yield Spread
// Fetch Vesu pool APYs from API
const vesuAPI = 'https://api.vesu.xyz/pools'
const pools = await fetch(vesuAPI).then(r => r.json())
const re7xBTC = pools.find(p => p.pool_id === '0x03a8416bf20d036df5b1cf3447630a2e1cb04685f6b0c3a70ed7fb1473548ecf')
const primeUSDC = pools.find(p => p.pool_id === '0x03976cac265a12609934089004df458ea29c776d77da423c96dc761d09d24124')
const usdcBorrowAPY = re7xBTC.usdc_borrow_apy // Cost
const usdcSupplyAPY = primeUSDC.usdc_supply_apy // Revenue
const btcfiRewardsAPY = 5.0 // Example STRK rewards
const netSpread = usdcSupplyAPY - usdcBorrowAPY + btcfiRewardsAPY
console.log('Net yield spread:', netSpread.toFixed(2) + '% APY')
Withdrawing WBTC
// Withdraw all (triggers flash loan unwind)
const maxWithdraw = await deltaNeutralVault.max_withdraw(account.address)
await deltaNeutralVault.withdraw(maxWithdraw, account.address, account.address)
// Flash loan process:
// 1. Withdraw ALL USDC from PRIME pool (~$50 if started with 0.1 WBTC)
// 2. Flash loan $0.50 USDC to cover rounding gap
// 3. Repay $50 USDC debt to Re7 + withdraw 0.1 WBTC collateral
// 4. Swap 0.001 WBTC -> $0.95 USDC (enough to repay flash loan)
// 5. User receives ~0.099 WBTC
Security Considerations
Risks
- Liquidation Risk: If BTC drops >50% suddenly, USDC debt could exceed 70% of collateral value
- Negative Spread Risk: If USDC borrow APY > supply APY, vault loses money until spread recovers
- Oracle Risk: Pragma Oracle failure could cause incorrect borrow amounts on auto-deploy
- Dual Pool Risk: Exposure to both Re7 xBTC and PRIME USDC smart contract risks
- Flash Loan Dependency: Withdrawals require Vesu flash loans to work
- USDC Liquidity Risk: Large withdrawals from PRIME pool could face liquidity issues
Risk Mitigation
- 50% LTV buffer: Leaves 20% margin before 70% liquidation threshold
- Flash loan safety: Only vault can initiate
on_flash_loan callback
- PRIME pool liquidity: Largest USDC pool on Vesu (~$50M TVL)
- Rounding buffer: Leaves 2 microUSDC on repayments to avoid reverts
- Pause mechanism: Owner can halt deposits if spread turns negative
- Proportional share burn: On partial unwinds, users only lose proportional shares (not full balance)
Health Factor Monitoring
// Monitor liquidation risk
const vesuPool = new Contract(vesuPoolABI, re7xBTCPoolAddress, provider)
const [position, collValue, debtValue] = await vesuPool.position(
wbtcAddress, // collateral_asset
usdcAddress, // debt_asset
deltaNeutralAddress // user (vault)
)
// Health factor = (collateral * LT) / debt
// LT (liquidation threshold) ≈ 70% for Re7 xBTC USDC debt
const healthFactor = (collValue * 70n) / (debtValue * 100n)
console.log('Health factor:', Number(healthFactor) / 100)
// Safe: health > 1.4
// Caution: health 1.0-1.4
// Danger: health < 1.0 (liquidation imminent)
Additional Resources