Skip to content

Commit 16622f5

Browse files
committed
fix: scale factor computation
1 parent 2861c82 commit 16622f5

File tree

4 files changed

+29
-18
lines changed

4 files changed

+29
-18
lines changed

src/chainlink/Oracle2.sol

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,15 @@ contract Oracle2 is IOracle {
3131
) {
3232
BASE_FEED = baseFeed;
3333
QUOTE_FEED = quoteFeed;
34-
// SCALE_FACTOR = 10 ** (36 + (baseTokenDecimals - baseFeedDecimals) - (quoteTokenDecimals - quoteFeedDecimals))
34+
// We note pB the base price, and pQ the quote price (price of 1e(decimals) asset).
35+
// We want to return 1e36 * (pB/1e(bDecimals) / (pQ/1e(qDecimals)).
36+
// Chainlink returns pB * bFeedPrecision and pQ * qFeedPrecision.
37+
// So we have 1e36 * (pB/1e(bDecimals) / (pQ/1e(qDecimals) = pB * 1e(bFeedPrecision) * SCALE_FACTOR / (pQ *
38+
// 1e(qFeedPrecision))
39+
// So SCALE_FACTOR = 1e36 / 1e(bDecimals) * 1e(qDecimals) * 1e(qFeedPrecision) / 1e(bFeedPrecision)
40+
// So SCALE_FACTOR = 1e(36 + qDecimals + qFeedPrecision - bDecimals - bFeedPrecision)
3541
SCALE_FACTOR =
36-
10 ** (36 + baseTokenDecimals + quoteFeed.getDecimals() - baseFeed.getDecimals() - quoteTokenDecimals);
42+
10 ** (36 + quoteTokenDecimals + quoteFeed.getDecimals() - baseFeed.getDecimals() - baseTokenDecimals);
3743
}
3844

3945
/* PRICE */

src/chainlink/Oracle4.sol

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,10 @@ contract Oracle4 is IOracle {
4141
SECOND_BASE_FEED = secondBaseFeed;
4242
FIRST_QUOTE_FEED = firstQuoteFeed;
4343
SECOND_QUOTE_FEED = secondQuoteFeed;
44-
// SCALE_FACTOR = 10 ** (36 + (firstQuoteFeedDecimals + secondQuoteFeedDecimals - quoteTokenDecimals) -
45-
// (firstBaseFeedDecimals + secondBaseFeedDecimals - baseTokenDecimals))
4644
SCALE_FACTOR = 10
4745
** (
48-
36 + baseTokenDecimals + firstQuoteFeed.getDecimals() + secondQuoteFeed.getDecimals()
49-
- firstBaseFeed.getDecimals() - secondBaseFeed.getDecimals() - quoteTokenDecimals
46+
36 + quoteTokenDecimals + firstQuoteFeed.getDecimals() + secondQuoteFeed.getDecimals()
47+
- firstBaseFeed.getDecimals() - secondBaseFeed.getDecimals() - baseTokenDecimals
5048
);
5149
}
5250

test/chainlink/Oracle2Test.sol

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ AggregatorV3Interface constant stEthEthFeed = AggregatorV3Interface(0x86392dC19c
1111
AggregatorV3Interface constant usdcEthFeed = AggregatorV3Interface(0x986b5E1e1755e3C2440e960477f25201B0a8bbD4);
1212
// 8 decimals of precision
1313
AggregatorV3Interface constant ethUsdFeed = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);
14+
// 8 decimals of precision
15+
AggregatorV3Interface constant usdcUsd = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);
1416

