According to the documentation and contract logic, DETokens are supposed to be redeemable 1:1 with RToken.
The DEToken (Debitum Emptor Token) is an implementation of the token used in the RAAC Stability Pool. It > represents a user's share in the Stability Pool and is redeemable 1:1 with RToken.
However, if we examine the transfer functions in the RToken
contract, we can see that the transfer
function divides the amount by LendingPool.getNormalizedIncome()
. In contrast, the transferFrom
function divides the amount by _liquidityIndex
.
The problem is that _liquidityIndex
is updated only by RToken.updateLiquidityIndex()
, which has an onlyReservePool
modifier, yet it is never called from the reserve pool (LendingPool).
As a result, when transfer()
is called, the amount is divided by a value that is actively updated by the lending pool, whereas transferFrom()
is divided by a value that is never updated. Simply put, transferFrom()
will always transfer a larger amount than transfer()
.
The discrepancy between these values is further amplified by _update()
, which divides the amount once again by LendingPool.getNormalizedIncome()
.
This inconsistency between the two functions causes the users to receive fewer RTokens when calling StabilityPool.withdraw()
for the same amount of DETokens.
The higher the liquidity index, the greater the discrepancy between the two values.
Place the following test case in StabilityPool.test.js
below describe("Core Functionality", function () { describe("Deposits", function () {
:
Logs:
Manual review
Update the following line in RToken.sol#transferFrom()
:
PoC logs after the fix confirm that the issue is resolved:
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.