Judging

Jupiter Lend

Earn Yield, Borrow Assets, Maximize Returns. Better for Borrowers, Simpler for Lenders.

  • Start date12 Feb 2026
  • End date13 Mar 2026
  • Total awards$107,000 in USDC
  • Duration29 days

Jupiter Lend audit details

  • Total Prize Pool: $107,000 in USDC
    • HM awards: up to $96,000 in USDC
      • If no valid Highs or Mediums are found, the HM pool is $0
    • QA awards: $4,000 in USDC
    • Judge awards: $6,500 in USDC
    • Scout awards: $500 in USDC
  • Read our guidelines for more details
  • Starts February 12, 2026 20:00 UTC
  • Ends March 13, 2026 20:00 UTC

❗ Important notes for wardens

  1. Since this audit includes live/deployed code, all submissions will be treated as sensitive:
    • Wardens are encouraged to submit High-risk submissions affecting live code promptly, to ensure timely disclosure of such vulnerabilities to the sponsor and guarantee payout in the case where a sponsor patches a live critical during the audit.
    • Submissions will be hidden from all wardens (SR and non-SR alike) by default, to ensure that no sensitive issues are erroneously shared.
    • If the submissions include findings affecting live code, there will be no post-judging QA phase. This ensures that awards can be distributed in a timely fashion, without compromising the security of the project. (Senior members of C4 staff will review the judges’ decisions per usual.)
    • By default, submissions will not be made public until the report is published.
    • Exception: if the sponsor indicates that no submissions affect live code, then we’ll make submissions visible to all authenticated wardens, and open PJQA to verified wardens per the usual C4 process.
    • The "live criticals" exception therefore applies.
  2. Judging phase risk adjustments (upgrades/downgrades):
    • High- or Medium-risk submissions downgraded by the judge to Low-risk (QA) will be ineligible for awards.
    • Upgrading a Low-risk finding from a QA report to a Medium- or High-risk finding is not supported.
    • As such, wardens are encouraged to select the appropriate risk level carefully during the submission phase.

Publicly known issues

Anything included in this section is considered a publicly known issue and is therefore ineligible for awards.

Known DoS Risk

If a transaction loads more than 64 accounts, per current architecture of protocol, the Liquidation program and its operation may be DoS'd. (See Zenith Audit Exhibit H1)

Token Extension Incompatibility

Token extensions support can break protocol. (See Zenith Audit Exhibit M5)

Rent Claim Issue

There is currently no way to close a position PDA to claim the rent back. (see Certora FV, exhibit L03)

First / Last Vault User Issues

Issues related to the first and last user of the Vault are out-of-scope as we are aware of concerns around that and we intend to create a forever-locked dust position on each market.

Phantom Debt Creation

It is possible for user to create a dust phantom debt position where the debt is not counted in the tick, but exists on position. But as tick acknowledges this debt during position interaction, so there is no effect on the working on the protocol.

Overview

A two layer modular architecture that enhances capital efficiency, scalability, and risk management.

Architecture

Jupiter Lend implements a two-layer modular architecture that separates liquidity management from user-facing operations, enabling unified liquidity across multiple protocols.

Architecture Diagram

┌─────────────────────────────────────────────────────────────────┐
│                          User Layer                             │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐              │
│  │   Wallets   │  │    dApps    │  │ Liquidators │              │
│  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘              │
└─────────┼─────────────────┼─────────────────┼───────────────────┘
          │                 │                 │
          ▼                 ▼                 ▼
┌──────────────────────────────────────────────────────────────────┐
│                      Protocol Layer                              │
│  ┌──────────────────┐         ┌──────────────────┐               │
│  │  Lending Protocol│         │  Vaults Protocol │               │
│  │                  │         │                  │               │
│  │  • Deposit       │         │  • Operate       │               │
│  │  • Withdraw      │         │  • Liquidate     │               │
│  │  • Rebalance     │         │  • Rebalance     │               │
│  └────────┬─────────┘         └────────┬─────────┘               │
│           │         ┌──────────────────┘                         │
│           │         │     CPI Calls (Cross-Program Invocations)  │
└───────────┼─────────┼────────────────────────────────────────────┘
            │         │
            ▼         ▼
┌──────────────────────────────────────────────────────────────────────────┐
│                      Liquidity Layer                                     │
│  ┌────────────────────────────────────────────────────────────────────┐  │
│  │          Unified Liquidity Pool (Single Orderbook)                 │  │
│  │                                                                    │  │
│  │  • Operate (Supply, Withdraw, Borrow, Payback)                     │  │
│  │  • Unified liquidity management, token limits and rates management.│  │
│  │  • Atomic transaction execution                                    │  │
│  └────────────────────────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────────────────────────┘
            ▲                              ▲
            │                              │
     ┌──────┴──────┐              ┌────────┴────────┐
     │   Oracle    │              │   Flash Loan    │
     │   Program   │              │    Program      │
     └─────────────┘              └─────────────────┘

