Skip to content

Commit fc21012

Browse files
committed
Remvoes ProxyUtils.sol and inlines the feed scaling
1 parent 57009b5 commit fc21012

File tree

3 files changed

+34
-46
lines changed

3 files changed

+34
-46
lines changed

contracts/NormalizedApi3ReaderProxyV1.sol

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
pragma solidity ^0.8.27;
33

44
import "./interfaces/INormalizedApi3ReaderProxyV1.sol";
5-
import "./ProxyUtils.sol";
65

76
/// @title An immutable proxy contract that converts a Chainlink
87
/// AggregatorV2V3Interface feed output to 18 decimals to conform with
@@ -13,8 +12,6 @@ import "./ProxyUtils.sol";
1312
/// Refer to https://github.com/api3dao/migrate-from-chainlink-to-api3 for more
1413
/// information about the Chainlink interface implementation.
1514
contract NormalizedApi3ReaderProxyV1 is INormalizedApi3ReaderProxyV1 {
16-
using ProxyUtils for int256;
17-
1815
/// @notice Chainlink AggregatorV2V3Interface contract address
1916
address public immutable override feed;
2017

@@ -36,7 +33,6 @@ contract NormalizedApi3ReaderProxyV1 is INormalizedApi3ReaderProxyV1 {
3633

3734
/// @notice Returns the price of the underlying Chainlink feed normalized to
3835
/// 18 decimals
39-
/// of underlying Chainlink feed
4036
/// @return value The normalized signed fixed-point value with 18 decimals
4137
/// @return timestamp The updatedAt timestamp of the feed
4238
function read()
@@ -48,7 +44,15 @@ contract NormalizedApi3ReaderProxyV1 is INormalizedApi3ReaderProxyV1 {
4844
(, int256 answer, , uint256 updatedAt, ) = AggregatorV2V3Interface(feed)
4945
.latestRoundData();
5046

51-
value = int224(answer.scaleValue(feedDecimals, 18));
47+
if (feedDecimals != 18) {
48+
uint8 delta = feedDecimals > 18
49+
? feedDecimals - 18
50+
: 18 - feedDecimals;
51+
int256 factor = int256(10 ** uint256(delta));
52+
answer = feedDecimals < 18 ? answer * factor : answer / factor;
53+
}
54+
55+
value = int224(answer);
5256
timestamp = uint32(updatedAt);
5357
}
5458

contracts/ProxyUtils.sol

Lines changed: 0 additions & 25 deletions
This file was deleted.

contracts/adapters/ScaledApi3FeedProxyV1.sol

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
pragma solidity ^0.8.27;
33

44
import "@api3/contracts/interfaces/IApi3ReaderProxy.sol";
5-
import "../ProxyUtils.sol";
65
import "./interfaces/IScaledApi3FeedProxyV1.sol";
76

87
/// @title An immutable Chainlink AggregatorV2V3Interface feed contract that
@@ -11,8 +10,6 @@ import "./interfaces/IScaledApi3FeedProxyV1.sol";
1110
/// @dev This contract assumes the source proxy always returns values with
1211
/// 18 decimals (as all IApi3ReaderProxy-compatible proxies do)
1312
contract ScaledApi3FeedProxyV1 is IScaledApi3FeedProxyV1 {
14-
using ProxyUtils for int256;
15-
1613
/// @notice IApi3ReaderProxy contract address
1714
address public immutable override proxy;
1815

@@ -118,19 +115,31 @@ contract ScaledApi3FeedProxyV1 is IScaledApi3FeedProxyV1 {
118115
updatedAt = startedAt;
119116
}
120117

121-
/// @notice Reads from the IApi3ReaderProxy value and scales it to target
122-
/// decimals
123-
/// @dev Casting the scaled value to int224 might cause an overflow but this
124-
/// is preferable to checking the value for overflows in every read due to
125-
/// gas overhead
126-
function _read()
127-
internal
128-
view
129-
returns (int256 scaledValue, uint32 timestamp)
130-
{
131-
(int256 value, uint32 proxyTimestamp) = IApi3ReaderProxy(proxy).read();
132-
133-
scaledValue = int224(value.scaleValue(18, targetDecimals));
118+
/// @notice Reads a value from the underlying `IApi3ReaderProxy` and
119+
/// scales it to `targetDecimals`.
120+
/// @dev Reads an `int224` value (assumed to be 18 decimals) from the
121+
/// underlying `IApi3ReaderProxy` and scales it to `targetDecimals`.
122+
/// The initial `int224` proxy value is widened to `int256` before scaling.
123+
/// The scaling arithmetic (`value * factor` or `value / factor`) is then
124+
/// performed using `int256` types. This allows the scaled result to exceed
125+
/// the `int224` range, provided it fits within `int256`.
126+
/// Arithmetic operations will revert on overflow or underflow
127+
/// (e.g., if `value * factor` exceeds `type(int256).max`).
128+
/// @return value The scaled signed fixed-point value with `targetDecimals`.
129+
/// @return timestamp The timestamp from the underlying proxy.
130+
function _read() internal view returns (int256 value, uint32 timestamp) {
131+
(int224 proxyValue, uint32 proxyTimestamp) = IApi3ReaderProxy(proxy)
132+
.read();
133+
134+
value = proxyValue;
134135
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+
}
135144
}
136145
}

0 commit comments

Comments
 (0)