Perennial V2 Update #2 — disclosed vulnerability reports and payouts

Every publicly disclosed and closed bug bounty report we hold for Perennial V2 Update #2, with our own summary of each finding and a link to the original disclosure.

Reports indexed
13
Total paid
$0
Critical
0
Largest payout
$0

This page collects the 13 closed, publicly disclosed Perennial V2 Update #2 reports indexed on CoinBuggie. Nothing here is active or unpatched — every entry was published by the programme or the researcher after remediation.

The findings concentrate in Logic error, Oracle manipulation, across EVM-Solidity. Reading a single protocol end to end is the fastest way to see which assumptions its codebase repeatedly gets wrong, which is usually a better predictor of where the next finding lives than the category alone.

Use the vulnerability class links below to compare these findings against the same bug class in other protocols.

What reviewers look for

  • Logic error findings disclosed against Perennial V2 Update #2
  • Oracle manipulation findings disclosed against Perennial V2 Update #2

Curated highlights

The largest disclosed payouts in this group, with our own summary of each. Every report links back to the original disclosure.

mediumLogic errorEVM-Solidity$0

Perennial V2 Update #2: Liquidator can set up referrals for other users

Perennial V2's referral registration logic let a liquidator permanently pin their own address as the referrer on a victim account that had never been liquidated before and had no referrer set. Liquidation orders are exempt from the usual non-empty-order authorization check, so a protected order carrying a non-zero referrer passed the two referral-setup conditions and stored the attacker's address, which then carried forward across future oracle-version currentIds. Because the stored referrer must match any incoming referrer on subsequent updates, the victim could never switch to a different referrer, permanently binding them to the liquidator's fee share. After sustained judge debate the issue was upheld as medium severity once the session showed referrers are not reset between ids, and the fix rejects any referrer supplied on a protected order.

Perennial V2 Update #2sherlockApr 6, 2024Open
mediumLogic errorEVM-Solidity$0

Perennial V2 Update #2: Vault and oracle keepers DoS in some situations due to `market.update(account,max,max,max,0,false)`

Perennial V2 used a no-op `market.update(account, max, max, max, 0, false)` call as the standard way to settle a market account, but `InvariantLib.validate` still enforces the margin requirement on that call. Because of this, any account that sits below its margin requirement causes the internal settle flows to revert, denying service to legitimate users. Two concrete paths are affected: keepers cannot settle accounts for a committed oracle version until every account recovers above margin (while oracle fees are still deducted), and the vault's `_updateUnderlying` reverts inside every `update`/`rebalance` and admin parameter change whenever a vault market position is below margin. Since rebalancing only happens inside `_manage`, which is only reached from `update`/`rebalance`, the vault can be effectively bricked until the offending position is liquidated or price recovers above margin, leaving only `Vault.settle` functional. The protocol team fixed the issue in PR #309, which the Lead Senior Watson signed off on.

Perennial V2 Update #2sherlockApr 6, 2024Open
highLogic errorEVM-Solidity$0

Perennial V2 Update #2: Vault global shares and assets change will mismatch local shares and assets change during settlement due to incorrect `_withoutSettlementFeeGlobal` formula

Perennial V2's vault settlement computes per-oracle-version accounting fees differently at the global versus local (per-user) level. The global `_withoutSettlementFeeGlobal` path deducts the full settlement fee for both a deposit and a redeem within the same oracle version, whereas the local path apportions a single settlement fee across all orders. This asymmetry credits individual depositors and redeemers with more shares and claimable assets than the vault's global totals can cover, and the gap compounds with every mixed deposit/redeem version. Eventually the global balances become too small to back the users' local claims and the `Vault._update` subtraction underflows, leaving the last redeemers and claimers unable to withdraw — a bank-run-style loss-of-funds failure.

Perennial V2 Update #2sherlockApr 6, 2024Open
mediumLogic errorEVM-Solidity$0

Perennial V2 Update #2: Vault checkpoints slightly incorrect conversion from assets to shares leads to slow loss of funds for long-time vault depositors

Perennial V2's vault checkpoint conversion from assets to shares mishandles the order/subtraction of the settlement fee and trade fee when calculating a depositor's shares. In actual market collateral accounting both fees are subtracted linearly from the deposit, but the checkpoint formula applies them as successive multiplicative discounts, multiplying (1 - settlementFeePct) by (1 - tradeFeePct). That creates a systematic over-crediting error equal to settlementFee times tradeFeePct for every deposit, silently inflating each new depositor's shares and diluting the share value of existing, long-time holders. Because the error recurs on every deposit in an active vault, the small per-transaction loss compounds into a steady daily drain. The finding was ruled a valid medium during judging and patched in PR 304 with Lead Senior Watson sign-off.

Perennial V2 Update #2sherlockApr 6, 2024Open
mediumOracle manipulationEVM-Solidity$0

Perennial V2 Update #2: ChainlinkFactory will pay non-requested versions keeper fees

Perennial's ChainlinkFactory oracle adapter computes keeper fees in `_applicableValue()` by summing the fee for every price payload in a batched commit, ignoring the `numRequested` argument even though the protocol spec states only requested versions should be reimbursed. Because all payloads are billed unconditionally, an attacker who wins the commit for a single requested version can pad the batched update with many unrequested reports and drain the factory's fee balance. The Lead Judge upheld this as a valid medium and Perennial fixed it in PR #293 by pro-rating the total fee by `numRequested / payloads.length`.

Perennial V2 Update #2sherlockApr 6, 2024Open
mediumLogic errorEVM-Solidity$0

Perennial V2 Update #2: When vault's market weight is set to 0 to remove the market from the vault, vault's leverage in this market is immediately set to max leverage risking position liquidation

In Perennial V2's vault strategy, removing a market is only possible by setting its weight to zero. When the vault next rebalances, StrategyLib allocates only the minimum margin to that removed market while leaving its existing position size unchanged, pushing the position to maximum leverage. If the position cannot be fully closed due to skew limits, or the price moves against it, the under-margined position faces liquidation risk. Additionally, since vault actions settle by calling market.update and revert when collateral drops below margin (but above maintenance), the vault becomes temporarily bricked until the position is liquidated or returns above margin. The finding was acknowledged by the protocol and ultimately adjudicated as a medium.

Perennial V2 Update #2sherlockApr 6, 2024Open

All reports in this group

Vulnerability classes disclosed here

Related protocol pages