Smart Contract Vulnerabilities List: Top 10 Risks (2026)
Share
Smart contracts handle billions of dollars in crypto assets, and attackers know it. In 2025 alone, exploits targeting flawed contract code drained over $2 billion from protocols, bridges, and DeFi platforms. If you interact with any blockchain-based application, a solid smart contract vulnerabilities list is something you need to study, whether you're a developer, an auditor, or a self-custody user trying to understand where your assets are actually at risk.
At FinTech Dynasty, we focus on one thing: helping you protect your crypto. That usually means hardware wallets, seed phrase management, and cold storage strategy. But security doesn't stop at your wallet. Every time you approve a transaction or connect to a dApp, you're trusting someone else's code. Knowing the most exploited smart contract flaws gives you a practical edge, it helps you spot red flags before you sign anything, and it raises your overall security awareness beyond just key management.
This guide breaks down the top 10 smart contract vulnerabilities actively exploited in 2026. Each entry includes a clear technical description, a code example where applicable, and specific mitigation strategies. Whether you're reviewing audit reports or simply deciding which protocols deserve your trust, this list gives you the knowledge to make that call. Let's get into it.
1. Access control vulnerabilities
Access control vulnerabilities are the most financially damaging category on any smart contract vulnerabilities list. They occur when a contract fails to restrict who can call privileged functions, allowing attackers to execute admin-level actions with a standard wallet.
What it is and why it matters
When a smart contract has no ownership checks on sensitive functions, anyone can call them. Minting unlimited tokens, draining treasuries, pausing protocols, or changing fee recipients are all possible if the wrong person gains access. The Ronin bridge hack in 2022, which resulted in over $600 million in losses, traced back partly to compromised validator keys with excessive permissions.
Poor access control is not a niche flaw. It consistently ranks as the top vulnerability class in post-mortems published by major security firms.
Where it shows up in real contracts
Token contracts often expose mint or burn functions without proper ownership checks. Governance contracts can allow arbitrary proposal execution without a quorum requirement. Proxy contracts sometimes leave admin slots exposed after deployment, letting anyone claim ownership if the initializer is not called immediately.
Common root causes
Developers frequently skip modifier checks during rapid prototyping and never restore them before launch. Copied contract templates from public repositories may carry outdated or missing access patterns that no longer match the intended design of the new contract.
Exploit patterns and red flags in code
Look for functions that modify state but carry no onlyOwner, onlyRole, or require(msg.sender == admin) guard. Unprotected initialize() functions in upgradeable contracts are a classic red flag, and any function that transfers assets or changes critical parameters without a caller check is a serious concern worth escalating in an audit.
Mitigation checklist
- Use OpenZeppelin's
OwnableorAccessControllibraries rather than writing custom permission logic - Apply role-based access control for multi-tiered permission systems
- Audit every state-changing function for missing modifiers before deployment
- Lock initializers in upgradeable contracts using
initializermodifiers
What users and token holders should watch for
Before depositing into any protocol, check whether the contract has a published audit that specifically reviewed access control. If a single admin wallet can pause withdrawals or mint tokens freely, your funds carry outsized counterparty risk regardless of how the project presents itself publicly.
2. Business logic vulnerabilities
Business logic vulnerabilities exist when a contract's core rules are correctly written in code but designed in a way that enables unintended economic behavior. The code does exactly what it was written to do, which makes these flaws particularly hard to catch in automated scans.
What it is and why it matters
Unlike syntax bugs, business logic flaws exploit the intended workflow of a contract. An attacker follows the protocol's own rules in the wrong order or with unexpected values to drain funds or gain an unfair advantage.
This is why business logic vulnerabilities regularly appear on any serious smart contract vulnerabilities list, since they bypass traditional code analysis tools entirely.
Where it shows up in real contracts
Lending protocols, AMM-based DEXes, and staking contracts are frequent targets. Reward calculation functions that do not account for edge-case deposit timings can allow an attacker to claim disproportionate yields with minimal capital.
Common root causes
Developers focus on the happy path during testing and overlook adversarial scenarios. Incentive models that look reasonable in documentation often break down under extreme inputs or rapid state changes no one anticipated.
Exploit patterns and red flags in code
Watch for reward or interest calculations that rely on snapshots without locking state, and functions that allow deposits and withdrawals within the same transaction block without restrictions.
Mitigation checklist
- Model all economic incentives before writing any code
- Write tests for edge cases, zero values, and maximum inputs
- Use formal verification for critical financial logic
What users and token holders should watch for
Check whether a protocol has gone through economic security reviews, not just standard code audits. A technically clean contract can still lose all deposited funds if its reward logic is exploitable.
3. Price oracle manipulation
Price oracle manipulation happens when an attacker forces a smart contract to read a corrupted or artificially skewed price, then exploits that mispricing to borrow, trade, or liquidate at favorable rates. This vulnerability appears on every serious smart contract vulnerabilities list because DeFi protocols depend entirely on accurate external price data to function correctly.

