Skip to main content
Jupiter Lend is built on three core programs: Liquidity (the shared lending engine), Lending (Earn), and Vaults (Borrow). Lending and Vaults do not hold tokens directly. They CPI into Liquidity, which holds all underlying assets and tracks supply and borrow positions.

Three-program design

ProgramPurposeProgram ID
LiquidityCore layer: token vaults, exchange prices, utilisation, ratesjupeiUmn818Jg1ekPURTpr4mFo29p46vygyykFJ3wZC
LendingEarn: deposit assets, mint jlTokens, supply into Liquidityjup3YeL8QhtSx1e253b2FDvsMNC87fDrgQZivbrndc9
VaultsBorrow: collateralize, borrow, liquidate, supply/borrow via Liquidityjupr81YtYssSyPt8jbnGuiWon5f6x9TcDEFxYe3Bdzi
Core architecture: Users → Lending (Earn) and Vaults (Borrow) → CPI → Operate → Liquidity Layer (Core)

Liquidity (core layer)

Liquidity serves as the foundational layer, owning all token vaults and custodying every deposited and borrowed asset. User-facing protocols never interact with tokens directly; they always make CPI calls into Liquidity to handle supply and borrow operations.

Key state

AccountPurpose
TokenReservePer-mint: vault, exchange prices, totals, utilisation, rate config
UserSupplyPositionPer (mint, protocol): supply amount, withdrawal limit, status
UserBorrowPositionPer (mint, protocol): borrow amount, debt ceiling, status
RateModelInterest rate curve driven by utilisation

Protocol registration

Protocols (Lending, Vaults) must be registered via init_new_protocol(supply_mint, borrow_mint, protocol):
  • Lending: supply mint only (Earn supplies into Liquidity, no borrow)
  • Vaults: supply mint (collateral) and borrow mint (debt)

Operate flow

  1. pre_operate(mint): marks the interacting protocol and timestamp on TokenReserve
  2. Caller moves tokens into the Liquidity vault (via SPL transfer)
  3. operate(supply_amount, borrow_amount, withdraw_to, borrow_to, transfer_type): updates exchange prices, UserSupplyPosition/UserBorrowPosition, TokenReserve totals, and performs transfers
Exchange prices and rates are updated during operate, so interest accrues on every interaction.

Lending (Earn)

Earn lets users deposit assets and receive jlTokens (shares). Deposits are supplied into Liquidity, and jlTokens represent a share of the pool with accrued interest and rewards.

Key state

AccountPurpose
LendingAdminFactory: authority, liquidity_program, rebalancer, auths
LendingPer-mint pool: mint, jl_token_mint, token_reserves_liquidity, supply_position_on_liquidity, exchange prices

User flow

  • Deposit: User transfers tokens → Lending CPIs Liquidity pre_operate + operate(supply) → mints jlTokens
  • Withdraw/Redeem: Burns jlTokens → CPIs Liquidity operate(withdraw) → user receives underlying
The protocol signer for Liquidity CPI is the Lending PDA (not the user). Each Lending pool has a single UserSupplyPosition on Liquidity for that mint. The rewards rate model (separate program) adjusts the jlToken exchange price to include rewards on top of base yield.

CPI summary

CallerSignerSupply positionBorrow position
LendingLending PDALending PDA (1 per mint)None

Vaults (Borrow)

Borrow vaults are collateralized lending markets. Each vault has a supply token (collateral) and a borrow token (debt). Users deposit collateral, borrow against it, and can be liquidated if collateral falls below the liquidation threshold. Positions are represented as NFTs.

Key state

AccountPurpose
VaultConfigParams: supply_token, borrow_token, oracle, collateral_factor, liquidation_threshold, rebalancer
VaultStateRuntime: total_supply, total_borrow, topmost_tick, absorbed debt/collateral
PositionUser position: vault_id, tick, supply_amount, debt, liquidation status
BranchLiquidation structure: minima tick, debt factor, status
TickPrice-ratio ticks for collateralization

Tick-based pricing

Vaults use tick-based pricing: collateralization is computed from a price-ratio tick rather than a simple LTV. Collateral factor is derived from tick ratio. Branches track liquidation state and merge positions when liquidated.

User flow

  • init_position: create Position + position mint NFT
  • operate: deposit/withdraw collateral, borrow/repay debt
  • liquidate: liquidate undercollateralized positions
  • rebalance: rebalancer supplies/borrows on Liquidity to match vault demand
The protocol signer for Liquidity CPI is the VaultConfig PDA. Each vault has both a UserSupplyPosition (collateral) and a UserBorrowPosition (debt) on Liquidity. The Oracle program provides prices for collateral valuation and liquidation checks.

CPI summary

CallerSignerSupply positionBorrow position
VaultsVaultConfig PDAVaultConfig PDAVaultConfig PDA

Shared data flow

Both Lending and Vaults share the same Liquidity layer:
Shared accountUsed byRole
TokenReserveBothAggregated supply/borrow per mint
UserSupplyPositionBothPer-protocol supply
UserBorrowPositionVaultsPer-protocol borrow
Vault (ATA)BothLiquidity holds all tokens
RateModelBothInterest rate parameters

Deposit (Earn)

User → Lending.deposit() → transfer tokens to Liquidity vault
                         → pre_operate (Lending PDA)
                         → operate(supply, borrow=0)
                         → mint jlTokens

Borrow (Vaults)

User → Vaults.operate() → transfer collateral to vault
                        → pre_operate (VaultConfig PDA)
                        → operate(supply=collateral, borrow=debt)
                        → update Position / Branch / Tick

Dependency graph

ProgramDepends on
LendingLiquidity (CPI), Lending Rewards Rate Model
VaultsLiquidity (CPI), Oracle
LiquidityStandalone
OracleStandalone