1517
contract FakeAggregator {
1618
int256 public answer;
@@ -37,25 +39,32 @@ contract OracleTest is Test {
3739
Oracle2 oracle = new Oracle2(stEthEthFeed, usdcEthFeed, 18, 6);
3840
(, int256 baseAnswer,,,) = stEthEthFeed.latestRoundData();
3941
(, int256 quoteAnswer,,,) = usdcEthFeed.latestRoundData();
40-
assertEq(oracle.price(), uint256(baseAnswer) * 10 ** (36 + 18 + 18 - 18 - 6) / uint256(quoteAnswer));
42+
assertEq(oracle.price(), uint256(baseAnswer) * 10 ** (36 + 18 + 6 - 18 - 18) / uint256(quoteAnswer));
4143
}
4244

4345
function testOracleEthUsd() public {
4446
Oracle2 oracle = new Oracle2(ethUsdFeed, AggregatorV3Interface(address(0)), 18, 0);
4547
(, int256 expectedPrice,,,) = ethUsdFeed.latestRoundData();
46-
assertEq(oracle.price(), uint256(expectedPrice) * 10 ** (36 + 18 - 8));
48+
assertEq(oracle.price(), uint256(expectedPrice) * 10 ** (36 - 18 - 8));
4749
}
4850

4951
function testOracleStEthEth() public {
50-
Oracle2 oracle = new Oracle2(stEthEthFeed, AggregatorV3Interface(address(0)), 18, 0);
52+
Oracle2 oracle = new Oracle2(stEthEthFeed, AggregatorV3Interface(address(0)), 18, 18);
5153
(, int256 expectedPrice,,,) = stEthEthFeed.latestRoundData();
52-
assertEq(oracle.price(), uint256(expectedPrice) * 10 ** (36 + 18 - 18));
54+
assertEq(oracle.price(), uint256(expectedPrice) * 10 ** (36 + 18 - 18 - 18));
55+
assertApproxEqRel(oracle.price(), 1e36, 0.01 ether);
5356
}
5457

5558
function testOracleEthStEth() public {
56-
Oracle2 oracle = new Oracle2(AggregatorV3Interface(address(0)), stEthEthFeed, 0, 18);
59+
Oracle2 oracle = new Oracle2(AggregatorV3Interface(address(0)), stEthEthFeed, 18, 18);
5760
(, int256 expectedPrice,,,) = stEthEthFeed.latestRoundData();
58-
assertEq(oracle.price(), 10 ** (36 + 18 - 18) / uint256(expectedPrice));
61+
assertEq(oracle.price(), 10 ** (36 + 18 + 18 - 18) / uint256(expectedPrice));
62+
assertApproxEqRel(oracle.price(), 1e36, 0.01 ether);
63+
}
64+
65+
function testOracleUsdcUsd() public {
66+
Oracle2 oracle = new Oracle2(usdcUsd, AggregatorV3Interface(address(0)), 6, 0);
67+
assertApproxEqRel(oracle.price(), 1e36 / 1e6, 0.01 ether);
5968
}
6069

6170
function testNegativeAnswer() public {

test/chainlink/Oracle4Test.sol

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ contract OracleTest is Test {
2626
(, int256 quoteAnswer,,,) = usdcUsdFeed.latestRoundData();
2727
assertEq(
2828
oracle.price(),
29-
(uint256(firstBaseAnswer) * uint256(secondBaseAnswer) * 10 ** (36 + 8 + 8 - 6 - 8 - 8))
30-
/ uint256(quoteAnswer)
29+
(uint256(firstBaseAnswer) * uint256(secondBaseAnswer) * 10 ** (36 + 8 + 6 - 8 - 8 - 8)) / uint256(quoteAnswer)
3130
);
3231
}
3332

@@ -38,16 +37,15 @@ contract OracleTest is Test {
3837
(, int256 secondQuoteAnswer,,,) = btcUsdFeed.latestRoundData();
3938
assertEq(
4039
oracle.price(),
41-
(uint256(baseAnswer) * 10 ** (36 + 8 + 8 + 6 - 8 - 8))
42-
/ (uint256(firstQuoteAnswer) * uint256(secondQuoteAnswer))
40+
(uint256(baseAnswer) * 10 ** (36 + 8 + 8 + 8 - 6 - 8)) / (uint256(firstQuoteAnswer) * uint256(secondQuoteAnswer))
4341
);
4442
}
4543

4644
function testOracleWbtcEth() public {
4745
Oracle4 oracle =
48-
new Oracle4(wBtcBtcFeed, btcEthFeed, AggregatorV3Interface(address(0)), AggregatorV3Interface(address(0)), 8, 0);
46+
new Oracle4(wBtcBtcFeed, btcEthFeed, AggregatorV3Interface(address(0)), AggregatorV3Interface(address(0)), 8, 18);
4947
(, int256 firstBaseAnswer,,,) = wBtcBtcFeed.latestRoundData();
5048
(, int256 secondBaseAnswer,,,) = btcEthFeed.latestRoundData();
51-
assertEq(oracle.price(), (uint256(firstBaseAnswer) * uint256(secondBaseAnswer) * 10 ** (36 + 8 - 8 - 18)));
49+
assertEq(oracle.price(), (uint256(firstBaseAnswer) * uint256(secondBaseAnswer) * 10 ** (36 + 18 - 8 - 8 - 18)));
5250
}
5351
}

0 commit comments

Comments
 (0)