← Back to Hack Archive

Compound Finance Bug

September 30, 2021$80 millionCode Upgrade ErrorEthereum

The Story

On September 30, 2021, Compound Finance, one of the largest lending protocols in DeFi with billions in total value locked, experienced a severe bug following the implementation of Proposal 62. The proposal was intended to fix the distribution of COMP tokens to users, but instead introduced a critical error that allowed users to claim far more COMP tokens than they were entitled to.

The bug affected the Comptroller contract, which is responsible for distributing COMP tokens to users as rewards. Some users were able to claim millions of dollars worth of COMP tokens that should not have been available to them. In total, approximately $80 million worth of COMP tokens were incorrectly distributed before the issue could be addressed.

What made this incident particularly challenging was Compound's governance structure. Due to the protocol's decentralized governance model, fixing the bug required a new proposal and a mandatory 7-day timelock period before implementation. During this waiting period, funds continued to be at risk, highlighting a fundamental tension between decentralized governance and emergency response capabilities.

Technical Analysis

The Compound Finance bug was introduced in a seemingly minor code update that changed the logic for reward distribution. The error occurred in the calculation of accrued COMP rewards in the Comptroller contract:

// The buggy code introduced in Proposal 62
function compAccrued(address user) public view returns (uint) {
    CompMarketState storage compState = compSupplyState[market];
    uint supplyIndex = compState.index;
    uint supplierIndex = compSupplierIndex[market][user];

    // The error was in this line - it incorrectly calculated rewards
    // by using the wrong index when calculating drip accruals
    if (supplierIndex == 0 && supplyIndex > compInitialIndex) {
        supplierIndex = compInitialIndex;
    }

    return compAccrued[user] + 
        divScalarByExpTruncate(
            mulScalarTruncate(supplyIndex - supplierIndex, compSupplySpeeds[market]), 
            compScale
        );
}

The key issue was that the update incorrectly tracked and calculated the COMP token rewards, particularly for users who had interacted with multiple Compound markets. The bug affected the accounting system, causing certain accounts to receive COMP tokens meant for distribution across all users.

Specifically, the error allowed users who had supplied and borrowed in the same market to receive rewards intended for all suppliers and borrowers in that market, resulting in massive over-allocations.

Lessons Learned

  1. Complex DeFi protocols should implement comprehensive testing frameworks, including invariant testing
  2. Critical code changes should be tested on testnet with real-world scenarios before deployment to mainnet
  3. Governance systems should have emergency mechanisms that can bypass timelocks in critical situations
  4. Rate-limiting mechanisms for token distributions can prevent catastrophic losses from bugs
  5. External security audits should be standard for all code changes, even seemingly minor ones