Open code423n4 opened 1 year ago
trust1995 marked the issue as primary issue
trust1995 marked the issue as satisfactory
0xBugsy marked the issue as sponsor confirmed
trust1995 marked the issue as selected for report
0xBugsy marked the issue as sponsor acknowledged
0xBugsy marked the issue as sponsor confirmed
We recognize the audit's findings on Anycall Gas Management. These will not be rectified due to the upcoming migration of this section to LayerZero.
Lines of code
https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/RootBridgeAgent.sol#L684 https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/RootBridgeAgent.sol#L728 https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/RootBridgeAgent.sol#L884-L886 https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/RootBridgeAgent.sol#L757-L767
Vulnerability details
Both
RootBridgeAgent._gasSwapIn()
andRootBridgeAgent._gasSwapOut()
do not negate the negative returned value of UniswapV3Pool.swap() before casting touint256
. That will cause the parent functionsanyExecute()
and_manageGasOut()
to revert on overflow when casting return values of_gasSwapIn()
and_gasSwapOut()
withSafeCastLib.toUint128()
.Impact
Several external functions in
RootBridgeAgent
(such asanyExecute()
,callOut()
,callOutAndBridge()
,callOutAndBridgeMultiple()
, etc) are affected by this issue. That meansRootBridgeAgent
will not function properly at all causing a DoS of the Ulysses Omnichain.Detailed Explanation
UniSwapV3Pool.swap()
returns a negative value for exact input swap (see documentation in link below). https://docs.uniswap.org/contracts/v3/reference/core/UniswapV3Pool#swapAnd this is evident in UniswapV3's
SwapRouter.sol
, which shows that the returned value is negated before casting touint256
. https://github.com/Uniswap/v3-periphery/blob/main/contracts/SwapRouter.sol#L111However, both
RootBridgeAgent._gasSwapIn()
andRootBridgeAgent._gasSwapOut()
do not negate the returned value before casting touint256
.In
anyExecute()
and_manageGasOut()
, both return value of_gasSwapIn()
and_gasSwapOut()
are converted usingSafeCastLib.toUint128()
. That means these calls will revert due to overflow, as casting a negativeint256
value touint256
will result in a large value exceedinguint128
.https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/RootBridgeAgent.sol#L884-L886
https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/RootBridgeAgent.sol#L757-L767
Proof of Concept
First, simulate a negative return value by adding the following line to
MockPool.swap()
in RootTest.t.sol#L1916Then run
RootTest.testCallOutWithDeposit()
, which will demonstrate thatswap()
will cause an overflow to revertCoreRootRouter.addBranchToBridgeAgent()
, preventingRootTest.setUp()
from completing.Recommended Mitigation Steps
Negate the return values of
UniswapV3Pool.swap()
inRootBridgeAgent._gasSwapIn()
andRootBridgeAgent._gasSwapOut()
before casting to uint256.Assessed type
DoS