Common vulnerability patterns in Blockchain / Solidity - Time & Space Complexity
When we look at common vulnerability patterns in blockchain code, we want to understand how the cost of running the code changes as inputs grow.
We ask: How does the program's work increase when it faces more data or more users?
Analyze the time complexity of the following code snippet.
function withdraw(uint amount) public {
require(balances[msg.sender] >= amount);
balances[msg.sender] -= amount;
(bool success, ) = msg.sender.call{value: amount}("");
require(success);
}
This code allows a user to withdraw funds from their balance, sending Ether to their address.
Look for loops or repeated actions that affect time.
- Primary operation: Single balance check and transfer call per withdrawal.
- How many times: Runs once per withdrawal request, no loops inside.
The work done is mostly fixed per withdrawal, no matter how many users or transactions happen.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 operations (one per withdrawal) |
| 100 | 100 operations |
| 1000 | 1000 operations |
Pattern observation: The cost grows linearly with the number of withdrawal calls.
Time Complexity: O(n)
This means the total work grows directly with the number of withdrawal requests made.
[X] Wrong: "The withdrawal function runs in constant time no matter how many users withdraw."
[OK] Correct: Each withdrawal call costs time, so more calls mean more total work, even if each call alone is simple.
Understanding how vulnerabilities affect time helps you explain risks clearly and shows you can think about code efficiency and safety together.
"What if the withdraw function included a loop over all users to update balances? How would the time complexity change?"