When a staker try to claim rewards by calling LiquidationPool.claimRewards
function, this function uses IERC20.transfer
to transfer rewards, but the return value of this call is never checked.
ERC20
implementations known for its inconsistency. transfer
for some implementations can return false
instead of revering.
Also the EIP-20 documentation states that:
Callers MUST handle
false
fromreturns (bool success)
. Callers MUST NOT assume thatfalse
is never returned!
But in LiquidationPool.claimRewards
we can see that an "unsafe" transfer
call performed at line 175:
Before calling transfer
, the Reward
record removed from rewards
(line 170). So, if transfer
failed and returned false
, claimRewards
will succeed, but the user will not receive expected rewards.
It can't be guaranteed that newly added ERC20
tokens will not use return false
, so there is no reason to ignore this case.
NOTE: this issue also reported in Aderyn Analysis Report(L-3), which includes more instances of "unsafe transfer". But I want to underline this particular case (and mark it as Medium risk) because the impact is different, and not explained in the report.
Instances in
LiquidationPoolManager
:
funds might be not transferred to Protocol
The funds will still be held by the Protocol's owned
LiquidationPoolManager
Instance in
LiquidationPool.claimRewards
:
funds might be not transferred to users
funds will stuck in
LiquidationPool
Reward
record will be removed, there is no events (or any other "onchain" tracking). So, there is no reliable way to recover lost rewards.
Reward tokens for stakers can be lost.
SafeERC20
already integrated by the Protocol. So we can just replace usages of transfer
with its "safe" version - safeTransfer
:
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.