The DebtToken contract is designed to track user debt in the RAAC lending protocol using a scaled balance mechanism inspired by Aave’s VariableDebtToken. Each user’s “actual” debt balance is calculated from an internally stored “scaled” balance and a usage (or reserve) index obtained from the LendingPool. While the contract correctly computes an individual user’s debt balance via an override of balanceOf—multiplying the stored (scaled) balance by the normalized debt—the override for totalSupply instead divides the stored scaled total supply by the normalized debt. This inversion leads to a severe miscalculation of the overall outstanding debt.
Standard Mechanism:
In variable debt tokens, the actual balance is typically computed as:
where RAY is a fixed scaling factor (typically 1e27).
Implementation in DebtToken:
The balanceOf function correctly returns:
This calculates
However, the totalSupply function returns:
which computes
Inversion Effect:
Instead of scaling the total supply up by the normalized debt (as with individual balances), it scales it down. For example, if the normalized debt is greater than RAY (indicating accrued interest), an account’s balance is inflated relative to its stored value, but the total supply is deflated. This discrepancy results in inconsistent and erroneous overall debt accounting.
Inaccurate Debt Representation:
The total supply of DebtToken, which represents the aggregate outstanding debt in the protocol, will be significantly misreported. For instance, if the normalized debt is 2×RAY, a user’s balance would be doubled, while totalSupply would be halved relative to their true cumulative debt.
Downstream Effects:
This miscalculation can have severe consequences on:
Interest accrual computations,
Liquidation triggers,
Reward and fee distribution,
Overall risk management across the lending protocol.
Such an error could lead to either an underestimation or overestimation of system-wide debt, potentially causing improper liquidations or misallocated rewards, and undermining confidence in the protocol’s financial integrity.
simplified Foundry test demonstrates the inconsistency between balanceOf and totalSupply when the normalized debt is set above RAY. For demonstration purposes, we simulate the LendingPool’s getNormalizedDebt function via a mock contract.
Explanation:
We deploy a mock LendingPool that returns a normalized debt of 2e27 (i.e. twice the base RAY).
We mint 100 units (scaled) of debt tokens to an address.
The overridden balanceOf correctly computes the user’s actual balance as 200 tokens, but the overridden totalSupply erroneously computes 50 tokens.
This discrepancy proves that the total supply calculation is inverted relative to individual balances.
Recommended Fix:
Modify the totalSupply override so that it uses the same scaling factor as balanceOf. In other words, it should multiply the stored scaled total supply by the normalized debt and then divide by RAY. For example, change:
to
This ensures consistency between individual balances and the aggregate total supply, correctly reflecting accrued interest and overall debt in the protocol.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.