Smart Contract Audits: 10 Security Checks Developers Should Perform

Smart Contract Audits

A withdrawal test can pass even when the deployer still has permission to upgrade the contract. The leftover role might only show up when you run the deployment script in a test environment and check what it actually granted.

For a Solidity release on Ethereum or another Ethereum Virtual Machine (EVM) chain, independent smart contract audits examine a specific code version, its design, and the controls around it. If the contract relies on outside data, the reviewer also needs to know which price feed it uses and who can replace it.

What to Prepare Before the Review

A reviewer should be able to build the release and trace a withdrawal without guessing which contracts are in scope. The Ethereum secure development workflow and the OWASP smart contract security checklist can help you spot gaps in the handoff.

  • Build. Include the commit hash, build instructions, compiler version and settings, and locked dependencies.
  • Deployment. Name the target chains and include the deployment scripts, proxy and implementation contracts, and expected addresses or configuration.
  • Scope. List the contracts that hold assets, control permissions, or supply prices. Call out known issues, excluded components, and trusted operators.
  • Protocol rules. Map where funds move. In a lending market, for example, explain what a partial repayment should do to debt, collateral, and protocol fees.

When requesting quotes for smart contract audits, give each provider the same commit and scope. Compare public reports on similar protocols and ask who will review your dependencies. Hacken lists complexity and integrations as pricing factors. A complex application can take weeks to review, according to Chainlink. Confirm the cost and timing of retesting.

10 Security Checks for Smart Contract Audits

Smart contract audits are easier to follow when reviewers can reproduce what your team tested. Run these checks against the code and configuration you plan to ship. Pay particular attention to who can move funds, what happens when a price feed fails, and whether users can still withdraw under load.

1. Test Access Controls From the Wrong Account

A role matrix can look right on paper. The deployment script tells you who gets the keys. With OpenZeppelin’s access control modules, map who can grant or revoke each role. Include inherited functions and privileges that run through governance or a proxy admin. With a multisig or timelock, find out who can lower the threshold or bypass the delay.

Run the deployment script in your test environment. For functions that mint, withdraw, pause, upgrade, change fees, or replace an oracle, the role tests should show that:

  • The intended caller succeeds.
  • An account without the role gets a revert.
  • A former role holder loses access. That includes the deployer if the script is supposed to hand off control.

2. Follow External Calls for Reentrancy

A callback doesn’t have to come back through the same function. If a withdrawal hands control to another contract before settling the balance, the callee could use a different entry point that reads the same balance or debt. Solidity’s checks-effects-interactions pattern puts the state update ahead of the external call where the design allows it. Try a second withdrawal and a callback through any other entry point that shares the accounting, even if one of them has a guard. In smart contract audits, a trace that shows which function ran, what it read, and how much actually left the contract makes the result easier to verify.

3. Check Rounding, Units, and Vault Accounting

A number can fit in its type and still be wrong. Write down which way deposits, withdrawals, fees, and liquidations should round. Follow the conversions between token decimals, oracle decimals, and vault shares.

The ERC-4626 inflation attack is easier to understand with small numbers. In a simplified vault with 100 asset units and one existing share, a deposit of 99 units rounds down to zero shares. A direct donation can create that kind of exchange rate before the next deposit.

Use the actual conversion formula and protections you ship to test zero, one base unit, the first deposit, a nearly empty vault, and a deposit after a donation.

4. Stress-Test Oracles and Price-Dependent Actions

A stale price can look perfectly reasonable in a log. For smart contract audits of lending markets or exchanges, follow that value into the borrow, trade, or liquidation that uses it. Record these settings for each chain:

  • Approved feed address and asset pair
  • Feed decimals
  • Maximum acceptable age, measured using the update timestamp in Chainlink’s data feed API

Try the action with stale data. If the feed should return a positive price, test zero and negative values as well. Where a rollup integration uses a sequencer uptime feed, cover both an outage and the recovery grace period.

