Incorrect auction trade execution due to issuancePremium
being applied in the RecollateralizationLib.basketRange
computation
#223
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
edited-by-warden
🤖_32_group
AI based duplicate group recommendation
sufficient quality report
This report is of sufficient quality
Lines of code
https://github.com/code-423n4/2024-07-reserve/blob/main/contracts/p1/mixins/RecollateralizationLib.sol#L116
https://github.com/code-423n4/2024-07-reserve/blob/main/contracts/p1/BasketHandler.sol#L429
https://github.com/code-423n4/2024-07-reserve/blob/main/contracts/plugins/assets/RTokenAsset.sol#L66
https://github.com/code-423n4/2024-07-reserve/blob/main/contracts/p1/BasketHandler.sol#L446
Vulnerability details
Impact
The
BasketHanlder.price(bool)
function is used to return the price of aBasket Unit
. The passed inboolean input parameter
indicates whether to apply the issuance premium to the high price. TheBasketHandler.price(bool)
function is called in theRecollateralizationLib.basketRange
function to determine theBasketRange.top
andBasketRange.bottom
values for a givenTradingContext
andAssetRegistry
.As you can see when calculating the
basket unit price
theissuance premium
is not applied (false
is passsed in). But there is a scenario where theissuance premium
is applied as explained below:Baket
can include a differentRTokenCollateral
(Not the RToken which the current basket maps to) as one of its collaterals. This is because when the primary basket is set only collaterals which are not allowed arersr
,rToken
andstRSR
as verified in theBasketHandler.requireValidCollArray
function.BackingManager.rebalance
function theRecollateralizationLib.prepareRecollateralizationTrade
is called which inturn calls theBasketHandler.basketRange
function. Here thectx.bh.price(false)
is called.Basket Unit
, theBasketHandler.price(bool)
function iterates through all the collaterals in the basket and calculates thelow and high
price of each of the collaterals as shown below:RTokenCollateral
is also an active collateral of theBasket
theRTokenAsset.price()
is called which inturn calls theRTokenAsset.tryPrice
function. In thetryPrice
function thebasketHandler.price(true)
call is made which applies theissuance premium
to the price of all of the collaterals which back theRTokenCollateral
, as shown below:As a result the
RTokenCollateral
price returned by theRTokenAsset.price()
accounts for theissuancePremium
if there is a depeg between the (tok/ref) of the respective collateral tokens of the RTokenCollateral. And this price which has theissuancePremium
accounted for, is returned to theBasketHandler.price(bool)
function.Eventhough the
quantity
of theRTokenCollateral
is not applied theissuancePremium (since it bool is false)
its price is applied theissuancePremium
as explained above. As a result when the price of the RTokenCollateral in the basket is calculated it includes theissuancePremium
as shown below:Hence now
high256
which is used to calculate the high value of thebasket unit
is now applied theissuancePremium
for theRTokenCollateral
which is not the intended behaviour since thebasket unit price calculation
didn't intend to include theissuancePremium
for any of its collaterals since thebool false
was passed in when calling thectx.bh.price(false)
via theRecollateralizationLib.basketRange
function.Since the
issuancePremium
is included in theabove basket unit price calculation
any oracle error (2%-3% either way) which occurs insavedPegPrice
could result in errorneousissuancePremium
calculation thus provding wrong (Higher or Lower than the accurate price)RTokenCollateral price
. This will further extend to providing a wrongBasket Unit Price
thus making theBasketRange.top
andBasketRange.bottom
values errorneous. As a result thetrade.sellAmount
andtrade.buyAmount
values of theTradeInfo
struct will be inaccurate. As a result thetriggerred auction trades
in theBackingManager.rebalance
function will have inaccurate trade parameters. This could lead to unintended behaviour such as trade auction not being initiated, basket not being properly rebalanced, trade being disadvantegeous to either the rsr staker or the RToken holder etc ...Above issue can be aggravated if multiple
RTokenCollaterals
are used as active collaterals of aBasket
, sinceissuancePremium
could be applied multiple times for the respectiveRTokenCollaterals
.Proof of Concept
https://github.com/code-423n4/2024-07-reserve/blob/main/contracts/p1/mixins/RecollateralizationLib.sol#L116
https://github.com/code-423n4/2024-07-reserve/blob/main/contracts/p1/BasketHandler.sol#L429
https://github.com/code-423n4/2024-07-reserve/blob/main/contracts/plugins/assets/RTokenAsset.sol#L66
https://github.com/code-423n4/2024-07-reserve/blob/main/contracts/p1/BasketHandler.sol#L446
Tools Used
Manual Review and VSCode
Recommended Mitigation Steps
Hence it is recommended to ensure the uniformity of not including the
issuancePremium
when calculating thebasket unit price
when computing the basketRange. Hence it is recommended to ensure thatRTokenAsset.tryPrice
function calls thebasketHandler.price
function withbool false
when the call is sent (msg.sender) from theBasketHandler contract
. This will ensure thatRTokenCollateral
will not include theissuancePremium
in its price calculation and as a result thebasket unit price
calculated in theBasketHandler.price()
function will provide an accurate price value. This will in turn provide the expectedBasketRange
value without unexpected behavior.Assessed type
Other
The text was updated successfully, but these errors were encountered: