Skip to content

Latest commit

 

History

History
36 lines (26 loc) · 2.28 KB

058.md

File metadata and controls

36 lines (26 loc) · 2.28 KB

0xlmanini

medium

Incorrect decimals in amountToSellUnits calculation

Summary

USSDRebalancer.sol#BuyUSSDSellCollateral is used when USSD's price w.r.t. DAI is below a given threshold, thus the system must sell some of its collateral for DAI and then sell such DAI for USSD, pumping its price w.r.t. DAI. When a given collateral's value is able to cover for the whole amount of DAI to be bought, the system sells just enough of such collateral to cover for such DAI amount.

Vulnerability Detail

The issue arises in BuyUSSDSellCollateral#L121 where the Rebalancer computes the exact amount of collateral to be sold on Uniswap, as amountToSellUnits. This amount should be in the decimal precision of the collateral token being considered at that moment. In reality, the amount calculated is in collateral[i].token.decimals - 18 decimal precision. Knowing that both amountToBuyLeftUSD and collateralval are in 18 dp, this line's decimal precision check evaluates to: collateral[i].token.decimals() * ((1e18 * 1e18 / 1e18) / 1e18) / 1e18 == collateral[i].token.decimals() / 1e18. Thus amountToSellUnits has 0 decimal precision digits for collateral tokens that use 18 decimals, and is set to 0 for tokens using less.

Impact

amountToSellUnits is then directly passed as an argument to UniV3SwapInput(), which sells that exact amount of tokens into Uniswap. As a consequence, the system will receive much less tokens than expected from the pool, as it has provided such a tiny amount of input tokens.

Code Snippet

USSDRebalancer.sol#BuyUSSDSellCollateral USSD.sol#UniV3SwapInput()

Tool used

Manual Review

Recommendation

Change the calculation of amountToSellUnits to:

- uint256 amountToSellUnits = IERC20Upgradeable(collateral[i].token).balanceOf(USSD) * ((amountToBuyLeftUSD * 1e18 / collateralval) / 1e18) / 1e18;
+ uint256 amountToSellUnits = IERC20Upgradeable(collateral[i].token).balanceOf(USSD) * (amountToBuyLeftUSD * 1e18 / collateralval) / 1e18;