Key Benefits

  • Unified Liquidity: All protocols share the same liquidity pool, maximizing capital efficiency and reducing fragmentation
  • Discrete Risk Framework: Each protocol (Lending, Vaults) maintains a distinct set of risk parameters (CF, LT, etc) while leveraging shared liquidity within set limits
  • Modular Design: New protocols can be added without modifying the core liquidity layer

Repository Structure

2026-02-jupiter-lend/
├── programs/                       # Solana programs
│   ├── liquidity/                  # Core liquidity layer
│   ├── lending/                    # Lending protocol
│   ├── vaults/                     # Collateralized borrow protocol
│   ├── oracle/                     # Oracle that utilizes multiple oracles
│   ├── flashloan/                  # Flash loan functionality
│   └── lending_reward_rate_model/  # Reward distribution
├── __tests__/                      # Test suite
├── temp/                           # Build artifacts
└── Anchor.toml                     # Anchor configuration

Program Overview

Liquidity

The Liquidity program serves as the foundational single-pool architecture that manages all liquidity within the system. It tracks the deposit and borrow positions of integrated programs and enforces program-specific borrowing and withdrawal controls, including rate-limited mechanisms such as debt ceilings and withdrawal limits. Access to this program is permission-based, and end users never interact with it directly. Only whitelisted programs, such as Vaults and Lending, can interact with it through CPIs. All other programs in the ecosystem are built on top of this liquidity infrastructure.

Key Method

  • Operate: The core interaction method that handles all liquidity operations (supply, withdraw, borrow, payback) in a single atomic transaction.

Lending

The Lending program provides a straightforward lending protocol that offers users direct exposure to yield generation. Users can supply assets to earn interest, making it the core yield-bearing mechanism within the protocol suite.

Key Methods:

  • Deposit: Allows users to supply assets into the protocol
  • Withdraw: Enables users to withdraw their supplied assets
  • Rebalance: Synchronizes the protocol's accounting with its actual position on the Liquidity layer, ensuring accurate asset tracking and exchange rates. When rewards are active, rebalance syncs the orderbook to incorporate accrued rewards

Vaults

The Vaults program implements a collateralized debt position (CDP) system. Users deposit collateral assets to borrow debt tokens against them, enabling leverage and capital efficiency. This program handles collateral management, debt issuance, and liquidation mechanisms through a tick-based architecture for efficient risk management.

Key Methods:

  • Operate: Manages collateral and debt positions by interacting with the Liquidity layer, handling deposits, withdrawals, borrows, and paybacks
  • Liquidate: Allows liquidators to repay debt on behalf of risky positions in exchange for collateral at a discount (liquidation penalty). Positions become liquidatable when they exceed the liquidation threshold (e.g., 90% LT). The liquidation mechanism operates on a tick-based system, where positions are liquidated based on their risk level. Positions with ratio above the liquidation max limit (e.g., 95% LML) is automatically absorbed by the protocol
  • Rebalance: Reconciles vault positions with the underlying Liquidity layer to maintain accurate collateral and debt accounting. When rewards are active on the protocol, rebalance syncs the orderbook to account for accrued rewards

Oracle

The Oracle program provides reliable price feeds for the protocol. It supports data sources from multiple providers including Pyth, Chainlink, and Solana-native pools to ensure accurate asset pricing.

Flash Loan

The Flash Loan program provides atomic loans that must be borrowed and repaid within a same transaction. This enables arbitrage, liquidations, and other advanced DeFi operations without requiring upfront capital.

Lending Reward Rate Model

The Lending Reward Rate Model program manages the calculation and distribution of rewards for the Lending protocol, determining reward rates based on protocol parameters and market conditions.


Scope

Files in scope

Note: The nSLoC counts in the following table have been automatically generated and may differ depending on the definition of what a "significant" line of code represents. As such, they should be considered indicative rather than absolute representations of the lines involved in each contract.

