#37311 [SC-High] Attackers can steal rewards by depositing, updating vault balance and withdrawing i

Submitted on Dec 2nd 2024 at 05:47:34 UTC by @niroh for Audit Comp | Jito Restaking

  • Report ID: #37311

  • Report Type: Smart Contract

  • Report severity: High

  • Target: https://github.com/jito-foundation/restaking/tree/master/vault_program

  • Impacts:

    • Theft of unclaimed yield

Description

Brief/Intro

When ST rewards are sent to a vault, the vault's vrt_token (shares) accrues the reward value only after a call to the update_vault_balance. The reward value accrues all at once after the update_vault_balance call. This enables an attack vector where a parasitic staker drains a large reward without contributing to the stake that produced the reward.

Vulnerability Details

Attack scenario:

  1. The vault has 10_000 ST deposits that have been staked for a cetrain period of time. The vault has a vrt_tokens supply of 10_000 that represents current stakers shares in the vault.

  2. At epoc X, an ST reward of 1000 ST is sent to the vault as a reward for the staking so far.

  3. An attacker who monitors the protocol identifies the deposit and immediately sends a transaction that does the following: A. completes a vault tracker update (without a balance update) B. deposits 1_000_000 ST to the vault, for which they receive 1_000_000 vrt_tokens. C. calls update_vault_balance D. enqueues a withdrawal ticket for the entire 1_000_000 vrt_tokens received in the deposit.

  4. At epoc X+2 the attacker's withdrawal matures and they can claim their 1_000_000 vrt_tokens for which they receive 1000990 ST tokens

  5. The attacker walks away with 99% of the reward that belongs to the original depositors. (see POC)

  6. Note that because the attacker immediately enqueues a withdrawal, their funds can not be delegated. This is becuase the vault::delegate function "reserves" ST funds for all enqueues/pending/ready withdrawals and will fail attempts to delegate beyond that. As can be seen in the code below:

This means that the attacker funds are never used for delegation and only "leech" on the rewards generated by other stakers.

Impact Details

Theft of unclaim yield (vault rewards) from stakers. Depending on the vault's TVL at the time of attack and on the attacker's funding, they can drain the majority of the reward (shown in the POC)

Recommendation

mint_to (deposit) instruction should update_vault_balance before calculating the reveived vrt_tokens.

References

https://github.com/jito-foundation/restaking/blob/406903e569da657035a2ca71ad16f8a930db6940/vault_program/src/update_vault_balance.rs#L12

Proof of Concept

Proof of Concept

  1. add to folloing function to integration_test/tests/fixtures/vault_client.rs (same as do_full_vault_update only without calling update_balance. required for the exploiter move)

  1. Add the following code to a test file under integration_tests/tests/vault/

  1. Run RUST_LOG=off RUST_BACKTRACE=1 cargo nextest run --nocapture sandwitch_update_balance

Last updated

Was this helpful?