@@ -45,20 +45,23 @@ contract ChainlinkOracle is IOracle {
45
45
BASE_FEED_2 = baseFeed2;
46
46
QUOTE_FEED_1 = quoteFeed1;
47
47
QUOTE_FEED_2 = quoteFeed2;
48
- // Let pB1 and pB2 be the base prices, and pQ1 and pQ2 the quote prices (price of 1e(decimals) asset), in a
49
- // common quote currency.
50
- // Chainlink feeds return pB1*b1FeedPrecision, pB2*b2FeedPrecision, pQ1*q1FeedPrecision and pQ2*q2FeedPrecision.
51
- // `price()` should return 1e36 * (pB1/1e(b1Decimals) * pB2/1e(b2Decimals)) / (pQ1/1e(q1Decimals) *
52
- // pQ2/1e(q2Decimals))
53
- // Yet `price()` returns (pB1*1e(b1FeedPrecision) * pB2*1e(b2FeedPrecision) * SCALE_FACTOR) /
54
- // (pQ1*1e(q1FeedPrecision) * pQ2*1e(q2FeedPrecision))
55
- // So 1e36 * (pB1/1e(b1Decimals) * pB2/1e(b2Decimals)) / (pQ1/1e(q1Decimals) * pQ2/1e(q2Decimals)) =
56
- // (pB1*1e(b1FeedPrecision) * pB2*1e(b2FeedPrecision) * SCALE_FACTOR) / (pQ1*1e(q1FeedPrecision) *
57
- // pQ2*1e(q2FeedPrecision))
58
- // So SCALE_FACTOR = 1e36 / 1e(b1Decimals) / 1e(b2Decimals) * 1e(q1Decimals) * 1e(q2Decimals) *
59
- // 1e(q1FeedPrecision) * 1e(q2FeedPrecision) / 1e(b1FeedPrecision) / 1e(b2FeedPrecision)
60
- // = 1e(36 + q1Decimals + q2Decimals + q1FeedPrecision + q2FeedPrecision - b1Decimals -
61
- // b2Decimals - b1FeedPrecision - b2FeedPrecision)
48
+ // Let pB1 and pB2 be the base prices, and pQ1 and pQ2 the quote prices (price taking into account the
49
+ // decimals of both tokens), in a common currency.
50
+ // We tackle the most general case in the remainder of this comment, where we assume that no feed is the address
51
+ // zero. Similar explanations would hold in the case where some of the feeds are the address zero.
52
+ // Let dB1, dB2, dB3, and dQ1, dQ2, dQ3 be the decimals of the tokens involved.
53
+ // For example, pB1 is the number of 1e(dB2) of the second base asset that can be obtained from 1e(dB1) of
54
+ // the first base asset.
55
+ // We notably have dB3 = dQ3, because those two quantities are the decimals of the same common currency.
56
+ // Let fpB1, fpB2, fpQ1 and fpQ2 be the feed precision of the corresponding prices.
57
+ // Chainlink feeds return pB1*1e(fpB1), pB2*1e(fpB2), pQ1*1e(fpQ1) and pQ2*1e(fpQ2).
58
+ // Because the Blue oracle does not take into account decimals, `price()` should return
59
+ // 1e36 * (pB1*1e(dB2-dB1) * pB2*1e(dB3-dB2)) / (pQ1*1e(dQ2-dQ1) * pQ2*1e(dQ3-dQ2))
60
+ // Yet `price()` returns (pB1*1e(fpB1) * pB2*1e(fpB2) * SCALE_FACTOR) / (pQ1*1e(fpQ1) * pQ2*1e(fpQ2))
61
+ // So 1e36 * pB1 * pB2 * 1e(-dB1) / (pQ1 * pQ2 * 1e(-dQ1)) =
62
+ // (pB1*1e(fpB1) * pB2*1e(fpB2) * SCALE_FACTOR) / (pQ1*1e(fpQ1) * pQ2*1e(fpQ2))
63
+ // So SCALE_FACTOR = 1e36 * 1e(-dB1) * 1e(dQ1) * 1e(-fpB1) * 1e(-fpB2) * 1e(fpQ1) * 1e(fpQ2)
64
+ // = 1e(36 + dQ1 + fpQ1 + fpQ2 - dB1 - fpB1 - fpB2)
62
65
SCALE_FACTOR = 10
63
66
** (
64
67
36 + quoteTokenDecimals + quoteFeed1.getDecimals () + quoteFeed2.getDecimals () - baseTokenDecimals
0 commit comments