FilenSLOC
crates/library/src/errors.rs31
crates/library/src/lib.rs4
crates/library/src/math/bn.rs488
crates/library/src/math/casting.rs34
crates/library/src/math/ceil_div.rs73
crates/library/src/math/floor_div.rs120
crates/library/src/math/merkle.rs386
crates/library/src/math/mod.rs8
crates/library/src/math/safe_math.rs129
crates/library/src/math/tick.rs204
crates/library/src/math/u256.rs494
crates/library/src/structs.rs16
crates/library/src/token/mod.rs2
crates/library/src/token/spl.rs130
programs/flashloan/src/constants.rs7
programs/flashloan/src/errors.rs32
programs/flashloan/src/events.rs13
programs/flashloan/src/invokes/liquidity_layer.rs91
programs/flashloan/src/invokes/mod.rs1
programs/flashloan/src/lib.rs138
programs/flashloan/src/state/context.rs99
programs/flashloan/src/state/mod.rs6
programs/flashloan/src/state/seeds.rs1
programs/flashloan/src/state/state.rs97
programs/flashloan/src/validate.rs118
programs/lending/src/constant.rs8
programs/lending/src/errors.rs30
programs/lending/src/events.rs42
programs/lending/src/invokes/f_token.rs47
programs/lending/src/invokes/liquidity_layer.rs91
programs/lending/src/invokes/mod.rs4
programs/lending/src/lib.rs95
programs/lending/src/module/admin.rs179
programs/lending/src/module/mod.rs4
programs/lending/src/module/user.rs63
programs/lending/src/state/context.rs370
programs/lending/src/state/mod.rs6
programs/lending/src/state/seeds.rs6
programs/lending/src/state/state.rs28
programs/lending/src/utils/deposit.rs100
programs/lending/src/utils/helpers.rs191
programs/lending/src/utils/mod.rs8
programs/lending/src/utils/rebalance.rs38
programs/lending/src/utils/withdraw.rs80
programs/lendingRewardRateModel/src/constants.rs8
programs/lendingRewardRateModel/src/errors.rs30
programs/lendingRewardRateModel/src/events.rs37
programs/lendingRewardRateModel/src/invokes/lending.rs46
programs/lendingRewardRateModel/src/invokes/mod.rs2
programs/lendingRewardRateModel/src/lib.rs137
programs/lendingRewardRateModel/src/state/context.rs264
programs/lendingRewardRateModel/src/state/mod.rs6
programs/lendingRewardRateModel/src/state/seeds.rs2
programs/lendingRewardRateModel/src/state/state.rs81
programs/liquidity/src/constants.rs18
programs/liquidity/src/errors.rs90
programs/liquidity/src/events.rs106
programs/liquidity/src/lib.rs184
programs/liquidity/src/module/admin.rs614
programs/liquidity/src/module/mod.rs2
programs/liquidity/src/module/user.rs249
programs/liquidity/src/state/context.rs379
programs/liquidity/src/state/mod.rs16
programs/liquidity/src/state/rate_model.rs508
programs/liquidity/src/state/seeds.rs7
programs/liquidity/src/state/state.rs71
programs/liquidity/src/state/structs.rs49
programs/liquidity/src/state/token_reserve.rs422
programs/liquidity/src/state/user_borrow_position.rs194
programs/liquidity/src/state/user_supply_position.rs180
programs/liquidity/src/utils/mod.rs2
programs/liquidity/src/utils/token.rs37
programs/oracle/src/constants.rs21
programs/oracle/src/errors.rs54
programs/oracle/src/events.rs15
programs/oracle/src/helper.rs164
programs/oracle/src/lib.rs180
programs/oracle/src/modules/chainlink.rs24
programs/oracle/src/modules/jup_lend.rs64
programs/oracle/src/modules/mod.rs14
programs/oracle/src/modules/msol_pool.rs38
programs/oracle/src/modules/pyth.rs67
programs/oracle/src/modules/redstone.rs38
programs/oracle/src/modules/single_pool.rs121
programs/oracle/src/modules/stake_pool.rs78
programs/oracle/src/state/context.rs54
programs/oracle/src/state/mod.rs9
programs/oracle/src/state/schema.rs183
programs/oracle/src/state/seeds.rs2
programs/oracle/src/state/state.rs18
programs/oracle/src/state/structs.rs58
programs/vaults/src/constants.rs29
programs/vaults/src/errors.rs152
programs/vaults/src/events.rs153
programs/vaults/src/invokes/liquidity_layer.rs102
programs/vaults/src/invokes/mint.rs61
programs/vaults/src/invokes/mod.rs6
programs/vaults/src/invokes/oracle.rs53
programs/vaults/src/lib.rs194
programs/vaults/src/module/admin.rs556
programs/vaults/src/module/mod.rs3
programs/vaults/src/module/user.rs938
programs/vaults/src/module/view.rs22
programs/vaults/src/state/branch.rs216
programs/vaults/src/state/context.rs693
programs/vaults/src/state/mod.rs22
programs/vaults/src/state/position.rs166
programs/vaults/src/state/seeds.rs11
programs/vaults/src/state/state.rs20
programs/vaults/src/state/structs.rs419
programs/vaults/src/state/tick.rs140
programs/vaults/src/state/tick_has_debt.rs1109
programs/vaults/src/state/tick_id_liquidation.rs78
programs/vaults/src/state/vault_config.rs22
programs/vaults/src/state/vault_state.rs313
programs/vaults/src/utils/common.rs52
programs/vaults/src/utils/liquidate.rs121
programs/vaults/src/utils/mod.rs8
programs/vaults/src/utils/operate.rs214
programs/vaults/src/utils/validate.rs267
Totals15195

