Skip to content

MasterVault ratio drift fix#182

Merged
waelsy123 merged 3 commits intoha/ybb-invariant-testsfrom
ha/ybb-ratio-drift-fix
Feb 27, 2026
Merged

MasterVault ratio drift fix#182
waelsy123 merged 3 commits intoha/ybb-invariant-testsfrom
ha/ybb-ratio-drift-fix

Conversation

@godzillaba
Copy link
Contributor

found a vulnerability while writing invariant tests:

Preconditions:

  • Fresh or near-empty vault (only dead shares + small deposits)
  • Attacker is the beneficiary, or colludes with them

Steps:

  1. Deposit dust — Attacker deposits 1 unit via gateway.
    totalSupply = 2e6, totalAssets = 2, ratio = 1e6 (perfect).

  2. Partial redeem — Attacker redeems 999,999 shares.
    floor(999999 * 2 / 2e6) = 0 assets returned
    totalSupply = 1,000,001, totalAssets = 2.
    totalPrincipal = ceil(1,000,001 / 1e6) = 2.
    totalProfit = 2 - 2 = 0 — drift is hidden.
    Actual ratio: 1,000,001 / 2 = 500,000 (should be 1,000,000).

  3. Victim deposits — Victim deposits V assets.
    shares = floor(V * 1,000,001 / 2) ≈ V * 500,000 (half the correct amount).
    totalPrincipal = ceil(newSupply / 1e6) ≈ V/2 + 2.
    totalProfit = V - V/2 = V/2 — half the deposit appears as profit.

  4. Extract fees — Attacker (as keeper) calls distributePerformanceFee().
    Beneficiary receives V/2 tokens.

  5. Victim redeems — Gets back V/2. Lost 50%.

  === Initial state ===
  totalSupply: 1000000
  totalAssets: 1
  totalProfit: 0
  === After attacker deposits 1 ===
  attacker shares: 1000000
  totalSupply: 2000000
  totalAssets: 2
  totalProfit: 0
  === After attacker redeems 999999 shares ===
  assets back: 0
  totalSupply: 1000001
  totalAssets: 2
  totalProfit: 0
  ratio (supply/assets): 500000
  expected ratio: 1000000
  === After victim deposits 1000000 ===
  victim shares: 500000500000
  totalSupply: 500001500001
  totalAssets: 1000002
  totalProfit: 500000
  === After fee distribution ===
  fees extracted: 500000
  totalAssets: 500002
  totalProfit: 0
  === Victim redeems ===
  victim deposited: 1000000
  victim received: 500000
  victim loss: 500000
  loss %: 50
  === Summary ===
  fees to beneficiary: 500000
  victim loss: 500000

@godzillaba godzillaba requested a review from waelsy123 February 26, 2026 19:11
@waelsy123
Copy link
Contributor

respect, that's impressive

@waelsy123 waelsy123 merged commit abe121b into ha/ybb-invariant-tests Feb 27, 2026
10 checks passed
@waelsy123 waelsy123 deleted the ha/ybb-ratio-drift-fix branch February 27, 2026 13:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants