Steadefi

Steadefi
DeFiHardhatFoundryOracle
35,000 USDC
View results
Submission Details
Severity: high
Invalid

calcMinTokensSlippageAmt calculates incorrect results if tokens are used that do not have 18 decimal places

Summary

A formula inside the calcMinTokensSlippageAmt function calculates incorrect results if tokens are used that do not have 18 decimal places.

Vulnerability Details

The calcMinTokensSlippageAmt function is used to calculate the minimum tokens to receive when removing liquidity and looks like this:

uint256 public constant SAFE_MULTIPLIER = 1e18;
...
function calcMinTokensSlippageAmt(
GMXTypes.Store storage self,
uint256 lpAmt,
address minLongToken,
address minShortToken,
uint256 slippage
) external view returns (uint256, uint256) {
uint256 _withdrawValue = lpAmt
* self.gmxOracle.getLpTokenValue(
address(self.lpToken),
address(self.tokenA),
address(self.tokenA),
address(self.tokenB),
false,
false
)
/ SAFE_MULTIPLIER;
(uint256 _tokenAWeight, uint256 _tokenBWeight) = GMXReader.tokenWeights(self);
uint256 _minLongTokenAmt = _withdrawValue
* _tokenAWeight / SAFE_MULTIPLIER
* SAFE_MULTIPLIER
/ GMXReader.convertToUsdValue(
self,
minLongToken,
10**(IERC20Metadata(minLongToken).decimals())
)
/ (10 ** (18 - IERC20Metadata(minLongToken).decimals()));
uint256 _minShortTokenAmt = _withdrawValue
* _tokenBWeight / SAFE_MULTIPLIER
* SAFE_MULTIPLIER
/ GMXReader.convertToUsdValue(
self,
minShortToken,
10**(IERC20Metadata(minShortToken).decimals())
)
/ (10 ** (18 - IERC20Metadata(minShortToken).decimals()));
return (
_minLongTokenAmt * (10000 - slippage) / 10000,
_minShortTokenAmt * (10000 - slippage) / 10000
);
}

Therefore, we have the following calculation for token A and B:

minLongTokenAmt = withdrawValue * tokenWeight / 1e18 * 1e18 / usdValueOfOneToken / (10 ** (18 - tokenDecimals)
withdrawValue = 500e18
tokenWeight = 0.5e18
usdValueOfOneToken = 100e18
For tokenDecimals = 18:
minLongTokenAmt = 500e18 * 0.5e18 / 1e18 * 1e18 / 100e18 / (10 ** (18 - 18) = 2.5e18
For tokenDecimals = 8:
minLongTokenAmt = 500e18 * 0.5e18 / 1e18 * 1e18 / 100e18 / (10 ** (18 - 8) = 2.5e8

As we can see, 10 decimal places are missing and therefore this formula does not work with tokens that have a precision other than 18 decimal places.

Impact

Loss of funds

Tools Used

Manual Review

Recommendations

Adjust the formula so that it can work with varying degrees of precision.

Updates

Lead Judging Commences

hans Lead Judge almost 2 years ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.