For a machine-readable version, see scope.txt

Files out of scope

For a machine-readable version, see out_of_scope.txt

Additional context

Areas of concern (where to focus for bugs)

Vault Protocol:

  • After liquidation the final position of a user should be loaded correctly.
  • Absorption and liquidation should work as intended.
  • Branch state should be maintained at all places required, like closed and merged.

Main invariants

  • Only the owner of an NFT should be able to withdraw or borrow from the protocol.
  • Only whitelisted users on the Liquidity Layer (LL) should be able to interact with it.
  • Amounts assigned to claim accounts on the LL should always be available for claiming at any time (reserved)
  • Exchange prices should only ever increase.
  • No interactions on the extreme sides should be possible, where e.g. 1 is given as the supply amount and leads to unexpected outcomes because of rounding, increasing on a property in storage but not on another data point.
  • The protocol must always round in its direction i.e. supply rounds down, borrow rounds up and so on.
  • Withdraw and borrow limits must be enforced properly.

All trusted roles in the protocol

All the child protocols of the LL are permissionless.

  • Vaults
  • Lending
  • Flashloan

The LL is a whitelist-based protocol.

Compilation

Prerequisites

The codebase of Jupiter Lend represents a suite of Solana programs (i.e. smart contracts) that require a set of specific version-locked compilation programs to be compiled properly.

The following commands have been written for Ubuntu / Linux environments, and Windows users must install the Windows-Subsystem-for-Linux (WSL) to be able to compile the codebase and run its tests.

Rust

The codebase relies on rustc and specifically version 1.81.0. The version can be installed by setting up the rustup toolkit via the following commands:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh rustup default 1.81.0

Solana CLI

The codebase relies on the Solana CLI and specifically version 2.3.0 which can be installed as follows:

sh -c "$(curl -sSfL https://release.anza.xyz/v2.3.0/install)"

Additionally, a keypair must be generated for the test suites to function properly:

solana-keygen new

This keypair will be located in the following path inside your $HOME directory: .config/solana/id.json

Anchor Framework

The anchor framework utilized to compile the programs is version 0.32.0 which can be installed through the avm version manager as follows:

# Install Anchor Version Manager (AVM) cargo install --git https://github.com/coral-xyz/anchor avm --locked --force # Install Anchor avm install 0.32.0 avm use 0.32.0

NodeJS & pnpm

The codebase relies on the NodeJS framework to install its dependencies as well as the pnpm toolkit to properly execute post-installation scripts and lock the versions of those dependencies. The versions tested for building the project were 20.9.0 and 10.29.2 respectively.

NodeJS can be installed via the official NodeJS website whereas pnpm can be installed as follows:

npm i -g pnpm

bun

Finally, the codebase relies on a JavaScript runtime / package manager called bun which can be installed as follows:

curl -fsSL https://bun.com/install | bash

Test Environment Setup

For the test suites of the repository to run properly, the Solana keypair path value must be configured in the ANCHOR_WALLET_PAHT variable, f.e. as follows:

export ANCHOR_WALLET_PATH=".config/solana/id.json"

A Solana RPC endpoint must also be configured for the test suites to run properly. Using the public rate-limited Solana RPC endpoint as an example:

export ANCHOR_PROVIDER_MAINNET_URL="https://api.mainnet.solana.com"

This is an example value, and trying to run test suites with the rate-limited public end point will fail due to the many requests performed. Wardens are advised to utilize their own RPC endpoint that is unrestricted.

Building

After all tools have been installed, the NodeJS dependencies of the project must be installed and setup via the following command:

pnpm i

Once the command finishes successfully, all programs of the codebase are ready to be built as follows:

pnpm build

Both the build and test commands accept an optional --program argument that permits the compilation / testing of a single program in the repository. The available options for the --program flag can be observed via the --list-program flag.

Running Tests

Tests can be executed via the following command:

pnpm test

Miscellaneous

Employees of Jupiter Lend and employees' family members are ineligible to participate in this audit.

Code4rena's rules cannot be overridden by the contents of this README. In case of doubt, please check with C4 staff.