redeemCustom() enables users to redeem their RToken balance for a custom basket of underlying assets in specific proportions. there is an issue with the post-checks performed at the end of the redeemCustom() function. The check for the received amounts of the expected output ERC20 tokens against the specified minimum amounts is incorrect leading to users receiving fewer tokens than expected during consecutive redemptions.
Impact
If a user attempts to perform consecutive redemptions using the same minAmounts values, the second redemption may fail even if the user has sufficient RToken balance. This is because the minAmounts array is not updated between consecutive calls, causing the function to revert when the received amounts do not meet the outdated minimum requirements.
In scenarios where users rely on consecutive redemptions to retrieve their underlying assets, the issue may prevent them from successfully redeeming their tokens. This can lead to funds being stuck in the contract and users being unable to access their assets.
Proof of Concept
In scenario where:
User Alice has a balance of 1000 RTokens and wants to redeem them for a custom basket of assets.
Alice calls the redeemCustom() function with the following parameters:
amount: 500 RTokens
basketNonces: [1, 2, 3]
portions: [0.5, 0.3, 0.2]
expectedERC20sOut: [TokenA, TokenB, TokenC]
minAmounts: [100, 50, 20]
The function performs the necessary checks and transfers the redeemed tokens to Alice's address. Alice receives:
TokenA: 120
TokenB: 60
TokenC: 30
Alice immediately calls the redeemCustom() function again with the same parameters, intending to redeem the remaining 500 RTokens.
The function performs the post-checks, comparing the received amounts against the minAmounts array.
Since the minAmounts array is not updated, the function expects to receive at least [100, 50, 20] tokens again.
However, the actual received amounts in the second redemption are:
TokenA: 80
TokenB: 40
TokenC: 20
The function reverts because the received amounts do not meet the minimum requirements specified in the minAmounts array.
Lines of code
https://github.com/code-423n4/2024-07-reserve/blob/3f133997e186465f4904553b0f8e86ecb7bbacbf/contracts/p1/RToken.sol#L338-L343
Vulnerability details
redeemCustom()
enables users to redeem their RToken balance for a custom basket of underlying assets in specific proportions. there is an issue with the post-checks performed at the end of theredeemCustom()
function. The check for the receivedamounts
of the expected output ERC20 tokens against the specified minimumamounts
is incorrect leading to users receiving fewer tokens than expected during consecutive redemptions.Impact
If a user attempts to perform consecutive redemptions using the same
minAmounts
values, the second redemption may fail even if the user has sufficient RToken balance. This is because theminAmounts
array is not updated between consecutive calls, causing the function to revert when the received amounts do not meet the outdated minimum requirements.In scenarios where users rely on consecutive redemptions to retrieve their underlying assets, the issue may prevent them from successfully redeeming their tokens. This can lead to funds being stuck in the contract and users being unable to access their assets.
Proof of Concept
In scenario where:
User Alice has a balance of 1000 RTokens and wants to redeem them for a custom basket of assets.
Alice calls the redeemCustom() function with the following parameters:
amount
: 500 RTokensbasketNonces
: [1, 2, 3]portions
: [0.5, 0.3, 0.2]expectedERC20sOut
: [TokenA, TokenB, TokenC]minAmounts
: [100, 50, 20]The function performs the necessary checks and transfers the redeemed tokens to Alice's address. Alice receives:
Alice immediately calls the
redeemCustom()
function again with the same parameters, intending to redeem the remaining 500 RTokens.The function performs the post-checks, comparing the received amounts against the
minAmounts
array.Since the
minAmounts
array is not updated, the function expects to receive at least [100, 50, 20] tokens again.However, the actual received amounts in the second redemption are:
The function reverts because the received amounts do not meet the minimum requirements specified in the
minAmounts
array.In the
redeemCustom()
function: RToken:L338-L343Tools Used
Manual review
Recommended Mitigation Steps
Should update the
minAmounts
array between consecutive calls.Assessed type
Math