The block that wasn't there
A blockchain is a database with strong opinions about history. Most of its bugs come from the places where those opinions aren't enforced.
A blockchain is a database that refuses to forget. That's the interesting property, and it's also where most of the security work lives: not in the cryptography, but in the gap between what the protocol guarantees and what a particular contract assumes.
Consensus is not correctness
Consensus tells you a transaction happened, in a specific order, and that everyone agrees. It says nothing about whether the transaction should have been allowed. A perfectly valid, perfectly final, perfectly disastrous transfer is still a valid transfer.
So the security question is never "can this be forged?" — usually it can't. It's:
- Who is allowed to call this?
- What state do they need to be in for the call to be safe?
- What happens if two of these calls land in the same block?
Same-block surprises
The block is a batching mechanism, and batching is where assumptions break. Code that is safe when called once is often not safe when called three times before anything settles:
// Assume `total` is read from storage somewhere far away,
// and balances are only reconciled at the end of the block.
for (uint i = 0; i < n; i++) {
accrue(user[i], total / n);
}
If total can move mid-block, every entry in that loop was calculated against a number that was
true exactly once, briefly, at the top.
The chain isn't lying to you. It's faithfully executing a program that assumed something the chain never promised.
What I look for first
Ordered by how often it pays off:
- External calls placed before state updates.
- Assumptions that a value can't change within a transaction.
onlyOwnerused as the whole security model.- Anything that reads a balance and then acts on it later.
Most exploits aren't clever. They're a
requirethat was obvious to the author and invisible to the reviewer, sitting in a file that both of them had already read twice.
That's the job: read it a third time, from the attacker's side of the glass.