(WIP)
This is the therory behind the vulnerabilities, if you are interested in learning the real world examples check: BugFix Reviews.
- Vulnerabilies
- Logic
- Re-entrancy
- Uninitialized
- Code injection via delegatecall [WIP]
- Access Control
- Wrong implementation of standards
- Flashloans
- Oracle manipulation
- Unchecked call return value
- Transaction reorganization (MEV)
- Bad Randomness
- Use of components with known vulnerabilities
- Blockchain Bridges
- Research Papers
- Resources:
- Assumptions using external functions
This can have a lot of variations, this case of calling an external function is very interesting: ValueDeFi Incident
- Decimal assuptions
For example, ERC20 decimals errors, the common value used for decimals is 18, but tokens like USDT and USDC have only 6.
This happens when you go below the minimum value (underflow) or exceed the maximum value (overflow) and the value will be considered 0.
Solidity has different value types, for integers you can use int
(negative and positive values) and uint
(just positive ones) and their size variations in steps of 8 for example: int8
2**8 different values,int16
, int24
... int256
2**256 values
Since version 0.8.0
Solidity automatically reverts on integer overflow and underflow instead of circling the value back to zero.
Resources: Consensys Insecure Arithmetic, Solidity Docs Integers
Reentrancy is when a program’s execution can be interrupted and re-run from a particular point, a vulnerability made famous in the DAO hack. One way this vulnerability could manifest is if a bank’s wire system only checked an account’s balance at the beginning of the wire, as opposed to also checking the balance when the wire is about to be sent, in order to ensure sufficient funds. This could lead to a reentrancy attack that calls the send function multiple times to send more funds than are available in the account.
In other words, this is an issue of temporality where a send function can be called before a check balance function is called.
In smart contracts, a function will make an external call, which if not done just correctly will allow an untrusted called contract to perform a re-entrancy attack on the original contract.
Resources: Consensys, SecuRing, Historical Collection of Reentrancy Attacks
First of all, you need to understand what is delegatecall
this function is a variant of message call but SolidityDocs delegatecall
- Default Visibility One of these common examples
Never use tx.origin
for authorization.
If for example you create a contract wallet with that authorization system, someone can trick you into sending Ether to an attack contract and that contract can call your unsafe wallet and drain all the funds because is checking the tx.origin
instead of the msg.sender
. Check the code of this example here
The particularity with msg.value
is that his value remains fixed during the whole function call. Do not use msg.value
inside a loop.
Resources: TrustChain, TrailOfBits
Information about standards: Ethereum docs, OpenZeppelin docs
Let's say that these standards are almost bulletproof, however, the most insignificant change can lead to critical vulnerabilities.
As an example, I'm going back to the spring of 2021 when a lot of projects decided to add a "transfer fee" to their tokens, this can be seen as an insignificant change but, most of the contracts weren't ready to handle these tokens. The common issue here was that someone could drain the pool staking and unstaking several times leading to miscalculations. This article Watchpug SafeDollar postmortem provides an example.
When a borrower uses a platform's smart contract to obtain a loan without providing collateral, this is referred to as a "Flash loan."
A flash loan attack happens when a hacker borrows a lot of assets that don’t require collateral, manipulates the price of a cryptocurrency asset on one exchange, and then sells it very rapidly on another.
An example is C.R.E.A.M. Finance flash loan attack. To know more, read: "C.R.E.A.M. Finance Post Mortem: Flash Loan Exploit Oct 27" resulted in a loss of ~$130M USD.
Bad Randomness arises when the attacker can predict the result of a random number. Depending on the circumstances, this may result in certain security risks.
Currently, two techniques are frequently employed to obtain randomness: using block variables or oracles.
The most frequently used block variables are block.difficulty
, blockhash
, block.number
, and block.timestamp
. Randomness generated by block data limits the possibility of regular users to predict that random number, but not to miners.
A miner can decide to broadcast or discard a block mined in a process called "Selective packing"; This process gives the possibility to mine and discard blocks to achieve a desired result. Only at that point the miner broadcast the block.
For randomness that isn't a part of the core application, block variables are a good option.
An example of an oracle is ChainLink. There are oracles specifically built to generate random number seeds that are then used by other applications to generate randomness.
This comes with some risks, such as being dependent on a third-party to provide you a random number seed and being sure that the oracle doesn't get corrupted. Even if you create your own oracle, your application will always depend on the integrity of it (check Oracle manipulation).
That said, oracles are the most reliable way to have strong randomness.
To know more about Bad Randomness, check this article from SlowMist: "Intro to Smart Contract Security Audits | Randomness"
- Smart contracts may have been created using an obsolete compiler with known flaws
- Libraries with known vulnerabilities have been imported
- Code reuse: for their apps, many programmers reuse code. To put it another way, if the copied code has flaws, so does the smart contract it was pasted into.
- SoK: Not Quite Water Under the Bridge: Review of Cross-Chain Bridge Hacks
- A Review on Cryptocurrencies Security
- Security, Privacy, and Decentralization in Web3
- Consensys Smart Contract Best Practices Attacks
- Consensys Smart Contract Best Practices Development Recommendations
- SWC Registry, Smart Contract Weakness Classification and Test Cases
- List of Security Vulnerabilities
- Secureum Audit Findings 101
- Secureum Audit Findings 201
- DeFiVulnLabs - Collection of Vulnerable Code Snippets