DebtToken's burn function fails to properly scale balances when burning debt tokens. This leads to incorrect debt accounting that could impact the entire lending protocol's solvency calculations when a user burns debt tokens with a high index value. The contract's scaling calculations for burning tokens produce incorrect results because the burn amount isn't properly scaled relative to the current index.
The scaled balance reduction is expected to match the burn amount divided by the index. However, the actual implementation in DebtToken.sol shows the scaling calculation isn't handling the ray math precision correctly.
The whitepaper specifically mentions scaled accounting for debt positions, but this wasn't fully implemented in the burn logic.
Imagine a mortgage system where borrowers could repay their loans using historical rates, completely ignoring years of accumulated interest, so this is exactly what's happening in RAAC's DebtToken contract.
It unfolds in the heart of RAAC's lending mechanism, where the DebtToken represents real estate-backed debt positions. When users borrow against their tokenized properties, their debt should grow with interest over time through an index multiplier, just like a traditional mortgage. However, the current implementation creates a dangerous shortcut.
Let's walk through a real scenario: Alice borrows 100,000 RAAC tokens against her tokenized property. After a year, the currentIndex has grown to 1.5, meaning her actual debt is now 150,000 RAAC. But here's where things break, when Alice calls burn() to repay 100,000 tokens, the contract accepts this as full repayment for that amount, completely ignoring the accumulated interest. She just saved 50,000 RAAC through a simple math error.
The root cause lives in this line: /DebtToken.sol#burn()
This flaw ripples through the entire RAAC ecosystem. The protocol's real estate lending system depends on accurate debt accounting to maintain proper collateralization ratios and trigger liquidations when needed. With this bug, the system progressively loses track of real debt obligations, potentially leading to protocol insolvency as users exploit this "discount" mechanism.
See the key vulnerability is in the final _burn() call where it uses the unscaled amount instead of the amountScaled value, creating the debt repayment discrepancy we identified.
The core of RAAC's lending system uses an interest-bearing debt token where balances scale with a rate index over time. Think of it like compound interest on a mortgage, your actual debt grows even though the number of tokens stays the same, users could repay less debt than they actually owe. The contract's scaling mechanism, which should adjust debt based on accumulated interest (like any real-world mortgage), fails to account for the current interest rate index during burns.
The bug emerges in the burn function
When a user repays their debt (burns tokens), the contract should divide the repayment amount by the current index to get the correct scaled balance reduction. Instead, it burns the raw amount, leading to incorrect debt accounting.
Real World Impact This isn't just a math error - it directly affects the protocol's ability to track real estate debt positions accurately. For example, if Alice borrows against her tokenized property with an initial index of 1.0, and the index later grows to 1.5, burning 100 tokens should only reduce her scaled balance by ~67. The current implementation would incorrectly reduce it by 100, essentially giving her a ~33% discount on her debt.
changing _burn(from, amount.toUint128()) to _burn(from, amountScaled.toUint128()), ensuring the debt reduction properly accounts for the accumulated interest through the index scaling.
Interest IS applied through the balanceOf() mechanism. The separate balanceIncrease calculation is redundant/wrong. Users pay full debt including interest via userBalance capping.
Interest IS applied through the balanceOf() mechanism. The separate balanceIncrease calculation is redundant/wrong. Users pay full debt including interest via userBalance capping.
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.