Out-of-range liquidity can be used to manipulate the USSD automated rebalances
Summary
An attacker can provide out-of-range liquidity on the USSD / DAI Uniswap V3 pool to manipulate the USSD automated rebalance mechanism. This can be used to permanently prevent rebalances, or manipulate the rebalance amounts.
Vulnerability Detail
The issue is that the USSDRebalance#rebalance() function uses the Uniswap V3 token proportion to determine the amount of tokens to buy or sell.
The implicit assumption in the USSDRebalance contract is that if the USSD and DAI proportion on the liquidity pool are the same, then the price of 1 USSD is exactly 1 DA1. This is true for Uniswap V2 pools, but it's simply not true for Uniswap V3 pools.
An attacker can easily provide out-of-range liquidity and unbalance the proportion of of USSD and DAI on the liquidity pool, and this not affect the price quoted in the pool.
Impact
This essentially defeats the purpose of the rebalance mechanism. An attacker can manipulate the magnitude of the buy/sells, and profit from that, or they can persistently de-peg USSD.
The USSDRebalance#rebalance function needs to be completely reworked. It should not rely on the Uniswap V3 pool asset proportion to compute the amount of tokens to buy / sell from the pool to bring it back to parity.
Computing the amount of tokens to buy / sell from a Uniswap V3 pool to move the price by a certain is non-trivial. A few options:
1) Replicate the Uniswap V3 logic.
2) Change the USSDRebalance#rebalance function to take as parameter as the amounts of tokens to buy / sell, the contract performs the buy / sell, but ensure that after the swap the price is closer to parity, otherwise revert. This effectively moves that computation off-chain.
0xRan4212
high
Out-of-range liquidity can be used to manipulate the USSD automated rebalances
Summary
An attacker can provide out-of-range liquidity on the USSD / DAI Uniswap V3 pool to manipulate the USSD automated rebalance mechanism. This can be used to permanently prevent rebalances, or manipulate the rebalance amounts.
Vulnerability Detail
The issue is that the
USSDRebalance#rebalance()
function uses the Uniswap V3 token proportion to determine the amount of tokens to buy or sell.The implicit assumption in the USSDRebalance contract is that if the USSD and DAI proportion on the liquidity pool are the same, then the price of 1 USSD is exactly 1 DA1. This is true for Uniswap V2 pools, but it's simply not true for Uniswap V3 pools.
An attacker can easily provide out-of-range liquidity and unbalance the proportion of of USSD and DAI on the liquidity pool, and this not affect the price quoted in the pool.
Impact
This essentially defeats the purpose of the rebalance mechanism. An attacker can manipulate the magnitude of the buy/sells, and profit from that, or they can persistently de-peg USSD.
Code Snippet
https://github.com/sherlock-audit/2023-05-USSD/blob/main/ussd-contracts/contracts/USSDRebalancer.sol#L94
Tool used
Manual Review
Recommendation
The
USSDRebalance#rebalance
function needs to be completely reworked. It should not rely on the Uniswap V3 pool asset proportion to compute the amount of tokens to buy / sell from the pool to bring it back to parity.Computing the amount of tokens to buy / sell from a Uniswap V3 pool to move the price by a certain is non-trivial. A few options: 1) Replicate the Uniswap V3 logic. 2) Change the
USSDRebalance#rebalance
function to take as parameter as the amounts of tokens to buy / sell, the contract performs the buy / sell, but ensure that after the swap the price is closer to parity, otherwise revert. This effectively moves that computation off-chain.Duplicate of #808