According to Chainalysis, crypto-native hackers stole an estimated $2.2 billion from Web3 platforms in 2024. This is 21% more than last year. Most of these incidents are traced back to bad engineering decisions made under launch pressure. If you’re planning on launching your own decentralized application, you should understand the most common dApp launch risks that could affect your performance.
We asked several Web3 engineers about the most common mistakes, and here’s what they said.
Key takeaways
- Treat security audits as an ongoing practice instead of a pre-launch formality, and re-audit after any change to state transitions or access control;
- Multisig wallets, hardware-backed signing, and time-locked upgrades address the access-control failures behind most crypto hacks;
- Gas costs and network load need testing against the forked mainnet state before launch;
- A single price oracle is a single point of failure for any protocol that reads price data to gate borrowing or liquidations;
- Adversarial testing, including fuzzing and formal verification, catches failure modes that standard unit tests miss;
- MEV protections such as private relays and default slippage limits stop front-running from quietly taxing every user;
- Onboarding friction is a security risk as much as a UX one: a confused signature is often the first step toward a drained wallet.
Table of contents
- Key takeaways
- 1. Treating the Audit as a Checkbox
- 2. Centralizing Keys and Admin Controls for dApp Launch
- 3. Underestimating Gas Costs and Network Load
- 4. Trusting a Single Price Oracle
- 5. Skipping Adversarial dApp Launch Testing Before Mainnet
- 6. Ignoring MEV and Transaction Ordering
- 7. Designing dApp Launch Only for Crypto-Native Users
- Building the Launch Correctly Instead of Patching It
- Summary
1. Treating the Audit as a Checkbox

Teams often schedule one external audit shortly before mainnet, patch the highest-severity findings, and assume the contract is ready. The problem is that an audit only covers the code and assumptions available during the review. Any meaningful change made afterward creates a new attack surface.
Audits also vary in scope.
A review may focus on contract logic but leave deployment scripts, admin permissions, integrations, frontend transaction building, and off-chain services largely untouched. Attackers do not respect those boundaries. They target whichever part of the system gives them the cheapest route to funds or control.
The audit should begin while the architecture is still flexible enough to change. Give reviewers access to threat models, role definitions, upgrade logic, and dependency assumptions, not just the repository. Findings should feed back into the design rather than become a rushed patch list.
After the first review, re-audit any change that affects:
- State transitions;
- Permissions;
- Accounting;
- Value transfer.
Keep a clear record of what was reviewed, which commit was approved, and what changed before deployment. A bug bounty should remain active after launch, when the protocol starts facing real capital, unusual transaction patterns, and attackers with no fixed testing window.
2. Centralizing Keys and Admin Controls for dApp Launch
Access control failures, not exotic cryptographic breaks, account for many of the largest crypto losses.
The Ronin Bridge hack that drained about $625 million from Axie Infinity in 2022 did not require breaking Ethereum. Attackers compromised five of nine validator keys, partly through a spear-phished employee, and used them to approve fraudulent withdrawals.
The same risk exists anywhere one credential can pause contracts, upgrade logic, mint assets, change oracle settings, or move treasury funds. A multisig helps, but only when signers are genuinely independent. Five signatures from laptops managed by the same person or stored in the same office provide little real protection.
Admin actions should be separated by function.
The account that pauses a contract should not automatically control upgrades, treasury movements, and oracle configuration. You can reduce the damage one compromised account can cause with:
- Hardware-backed signing;
- Meaningful multisig thresholds;
- Time-locked upgrades;
- Transaction simulation;
- Withdrawal limits.
You will also need a dApp launch recovery plan. It should define how signers are replaced, how compromised credentials are revoked, who can trigger an emergency pause, and how control is restored without creating another single point of failure.
These decisions must be tested before launch and not written during an incident.
3. Underestimating Gas Costs and Network Load

