sherlock-audit / 2024-08-cork-protocol-judging

2 stars 2 forks source link

eta - Arbitrage Opportunity Due to Mismatch in `getAmountIn` and `getAmountOut` Calculations in DsSwapperMathLib.sol #238

Closed sherlock-admin2 closed 2 months ago

sherlock-admin2 commented 2 months ago

eta

High

Arbitrage Opportunity Due to Mismatch in getAmountIn and getAmountOut Calculations in DsSwapperMathLib.sol

Summary

The getAmountIn and getAmountOut functions in the DsSwapperMathLib.sol contract calculate the required RA assets for purchasing DS assets and the RA assets received from selling DS assets, respectively. However, due to an inconsistency in their calculations, an arbitrage opportunity arises.

Vulnerability Detail

The getAmountIn function is designed to calculate the amount of RA assets required to purchase a specified amount of DS assets. The result can be simplified to ds * (ds / ra). The getAmountOut function, on the other hand, calculates the RA assets received from selling a specified amount of DS assets, and its result can be simplified to ds / (ds / ra).

Depeg-swap/contracts/libraries/DsSwapperMathLib.sol:getAmountIn_L77

                function getAmountIn(
                    uint256 amountOut, // Amount of DS tokens to buy
                    uint112 raReserve, // Reserve of the input token
                    uint112 ctReserve, // Reserve of the other token (needed for price ratio calculation)
                    uint256 dsExchangeRate // DS exchange rate
                ) external pure returns (uint256 amountIn) {
                    if (amountOut == 0) {
                        revert InsufficientOutputAmount();
                    }

                    if (raReserve == 0 || ctReserve == 0) {
                        revert InsufficientLiquidity();
                    }

                    uint256 dsPrice = calculateDsPrice(raReserve, ctReserve, dsExchangeRate);

77 @audit=>         amountIn = (amountOut * dsPrice) / 1e18;
                }

Depeg-swap/contracts/libraries/DsSwapperMathLib.sol:getAmountOut_L96


                function getAmountOut(
                    uint256 amountIn, // Amount of input tokens
                    uint112 reserveIn, // Reserve of the input token
                    uint112 reserveOut, // Reserve of the other token (needed for price ratio calculation)
                    uint256 dsExchangeRate // DS exchange rate
                ) external pure returns (uint256 amountOut) {
                    if (amountIn == 0) {
                        revert InsufficientInputAmount();
                    }

                    if (reserveIn == 0 || reserveOut == 0) {
                        revert InsufficientLiquidity();
                    }

                    uint256 dsPrice = calculateDsPrice(reserveIn, reserveOut, dsExchangeRate);

96 @audit=>         amountOut = amountIn / dsPrice;
                }

The issue is that the result of buying DS assets does not match the result of selling the same amount of DS assets. Specifically, ds * (ds / ra) != ds / (ds / ra). This discrepancy creates an arbitrage opportunity, as the cost to purchase DS assets differs from the amount received when selling the same amount of DS assets.

Impact

This discrepancy leads to a pricing imbalance between buying and selling DS assets, allowing users to exploit arbitrage opportunities, potentially draining the contract of RA assets or destabilizing the DS asset price.

Code Snippet

Depeg-swap/contracts/libraries/DsSwapperMathLib.sol:getAmountIn_L77 Depeg-swap/contracts/libraries/DsSwapperMathLib.sol:getAmountOut_L96

Tool used

Manual Review

Recommendation

Adjust the calculations in the getAmountIn and getAmountOut functions to ensure that the amount of RA required to buy DS assets is consistent with the amount of RA received from selling the same amount of DS assets. This will eliminate the arbitrage opportunity and ensure accurate pricing.

sherlock-admin2 commented 2 months ago

1 comment(s) were left on this issue during the judging contest.

tsvetanovv commented:

Arbitrage Opportunity are appreciated by the Protocol. You can see the documentation: https://corkfi.notion.site/Litepaper-One-pager-2d846fc6b93f49558e2a185665e94944