The transferFrom
function in RToken calculates a scaled transfer amount before checking the user’s allowance. This discrepancy allows spenders to exceed the user’s intended approval, resulting in unauthorized transfers of more tokens than permitted.
The RToken contract uses a liquidity index to scale down transfer amounts before calling super.transferFrom
. This design breaks the standard ERC20 allowance, which expects approve(spender, X)
to limit the spender to exactly X
tokens.
In RToken, a higher liquidity index reduces the amount checked against the allowance, letting attackers pass a large “underlying” amount and only check a smaller scaled value. The protocol’s logic permits a spender to transfer more real tokens than the user explicitly approved. This exploit relies on the liquidity index growing over time, rendering the mismatch increasingly significant.
Attackers supply a normal transfer amount that looks safe to the user but bypasses the intended allowance check because of the scaling step.
Attackers can siphon tokens by carefully selecting an amount that appears within the “scaled” allowance, but which corresponds to a larger actual balance. The exploit is straightforward as soon as the allowance is set and the liquidity index differs substantially from 1-to-1 scaling. I've rated this as a high because it enables direct theft of user funds, and the likelihood is high because this mismatch appears any time transferFrom
is used with a non-trivial liquidity index.
Setup: Alice sets approve(spender, 100)
believing it limits the spender to 100 RToken in normal units.
Growing Liquidity Index: Over time, _liquidityIndex
increases to 2x.
Exploit: The attacker calls transferFrom(Alice, attacker, 100)
, but transferFrom
internally scales 100 down to 50 before checking the allowance.
If Alice only approved “100 tokens,” the actual check is only for “50 scaled tokens,” letting the attacker move 200 real tokens in multiple calls.
Manual Review
Align the allowance mechanism with scaled amounts or convert approve
and transferFrom
to share the same reference (scaled vs. underlying). One fix is ensuring the user’s approved amount is also scaled at approval time, so no mismatch occurs:
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.