Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ERRORNEOUS minOut CALCULATION IN THE RdpxV2Core._curveSwap FUNCTION BREAKS THE EXPECTED BEHAVIOUR OF THE PROTOCOL #1613

Closed
code423n4 opened this issue Sep 5, 2023 · 5 comments
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working downgraded by judge Judge downgraded the risk level of this issue duplicate-1558 satisfactory satisfies C4 submission criteria; eligible for awards sufficient quality report This report is of sufficient quality

Comments

@code423n4
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2023-08-dopex/blob/main/contracts/core/RdpxV2Core.sol#L545-L549

Vulnerability details

Impact

The RdpxV2Core._curveSwap function is used to swap token A to token B based on the value of the _ethToDpxEth Boolean variable. _ethToDpxEth value denotes whether swap is from ETH to dpxETH or dpxETH to ETH.

Before the actual dpxEthCurvePool.exchange happens the minOut value is calculated as slippage protection as shown below:

uint256 minOut = _ethToDpxEth
  ? (((_amount * getDpxEthPrice()) / 1e8) - 
    (((_amount * getDpxEthPrice()) * slippageTolerance) / 1e16)) 
  : (((_amount * getEthPrice()) / 1e8) -
    (((_amount * getEthPrice()) * slippageTolerance) / 1e16));

If the _ethToDpxEth is true which means the swap is from Eth to dpxEth, the _amount is multiplied by value returned from getDpxEthPrice(). Here the _amount is in Eth and getDpxEthPrice() value is in Eth/DpxEth unit with 1e8 precision. Hence it is clear this calculation is wrong. Because we want to multiply the _amount (Eth value) by the getEthPrice() value and not by the getDpxEthPrice() value. Because getEthPrice() returns the dpxEth/Eth value in 1e8 precision which is the correct value to use to multiply the Eth _amount to obtain the minOut value in dpxEth units.

Similarly if the _ethToDpxEth is false which means the swap is from dpxEth to Eth, the _amount is multiplied by value returned from getEthPrice(). Here the _amount is in dpxEth and getEthPrice() value is in dpxEth/Eth unit with 1e8 precision. Hence it is clear this calculation is wrong. Because we want to multiply the _amount (dpxEth value) by the getDpxEthPrice() value and not by the getEthPrice() value. Because getDpxEthPrice() returns the Eth/dpxEth value in 1e8 precision which is the correct value to use to multiply the dpxEth _amount to obtain the minOut value in Eth units.

Above error in calculating the value of minOut could prompt the dpxEthCurvePool.exchange transaction to revert since we are providing the wrong slippage protection value to the actual swap happening in the exchange transaction.

This will prompt the _curveSwap transaction to behave in unexpected manner thus breaking the protocol unexpectedly.

Proof of Concept

    uint256 minOut = _ethToDpxEth
      ? (((_amount * getDpxEthPrice()) / 1e8) -
        (((_amount * getDpxEthPrice()) * slippageTolerance) / 1e16))
      : (((_amount * getEthPrice()) / 1e8) -
        (((_amount * getEthPrice()) * slippageTolerance) / 1e16));

https://github.com/code-423n4/2023-08-dopex/blob/main/contracts/core/RdpxV2Core.sol#L545-L549

Tools Used

Manual Review and VSCode

Recommended Mitigation Steps

Hence it is recommended to correct the minOut value in the RdpxV2Core._curveSwap function as shown below:

uint256 minOut = _ethToDpxEth
  ? (((_amount * getEthPrice()) / 1e8) - 
    (((_amount * getEthPrice()) * slippageTolerance) / 1e16)) 
  : (((_amount * getDpxEthPrice()) / 1e8) -
    (((_amount * getDpxEthPrice()) * slippageTolerance) / 1e16));

The above change will ensure the correct minOut value is calculated based on the Boolean value of _ethToDpxEth thus ensuring successful execution of the RdpxV2Core._curveSwap transaction.

Assessed type

Other

@code423n4 code423n4 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Sep 5, 2023
code423n4 added a commit that referenced this issue Sep 5, 2023
@c4-pre-sort
Copy link

bytes032 marked the issue as duplicate of #2172

@c4-pre-sort
Copy link

bytes032 marked the issue as sufficient quality report

@c4-pre-sort c4-pre-sort added the sufficient quality report This report is of sufficient quality label Sep 12, 2023
@c4-pre-sort
Copy link

bytes032 marked the issue as duplicate of #970

@c4-judge
Copy link
Contributor

GalloDaSballo marked the issue as satisfactory

@c4-judge c4-judge added satisfactory satisfies C4 submission criteria; eligible for awards 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value downgraded by judge Judge downgraded the risk level of this issue and removed 3 (High Risk) Assets can be stolen/lost/compromised directly labels Oct 18, 2023
@c4-judge
Copy link
Contributor

GalloDaSballo changed the severity to 2 (Med Risk)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working downgraded by judge Judge downgraded the risk level of this issue duplicate-1558 satisfactory satisfies C4 submission criteria; eligible for awards sufficient quality report This report is of sufficient quality
Projects
None yet
Development

No branches or pull requests

3 participants