Simple Base SwapSimple Base SwapOpen app
← All articles
Sep 26, 2026·6 min read

Common Smart Contract Vulnerabilities Explained: Reentrancy, Access Control and Price Manipulation

basesecuritysmart-contractsdefi
base

When a DeFi protocol is exploited, the headlines rarely explain what actually went wrong. The phrase "a vulnerability in the contract" hides a lot of detail. In practice, the same small set of bug types shows up again and again, and knowing them helps you understand why audits matter, why some risks cannot be removed, and why keeping your funds spread across fewer, better-understood apps is usually wiser.

This article is a beginner-friendly tour of three of the most common categories. You do not need to read code to follow it.

Why smart contract bugs are different

A smart contract is a program that lives on the blockchain and holds real assets. Two properties make bugs especially costly:

  • Deployed code is public. Anyone can read it, including people looking for mistakes.
  • Transactions are hard to undo. If an attacker finds a flaw and drains a contract, the network does not roll back the transaction. It was valid according to the rules the code defined.

So the question is never "did the attacker break the blockchain?" but "did the contract's own rules allow something its authors did not intend?"

1. Reentrancy

The idea

Reentrancy is a bug where a contract sends value or calls another contract before it has finished updating its own records, and the receiving contract uses that moment to call back in.

Think of a bank teller who hands you cash and only afterwards writes down that your balance went down. If you could ask for cash again during the handover, before the balance was updated, the teller would happily pay out twice, because the ledger still says you have the money.

In code terms, a vulnerable withdrawal function does this:

  1. Check that the user has a balance.
  2. Send the funds to the user (an external call).
  3. Set the user's balance to zero.

If the receiving address is itself a contract, step 2 can trigger its code, which calls the withdrawal function again. The balance is still not zero, so the check passes again. The loop repeats until the contract is empty or the attacker stops.

A famous example

The best known case is The DAO in June 2016, an early Ethereum investment fund that lost roughly 3.6 million ETH to a reentrancy flaw. The event was serious enough that the Ethereum community held a contentious hard fork in July 2016 to reverse its effects, and the chain that kept the original history continued as Ethereum Classic. It is one of the reasons the industry takes this bug class so seriously.

How developers defend against it

  • Checks, effects, interactions. Do the checks first, update the internal records second, and make external calls last. Then a callback sees an already updated balance.
  • Reentrancy guards. A small lock, such as the widely used nonReentrant modifier in OpenZeppelin's contract library, prevents a function from being entered again while it is still running.

Neither is a complete cure alone. Variants exist, such as "cross-function" reentrancy, where the callback enters a different function that shares the same state, and "read-only" reentrancy, where a third protocol reads a value from a contract at a moment when it is temporarily inconsistent. This is one reason a clean audit is not a guarantee.

2. Broken access control

The idea

Many contract functions are meant to be restricted: changing fees, upgrading the code, minting tokens, pausing trading, withdrawing treasury funds. Access control is the logic that decides who may call them.

Bugs here are often embarrassingly simple:

  • A sensitive function that was supposed to be "owner only" was left open to everyone.
  • An initialization function, meant to run once at deployment, can be called again by anyone, letting them make themselves the owner.
  • A privileged key is stored insecurely and gets stolen, which is an operational failure rather than a code bug, but with the same result.

Why users should care

Even when access control is coded correctly, it defines who holds power over the contract. If a single address can upgrade the code or mint unlimited tokens, then the security of your funds partly depends on that address staying safe and honest. Our guides on token owner privileges and upgradeable contracts cover what to look for. Safer designs often use a multisig wallet and a timelock so that no single person can make an instant change.

3. Price and oracle manipulation

The idea

Lending protocols, derivatives and many other DeFi apps need to know what an asset is worth. If a contract asks the wrong source, or a source that can be pushed around cheaply, an attacker can distort the price, then trade against the contract at the fake price.

A typical pattern looks like this:

  1. The attacker temporarily moves the price on a thin, low liquidity pool, often using a large amount of borrowed capital (see flash loans).
  2. The vulnerable protocol reads that spot price as if it were the true market price.
  3. The attacker borrows or withdraws far more than they should be able to.
  4. The price is restored and the attacker keeps the difference.

The weakness is not in the arithmetic but in trusting a price that is easy to move within a single transaction. Defenses include using price oracles that aggregate many sources, averaging prices over time, and setting sensible limits on how much can be borrowed against illiquid assets.

Other categories worth knowing

The three above are not the full list. You will also hear about:

  • Arithmetic and rounding errors, where amounts are calculated slightly wrong, sometimes exploitably when repeated many times.
  • Unchecked external calls and unsafe assumptions about how other tokens behave, for example tokens that charge fees on transfer (see fee on transfer tokens).
  • Compiler or tooling bugs, where the developer's code was fine but the software that translated it was not. A well known example involved certain Vyper compiler versions and several Curve pools in July 2023.
  • Upgrade and configuration mistakes, such as deploying a new version with a setting left at an unsafe default.

What this means for you as a user

You cannot audit code yourself, but you can make risk-aware choices:

  • Favor time-tested contracts. Code that has held significant value for a long period, across market stress, has been tested by real attackers already. New code has not.
  • Read what is public. Look for audits, whether the contract is verified on Basescan, and who controls admin functions. An audit reduces risk but never removes it.
  • Do not concentrate everything in one app. If one protocol fails, you want the loss to be a fraction of your holdings, not all of them.
  • Limit approvals. A bug in a contract you have approved can drain tokens you gave it access to, so review and revoke approvals you no longer need.
  • Treat high yields as a warning sign. Unusually high returns often come with unusually high smart contract or design risk.

The bottom line

Reentrancy, broken access control and price manipulation are the recurring themes behind many of DeFi's worst days. They are well understood, and modern tooling and audits catch many of them, but new code is written every day and every deployment carries some residual risk. Understanding the failure modes will not make you immune, but it helps you judge what you are trusting when you interact with an app on Base.

This article is educational and not financial advice. Smart contracts can fail in ways no one predicted, so only use funds you can afford to lose.

Ready to try it yourself?

Create a non-custodial wallet on Base in seconds. No account, no sign-up.

Open the web app