The GeVault#`poolMatchesOracle()` would always return `false` due to the overflow if the `sqrtPriceX96 >= 2^128`, which lead to reverting the transaction of rebalancing the GeVault #274
The GeVault#poolMatchesOracle() would always return false due to the overflow if the sqrtPriceX96 is greater than or equal to 2^128, which lead to reverting the transaction of rebalancing the GeVault that is called via the GeVault#rebalance().
/// @notice Rebalance tickers
/// @dev Provide the list of tickers from
function rebalance() public {
require(poolMatchesOracle(), "GEV: Oracle Error"); /// @audit
removeFromAllTicks();
if (isEnabled) deployAssets();
}
Within the SimpleManager contract, the rebalance function includes a price calculation that triggers a revert if sqrtPriceX96 is greater than or equal to 2^128. The calculation involves squaring sqrtPriceX96, and if the result is larger than or equal to 2^256, an overflow occurs, leading to the revert.
Within the GeVault#poolMatchesOracle(), the sqrtPriceX96, which is returned from uniswapPool.slot0(), would be used as it is for the subsequent calculation.
However, the GeVault#poolMatchesOracle() would always return false due to the overflow if the sqrtPriceX96 is greater than or equal to 2^128, which lead to reverting the transaction of rebalancing the GeVault that is called via the GeVault#rebalance().
Because if the sqrtPriceX96 would 0 due to overflow, the priceX8 would also be 0.
Thus, the matches below at the final line of the GeVault#poolMatchesOracle() would always be False (if the sqrtPriceX96 is greater than or equal to 2^128) and then it would be returned.
Since the matches, which is returned-value from the GeVault#poolMatchesOracle() above, would always be False (if the sqrtPriceX96 is greater than or equal to 2^128), the transaction would always be reverted at the line of the condition in the the GeVault#rebalance() below:
Remarks).
By the way, the GeVault#poolMatchesOracle() would be called for the validation in the following functions as well.
Thus, the transaction of the following functions would also be reverted if the same situation above.
Lines of code
https://github.com/code-423n4/2023-08-goodentry/blob/main/contracts/GeVault.sol#L203 https://github.com/code-423n4/2023-08-goodentry/blob/main/contracts/GeVault.sol#L368
Vulnerability details
Impact
The GeVault#
poolMatchesOracle()
would always returnfalse
due to the overflow if thesqrtPriceX96
is greater than or equal to2^128
, which lead to reverting the transaction of rebalancing the GeVault that is called via the GeVault#rebalance()
.Proof of Concept
Within the GeVault#
rebalance()
, the GeVault#poolMatchesOracle()
would be called for the validation like this: https://github.com/code-423n4/2023-08-goodentry/blob/main/contracts/GeVault.sol#L203Within the GeVault#
poolMatchesOracle()
, thesqrtPriceX96
would be returned fromuniswapPool.slot0()
like this: https://github.com/code-423n4/2023-08-goodentry/blob/main/contracts/GeVault.sol#L368According to the
Revert for sqrtPriceX96 >= 2^128
part in the other protocol's audit report, if the result of thesqrtPriceX96
is greater than or equal to2^128
, anoverflow
would occur like this:Within the GeVault#
poolMatchesOracle()
, thesqrtPriceX96
, which is returned fromuniswapPool.slot0()
, would be used as it is for the subsequent calculation.However, the GeVault#
poolMatchesOracle()
would always returnfalse
due to the overflow if thesqrtPriceX96
is greater than or equal to2^128
, which lead to reverting the transaction of rebalancing the GeVault that is called via the GeVault#rebalance()
.Because if the
sqrtPriceX96
would0
due to overflow, thepriceX8
would also be0
. Thus, thematches
below at the final line of the GeVault#poolMatchesOracle()
would always beFalse
(if thesqrtPriceX96
is greater than or equal to2^128
) and then it would be returned.Since the
matches
, which is returned-value from the GeVault#poolMatchesOracle()
above, would always beFalse
(if thesqrtPriceX96
is greater than or equal to2^128
), the transaction would always be reverted at the line of the condition in the the GeVault#rebalance()
below:Remarks). By the way, the GeVault#
poolMatchesOracle()
would be called for the validation in the following functions as well. Thus, the transaction of the following functions would also be reverted if the same situation above.GeVault#
deposit()
https://github.com/code-423n4/2023-08-goodentry/blob/main/contracts/GeVault.sol#L250GeVault#
withdraw()
https://github.com/code-423n4/2023-08-goodentry/blob/main/contracts/GeVault.sol#L215Tools Used
Recommended Mitigation Steps
Consider using the uniswap oracle library methodology to square the value. This will prevent reverts due to overflows.
Assessed type
Under/Overflow