Home / reference
reference

Smart contract vulnerability library

Each vulnerability class explained with a vulnerable example and its fixed version, so you can recognize and remediate the pattern.

Reentrancy

An external call made before updating state lets an attacker re-enter the function before balances are decremented. Follow checks-effects-interactions and use a reentrancy guard.

// vulnerable
function withdraw(uint a) public {
  require(bal[msg.sender] >= a);
  (bool ok,) = msg.sender.call{value:a}("");
  bal[msg.sender] -= a; // too late
}
// fixed
function withdraw(uint a) public nonReentrant {
  require(bal[msg.sender] >= a);
  bal[msg.sender] -= a;                 // effects first
  (bool ok,) = msg.sender.call{value:a}("");
  require(ok);
}

tx.origin authentication

Using tx.origin for authorization allows an intermediary contract to act on the user's behalf. Use msg.sender.

Oracle / price manipulation

Reading a spot price from a single pool makes it manipulable by a large swap, often funded with a flash loan. Prefer a time-weighted average price (TWAP) or an aggregated oracle.

Missing access control

A sensitive function without a restricting modifier can be called by anyone. Gate privileged functions with onlyOwner or role checks.

Unchecked external call

Ignoring a low-level call's return value lets the contract continue after a failed transfer. Always check the boolean result.

Business logic flaws

An inverted comparison or wrong share math breaks an invariant. These flaws are contract-specific, escape generic detectors, and are often the costliest. Describe the intended behavior and compare it to the code.

Want to practice exploiting these safely? See Learn. Ready to scan your own contract? Open the scanner.

▶ Open the scanner