@@ -13,8 +13,16 @@ contract ScaledApi3FeedProxyV1 is IScaledApi3FeedProxyV1 {
1313 /// @notice IApi3ReaderProxy contract address
1414 address public immutable override proxy;
1515
16+ /// @dev Target decimals for the scaled value.
1617 uint8 private immutable targetDecimals;
1718
19+ /// @dev Pre-calculated factor for scaling from 18 decimals.
20+ int256 private immutable scalingFactor;
21+
22+ /// @dev True for upscaling (multiply by scalingFactor), else downscaling
23+ /// (divide by scalingFactor).
24+ bool private immutable isUpscaling;
25+
1826 /// @param proxy_ IApi3ReaderProxy contract address
1927 /// @param targetDecimals_ Decimals used to scale the IApi3ReaderProxy value
2028 constructor (address proxy_ , uint8 targetDecimals_ ) {
@@ -24,9 +32,16 @@ contract ScaledApi3FeedProxyV1 is IScaledApi3FeedProxyV1 {
2432 if (targetDecimals_ == 0 || targetDecimals_ > 36 ) {
2533 revert InvalidDecimals ();
2634 }
27-
35+ if (targetDecimals_ == 18 ) {
36+ revert NoScalingNeeded ();
37+ }
2838 proxy = proxy_;
2939 targetDecimals = targetDecimals_;
40+ uint8 delta = targetDecimals_ > 18
41+ ? targetDecimals_ - 18
42+ : 18 - targetDecimals_;
43+ scalingFactor = int256 (10 ** uint256 (delta));
44+ isUpscaling = targetDecimals_ > 18 ;
3045 }
3146
3247 /// @dev AggregatorV2V3Interface users are already responsible with
@@ -124,22 +139,16 @@ contract ScaledApi3FeedProxyV1 is IScaledApi3FeedProxyV1 {
124139 /// performed using `int256` types. This allows the scaled result to exceed
125140 /// the `int224` range, provided it fits within `int256`.
126141 /// Arithmetic operations will revert on overflow or underflow
127- /// (e.g., if `value * factor ` exceeds `type(int256).max`).
142+ /// (e.g., if `value * scalingFactor ` exceeds `type(int256).max`).
128143 /// @return value The scaled signed fixed-point value with `targetDecimals`.
129144 /// @return timestamp The timestamp from the underlying proxy.
130145 function _read () internal view returns (int256 value , uint32 timestamp ) {
131146 (int224 proxyValue , uint32 proxyTimestamp ) = IApi3ReaderProxy (proxy)
132147 .read ();
133148
134- value = proxyValue;
149+ value = isUpscaling
150+ ? proxyValue * scalingFactor
151+ : proxyValue / scalingFactor;
135152 timestamp = proxyTimestamp;
136-
137- if (18 != targetDecimals) {
138- uint8 delta = 18 > targetDecimals
139- ? 18 - targetDecimals
140- : targetDecimals - 18 ;
141- int256 factor = int256 (10 ** uint256 (delta));
142- value = 18 < targetDecimals ? value * factor : value / factor;
143- }
144153 }
145154}
0 commit comments