What it is and why it matters
Oracles feed real-world price data into smart contracts. When that data is manipulated, a contract may allow someone to borrow $10 million in assets against $1 million in collateral simply because the collateral's reported price was temporarily inflated within a single block.
A single manipulated price feed can drain an entire lending pool in one transaction.
Where it shows up in real contracts
Lending protocols and derivatives platforms are the primary targets. Any contract that reads a spot price from a DEX pool without time-weighting that data is directly exposed to same-block price manipulation.
Common root causes
Developers rely on single-source, spot-price oracles that reflect the current pool ratio rather than a volume-weighted or time-averaged price, making manipulation cheap and fast to execute.
Exploit patterns and red flags in code
Watch for contracts that call getReserves() directly and use the raw result immediately without any TWAP (time-weighted average price) adjustment or secondary validation.
Mitigation checklist
- Use Chainlink price feeds or TWAP-based oracle designs
- Require multiple independent price sources before executing sensitive operations
What users and token holders should watch for
Check audit reports specifically for oracle design coverage. If a protocol pulls a single on-chain spot price without averaging or cross-referencing, your deposited funds carry real manipulation risk that no wallet security practice can protect you from.
4. Flash loan–enabled economic attacks
Flash loans let anyone borrow massive amounts of capital with zero collateral, provided the loan is repaid within the same transaction block. Attackers exploit this mechanic to temporarily distort market conditions inside a single transaction, then exit before any liquidation or safety check applies.
What it is and why it matters
A flash loan attack combines uncollateralized borrowing with rapid protocol manipulation to extract value far exceeding what an attacker could deploy with their own funds. This class of exploit belongs on every smart contract vulnerabilities list because it turns small design weaknesses into catastrophic, single-transaction losses.
Flash loans do not create vulnerabilities; they amplify existing ones that developers left unaddressed.
Where it shows up in real contracts
Lending platforms and AMM-based liquidity pools are the primary targets, particularly those using spot prices for collateral valuation within a single block.
Common root causes
Protocols fail to account for within-block state changes, letting an attacker borrow, manipulate, and repay before any external system detects the transaction's true impact on protocol state.
Exploit patterns and red flags in code
Watch for price-sensitive functions that lack TWAP protection or contracts that allow governance votes, large withdrawals, or collateral appraisals within the same transaction context as a large capital inflow.
Mitigation checklist
- Separate price reads from state changes across blocks
- Use TWAP oracles instead of spot prices for any valuation logic
- Apply reentrancy guards on all fund-moving functions
What users and token holders should watch for
Check whether the protocol's audit explicitly covers flash loan attack scenarios. If it does not, your deposited funds rely on untested assumptions about real attacker behavior that could drain the protocol in a single block.
5. Reentrancy
Reentrancy is one of the most infamous entries on any smart contract vulnerabilities list, responsible for the 2016 DAO hack that drained $60 million in ETH and ultimately triggered the Ethereum hard fork. Despite being well-documented for nearly a decade, it still appears in modern contract audits with troubling regularity.

