Light ModeLight
Light ModeDark

One Bug Per Day

One H/M every day from top Wardens

Checkmark

Join over 1090 wardens!

Checkmark

Receive the email at any hour!

Ad

Decimal Limitation in CamelotRelayer and UniV3Relayer Contract Deployment

mediumCode4rena

Lines of code

https://github.com/open-dollar/od-contracts/blob/v1.5.5-audit/src/contracts/oracles/CamelotRelayer.sol#L58 https://github.com/open-dollar/od-contracts/blob/v1.5.5-audit/src/contracts/oracles/CamelotRelayer.sol#L103-L105 https://github.com/open-dollar/od-contracts/blob/v1.5.5-audit/src/contracts/oracles/UniV3Relayer.sol#L64 https://github.com/open-dollar/od-contracts/blob/v1.5.5-audit/src/contracts/oracles/UniV3Relayer.sol#L110-L112

Vulnerability details

Impact

The current design of the CamelotRelayer and UniV3Relayer contracts limits its compatibility to only those _quoteTokens that have a decimal count of 18 or fewer. If an attempt is made to deploy the contract with a token having more than 18 decimals as the _quoteToken, the contract deployment will fail due to an underflow issue during the multiplier calculation. This poses no financial risk but restricts the contract's adaptability in the wider DeFi ecosystem, preventing its use with tokens that have more than 18 decimals.

Proof of Concept

The restriction emerges from the constructor, where the multiplier is deduced as 18 - IERC20Metadata(_quoteToken).decimals().

https://github.com/open-dollar/od-contracts/blob/v1.5.5-audit/src/contracts/oracles/CamelotRelayer.sol#L58 https://github.com/open-dollar/od-contracts/blob/v1.5.5-audit/src/contracts/oracles/UniV3Relayer.sol#L64

solidity
multiplier = 18 - IERC20Metadata(_quoteToken).decimals();

For tokens like YAMv2, which possess 24 decimals, the computation would attempt 18 - 24, which results in an underflow, making the contract deployment unsuccessful.

Tools Used

Manual

Recommended Mitigation Steps

  1. Alter the datatype of multiplier to int256 to account for both positive and negative values.

  2. Adjust the multiplier's computation in the constructor to handle situations where token decimals might be greater or less than 18.

solidity
int8 decimalsDifference = 18 - int8(IERC20Metadata(_quoteToken).decimals()); multiplier = int256(decimalsDifference);
  1. Revise the _parseResult function to either multiply or divide the _quoteResult depending on the multiplier value.
solidity
function _parseResult(uint256 _quoteResult) internal view returns (uint256 _result) { if (multiplier > 0) { return _quoteResult * (10 ** uint256(multiplier)); } else if (multiplier < 0) { return _quoteResult / (10 ** uint256(-multiplier)); } else { return _quoteResult; } }

Note: It will require additional code refactoring to make baseAmount and its value assignment as int256 as well.

Assessed type

Under/Overflow