Smart contracts are the foundation of many Web3 applications, including DeFi protocols, NFT platforms, and decentralized applications. However, unlike traditional software, smart contract vulnerabilities can directly affect user assets and protocol funds.
At PandaSecurity, we review smart contracts from an attacker’s perspective. During security reviews, we often find that many risks are not caused by extremely complex code. Instead, they come from simple mistakes in logic, assumptions, and contract design.
This article explains some of the most common Solidity mistakes that can introduce security risks.
Access control determines who can execute sensitive functions.
Many contracts contain privileged operations such as:
A common mistake is forgetting to restrict these functions.
Example:
function setFee(uint256 newFee) external {
fee = newFee;
}
Without proper authorization, any user could modify important protocol settings.
A safer design should include appropriate permission checks:
function setFee(uint256 newFee) external onlyOwner {
fee = newFee;
}
However, security reviews should not only check whether a modifier exists. Auditors should also verify:
Incorrect access control remains one of the most common causes of smart contract security issues.
Smart contracts frequently interact with external contracts, including tokens, oracles, and other protocols.
External calls should always be treated as potentially dangerous because the called contract can execute unexpected logic.
A classic example is updating state after making an external call:
function withdraw() external {
uint256 amount = balances[msg.sender];
payable(msg.sender).call{value: amount}("");
balances[msg.sender] = 0;
}
The problem is that the user-controlled contract receives execution control before the internal balance is updated.
A safer approach follows the Checks-Effects-Interactions pattern:
function withdraw() external {
uint256 amount = balances[msg.sender];
balances[msg.sender] = 0;
payable(msg.sender).call{value: amount}("");
}
The key security principle is simple:
Do not trust external calls.
Many Solidity developers assume every ERC20 token behaves exactly the same.
In reality, tokens may have different implementations:
For example, a protocol that calculates accounting based only on requested transfer amounts may become inconsistent if the actual received amount is different.
When interacting with ERC20 tokens, developers should carefully handle transfer results and understand token behavior.
Security reviews often focus on whether protocol assumptions match real token behavior.
Many DeFi protocols rely on external price information.
The oracle itself may be secure, but the integration logic can still introduce vulnerabilities.
Common mistakes include:
For lending protocols, exchanges, and derivatives platforms, incorrect price handling can affect:
Oracle security requires reviewing both the data source and how the protocol consumes that data.
Solidity uses integer arithmetic, which means division can lose precision.
Example:
uint256 reward = amount * 5 / 100;
In financial applications, small rounding differences can become important when repeated over many transactions.
Common areas requiring attention include:
Developers should carefully consider rounding direction and ensure accounting remains consistent.
Upgradeable contracts introduce additional complexity.
Proxy-based systems require careful management of:
A secure implementation can still become vulnerable if the upgrade mechanism is poorly designed.
Security reviews should analyze the complete upgrade architecture, not only the implementation logic.
Reading individual functions is not always enough to discover smart contract vulnerabilities.
Auditors often define important rules that should always remain true.
Examples:
These rules are known as invariants.
Testing invariants through fuzzing and manual analysis can reveal unexpected edge cases.
Modern Web3 protocols are highly interconnected.
A contract may interact with:
A function that appears safe alone may become dangerous when combined with another component.
Attackers usually analyze the complete system, not just a single contract.
At PandaSecurity, we combine manual security research with automated analysis tools to identify realistic attack paths.
Our security review approach focuses on:
Security is not only about finding known vulnerability patterns. It is about understanding how a protocol can fail under unexpected conditions.
Most Solidity security issues are not caused by complicated programming mistakes.
They usually come from incorrect assumptions:
Smart contract security should be considered from the beginning of development.
A professional security review provides another perspective before attackers find these weaknesses.
PandaSecurity helps Web3 teams improve contract security through smart contract auditing and security research.
UNCX's token vesting contract lost roughly $87.7K when an attacker exploited a share-accounting flaw in release(), topUpVesting(), and cancel(). We break down the root cause, the exact attack sequence, and what builders should take away from it — without the jargon.
Autheo’s THEO token lost 92% after attackers used a Hyperlane TrustedRelayerIsm misconfiguration to mint 19 million unbacked tokens on Base and extract roughly $1.76 million. Here’s how the attack worked and why single-key security models remain dangerous for cross-chain assets.
Uniswap v4 hooks explained: the PoolManager singleton, flash accounting, and what the Cork and Bunni exploits teach us about hook security. A PandaSecurity deep dive.
An attacker forced a Uniswap V4 vault into a zero-liquidity state, redeemed one minimal share unit, and withdrew roughly 14,838.47 DAI. Panda Security breaks down the transaction, vulnerable code, root cause, and practical fixes.