tallo
high
USSDRebalancer.getOwnValuation and getSupplyProportion are vulnerable to manipulation due to how they calculate token balances
USSDRebalancer.getOwnValuation
uses the UniV3.slot0
function to calculate its current token price. This calculated value is the most recent spot price and can be easily manipulated.
The getOwnValuation function returns the most recent spot price.
function getOwnValuation() public view returns (uint256 price) {
(uint160 sqrtPriceX96,,,,,,) = uniPool.slot0();
if(uniPool.token0() == USSD) {
price = uint(sqrtPriceX96)*(uint(sqrtPriceX96))/(1e6) >> (96 * 2);
} else {
price = uint(sqrtPriceX96)*(uint(sqrtPriceX96))*(1e18 /* 1e12 + 1e6 decimal representation */) >> (96 * 2);
// flip the fraction
price = (1e24 / price) / 1e12;
}
}
getSupplyProportion uses the current token0 and token1 balance.
function getSupplyProportion() public view returns (uint256, uint256) {
uint256 vol1 = IERC20Upgradeable(uniPool.token0()).balanceOf(address(uniPool));
uint256 vol2 = IERC20Upgradeable(uniPool.token1()).balanceOf(address(uniPool));
if (uniPool.token0() == USSD) {
return (vol1, vol2);
}
return (vol2, vol1);
}
All functionality that uses the spot price is vulnerable such as USSDRebalancer.rebalance
, USSDRebalancer.SellUSSDBuyCollateral
, and USSDRebalancer.BuyUSSDSellCollateral
https://github.com/sherlock-audit/2023-05-USSD/blob/main/ussd-contracts/contracts/USSDRebalancer.sol#L71 https://github.com/sherlock-audit/2023-05-USSD/blob/main/ussd-contracts/contracts/USSDRebalancer.sol#LL83C45-L83C45
Manual Review
It would be ideal to take an average of the uniswap price over certain time periods (TWAP) so its much harder to manipulate