A contract that works in a local test environment may fail once it meets real gas prices, crowded blocks, and a large state. Unbounded loops, repeated storage writes, and functions that depend on growing arrays often look harmless during development because test datasets are small.
The failure may not appear as a clean outage. Some users may complete a transaction while others repeatedly hit gas limits. Liquidations, claims, withdrawals, or settlement functions may become too expensive to execute at the exact moment they are most needed.
Gas profiling should cover every public function under realistic state sizes.
You must test worst-case paths, not just the average ones. A withdrawal function that works with ten positions may become unusable with ten thousand. The same applies to reward distribution, voting, batch processing, and asset enumeration.
Tests should run against a forked mainnet state with realistic:
- Token balances;
- Liquidity;
- Storage size;
- Network conditions.
Your team also needs a response for sudden fee spikes. That may include batching, pagination, off-chain computation with on-chain verification, or moving selected operations to an L2. Network choice should follow expected usage and cost limits because the environment used for the first prototype might not work.
4. Trusting a Single Price Oracle
The 2022 Mango Markets exploit showed how dangerous a weak price source can be.
An attacker used roughly $10 million to manipulate the price of a thinly traded token, then borrowed against the inflated collateral and drained $117 million from the protocol. The contracts followed their rules. The price they trusted was the weak point.
Any price used for lending, liquidation, minting, collateral valuation, or settlement should be treated as hostile input. A feed may be delayed, manipulated, unavailable, or technically correct. However, it could be based on a market with too little liquidity to support the protocol’s exposure.
A safer setup combines independent sources and checks them against each other. Time-weighted pricing can reduce the effect of short-lived manipulation, while deviation limits can block updates that move too far from recent market data. Protocols should also define what happens when feeds disagree or stop updating.
Circuit breakers need clear thresholds and limited authority. Pausing borrowing may be safer than freezing all withdrawals. Also, collateral limits should reflect the real liquidity available for an asset.
5. Skipping Adversarial dApp Launch Testing Before Mainnet
Unit tests confirm a contract does what you expect. They don’t confirm it resists what an attacker will try. The 2023 Curve Finance incident, which drained close to $52 million across several protocols, originated not in application logic but in a compiler-level bug in specific Vyper versions that broke reentrancy protection in a way standard tests never would have caught.
“Most teams test that a contract does what it’s supposed to do and stop there,” says Max Tatarchenko, CTO at SapientPro. “The launches that hold up are the ones where someone spent real time trying to make the contract fail: fuzzing inputs, simulating flash loan attacks, checking what happens when a dependency you didn’t write behaves in a way you didn’t expect.”
Fuzzing should target:
- Input ranges;
- Transaction ordering;
- Repeated calls;
- Cross-contract interactions.
Invariant tests should check properties that must always hold, such as total assets matching total liabilities or users never withdrawing more than they own. High-value functions may also justify formal verification.
The test environment should include hostile token contracts, failing oracles, reentrant callbacks, stale data, paused dependencies, and extreme market conditions. The goal is is to find the cheapest way to break the system before someone else does.
6. Ignoring MEV and Transaction Ordering
Transactions in a public mempool can be inspected before confirmation.
In the case of trades, liquidations, auctions, NFT mints, and other order-sensitive operations, this allows bots to copy, front-run, back-run, or encircle a user’s transaction.
A dramatic exploit isn’t always the result. Users may simply receive worse prices, lose liquidation rewards, or pay more than expected. Over time, that hidden cost makes the application feel unreliable even when the contracts behave as written.
You should map every function where transaction order changes the result.
Swaps need reasonable default slippage limits and deadlines. Sensitive transactions may need private relays. Auctions and sealed bids may require commit-reveal logic. Also, consider that batch auctions can reduce the advantage of precise ordering by settling users at the same clearing price.
Protection also belongs in the frontend. A contract may support strict slippage limits, but that does little if the interface defaults to a wide range or hides the setting. Users should see the expected output, maximum price impact, deadline, and likely failure conditions before signing.
MEV cannot always be removed, but its cost can be limited and made visible. The dangerous approach is to ignore it until users start comparing the quoted price with what they actually received.
7. Designing dApp Launch Only for Crypto-Native Users
A contract can be secure and still fail because the first session is too difficult.
Many dApps assume users already have the correct wallet, network, token balance, and gas asset. Each extra step creates another chance to leave, switch to the wrong network, approve the wrong contract, or sign something they do not understand.
Signature requests are a common weak point. Wallet prompts often show technical data without explaining the real effect. A user may think they are logging in when they are granting token approval, signing a permit, or authorizing a transfer.
The product should explain every request in easy language before the wallet opens.
Users need to know what asset is involved, which contract receives permission, whether the approval is limited or unlimited, and whether the action can be reversed. The interface should also warn users about unexpected contract addresses or network changes.
Account abstraction under ERC-4337 can remove several early barriers. Applications can sponsor gas, group several actions into one flow, add recovery rules, and let users pay fees in a token they already hold. These features still need limits so sponsored transactions cannot be abused.
Failed transactions also need useful explanations.
“Execution reverted” tells the user nothing. The application should state whether the problem is insufficient balance, slippage, a paused contract, expired approval, or the wrong network. Better onboarding is not cosmetic. It reduces unsafe signatures, support requests, and costly user mistakes.
Building the Launch Correctly Instead of Patching It
Unfortunately, most of these mistakes aren’t new: audits, key management, load testing, oracle design, and others have been known in the industry for quite some time. What breaks launches is usually sequencing, treating security and scalability work as post dApp launch cleanup instead of prerequisites.
Teams without deep in-house blockchain engineering bandwidth often bring in a tech partner for the application layer around the contracts:
- Wallet integration;
- Backend infrastructure;
- User-facing product;
- Smart contracts logic.
Working with a web3 development company that provides these services is usually what closes the gap between a working contract and a product people can actually use. The projects that hold up under real usage are usually the ones where someone insisted on doing the unglamorous engineering work before mainnet, not after the first exploit.
Summary
Most modern dApp launches fail because of engineering decisions made under deadline pressure. You can’t treat an audit as a formality or skip must-have tests just because you’re in a rush. That’s the reason many teams fail to launch their products without extra issues.
If you want to launch your dApp successfully, never take shortcuts when working on your platform’s sensitive blocks. It might take a little bit longer, but it will be totally worth it by protecting you from hacks and other challenges.