What it is and why it matters
A reentrancy attack happens when a malicious contract calls back into the victim contract before the first execution completes, allowing an attacker to withdraw funds repeatedly in a single transaction before the balance is updated.
Reentrancy is one of the most preventable exploits in existence, yet it continues to surface in newly deployed contracts every year.
Where it shows up in real contracts
Withdrawal functions and ETH transfer logic in DeFi protocols are the most common targets, particularly anywhere a contract sends ETH before updating its internal accounting.
Common root causes
Developers write the external call before the state update, directly violating the checks-effects-interactions pattern. Contracts that send ETH to caller-controlled addresses without guarding against recursive execution leave this attack path fully open.
Exploit patterns and red flags in code
Watch for code where call{value}() appears before a balance variable is decremented. Any function that sends ETH to a user-supplied address without a reentrancy guard warrants immediate scrutiny in a review.
Mitigation checklist
- Follow the checks-effects-interactions pattern on every state-changing function
- Apply OpenZeppelin's
ReentrancyGuardmodifier to all fund-moving functions - Avoid calling untrusted external contracts mid-execution
What users and token holders should watch for
Check audit reports for explicit reentrancy test coverage, especially in protocols that process withdrawals or route ETH directly to user-controlled wallet addresses.
6. Lack of input validation
Lack of input validation is a straightforward but consistently underestimated entry on any smart contract vulnerabilities list. When a contract accepts function arguments without checking them against expected bounds or types, attackers pass crafted values that push contract logic into unintended states.
What it is and why it matters
Input validation flaws occur when a contract trusts caller-supplied data without verifying it. An attacker can pass a zero address, a wildly out-of-range integer, or a malformed array to trigger underflows, bypass logic checks, or redirect funds to an address the developer never intended to support.
Skipping input validation is the smart contract equivalent of leaving a form field on a website wide open to arbitrary data.
Where it shows up in real contracts
Token transfer functions, governance parameter setters, and fee configuration functions are the most common locations. Any function that accepts an address or numeric value without boundary checks is directly exposed.
Common root causes
Developers prioritize core logic over defensive checks and assume callers will supply clean data. Contracts ported from trusted internal systems often carry implicit assumptions about input ranges that do not hold when the contract is publicly accessible on-chain.
Exploit patterns and red flags in code
Watch for functions that accept an address parameter without a require(addr != address(0)) check, and arithmetic operations on user-supplied integers that lack upper or lower bound validation before they interact with balances.
Mitigation checklist
- Validate every function parameter at the top of each function before any state change
- Reject zero addresses and out-of-range integers explicitly using
requirestatements - Use SafeMath or Solidity 0.8+ overflow protection for all arithmetic involving user inputs
What users and token holders should watch for
Look for audit reports that specifically test boundary conditions and edge-case inputs. A protocol that skips this coverage leaves predictable attack paths open that an attacker can probe with minimal effort and no specialized tooling.
7. Unchecked external calls
When a smart contract calls an external address and ignores the return value, it assumes the call succeeded even when it failed silently. This flaw appears on every serious smart contract vulnerabilities list because it lets attackers trigger partial state changes that leave protocol accounting permanently broken.
What it is and why it matters
Solidity's low-level call() function returns a boolean indicating success or failure. When developers skip checking that boolean, a failed transfer passes through undetected, and the contract updates its internal state as if the call had succeeded.
Ignoring a return value on an external call is equivalent to confirming a wire transfer without ever checking whether the funds actually moved.
Where it shows up in real contracts
Payment distribution contracts and multi-recipient reward systems are the most common locations. Any function that loops through addresses and sends funds without verifying each individual call result leaves room for attackers to corrupt the payout accounting silently.
Common root causes
Developers use low-level call() instead of higher-level transfer abstractions and skip the return value check during rapid iteration, often because the contract compiled cleanly without warnings.
Exploit patterns and red flags in code
Watch for address.call{value}() without an immediate require(success, ...) statement following it directly in the same execution block.
Mitigation checklist
- Always check return values with
require(success, "call failed") - Prefer OpenZeppelin's
Address.sendValue()over raw low-level calls
What users and token holders should watch for
Check audit reports for explicit low-level call coverage. Protocols that process batch payments without verified return checks can lose funds to silent failures with no clear on-chain indication that anything went wrong.
8. Denial of service and gas griefing
DoS and gas griefing attacks don't steal funds directly. Instead, they lock a contract into a broken state or force legitimate users to pay unsustainable gas costs, effectively making the protocol unusable for everyone.
What it is and why it matters
A DoS vulnerability occurs when an attacker deliberately pushes a contract past its operational limits, blocking users from withdrawing funds or calling critical functions. Gas griefing is a related pattern where an attacker forces expensive computation onto a relayer or counter-party without bearing that cost themselves.
These attacks are particularly damaging in time-sensitive protocols where blocked withdrawals translate directly into financial losses for depositors.
Where it shows up in real contracts
Auction contracts and pull-payment systems are common targets, as are any functions that loop over unbounded arrays of user-supplied addresses without a hard cap on how many iterations the function can run.
Common root causes
Developers write loops over dynamic arrays without restricting their size, allowing an attacker to grow the list until the function exceeds the block gas limit and fails permanently on every subsequent call.
Exploit patterns and red flags in code
Watch for functions that iterate over all depositors or claimants in a single transaction, and for external calls inside loops where a single reverting recipient can block the entire batch.
Mitigation checklist
- Use pull-payment patterns so each user withdraws individually rather than through a shared batch function
- Cap iteration counts and reject unbounded array inputs in any state-changing function
What users and token holders should watch for
Check whether a protocol processes batch operations over user arrays. If it does, verify that the audit explicitly tested what happens when that array grows large or contains a malicious contract address.
9. Insecure randomness
Insecure randomness occurs when a smart contract relies on predictable or manipulable data sources to generate random numbers, giving attackers the ability to predict outcomes before they commit to a transaction. This flaw consistently appears on any serious smart contract vulnerabilities list because it undermines every protocol feature that depends on fair chance.
What it is and why it matters
On a public blockchain, all data is transparent, including block hashes, timestamps, and miner-controlled values. Any contract that uses these as a randomness source lets an attacker or validator predict the outcome and only submit a transaction when the result favors them.
Blockchain randomness is not random by default; it requires deliberate architectural choices to achieve unpredictability.
Where it shows up in real contracts
NFT minting contracts and lottery systems are the most frequent targets, along with any protocol that assigns rewards, rare traits, or selection outcomes using block-level data as its entropy source.
Common root causes
Developers treat block.timestamp or blockhash as convenient entropy sources without recognizing that validators can influence both values within narrow windows before a block is finalized.
Exploit patterns and red flags in code
Watch for keccak256(abi.encodePacked(block.timestamp, msg.sender)) used as a random seed, since any attacker can reproduce that calculation off-chain and only broadcast their transaction when the output favors them.
Mitigation checklist
- Use Chainlink VRF (Verifiable Random Function) for all on-chain randomness requirements
- Never source entropy from block variables alone or from any caller-supplied data
What users and token holders should watch for
Check whether NFT projects or lottery protocols explicitly disclose how randomness is generated. If the audit does not specifically address the randomness implementation, the fairness of any outcome-dependent feature remains unverified.
10. Upgradeability and initialization flaws
Upgradeable contracts give developers the ability to patch bugs after deployment, but that flexibility introduces a class of security problems that belong on every smart contract vulnerabilities list. When the upgrade mechanism or initialization process is implemented incorrectly, attackers can permanently seize control of the contract.

