Skip to content

CRITICAL: First Depositor Exchange Rate Manipulation (Donation Attack) in New Markets #25

@pk009900

Description

@pk009900

I have identified a critical precision loss vulnerability in the core CToken.sol contract (specifically within mintFresh and exchangeRateStoredInternal) that affects newly deployed or empty markets. This is a variant of the classic Compound V2 "Empty Market" attack.

When a market has a totalSupply of 0, a malicious first depositor can artificially inflate the exchange rate by minting the smallest possible number of shares (e.g., 1 wei) and subsequently transferring (donating) a large amount of underlying tokens directly to the CToken contract.

Because exchangeRateStoredInternal calculates the rate using (totalCash + totalBorrows - totalReserves) / totalSupply, the donated cash massively inflates the numerator while the denominator remains at 1.

Impact:
When subsequent users attempt to deposit funds via mint(), the divScalarByExpTruncate function calculates their minted shares. Due to the hyper-inflated exchange rate, the division results in a fractional share (e.g., 0.99), which Solidity truncates to 0. The victim's underlying tokens are added to the protocol, but they receive 0 jTokens in return. The attacker can then redeem their initial 1 share to sweep the entire vault, effectively stealing the victim's deposit.

Steps to Reproduce:

  1. Attacker calls mint() with 1 wei of the underlying asset on a newly deployed, empty CToken market. Attacker receives 1 wei of jTokens.

  2. Attacker transfers a large amount of the underlying asset (e.g., 10,000 tokens) directly to the CToken contract address, bypassing the mint function. The exchange rate is now highly inflated.

  3. Victim calls mint() with an amount smaller than the attacker's donation (e.g., 5,000 tokens).

  4. The calculation victim_deposit / exchange_rate results in < 1. The value truncates to 0. Victim receives 0 shares.

  5. Attacker calls redeem() to burn their 1 wei of jTokens, sweeping the initial 1 wei, the 10,000 token donation, and the victim's 5,000 token deposit.

Suggested Remediation:
To prevent exchange rate manipulation in empty markets, consider implementing a "dead shares" burn mechanism upon market initialization. Require the market creator or the first depositor to permanently lock a minimum amount of initial jTokens (e.g., 1000 wei) to the address(0) or a dead address. This ensures totalSupply can never be easily manipulated against a 1 wei denominator, making the cost of the donation attack economically unfeasible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions