Skip to main content

Sable Trident

The Trident vault executes a 3-loop recursive staking strategy using Endur and Vesu to amplify base staking APY by ~3x.
Risk Level: 3 (Medium)
Strategy: 3x loop: WBTC → Endur → xWBTC → Vesu supply → borrow WBTC → repeat

Strategy Overview

Loop 1: WBTC → Endur → xWBTC → Vesu collateral → borrow WBTC (70% LTV)
Loop 2: Borrowed WBTC → Endur → xWBTC → Vesu collateral → borrow WBTC
Loop 3: Borrowed WBTC → Endur → xWBTC → Vesu collateral (no final borrow)

Result: 3x exposure to Endur staking APY via recursive leverage

How It Works

  1. Deposit WBTC into Endur → receive xWBTC liquid staking shares
  2. Supply xWBTC to Vesu Re7 xBTC pool as collateral
  3. Borrow WBTC against xWBTC collateral (70% LTV)
  4. Repeat steps 1-3 two more times
Final position: ~3.4x WBTC value in xWBTC staking for same initial deposit.

Yield Sources

SourceTypeAmplification
Endur Staking APYBase yield3x (three staked positions)
xWBTC AppreciationCapital gain3x exposure to xWBTC/WBTC ratio
BTCFi STRK RewardsIncentiveOn all Vesu collateral
Example: If Endur base APY = 5%, Trident effective APY ≈ 15% (minus borrow cost, which is offset by BTCFi rewards).

Risk Profile

  • Moderate leverage: 3x loop creates ~2.4x net leverage
  • Liquidation risk: If xWBTC/WBTC ratio drops sharply, Vesu positions could be liquidated
  • Borrow cost: WBTC borrow APY reduces net yield (but BTCFi rewards cover this)
  • Unwinding complexity: Requires iterative deleverage or flash loan

Contract Architecture

File: trident.cairo (~700 LOC)
Deployed: 0x058aadc9db62700de03d89a7c8f2952851d94e75f854cc6a340ef92d00cd3fb8

Core Components

Trident executes 3 staking loops on every deposit:
fn _deploy_to_strategy(ref self: ContractState, amount: u256) {
    let num_loops: u8 = 3;
    let mut remaining_wbtc = amount;
    let mut total_xwbtc_added: u256 = 0;
    let mut total_wbtc_borrowed: u256 = 0;
    let mut i: u8 = 0;

    while i < num_loops {
        // 1. Stake WBTC -> Endur -> xWBTC
        wbtc.approve(endur_addr, remaining_wbtc);
        let xwbtc_shares = endur.deposit(remaining_wbtc, this);
        total_xwbtc_added += xwbtc_shares;

        // 2. Supply xWBTC to Vesu as collateral
        xwbtc_token.approve(vesu_addr, xwbtc_shares);
        vesu.modify_position(/* deposit collateral */);

        // 3. Borrow WBTC from Vesu (70% LTV)
        let borrow_amount = (remaining_wbtc * 70) / 100;
        if borrow_amount == 0 { break; }
        vesu.modify_position(/* borrow WBTC */);
        total_wbtc_borrowed += borrow_amount;

        // 4. Use borrowed WBTC for next loop
        remaining_wbtc = borrow_amount;
        i += 1;
    };
}
From trident.cairo:823

Key Functions

User Functions

deposit
function
Deposit WBTC and receive yvBTC-TRI sharesParameters:
  • assets (u256): Amount of WBTC to deposit (must be ≥ min_deposit)
  • receiver (ContractAddress): Address to receive vault shares
Returns: u256 — Number of shares minted
Auto-executes 3-loop strategy:
  1. Loop 1: 100% WBTC → 70% borrow
  2. Loop 2: 70% WBTC → 49% borrow
  3. Loop 3: 49% WBTC → no borrow
Final: ~2.19x WBTC staked, ~1.19x WBTC debt
withdraw
function
Burn shares and withdraw WBTC (flash loan unwind)Parameters:
  • assets (u256): Amount of WBTC to withdraw
  • receiver (ContractAddress): Address to receive WBTC
  • owner (ContractAddress): Share owner
Returns: u256 — Number of shares burned
Automatic Flash Loan Unwind:
  • Flash borrows full WBTC debt from Vesu
  • Repays debt + withdraws all xWBTC collateral
  • Swaps xWBTC → WBTC via AVNU (hardcoded Ekubo route)
  • Repays flash loan from swap proceeds
  • User receives remaining WBTC
Tolerance: Accepts up to 0.5% slippage due to xWBTC swap conversion rounding.

Curator Functions

execute_staking_loop
function
Manually execute N staking loops (for idle WBTC)Parameters:
  • wbtc_amount (u256): WBTC to deploy
  • num_loops (u8): Number of loops (1-10)
fn execute_staking_loop(ref self: ContractState, wbtc_amount: u256, num_loops: u8)
Implementation at trident.cairo:412
deleverage
function
Iteratively unwind N loops (repay debt → withdraw collateral → unstake)Parameters:
  • loops_to_unwind (u8): Number of loops to reverse
fn deleverage(ref self: ContractState, loops_to_unwind: u8)
Implementation at trident.cairo:497
Endur Queue: If Endur has liquidity, unstakes xWBTC immediately. Otherwise, xWBTC remains idle.
flash_unwind
function
Atomically close all positions via flash loanParameters:
  • min_amount_out (u256): Minimum WBTC from xWBTC swap (slippage protection)
  • routes (Array<Route>): AVNU swap routes (xWBTC → WBTC)
