F-2024-0001·decimal-mismatch

Potential scaling to unexpected decimal places in MultiFeedAdapterWithoutRounds.priceOf()

Acknowledgedoracleprice-feeddata-streamsgithub.com/redstone-finance/redstone-oracles-monorepo
TL;DR

priceOf() always multiplies by 10^10 assuming 10^8 decimals, ignoring the data feed's actual decimals. Feeds with non-default decimals produce incorrect prices.

Severity
MEDIUM
Impact
MEDIUM
Likelihood
MEDIUM
Method
MManual review
CAT.
Complexity
LOW
Exploitability
MEDIUM
02Section · Description

Description

The MultiFeedAdapterWithoutRounds contract allows updates and price retrieval for multiple feeds. One way to obtain an asset's price is through the priceOf(...) function, which accepts the asset's address as input:

solidity
function priceOf(address asset) public view virtual returns (uint256) {
bytes32 dataFeedId = getDataFeedIdForAsset(asset);
uint256 latestValue = getValueForDataFeed(dataFeedId);
return convertDecimals(dataFeedId, latestValue);
}

This function retrieves the data feed ID using the asset address, gets the latest price, and then scales it to 10^18 decimals using:

solidity
function convertDecimals(bytes32 /* dataFeedId */, uint256 valueFromRedstonePayload) public view virtual returns (uint256) {
// @audit-issue Missing address(dataFeed).decimals() and proper scaling to reflect correct decimals
return valueFromRedstonePayload * DEFAULT_DECIMAL_SCALER_LAYERBANK;
}

The issue is that the price is always multiplied by 10^10, assuming a default of 10^8 decimals from the PriceFeed. However, the function does not consider the actual decimals of the specific data feed. This could lead to a mismatch where the smart contract receives a price in a different decimal format than expected, potentially causing incorrect calculations.

03Section · Impact

Impact

Consumers of the multi-feed adapter that rely on priceOf(...) may receive a value scaled with the wrong assumption when the underlying data feed does not use 8 decimals, producing prices with the wrong order of magnitude.

04Section · Recommendation

Recommendation

Incorporate the data feed's decimals() function to adjust the scaling based on the returned value dynamically.

05Section · Resolution

Resolution

RedStone: We have assumed we will override the convertDecimals function for such cases. In practice, this LayerBank interface is in use only by one project and we will probably remove it in future.

F-2024-0001

oog
zealynx

Smart Contract Security Digest

Monthly exploit breakdowns, audit checklists, and DeFi security research — straight to your inbox

© 2026 Zealynx