Steadefi

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

ChainlinkARBOracle maxDeviation mapping values not scaled to the tokens decimals

Summary

All calls to ChainlinkARBOracle.consultIn18Decimals will revert if the deviation param of the token is not scaled to SAFE_MULTIPLIER (1e18) when added to the vault.

Vulnerability Details

SteadeFi uses the mapping named maxDeviation in the ChainlinkARBOracle to check whether the price of a token has changed more than needed between 2 chainlink responses.

The root cause of the problem is in the addTokenMaxDeviation function which sets the max deviation factor of a given token:

/**
* @notice Add Chainlink max deviation for token
* @param token Token address
* @param maxDeviation Max deviation allowed in seconds
*/
function addTokenMaxDeviation(address token, uint256 maxDeviation) external onlyOwner {
if (token == address(0)) revert Errors.ZeroAddressNotAllowed();
if (feeds[token] == address(0)) revert Errors.NoTokenPriceFeedAvailable();
if (maxDeviation < 0) revert Errors.TokenPriceFeedMaxDeviationMustBeGreaterOrEqualToZero();
//@audit maxDeviation isn't scaled to 1e18
maxDeviations[token] = maxDeviation;
}

As we can see the number used is not scaled, instead of it relies on the user input directly, and when consultIn18Decimals function is called it will check if there is a bad price deviation implemented that way:

/**
* @notice Check to see if Chainlink oracle current response's price price deviation
* is too large compared to previous response's price
* @param currentResponse Current Chainlink response
* @param prevResponse Previous Chainlink response
* @param token Token address
* @return Status of check in boolean
*/
function _badPriceDeviation(
ChainlinkResponse memory currentResponse,
ChainlinkResponse memory prevResponse,
address token
) internal view returns (bool) {
// Check for a deviation that is too large
uint256 _deviation;
if (currentResponse.answer > prevResponse.answer) {
_deviation =
uint256(currentResponse.answer - prevResponse.answer) * SAFE_MULTIPLIER / uint256(prevResponse.answer);
} else {
_deviation =
uint256(prevResponse.answer - currentResponse.answer) * SAFE_MULTIPLIER / uint256(prevResponse.answer); //@audit 10e8 + 10e18 = 10e26
}
//@audit maxDeviation will be without any decimals
return _deviation > maxDeviations[token];
}

That will result in everytime when _badPriceDeviation is called it will result in true, which will make the functions using it to revert, DOS-sing this core functions of the GMXVault:

  • Deposit

  • Withdraw

  • tokenWeights

And will require multiSig owner to have 2 signatures in order to change the deviation to an appropriate number.

Impact

DOS-sing of the core functions by deployer mistake

Tools Used

Manual

Recommendations

When adding the token to the maxDeviation mapping scale the maxDeviation of the appropriate decimals of the token.

Updates

Lead Judging Commences

hans Lead Judge almost 2 years ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
blckhv Submitter
almost 2 years ago
hans Auditor
almost 2 years ago
blckhv Submitter
almost 2 years ago
hans Auditor
almost 2 years ago
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.