Attack Pattern Intelligence
Learning from Historical DeFi Exploits
An analysis of recurring vulnerability patterns extracted from real-world smart contract exploits, and how those patterns inform automated detection.
Attack Pattern Intelligence
Most smart contract exploits do not introduce genuinely new techniques. They reuse known vulnerability classes against contracts that were never checked for them. This article documents the recurring patterns we observe across historical DeFi incidents, explains what makes each one detectable at the bytecode level, and discusses where automated analysis can and cannot substitute for manual review.
What the Historical Record Shows
The DeFi exploit record from 2016 through 2024 is long enough to draw meaningful conclusions about which vulnerability classes cause the most damage in practice.
Reentrancy has been consistently exploitable since The DAO hack in 2016 (approximately $60M at the time). The basic pattern — an external call made before state is updated — has not changed. What has changed is where the vulnerability hides. Later incidents like Cream Finance (approximately $130M, October 2021) and Rari Capital (approximately $80M, April 2022) involved cross-contract and cross-function variants that are structurally identical to the 2016 case but harder to spot in code review.
Oracle manipulation emerged as a major category once flash loans became available in 2020. Harvest Finance (approximately $34M, October 2020) and Warp Finance (approximately $7.7M, December 2020) both used flash-loaned capital to distort AMM spot prices within a single transaction. The contracts trusted the manipulated price for a critical decision, then the attacker repaid the loan. The vulnerability is in the oracle consumption pattern, not in flash loans themselves.
Access control failures span a wide range of severity. The Parity Wallet freeze (November 2017, approximately $150M in ETH locked permanently) resulted from an unprotected initialization function on the library contract. An attacker called initWallet on the deployed library, took ownership, and called kill — functions that existed, were reachable, and had no caller validation. The Poly Network hack (August 2021, approximately $611M) exploited a different access control failure: a cross-chain message handler accepted attacker-controlled data to authorize arbitrary function calls.
Flash loan governance attacks became viable once protocols with on-chain voting held significant treasuries. Beanstalk (April 2022, approximately $182M) is the clearest example: an attacker took a flash loan to acquire a supermajority of voting tokens, proposed and immediately executed a malicious governance action, and returned the loan in the same transaction. The vulnerability was not in the governance logic per se — it was the absence of any snapshot mechanism to prevent same-block acquisition and voting.
The table below summarizes approximate losses by year across major incidents that have been incorporated into pattern detection work. These figures are approximate and drawn from public post-mortems:
| Period | Examples | Approximate Losses |
|---|---|---|
| 2016–2019 | The DAO, Parity Wallet, bZx | >$500M |
| 2020 | Harvest Finance, Warp Finance, Pickle | ~$200M |
| 2021 | Cream Finance, Rari Capital, Poly Network | ~$900M |
| 2022 | Wormhole, Ronin, Nomad, Beanstalk | >$3B |
| 2023 | Euler Finance, Curve (Vyper), Multichain | ~$800M |
| 2024 | Input validation failures, bridge attacks | ~$300M |
Pattern Categories
The following sections describe the main vulnerability classes, what structural properties make them detectable, and where detection has limits.
Reentrancy
Classic single-function reentrancy has a recognizable bytecode signature: an external CALL instruction followed by a SSTORE on a path reachable through that call. Control flow graph analysis can find these sequences directly.
Cross-function reentrancy is harder. It requires building an interprocedural call graph and identifying cases where function A makes an external call and function B — callable during that external call — modifies state that A depends on. The detection requires understanding shared state, not just local call sequences.
Read-only reentrancy is the most recent variant to cause significant losses. A contract’s view function returns a value computed from storage that may be in an inconsistent state during a reentrant call. The calling contract trusts the view result. Detection requires identifying view functions whose return values are consumed by other contracts for pricing or collateral calculations.
All three variants are detected through call graph analysis and state dependency tracking in Sigvex, though confidence varies: single-function reentrancy has very high detection confidence, while read-only reentrancy in multi-contract systems requires context that static analysis does not always have.
Flash Loan Vectors
A flash loan does not introduce new on-chain state from the attacker’s perspective — it just removes capital as a constraint within a single transaction. This means flash loan vulnerabilities are fundamentally about what decisions a contract makes when token balances or prices change dramatically and temporarily.
Spot price dependency: A contract calls getAmountsOut or reads a Uniswap pair’s reserves directly and uses the result for a critical calculation. An attacker with flash-loaned capital can move that price substantially before the read. Detection checks whether price feeds are consumed without any time-averaging or manipulation-resistance mechanism.
Governance snapshot timing: A voting contract reads token balances at the moment of voting rather than at a snapshot block before the proposal was created. Detection identifies governance contracts where the voting power query and the vote submission occur in the same block with no temporal separation enforced.
Collateral inflation: A lending protocol values collateral by querying a spot price. An attacker inflates the spot price, borrows against the inflated value, and lets the collateral deflate after repaying the flash loan. This is structurally identical to spot price dependency but in a lending rather than trading context.
Oracle Security
Oracle vulnerabilities reduce to two root causes: using prices that can be moved within a single transaction (spot prices from AMMs), and using prices that may be stale (off-chain oracle feeds without freshness checks).
TWAP mechanisms help with the first problem but are not a complete solution. A 30-minute TWAP can still be shifted profitably if the position size is large enough and the manipulation is sustained over multiple blocks. The Mango Markets exploit (October 2022, approximately $114M) was not a flash loan attack — the attacker held their manipulative position for hours. Detection can flag TWAP window sizes that are too short for the value at risk, though appropriate window size depends on the specific protocol.
Chainlink feed staleness is a different problem: detection checks whether the contract validates the updatedAt timestamp returned by latestRoundData. Many contracts do not. If the Chainlink aggregator pauses during market volatility and the contract keeps operating with a stale price, the contract’s risk calculations are wrong.
Access Control
Access control failures share a common pattern: a function that should only be callable by a specific role either has no caller check or has a check that can be bypassed.
Unprotected initialization is particularly common in proxy-pattern contracts. The implementation contract often has an initialize function that sets the owner. If this function is callable after deployment — because it lacks an initialized flag — anyone can call it. Detection identifies functions with initialization-style naming or logic and verifies they are protected against re-invocation.
Privilege escalation through function call sequences is harder to detect automatically. It requires understanding which combinations of calls, made in a specific order, can transition a contract into a state where an unprivileged caller can invoke restricted functionality. This type of vulnerability often requires manual review to find.
Economic Attack Patterns
Several attack patterns target users rather than contracts, but arise from exploitable code properties.
Sandwich attacks are possible when a DEX trade can be front-run and back-run in the same block. The vulnerability is the absence of a minimum output amount — a parameter that the user should set but often defaults to zero. Detection identifies swap calls where the slippage parameter is zero or absent.
Just-in-time (JIT) liquidity exploitation targets concentrated liquidity AMMs. A liquidity provider adds liquidity in the same block as a large trade, collects fees, then removes liquidity. This is not a vulnerability in the traditional sense — it is a behavior the protocol permits — but it can disadvantage other LPs in ways that are worth flagging.
Pattern Representation
Each documented pattern is stored with four components: preconditions (what the contract must look like for the attack to be possible), execution sequence (what transaction sequence constitutes the attack), postconditions (expected outcome and damage), and detection rules (both static analysis patterns and, where applicable, dynamic signatures).
The detection pipeline applies these in three phases:
-
Structural matching: Compare contract architecture against vulnerability prerequisites. Does the contract have external calls before state updates? Does it read from AMM spot prices?
-
Semantic matching: Analyze economic flows and trust boundary crossings at a higher level. Does user-controlled data reach a sensitive storage write? Is collateral valued using a manipulable source?
-
Variant detection: Generalize known patterns to identify implementations that are functionally identical to historical vulnerabilities but structurally different. A reentrancy guard bypassed through a delegatecall chain looks different in bytecode than a direct reentrancy, but the state dependency pattern is the same.
Where Automated Detection Has Limits
Automated pattern matching is effective for vulnerability classes that have a clear structural signature. Reentrancy, unprotected initialization, missing staleness checks — these produce consistent bytecode or control flow patterns that tools can find reliably.
It is less effective for:
-
Business logic errors: Vulnerabilities that are only visible when you understand the protocol’s intended invariants. Euler Finance’s approximately $197M exploit (March 2023) involved a subtle interaction between donate-to-reserve functionality and liquidation math. There was no unusual bytecode pattern; the logic was simply wrong.
-
Multi-contract interaction vulnerabilities: Bugs that only manifest when two specific contracts interact in a specific way, where neither contract is individually vulnerable.
-
Economic design flaws: Protocols that are technically correct but incentive-incompatible — where rational actors can extract value in ways the designers did not anticipate.
For these cases, pattern databases inform what to look for, but the actual investigation requires a human analyst who understands the protocol’s economics.
Keeping the Database Current
New exploits are reviewed within 24 hours of public disclosure. If the incident represents a pattern variant not already covered, a detection rule is drafted, validated against historical contract data to check for acceptable false positive rates, and added to the database. If the pattern was already covered, the incident is added as a reference case and the detection confidence model may be updated.
The goal is not to catch attacks in progress — blockchain transactions are irreversible — but to ensure that the next contract written with the same vulnerability pattern is flagged before deployment.
Using Pattern Data in Practice
The most direct use of the pattern database is pre-deployment analysis: run the contract through the detector suite, review findings ordered by severity and confidence, and investigate any matches against historical exploit patterns. The similar_exploits field in each finding links to the historical incident that established the pattern, which provides context for understanding exploitability.
A secondary use is exposure assessment when a new exploit is disclosed. If a novel attack vector is announced, the question “do any of our deployed contracts match this pattern?” can be answered by running the new detector against previously analyzed contracts. This is where having a systematic pattern representation pays off versus ad-hoc analysis.
Sigvex maintains the pattern database and runs it against contracts on-demand. The 35+ patterns currently documented cover the major vulnerability classes responsible for the bulk of historical DeFi losses, with ongoing additions as the threat landscape develops.
References
- Smart Contract Weakness Classification (SWC) Registry
- EVM Opcodes Reference
- Luu, L. et al. “Making Smart Contracts Smarter.” CCS 2016.
- Atzei, N., Bartoletti, M., and Cimoli, T. “A Survey of Attacks on Ethereum Smart Contracts.” IACR ePrint 2016/1007; POST 2017.
- Torres, C. F. et al. “Reentrancy Vulnerability Identification in Ethereum Smart Contracts.” IEEE WETSEB 2021.