fn flash_unwind(ref self: ContractState, min_amount_out: u256, routes: Array<Route>)
Implementation at trident.cairo:630Used internally by _ensure_idle_balance during withdrawals.

Integration with External Protocols

Endur xWBTC Vault

Address: endur_vault (constructor parameter) Trident stakes WBTC 3 times via Endur’s ERC-4626 vault:
let endur = IERC4626Dispatcher { contract_address: endur_addr };
let xwbtc_shares = endur.deposit(wbtc_amount, vault_address);

Vesu Re7 xBTC Pool

Pool ID: 0x03a8416bf20d036df5b1cf3447630a2e1cb04685f6b0c3a70ed7fb1473548ecf Trident uses this pool for:
  • Collateral: xWBTC shares
  • Debt: WBTC borrowed at 70% LTV
vesu.modify_position(ModifyPositionParams {
    collateral_asset: endur_addr,  // xWBTC
    debt_asset: wbtc_addr,         // WBTC
    user: vault_address,
    collateral: Amount { /* xWBTC shares, positive = deposit */ },
    debt: Amount { /* WBTC amount, positive = borrow */ },
});

AVNU xWBTC/WBTC Swap

For flash loan unwind, Trident swaps all xWBTC → WBTC via Ekubo (hardcoded route):
let swap_params: Array<felt252> = array![
    wbtc_felt,    // token0 (WBTC < xWBTC by address)
    endur_felt,   // token1 (xWBTC)
    0x68db8bac710cb4000000000000000, // fee 0.01%
    0xc8,         // tick_spacing = 200
    0x0,          // extension
    0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, // sqrt_ratio_limit (max)
];
From trident.cairo:920

Example Usage

Depositing WBTC

import { Contract } from 'starknet'

const tridentVault = new Contract(tridentABI, tridentAddress, account)
const wbtc = new Contract(erc20ABI, wbtcAddress, account)

// Check minimum deposit
const minDeposit = await tridentVault.min_deposit()
console.log('Min deposit:', minDeposit / 1e8, 'WBTC')

// Deposit (auto-executes 3-loop strategy)
const amount = 20_000_000n // 0.2 WBTC
await wbtc.approve(tridentAddress, amount)
await tridentVault.deposit(amount, account.address)

// Check yvBTC-TRI balance
const shares = await tridentVault.balance_of(account.address)

Checking Leverage Stats

// Strategy info: (collateral, debt, loops, paused)
const [xwbtcCollateral, wbtcDebt, numLoops, paused] = await tridentVault.get_strategy_info()

console.log('xWBTC collateral:', xwbtcCollateral / 1e8)
console.log('WBTC debt:', wbtcDebt / 1e8)
console.log('Leverage loops:', numLoops)

// Convert xWBTC collateral to WBTC equivalent
const endurVault = new Contract(erc4626ABI, endurAddress, provider)
const wbtcValue = await endurVault.convert_to_assets(xwbtcCollateral)
console.log('Total WBTC staked value:', wbtcValue / 1e8)

// Net exposure
const netExposure = wbtcValue - wbtcDebt
console.log('Net WBTC exposure:', netExposure / 1e8)

Withdrawing WBTC

// Get max withdrawable
const maxWithdraw = await tridentVault.max_withdraw(account.address)

// Withdraw (triggers flash loan unwind)
await tridentVault.withdraw(maxWithdraw, account.address, account.address)

// Flash loan automatically:
// 1. Borrows full WBTC debt from Vesu (zero fee)
// 2. Repays debt + withdraws all xWBTC
// 3. Swaps xWBTC -> WBTC via AVNU
// 4. Repays flash loan
// 5. Sends remaining WBTC to user

Security Considerations

Risks

  1. Liquidation Risk: If xWBTC/WBTC ratio drops >30%, Vesu positions could be liquidated
  2. Flash Loan Dependency: Withdrawals require Vesu flash loans to work
  3. Swap Slippage: Large withdrawals may face xWBTC/WBTC swap slippage on Ekubo
  4. Endur Protocol Risk: All positions depend on Endur’s xWBTC mechanism
  5. Vesu Pool Risk: Smart contract vulnerabilities in Re7 xBTC pool

Risk Mitigation

  • Conservative LTV: 70% LTV leaves 30% buffer before liquidation
  • xWBTC backing: Endur’s 1:1 WBTC backing mechanism keeps xWBTC stable
  • Flash loan safety: Trident only initiates flash loans (Vesu can’t call on_flash_loan directly)
  • Tolerance buffer: Withdrawals accept up to 0.5% slippage to handle rounding
  • Pause mechanism: Owner can halt deposits if issues arise

Health Factor Monitoring

// Monitor health factor manually
const vesuPool = new Contract(vesuPoolABI, vesuPoolAddress, provider)
const [position, collValue, debtValue] = await vesuPool.position(
  endurAddress,  // collateral_asset (xWBTC)
  wbtcAddress,   // debt_asset
  tridentAddress // user (vault)
)

// Health factor = (collateral * LT) / debt
// LT (liquidation threshold) ≈ 75% for Vesu Re7 xBTC
const healthFactor = (collValue * 75n) / (debtValue * 100n)
console.log('Health factor:', Number(healthFactor) / 100)

// Safe: health > 1.5
// Caution: health 1.0-1.5
// Danger: health < 1.0 (liquidation risk)

Additional Resources

Build docs developers (and LLMs) love