A fresh price can still be manipulated. If it comes from a thin market, could one transaction move it far enough to increase borrowing power or trigger a liquidation? That’s where DeFi security risks become a concrete test of your protocol’s rules.

5. Test Token Transfers and Dependency Failures

A user deposits 100 tokens, and the vault receives 99 after a transfer fee. Crediting the full 100 puts the accounting out of step with the balance. SafeERC20 can handle tokens that return no value on a successful transfer. The vault still has to decide how much credit to record. Use the tokens you support or test doubles that reproduce their behavior, and compare the credit with what actually arrived. Include a reverting transfer and any relevant fees, callbacks, or balance changes.

6. Prevent Signature and Message Replay

A signature needs to cover the signer, action, and parameters. The EIP-712 signing domain can distinguish chains and verifying contracts. Your application still has to consume a nonce or another unique identifier for one-time actions and enforce any deadline it sets.

  • Submit the same signed withdrawal twice.
  • Submit a different, unused authorization after its deadline so a consumed nonce can’t mask a missing expiry check.
  • Change the recipient. Where applicable, also try the wrong chain or verifying contract.

For cross-chain Web3 applications, the destination needs to check the source chain and authorized sender. Keep separate tests for an unproven message and a valid message that has already been processed. Those are different ways a message can be ineligible to execute.

7. Rehearse Proxy Initialization and Upgrades

The 2022 Nomad bridge exploit started with a detail already in storage. The proxy trusted a zero root. After an upgrade changed message verification, an unproven message could resolve to that same default value and pass validation. If your release changes how proofs or permissions are checked, test what happens when the relevant mapping entry is missing.

For smart contract audits of live upgrades, a fork at a recorded block lets the reviewer run the new code against existing state. For a first release, seed representative balances, roles, and open positions in a test environment. Compare those values before and after the upgrade. Try the authorized and unauthorized paths, and check whether a migration can run twice.

OpenZeppelin’s upgrade guidance covers storage compatibility and initialization. Verify who can initialize the proxy and lock the standalone implementation where the pattern calls for it.

8. Keep Withdrawals and Other Critical Actions Executable

Five withdrawals might fit in a test transaction. A longer queue can push the same loop past the block gas limit, a failure mode described in the Solidity documentation on gas limits. A recipient that rejects payment can also stall a batch when one transaction pays everyone. Measure worst-case gas and test the rejection separately. For bounded batches or individual claims, the useful result is evidence that other users can still exit, processing can resume, and a claim can’t be paid twice.

9. Pair Static Analysis With Tests of Protocol Rules

Slither flags patterns worth a closer look. It’s one of several tools available for Web3 security reviews, and its findings need to be read in the context of your code. Fuzzing varies inputs. Foundry’s invariant tests can go further by checking what happens across a sequence of calls. In a token with a fixed supply cap, for instance, supply should stay within the cap through any valid sequence of mints and burns.

A passing test tells you very little if the runner tolerates reverts and no call changes state. Save the test configuration, the seed if available, and a minimal failing sequence so the reviewer can replay it.

10. Verify the Deployed Build and Retest Every Fix

A fix can be merged and reviewed, then miss the release because the deploy job picks up an older commit. The commit recorded during smart contract audits gives you a concrete point of comparison. Turn confirmed findings into regression tests and send material fixes back to the independent reviewer for retesting.

After deployment, source verification on Ethereum checks that the source and build settings correspond to the deployed bytecode. Then there’s the security work beyond contract code. Check the active proxy implementation, admin roles, timelock settings, and oracle addresses on the target chain. Someone on the team should own monitoring for changes and rehearse the incident actions the deployment supports.

Before You Ship

Keep the commit, the tests that reproduce findings, and the decisions from smart contract audits together. If a late change affects who controls funds, how prices are read, or how balances are calculated, reopen the affected checks before release.

Frequently Asked Questions About Smart Contract Audits

When Should Smart Contract Audits Be Reopened?

A small fix may only need targeted retesting. Send the reviewer the code diff and any configuration changes. Revisit the wider scope if the fix touches shared accounting, permissions, or price inputs.

