Worked example · 2022-20
Smart-Contract Architecture Exploit Cohort — 2022–2025
Summary
Timeline
T9.008 from 2022-03-20 (Li.Fi v1) to 2024-07 (Li.Fi, GasZipFacet); T9.009 from 2023 onward (post-UUPS/transparent-proxy proliferation); T9.010 from 2022 (class characterised; Market.xyz on QuickSwap, October 2022 canonical anchor).
T9.008 — Diamond-Pattern Facet-Audit Incomplete
The diamond proxy (EIP-2535) pattern's multi-facet architecture creates a structural audit-scope gap: an audit of Facets A, B, C does not cover Facet D added post-audit. The audited facets match their audited bytecode; the gap is the unaudited facets.
Canonical case: Li.Fi — July 2024 — reported $8M–$11.6M. An arbitrary-call flaw in depositToGasZipERC20() of the GasZipFacet, deployed five days before the attack (Decurity), let the attacker drain wallets that had granted infinite approvals (Ethereum and Arbitrum, 153 wallets per Forklog); Threesigma noted the facet was deployed unaudited. The earlier Li.Fi exploit (2022-03-20, ~$600K from 29 wallets) was an unchecked external call (call injection) in the swap path, not a facet-addition case.
Two sub-patterns:
- Post-audit facet addition introduces exploit surface. New facet holds treasury-routing, fee-extraction, or upgrade-authority functionality.
- Facet-selector collision. Post-audit facet shadows an audited facet's function selectors, redirecting calls to unaudited logic.
T9.009 — Cross-Contract Reinitialization Attack
The attacker triggers the initialisation function of a target contract via a callback from a peer contract, exploiting the absence of reinitialisation guards across the cross-contract boundary. The target contract's initializer modifier sets a storage flag after the first successful initialisation — but the flag is set at the end of the initialiser's execution, not before external calls made during initialisation.
The structural parallel to T9.005 (Reentrancy): in T9.005, the defence is checks-effects-interactions; in T9.009, the defence is initialise-then-interact — performing all external calls after the initialisation state flag has been set.
The attack is a specific failure of the UUPS/Transparent proxy initialisation discipline but generalises to any contract with a once-only initialisation path that makes external calls before setting the "already initialised" flag.
T9.010 — Read-Only Reentrancy
The attacker re-enters a view/pure function on a target contract while the target is mid-execution, reading state that is temporarily inconsistent. The re-entry is a staticcall (EVM-enforced as read-only), and no state is double-spent on the target — the loss is realised on a third protocol that consumes the stale view-function output for pricing, accounting, or liquidation decisions.
Canonical case (mechanism per the OAK example file, not per the news sources cited here, which describe a flash-loan price manipulation of a Curve-based feed): Market.xyz — QuickSwap (Polygon), 2022-10-24, ~$220K. Market.xyz priced Curve LP-token collateral via get_virtual_price() — a view function. Curve's remove_liquidity transfers a native asset to the caller before settling the pool's accounting, so during that callback get_virtual_price() returns an inflated value; the attacker re-entered Market.xyz's borrow path in that window and extended a loan against inflated collateral (~$220K, flash-loan-funded). The Curve pool itself lost nothing; Market.xyz lost the loan principal. See examples/2022-10-market-xyz-curve-lp-oracle-read-only-reentrancy.md. (Distinct from the July 2023 Curve/Vyper compiler-lock event.)
Additional cases:
The T9.005 mitigation (checks-effects-interactions + ReentrancyGuard) does not close T9.010 because ReentrancyGuard does not block staticcall to view functions. The mitigation is at the consumer-protocol layer: only read view functions from target contracts whose outermost call frames have returned in the current transaction.
Public references
[lifi2024july]— Li.Fi July 2024 post-mortem (~$10M diamond facet exploit)[lifi2022march]— Li.Fi March 2022 post-mortem (~$600K diamond facet exploit)[eip2535]— EIP-2535 Diamond Proxy standard[openzeppelininitializable]— OpenZeppelin Initializable contract andinitializermodifier[curvevyper2023]— Curve Finance Vyper compiler reentrancy incident (July 2023)[quillauditsmarketxyz2022]— Market.xyz (QuickSwap / Polygon) Curve LP-oracle read-only reentrancy, October 2022, ~$220K (seeexamples/2022-10-market-xyz-curve-lp-oracle-read-only-reentrancy.md)[lififorklog]— Forklog, "LI.FI reveals details of $11.6 million hack" (2024-07): https://forklog.com/en/li-fi-reveals-details-of-11-6-million-hack/amp[lifirevoke]— Revoke.cash, LI.FI 2024 exploit entry: https://revoke.cash/exploits/lifi-2024[lifi3sigma]— Three Sigma, "LI.FI $9M protocol exploit analysis": https://threesigma.xyz/blog/lifi-9m-protocol-exploit-analysis[lifipm2022]— LI.FI, "LI.FI Smart Contract Vulnerability Post Mortem" (2022-03): https://blog.li.fi/20th-march-the-exploit-e9e1c5c03eb9[lifiblocksec]— BlockSec, "LI.FI attack: a cross-chain bridge vulnerability? No, it's due to unchecked external call" (2022-03): https://blocksec.com/blog/li-fi-attack-a-cross-chain-bridge-vulnerability-no-it-s-due-to-unchecked-external-call[qswapblock]— The Block, "Decentralized exchange QuickSwap exploited for $220K, plans to close lending markets" (2022-10-24): https://www.theblock.co/post/179333/decentralized-exchange-quickswap-exploited-for-220k-plans-to-close-lending-markets