Hashtag Web3 Logo

Advanced Solidity Exploits

9 min
advanced

Moving Beyond Reentrancy

A contract can pass unit tests and still fail when combined with other contracts. Audit the assumptions it makes about market prices, initialization, and signed messages.

The examples below describe three areas to test in an authorized local environment.

Flash Loan Attack Flow 1. Borrow $50M Flash Loan 2. Manipulate Pump DEX price 3. Exploit Borrow vs inflated 4. Repay Return loan 5. Profit Keep $40M 💰 🛡️ Fix: Use Chainlink oracles, not single DEX pool prices

1. Flash Loans and Oracle Manipulation

A flash loan makes liquidity available without collateral on the condition that repayment and the fee occur within the same transaction. If the lender's repayment check fails, the transaction reverts. Available liquidity and fees depend on the lending protocol.

This temporary capital can be used to move a thin market's price and test whether another protocol accepts that price as collateral value.

The Exploit:

  1. Temporary liquidity is used to move a token's price in a pool.
  2. A vulnerable lender reads that pool's spot price and overvalues collateral.
  3. The lender allows excessive borrowing against that valuation.
  4. The attempt only succeeds if the full sequence can repay the flash loan and cover trading costs. Otherwise it reverts.

Review: Check how collateral prices are obtained, how stale data is rejected, and how liquidity affects manipulation cost. Aggregated feeds and time-weighted prices have different assumptions; neither removes the need to validate the integration.

2. Uninitialized Proxies

Smart contracts are immutable. To fix bugs, developers use a "Proxy Pattern." The users interact with Contract A (the Proxy), which holds the money. Contract A forwards the logic to Contract B (the Implementation). If Contract B has a bug, the admin tells Contract A to point to a new Contract C.

Because of how this architecture works, you cannot use a standard constructor() function to set up the admin. You must use an initialize() function.

The Exploit:

An uninitialized proxy may let an unauthorized caller assign privileged roles. Implementation contracts also need their initializers disabled where appropriate. The impact depends on the contract's permissions and deployment design.

Review: Initialize the proxy atomically during deployment, protect initialization from repeat calls, and lock the implementation's initializer. Test the actual deployment sequence, not only individual functions.

3. Signature Replay Attacks

To save users gas money, protocols often ask users to "sign a message" with their wallet off-chain, rather than executing an on-chain transaction. The protocol then submits this signature to the smart contract to execute an action (like a trade on OpenSea).

The Exploit:

If the smart contract isn't coded securely, a hacker can take a signature you generated yesterday (e.g., "Transfer 1 ETH to Bob") and submit it to the contract again today. If the contract doesn't track that the signature was already used, it will transfer another 1 ETH to Bob.

if the signature doesn't specify the blockchain, a hacker could take a signature meant for Ethereum and execute it on Polygon (where you might also have funds).

Review: Bind signed messages to the intended chain, verifying contract, action, and parameters. Track consumed nonces and enforce deadlines where appropriate. EIP-712 provides typed signing and domain separation; the application still has to enforce replay protection.

Key takeaways

  • Flash loans provide temporary capital; repayment, fees, and transaction costs still apply.
  • Collateral valuation needs a price source whose assumptions match the lending design.
  • Upgradeable contracts (Proxies) require careful initialization to prevent hackers from hijacking ownership.
  • Cryptographic signatures must include nonces and chain IDs to prevent replay attacks.

Quiz: Advanced Solidity Exploits

1 / 5

What makes a Flash Loan unique compared to traditional loans?