In the BackingManager.rebalance function the RecollateralizationLib.prepareRecollateralizationTrade function is called. In the prepareRecollateralizationTrade function the RecollateralizationLib.nextTradePair function is called to determine the trading parameters for the new trade auction which is going to be initiated to rebalance the basket.
The RecollateralizationLib.nextTradePair function calls the Asset.price() function of each of the registered assets in the reserve protocol as shown below:
if (ctx.bals[i].gt(needed)) {
(uint192 low, uint192 high) = reg.assets[i].price();
The issue here is if multiple RTokenCollaterals are registered in the reserve protocol then the nextTradePair function will call the price() function of each of those RTokenCollaterals. As a result the RTokenAsset.tryPrice function will be called in the execution flow which in turn will call the basketHandler.price(true) as shown below:
Since true is passed onto the basketHandler.price the issuancePremium is applied to the price calculation if the collateral is experiencing a depeg in tok/ref. This could introduce oracle error (2%-3% either way) in the savedPegPrice to the issuancePremium thus this error could get transferred to the collateral high price value of the RTokenCollateral. This could make the TradePrice.buyHigh and TradePrice.sellHigh parameters erroneous. As a result the initiated trade auctions during the BackingManager.rebalance execution will have erroneous trade parameters. This could lead to erroneous initiations in the DutchTrade.init auctions thus resulting in erroneous prices for the auctions at a particular timestamp (calculated in the DutchTrade._price function). This could be disadvantageous and loss of funds to either the rsrStakers or the RToken holders.
Hence when the price() function of a RTokenCollateral is called from the BackingManger contract (BackingManager.rebalance), it is recommended to ensure that the issuancePremium is not applied to the price calculation of the RTokenCollateral. This will ensure the oracle error which could be introduced via the issuancePremium onto the trade parameters of the auctions initiated during the BackingManager.rebalance execution, will be eliminated.
Lines of code
https://github.com/code-423n4/2024-07-reserve/blob/main/contracts/p1/mixins/RecollateralizationLib.sol#L299-L300 https://github.com/code-423n4/2024-07-reserve/blob/main/contracts/p1/mixins/RecollateralizationLib.sol#L336-L338 https://github.com/code-423n4/2024-07-reserve/blob/main/contracts/plugins/assets/RTokenAsset.sol#L66
Vulnerability details
Impact
In the
BackingManager.rebalance
function theRecollateralizationLib.prepareRecollateralizationTrade
function is called. In theprepareRecollateralizationTrade
function theRecollateralizationLib.nextTradePair
function is called to determine the trading parameters for thenew trade auction
which is going to be initiated to rebalance the basket.The
RecollateralizationLib.nextTradePair
function calls theAsset.price()
function of each of the registered assets in thereserve protocol
as shown below:The issue here is if multiple
RTokenCollaterals
are registered in thereserve protocol
then thenextTradePair
function will call theprice()
function of each of thoseRTokenCollaterals
. As a result theRTokenAsset.tryPrice
function will be called in the execution flow which in turn will call thebasketHandler.price(true)
as shown below:Since
true
is passed onto thebasketHandler.price
theissuancePremium
is applied to the price calculation if thecollateral
is experiencing adepeg
intok/ref
. This could introduce oracle error (2%-3% either way) in thesavedPegPrice
to theissuancePremium
thus this error could get transferred to thecollateral high price value
of theRTokenCollateral
. This could make theTradePrice.buyHigh
andTradePrice.sellHigh
parameters erroneous. As a result the initiatedtrade auctions
during theBackingManager.rebalance
execution will have erroneous trade parameters. This could lead to erroneous initiations in theDutchTrade.init
auctions thus resulting in erroneous prices for the auctions at a particular timestamp (calculated in theDutchTrade._price
function). This could be disadvantageous and loss of funds to either the rsrStakers or the RToken holders.Proof of Concept
https://github.com/code-423n4/2024-07-reserve/blob/main/contracts/p1/mixins/RecollateralizationLib.sol#L299-L300
https://github.com/code-423n4/2024-07-reserve/blob/main/contracts/p1/mixins/RecollateralizationLib.sol#L336-L338
https://github.com/code-423n4/2024-07-reserve/blob/main/contracts/plugins/assets/RTokenAsset.sol#L66
Tools Used
Manual Review and VSCode
Recommended Mitigation Steps
Hence when the
price()
function of aRTokenCollateral
is called from theBackingManger
contract (BackingManager.rebalance
), it is recommended to ensure that theissuancePremium
is not applied to the price calculation of theRTokenCollateral
. This will ensure the oracle error which could be introduced via theissuancePremium
onto thetrade parameters
of the auctions initiated during theBackingManager.rebalance
execution, will be eliminated.Assessed type
Other