
Smart contract vulnerabilities have cost the Web3 ecosystem over $3.8 billion in losses since 2020. Most of these exploits weren't sophisticated zero-days — they were the same recurring vulnerability classes, exploited again and again on contracts that were never properly audited.
At Blockhertz, our AI Auditor has analyzed hundreds of smart contracts across EVM-compatible chains. After running thousands of audit passes and mapping findings against real-world exploits, we've identified 14 distinct vulnerability classes that every Solidity developer must understand before deploying to mainnet.
This is not a surface-level list. For each class, we cover what it is, why it's dangerous, a real-world example, and how to fix it.
1. Reentrancy
What it is: A contract sends ETH or makes an external call before updating its internal state. The receiving contract can call back into the original contract and repeat the action — typically a withdrawal — before the balance is updated.
Why it's dangerous: This is how the original DAO hack drained $60M in 2016. In 2023, Curve Finance lost over $61M to a reentrancy bug in Vyper's compiler — not even Solidity code.
Fix: Always follow Checks-Effects-Interactions: check conditions, update state, then make external calls. Use OpenZeppelin's ReentrancyGuard modifier on any function that sends ETH or calls external contracts.
// BAD
function withdraw(uint amount) external {
require(balances[msg.sender] >= amount);
(bool success,) = msg.sender.call{value: amount}(""); // external call BEFORE state update
balances[msg.sender] -= amount;
}
// GOOD
function withdraw(uint amount) external nonReentrant {
require(balances[msg.sender] >= amount);
balances[msg.sender] -= amount; // state update FIRST
(bool success,) = msg.sender.call{value: amount}("");
require(success);
}
2. Access Control Vulnerabilities
What it is: Privileged functions — mint, pause, upgrade, withdraw — are callable by anyone because ownership checks are missing, misconfigured, or bypassed.
Why it's dangerous: Access control is the #1 vulnerability class in OWASP Smart Contract Top 10 for 2026. Unprotected initialize() functions on upgradeable contracts have been exploited repeatedly — an attacker calls it first and becomes the owner.
Fix: Use OpenZeppelin's Ownable or AccessControl. Initialize in the constructor or atomically in the deployment script. Add timelocks to admin functions.
// BAD — anyone can call this
function initialize(address admin) public {
owner = admin;
}
// GOOD — can only be called once
function initialize(address admin) public initializer {
__Ownable_init(admin);
}
3. Integer Overflow and Underflow
What it is: Arithmetic operations exceed the bounds of their data type, wrapping silently to unexpected values. In Solidity <0.8, a uint at 0 minus 1 becomes 2^256-1.
Why it's dangerous: The 2018 batchOverflow exploit on BEC token minted effectively unlimited tokens from a single transaction. Solidity 0.8+ adds overflow checks by default, but unchecked blocks, assembly, and unsafe casts still introduce risk.
Fix: Use Solidity 0.8+. If you use unchecked blocks for gas savings, audit them individually. Never use unchecked on user-supplied values.
4. Oracle Manipulation
What it is: A protocol reads prices from an on-chain source (like a DEX spot price) that an attacker can manipulate — typically via a flash loan — within a single transaction.
Why it's dangerous: The 2022 Mango Markets exploit inflated a thinly traded token's price to borrow $116M against it. The attacker used their own positions to move the price.
Fix: Use Chainlink or other decentralized oracle networks. If using DEX prices, use a Time-Weighted Average Price (TWAP) over at least 30 minutes. Add staleness checks — reject prices older than N blocks.
5. Unchecked Return Values
What it is: Low-level calls (call, send, delegatecall) return a boolean indicating success or failure. If that return value isn't checked, failed operations are silently ignored and execution continues.
Why it's dangerous: A transfer that silently fails can leave balances inconsistent, allow double-spends, or bypass critical state transitions. This is SC06 in the OWASP Smart Contract Top 10.
Fix: Always check return values from low-level calls. Prefer SafeERC20's safeTransfer() over raw call() for token transfers.
// BAD
token.transfer(recipient, amount); // return value ignored
// GOOD — use SafeERC20
token.safeTransfer(recipient, amount);
6. Tx.Origin Authentication
What it is: Using tx.origin for authorization instead of msg.sender. tx.origin is always the original EOA that initiated the transaction — if a user is tricked into calling an attacker's contract, that contract can then call your contract and tx.origin will still be the legitimate user.
Why it's dangerous: Phishing attacks can exploit this. The attacker deploys a malicious contract, tricks the owner into calling it, then uses the owner's tx.origin to drain your contract.
Fix: Never use tx.origin for authorization. Always use msg.sender.
// BAD
require(tx.origin == owner, "Not owner");
// GOOD
require(msg.sender == owner, "Not owner");
7. Improper Input Validation
What it is: Functions that accept addresses, amounts, or calldata from users without validating them. This can allow zero-address assignments, overflow of expected ranges, or arbitrary external calls routed through your contract.
Why it's dangerous: A missing zero-address check on a token contract can permanently lock tokens. Unvalidated calldata in a contract that forwards calls can turn your contract into a proxy for attacks on other protocols.
Fix: Validate every external input. Check for zero addresses. Bound numeric inputs. If your contract forwards calls, whitelist allowed target addresses.
// BAD
function setOwner(address newOwner) external onlyOwner {
owner = newOwner; // could be address(0)
}
// GOOD
function setOwner(address newOwner) external onlyOwner {
require(newOwner != address(0), "Zero address");
owner = newOwner;
}
8. Delegatecall to Untrusted Contracts
What it is: delegatecall executes external code in the context of your contract — using your storage, your ETH balance, your identity. If the target contract is malicious or upgradeable to become malicious, it can overwrite your storage or drain your funds.
Why it's dangerous: Proxy upgrade patterns rely on delegatecall. Uninitialized implementation contracts are a known attack vector — an attacker calls initialize() on the implementation directly, takes ownership, then self-destructs it, bricking every proxy.
Fix: Never delegatecall to user-supplied addresses. Validate implementation contracts before upgrade. Lock implementation contracts against direct initialization.
9. Front-Running and MEV
What it is: Transactions sit in the public mempool before being mined. Miners and bots can observe pending transactions and insert their own before yours — buying before your large buy, sandwiching your trade, or sniping your NFT mint.
Why it's dangerous: On DEXes, sandwich attacks consistently extract value from traders. For NFT mints and token launches, front-running bots capture the best prices before legitimate users.
Fix: Enforce slippage limits and transaction deadlines. Use commit-reveal schemes for sensitive operations. Consider private transaction relays (Flashbots Protect, MEV Blocker) for high-value operations.
10. Signature Replay Attacks
What it is: A valid signature intended for one transaction is reused — either on the same chain or across chains. Without nonces and chain IDs, any signed message can be replayed indefinitely.
Why it's dangerous: A signed permit or meta-transaction can be replayed to approve unlimited transfers. Cross-chain replays exploit contracts deployed at the same address on multiple chains.
Fix: Use EIP-712 structured signatures with a chain-specific domain separator. Include a nonce per signer. Enforce signature deadlines. Invalidate used signatures immediately.
11. Flash Loan Attack Vectors
What it is: Flash loans allow attackers to amplify any existing vulnerability with enormous capital within a single transaction, then repay the loan before the block closes.
Why it's dangerous: Flash loans turned small price manipulation bugs into nine-figure exploits. Euler Finance ($197M), Beanstalk ($182M), and dozens of others were drained via flash loan-amplified attacks.
Fix: There's no fix for flash loans themselves — fix the underlying vulnerabilities they amplify: oracle manipulation, reentrancy, governance attacks. Treat flash loan scenarios as part of your threat model from day one.
12. Business Logic Vulnerabilities
What it is: The code executes exactly as written, but the specification itself is flawed. The contract does what it was told to do — but what it was told to do allows exploitation. These are design bugs, not coding bugs.
Why it's dangerous: No static analyzer catches these. The code passes all tests. Only a reviewer who deeply understands the protocol's intended behavior can spot them. This is why human review remains essential even with AI auditing.
Fix: Formal specification before coding. Invariant testing with Foundry's fuzzer. Economic modeling — think about how an adversarial actor with unlimited capital would interact with every function.
13. Rounding and Precision Errors
What it is: Solidity uses integer arithmetic — there are no decimals. Division always truncates toward zero. In share-based vaults and lending protocols, repeated rounding in the wrong direction can be exploited.
Why it's dangerous: The vault inflation attack: an attacker deposits 1 wei into an empty vault, then donates a large amount directly. The next depositor receives zero shares due to rounding. The attacker redeems their 1 share for nearly all the funds.
Fix: Always round in the protocol's favor. Seed vaults with an initial deposit. Use virtual shares/assets offsets. Run fuzz tests specifically against rounding edge cases.
14. Improper Upgrade Patterns
What it is: Upgradeable contracts using proxy patterns can introduce storage collisions between proxy and implementation, missing authorization on upgrade functions, or implementation contracts that can be initialized by anyone.
Why it's dangerous: A UUPS proxy without proper authorization on _authorizeUpgrade() lets anyone replace your implementation. Storage collisions can silently corrupt critical variables during upgrades.
Fix: Use OpenZeppelin's audited upgrade patterns. Run storage layout checks before every upgrade. Never leave implementation contracts uninitialized.
Quick Reference: All 14 Vulnerability Classes
| # | Vulnerability Class | Severity | AI Detectable |
|---|---|---|---|
| 1 | Reentrancy | Critical | ✅ Yes |
| 2 | Access Control | Critical | ✅ Yes |
| 3 | Integer Overflow/Underflow | High | ✅ Yes |
| 4 | Oracle Manipulation | Critical | ⚠️ Partial |
| 5 | Unchecked Return Values | High | ✅ Yes |
| 6 | Tx.Origin Authentication | High | ✅ Yes |
| 7 | Improper Input Validation | Medium–High | ✅ Yes |
| 8 | Delegatecall to Untrusted Contracts | Critical | ✅ Yes |
| 9 | Front-Running / MEV | Medium | ⚠️ Partial |
| 10 | Signature Replay | High | ✅ Yes |
| 11 | Flash Loan Attack Vectors | Critical | ⚠️ Partial |
| 12 | Business Logic Vulnerabilities | Critical | ❌ Human review required |
| 13 | Rounding and Precision Errors | High | ⚠️ Partial |
| 14 | Improper Upgrade Patterns | Critical | ✅ Yes |
How Blockhertz AI Auditor Detects These
Our AI Smart Contract Auditor scans for all 14 of these vulnerability classes in seconds. Paste your Solidity code or provide a verified contract address on any EVM-compatible chain, and get a detailed risk report with severity scores, affected lines, and remediation guidance.
The AI Auditor uses a 0–100 risk scoring system (lower is safer). Contracts scoring above 20 are flagged for manual review before mainnet deployment.
Important: Automated auditing is a first pass, not a final verdict. AI reliably catches structural and syntactic vulnerabilities (#1–#11, #13–#14), but business logic vulnerabilities (#12) require human expertise. Use the AI Auditor to eliminate known risks fast, then bring in a manual review for high-value deployments.
→ Run a free audit on your contract
→ Install the hardhat-blockhertz plugin for continuous auditing in your CI pipeline
Resource Hub
Explore our Smart Contract Security Hub →
Free AI auditor, vulnerability guides and security research
Related Articles
Related Blockhertz Tools
Explore Blockhertz
Views
3
Read Time
12 min read
Likes
0
Published
Nov 4, 2026
SIGNAL THREAD
NO SIGNALS YET — BE FIRST TO TRANSMIT
Muhammad Asif
Senior Blockchain Developer & Founder, Blockhertz
Blockchain developer and security engineer with 8+ years of experience. Founded Blockhertz in 2018 to build AI-powered tools for Web3 teams — smart contract auditing, architecture generation, gas optimization, and RWA tokenization platforms. Serving clients worldwide.