How Do I Verify the Implementation Behind a Live Proxy?

For an ERC-1967 proxy, read the implementation slot or resolve the implementation through its beacon. At a recorded block, compare the address and bytecode with the release record. Custom proxies may resolve the address differently.

How Can I Tell if My Invariant Tests Reach Useful States?

Compare successful calls with reverts for each action. If redemptions never succeed, give the test handler a funded account, the required approvals, and valid inputs. Test expected reverts separately.

Should Stale Oracle Data Block Repayments Too?

A repay-only path that reduces debt without a price may be able to stay open. If repayment also releases collateral or changes a position’s eligibility, test those effects under stale data first.


Subscribe to Our Newsletter

Related Articles

Top Trending

Smart Contract Audits
Smart Contract Audits: 10 Security Checks Developers Should Perform
Bangladesh garment wage protests
Bangladesh’s Garment Wage Crisis Is a Global Pricing Problem [Part: 02]
CBDCs vs Stablecoins
CBDCs vs Stablecoins: 8 Important Differences
Interactive product demo software
10 Best Interactive Product Demo Software for B2B SaaS Teams
AI productivity
AI Should Give People Time Back, Not Simply Help Them Produce More

Technology & AI

Smart Contract Audits
Smart Contract Audits: 10 Security Checks Developers Should Perform
AI productivity
AI Should Give People Time Back, Not Simply Help Them Produce More
apps that identify fonts colours products
8 Apps That Identify Fonts, Colours, Songs, and Products
Drone Accident Liability
8 Common Drone Accidents and Their Liability Questions
multi-model AI generation pipeline
How to Build a Scalable Multi-Model AI Generation Pipeline for Production SaaS

GAMING

10 Common Gaming and Esports Injuries Players Should Know
10 Common Gaming and Esports Injuries Players Should Know
Ergonomic Gaming Setup 8 Upgrades for Better Comfort
8 Ergonomic Upgrades for a Healthier Gaming Setup
Gaming Accessibility Technology
10 Accessibility Technologies Making Gaming More Inclusive
Discord Bots for Gaming Communities
10 Best Discord Bots for Gaming Communities
Video Games and Mental Health Benefits, Limits and Risks
Can Video Games Support Mental Health and Emotional Well-Being?

Business & Marketing

Best AI Landing Page Builders for Small Businesses
7 Best AI Landing Page Builders for Small Businesses in 2026: What You Can Actually Publish for Free
Review Management Software for Local Business
10 Best Review Management Software for Local Businesses
How to Start and Scale a Profitable Meal Prep Delivery Business
How to Start and Scale a Profitable Meal Prep Delivery Business
What Is an Industrial Metal 3D Printer
What Is an Industrial Metal 3D Printer: How Wire Arc Additive Manufacturing Scales Metal Production?
Best Vendor Management Software for SMBs
10 Best Vendor Management Software for SMBs

EdTech & E-Learning

generative AI in vocational skill assessment
20 Ways Generative AI Is Reshaping Vocational and Technical Skill Assessments
math games for early learners
The Mystery of Numbers: Gamified Math Adventures for Early Learners
Online Learning Career Skills
7 Ways Online Learning Helps Adults Develop Career Skills
Formative Assessment in Learning Apps
What Is Formative Assessment in Learning Apps? A Practical Guide
Learning streaks
How Learning Streaks Motivate And When They Backfire

Software & Apps

apps that identify fonts colours products
8 Apps That Identify Fonts, Colours, Songs, and Products
multi-model AI generation pipeline
How to Build a Scalable Multi-Model AI Generation Pipeline for Production SaaS
One-Time-Purchase Apps
12 One-Time-Purchase Apps That Can Replace Monthly Subscriptions
Apps for Splitting Bills and Shared Expenses
10 Best Apps for Splitting Bills and Shared Expenses
Best Tenant Screening Services for Landlords
10 Best Tenant Screening Services for Landlords