Skip to content
#12 largest Arithmetic 2021

The Compound Finance hack — $147M lost

Loss$147M
Date29 Sep 2021
ChainEthereum
Failure classArithmetic
In assetsgiven away, not stolen
Targetthe $147M character
1

What happened

Governance Proposal 62 split COMP rewards into separate supply-side and borrow-side speeds. Inside distributeSupplierComp, the guard that initializes a first-time supplier's index used > where it needed >=. For a market whose supply index was still exactly compInitialIndex, the branch never fired, the supplier's index stayed at 0, and the reward delta became the entire 1e36 index. Users started claiming COMP by the truckload — and because Compound governance requires a 7-day process, everyone watched the bug pay out for a week with no way to stop it.

2

How the attack ran

  1. Proposal 62 shipsCOMP rewards split into supply and borrow speeds
  2. A first-time supplier claimsTheir stored index is still 0
  3. > where >= was neededThe init branch is skipped, so the delta becomes the full 1e36
  4. Paid out for a week~$147M — a 7-day timelock and no pause switch
3

The code

Comptroller.sol — distributeSupplierComp
// ❌ shipped in Proposal 62
if (supplierIndex.mantissa == 0 && supplyIndex.mantissa > compInitialIndex) {
    supplierIndex.mantissa = compInitialIndex;   // 1e36
}
Double memory deltaIndex = sub_(supplyIndex, supplierIndex);
uint supplierDelta = mul_(supplierTokens, deltaIndex);

// ✅ fixed in Proposal 64
if (supplierIndex.mantissa == 0 && supplyIndex.mantissa >= compInitialIndex) {
    supplierIndex.mantissa = compInitialIndex;
}

// With > :  supplyIndex == compInitialIndex == 1e36 → branch skipped
//            supplierIndex stays 0  →  deltaIndex = 1e36 − 0 = 1e36
//            rewards paid against an index of 1e36 instead of 0.
→ result: ~$147M of COMP accrued and claimable in error
4

What would have caught it

What an audit looks for: off-by-one boundaries in every comparison, and the fact that a bug fix is a code change like any other — this one was introduced by a fix for a previous reward bug. Also worth auditing: your own emergency response. A 7-day timelock with no pause switch means a live bug runs to completion.
6

Sources

Every figure on this page comes from the post-mortems above, not from us. Losses are US dollars at the time of the incident.

Check your own contract for this

Arithmetic is one of the 203 classes the SaferICO scanner checks for. It will not review your signing process — but it will read your Solidity.

Run the scanner See how it is attacked Read the docs