How smart contract exploits execute on chain: reentrancy, price manipulation, flash loans, accounting flaws, and missing authorization checks.

A smart contract exploit is a profitable transaction path that exits value from a protocol in a way its designers did not intend. In pooled-fund systems, such paths can derive from coding errors, from faulty integration assumptions, or from economic conditions that are treated by the contracts as trustworthy, whereas in reality they are not.
When protocols hold funds of pooled users for them, a weakness in code or system design (vulnerability) needs to be distinguished from a sequence of transactions that exploits this weakness to gain value (exploit).
Even if each function of a lending market, vault or AMM is implemented correctly, the whole system can be exploitable. As an example, a vault might price shares in a manipulable reserve balance, or a lending pool might rely on a value that can be moved inside one block of transactions. Thus smart contract security for pooled-fund systems has to distinguish between implementation correctness and economic correctness.
| Term | Meaning in pooled-fund protocols | What creates loss |
|---|---|---|
| Vulnerability | A flaw or unsafe assumption in contract logic, integration logic, or pricing logic | Nothing, until a profitable execution path exists |
| Exploit | A transaction sequence that realizes profit from that flaw or assumption | Asset extraction, bad debt, or mispriced share issuance |
| Smart contract bug | Incorrect code behavior relative to intended logic | Can be exploitable, but is not required |
| Economic failure | Contract behaves as written, but trust in an external state was misplaced | Often enough for a smart contract hack |
Exploits on smart contracts that hold pooled user funds typically follow the exact mechanical steps of a setup, an entry into the vulnerable part of the code, some manipulation of the states to allow for extraction of assets of value, an extraction of the value from the manipulated states, and an exit that settles any obligations the attacker took on along the way. Entry refers to the function on the contract that the attacker uses to reach the vulnerable path.
Atomicity is what makes this all work. On an Ethereum-compatible system, all the changes of state within a single transaction will either all commit or else all revert. A single transaction can borrow funds, move an oracle-relevant price, mint undervalued shares, extract overpriced assets, and repay temporary borrowings to pocket the spread, all before anyone can react.
Many smart contract hacking paths are a single transaction because adding in multiple transactions creates uncertainty for dependencies in between transactions.
A reentrancy attack in a pooled fund happens when a smart contract makes an external call before it has finished its internal book keeping. The callee can then reenter the caller before the caller has finished updating its internal state variables. This attack typically happens when someone withdraws or claims a reward which first transfers the necessary tokens and then decreases the balances of the tokens in the pool. The fallback or callback of the recipient of the tokens is typically under the control of an attacker.
The issue is not limited to re-entering the same function. In pooled asset holding systems, cross-function reentrancy can be even more problematic. This is because in such systems, functions update only parts of the overall accounting model. For example, a withdrawal function might mark token balances late, while a borrow function might read old collateral state values, assuming that the first call has already settled. The attacker does not even need to re-enter the same function. A second function will read values as if the first call had already settled. This creates a stale state that can be exploited by the attacker.
Read-only reentrancy in the context of a pooled fund is somewhat subtle and still relevant. A view function returns share price, the current reserves and similar metrics in the state of the pool right before an update. Some other integrating contracts then call this view function in the middle of their own critical paths of code and, due to the nature of call order, treat the transient values in between the update steps as the settled truth. They then make decisions for lending, minting or liquidation based on these bad values, with no storage writes having occurred in the meantime. The Solidity documentation flags the call-order risk at the language level in its Solidity security considerations.
When a protocol holds pooled funds for its users, price manipulation typically starts with an easy to move source of truth for spot prices, such as a DEX pool. If the pool is thin, a single large trade inside the same block can create a skewed reserve ratio, which the attacker then exploits by calling the lending or vault contracts that trust this ratio as fair value.
Once the protocol has accepted the manipulated price, the attacker withdraws value from the pooled funds by having a borrower put up overpriced collateral to draw out too many assets from the pool, or by having a vault overissue shares to a depositor because the asset side of the ratio was made to appear larger or smaller than it really is. The attacker then unwinds their market position, repays any temporary financing used to move the price, and keeps the value taken from the protocol.
A stale data failure path exists where a protocol uses a price feed. Even though the feed is correctly signed and syntactically correct, the data can be economically old relative to the withdrawal, borrow, or liquidation event. Thin liquidity is a different scenario: the price is current, but market depth is too small for the protocol to determine a fair value. The Chainlink Data Feeds documentation separates robust reference feeds from a spot read of a single pool. This is particularly visible in DeFi protocol development, where lending, vault, and swap components share assumptions about what a price means.
During protocol development these issues tend to surface at the border of the pooled fund accounting and market data semantics.
A flash loan is not a vulnerability in a pooled-fund smart contract. Instead, it is a pattern of transactions that makes it easier for someone to attack a smart contract by removing the need to have a large amount of money upfront. Flash loans are implemented according to the EIP-3156 flash loan standard. This specifies a sequence of actions: borrow money, then execute any action, then repay the borrowed money before the end of the transaction. If repayment of the borrowed money fails, then the entire transaction will fail and be rolled back.
Prior to flash loans, many smart contract risks were economically impractical rather than technically infeasible. Flash loans turn capital-constrained ideas into executable transaction plans against a pooled fund. This pattern also makes reentrancy, price manipulation and accounting errors much worse, because it puts large position size in the attacker's hands exactly while the smart contract is computing balances or prices.
Accounting exploits against pooled funds can appear innocent enough when shown as code, because each single operation will mathematically work as intended. The problem here is the way value is transferred during said series of operations. Share issuance and redemption formulas for vault-style systems will hold the key to controlling the residual value when ratios don't form whole numbers. This residual value is then rounded to the caller's advantage during mint, redeem or even preview operations in said vaults.
An even more fragile vault is an empty one. Here, the first depositor can create a very distorted initial exchange rate. All subsequent deposits will then mint too few shares compared to the value of the assets deposited. This can be even more severe if the attack starts with a direct token donation to the vault. In such a case, assets are transferred to the vault without going through the deposit path, which changes the assets-to-shares ratio of the vault, even though no new shares were minted. The mechanics of such an attack are described in the ERC-4626 tokenized vault standard and in even more detail in the OpenZeppelin ERC-4626 inflation attack documentation.
Small losses repeat and add up quickly. Since the exploit does not consist of a single very large extraction, atomic batching of a series of such operations turns dust into money of value. This is why smart contract vulnerabilities in accounting logic show up as invariant drift rather than as a single broken transfer. In protocol development, this class typically appears where pooled-fund math spans deposits, redemptions and fee accrual, as well as direct token balance reads.
Proxy patterns are an easy way to shoot yourself in the foot, since the proxy holds the state and the implementation holds the logic. An attacker can for example call the initializer of an implementation contract left uninitialized by the contract author, in order to set privileged variables which can affect upgradeability or even execution of the contract in a later call. The storage-slot conventions for such proxies are documented in EIP-1967 proxy storage slots. Mistakes at these storage convention boundaries can have severe consequences for pooled assets.
There is also the simpler path of an initializer or admin-only function being callable by anyone, because the expected check is not in place. Attackers can use such functions in pooled-fund vaults and lending contracts, for example by redirecting fee payments, by swapping the implementation for a different one, by setting critical addresses to point to attacker-controlled code, or by calling an emergency function that transfers large amounts of assets under rules intended only for privileged actors.
Delegatecall expands the impact, because the EVM executes the called code in the context of the caller's storage. If a pooled-fund contract delegatecalls into attacker-written code, that code does not need prior write access to the relevant storage slots. It runs as if it were the protocol itself, with full access to the balances, the allowances, and the internal bookkeeping of the pool.
A post-mortem for a pooled-fund protocol generally finds that the line where funds left the contract was not the true root cause of the problem. Rather, it was an assumption that had been made earlier in the code, for example that a callback would not re-enter critical parts of the code, or that a particular price source would return a fair value, or that a particular token balance would equal the accounted assets for that token, or that an integrating contract only reads settled state, or that an initializer cannot be called again. The exploit transaction then simply finds the shortest path from that assumption to making transferable value.
A decent blockchain security audit report or post-mortem for a pooled fund will identify the failed assumption, list the states that were read and/or written as part of that assumption, and then explain why the protocol treated each of those as final when in reality they were only temporary, manipulated, or unauthorized in some way. That level of review is what smart contract development at protocol scale has to account for before funds are pooled behind the code.
A vulnerability is a flaw or unsafe assumption in a pooled-fund protocol. An exploit is the transaction sequence that turns it into profit or bad debt.
Yes. A pooled-fund protocol can execute exactly as written and still be exploitable if it trusts a manipulable price, stale state, or a bad integration assumption.
Atomicity lets the attacker manipulate state, extract value from pooled funds, and settle temporary obligations without giving the market time to interfere. If any step fails, the whole transaction reverts.
It is a case where a pooled-fund protocol exposes a mid-update value through a view function, and another protocol acts on that transient value as if it were settled state.
No. A flash loan often only supplies temporary capital. The actual exploit usually sits in the pooled-fund protocol that misprices assets, misorders calls, or miscomputes accounting.



