All vulnerabilities
CRITICALWeb3exploited in the wild

WEB3-PENPIE-2024

Web3 · Ethereum · Penpie

Summary

On September 3, 2024, Penpie, a yield protocol built on Pendle, was drained of about $27.3 million (11,113.6 ETH in wstETH, sUSDe, egETH and rswETH) across Ethereum and Arbitrum. The root cause was a cross-function reentrancy enabled by permissionless market registration: registerPenpiePool trusted any market from Pendle's PendleMarketFactoryV3 without validating the Standardized Yield (SY) token, so the attacker registered a fake market whose SY was their own contract. PendleStakingBaseUpg.batchHarvestMarketRewards (and its internal _harvestBatchMarketRewards) snapshotted reward-token balances before and after calling the market's redeemRewards, but lacked a nonReentrant guard. The malicious SY's claimRewards callback re-entered PendleStakingBaseUpg.depositMarket with flash-loaned Pendle LP tokens mid-accounting, so the deposit was misattributed as harvested rewards, inflating the attacker's reward balance. Although depositMarket itself carried a nonReentrant modifier, the two functions did not share a lock, so the unguarded harvest path let the attacker re-enter the guarded deposit path and claim the inflated rewards via MasterPenpie.multiclaim.

How to avoid it in your code

  • Place a shared nonReentrant mutex across all reward-harvest and deposit/withdraw entrypoints, not per-function.
  • Snapshot balances and finalize accounting before any external call into market or token contracts.
  • Validate registered markets: whitelist SY/reward tokens, reject permissionlessly created markets with untrusted code.
  • Treat reward-token redeemRewards/claimRewards callbacks as untrusted external calls into attacker code.
  • Re-read storage after external calls; never credit post-call balance deltas as protocol rewards.

References

Related vulnerabilities

All Web3 →