code-423n4 / 2024-01-salty-findings

7 stars 4 forks source link

In atomic arbitrage, when searching for the optimal arbitrage point, the search range may exceed the predetermined range #460

Closed c4-bot-7 closed 5 months ago

c4-bot-7 commented 6 months ago

Lines of code

https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/arbitrage/ArbitrageSearch.sol#L80 https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/arbitrage/ArbitrageSearch.sol#L101-L136 https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/pools/Pools.sol#L321-L342 https://github.com/code-423n4/2024-01-salty/blob/53516c2cdfdfacb662cdea6417c52f23c94d5b5b/src/pools/Pools.sol#L302-L317

Vulnerability details

Impact

The results of the atomic arbitrage search are not optimal

Proof of Concept

With the _bisectionSearch method we know that the search for the optimal arbitrage point is mainly done by bisection search. The values of the left, right and midpoints are used to confirm whether the new most profitable point is located to the left or right of the midpoint. Let the midpoint be shifted to the right by one tick and compare it with the value of the original midpoint to confirm that the best bargain point is not on the right side. The implementation is in the _rightMoreProfitable method. The problem occurs when the midpoint is shifted one tick to the right

    function _rightMoreProfitable( uint256 midpoint, uint256 reservesA0, uint256 reservesA1, uint256 reservesB0, uint256 reservesB1, uint256 reservesC0, uint256 reservesC1 ) internal pure returns (bool rightMoreProfitable)
        {
...
            // Calculate the AMM output of a point just to the right of the midpoint
-->         midpoint += MIDPOINT_PRECISION; // Offset by one tick to the right

...
        }

We see that MIDPOINT_PRECISION= 0.001e18 is defined as the precision of the search.

With the _determineSwapAmountInValueInETH method, we can see that as long as the arbitrage is greater than or equal to 100 a bisection search is run to find the best arbitrage point.

For example, we now have an arbitrage point of 100000. We want to see if there are more favorable points around him. The search range is leftPoint = 781( 100000>>7) and rightPoint = 125000(100000+(100000>>2)). midPoint = 62890((leftPoint+rightPoint) >> 1). 0.001e18 = 1000000000000000.

leftPoint = 781( 100000>>7)
rightPoint = 125000(100000+(100000>>2))
midPoint = 62890((leftPoint+rightPoint) >> 1)
MIDPOINT_PRECISION = 0.001e18 = 1000000000000000

Although the impact is a small amount of arbitrage, but if the arbitrage space has been small, it will still have a large impact on the final result. The exact loss depends on the circumstances.

Tools Used

Manual Review && Foundry

Recommended Mitigation Steps

The amount by which the midpoint is shifted to the right is determined by the size of the midpoint. For example, midPoint = midPoint+ midPoint/100, thus avoiding midPoint exceeding the search range.

Assessed type

Math

c4-judge commented 5 months ago

Picodes marked the issue as primary issue

c4-sponsor commented 5 months ago

othernet-global (sponsor) disputed

othernet-global commented 5 months ago

If the ETH equivalent of the trade is less than .001 ETH, it is acceptable that the arbitrage search fails to find an optimal value.

Picodes commented 5 months ago

It's clear that there are cases in which the bisection search will miss the maximal arb so I'll downgrade this to Low

c4-judge commented 5 months ago

Picodes changed the severity to QA (Quality Assurance)