What it is and why it matters
Proxy-based upgrade patterns separate a contract's logic from its storage, letting developers swap the implementation without migrating user funds. When misconfigured, an attacker can point the proxy at a malicious implementation they control, gaining full administrative access to everything the proxy holds.
An uninitialized upgradeable contract is effectively ownerless, and the first person to call its initializer becomes its administrator.
Where it shows up in real contracts
DeFi protocols using the transparent proxy or UUPS pattern are the primary targets. Any contract that uses an initialize() function instead of a constructor is at risk if that function can be called more than once or by anyone.
Common root causes
Developers deploy an implementation contract without immediately calling initialize(), leaving a window where anyone can claim ownership by calling it first.
Exploit patterns and red flags in code
Watch for initialize() functions that lack an initializer modifier, and implementation contracts deployed without a corresponding initialization call in the same transaction.
Mitigation checklist
These two controls eliminate the most common initialization and upgrade attack paths for proxy-based contracts.
- Lock implementation contracts using
_disableInitializers()in the constructor - Call
initialize()atomically in the same deployment transaction
What users and token holders should watch for
Verify that any protocol using upgradeable contracts has a published audit covering the proxy pattern and initialization sequence before you deposit funds.

Next steps
This smart contract vulnerabilities list covers the ten attack classes that account for the majority of crypto losses in active protocols today. Understanding these flaws gives you a real advantage, whether you are reviewing an audit report, evaluating a DeFi protocol before depositing, or simply trying to make smarter decisions about where your assets go.
Knowing what can go wrong in contract code is one layer of security. Protecting the assets you control directly is another. Cold storage, seed phrase hygiene, and wallet selection decisions all sit on your side of the equation, and they matter just as much as the protocols you interact with. If you want to build a complete foundation for crypto security from the ground up, our crypto self-custody course walks you through every practical step in clear, structured lessons. Start there before trusting any application with funds you cannot afford to lose.