Skip to content

Commit 8841e02

Browse files
Remove the updateTime retval from Oracle.latestPrice(): saves gas and we don't use it anymore.
1 parent 96b3d0d commit 8841e02

17 files changed

+76
-130
lines changed

contracts/USM.sol

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ contract USM is IUSM, ERC20Permit, OptOutable {
179179
require(ls.ethPool > 0, "Fund before minting");
180180

181181
// 3. Refresh the oracle price (if available - see checkForFreshOraclePrice() below):
182-
(ls.ethUsdPrice,, ls.bidAskAdjustment) = checkForFreshOraclePrice(ls);
182+
(ls.ethUsdPrice, ls.bidAskAdjustment) = checkForFreshOraclePrice(ls);
183183

184184
// 4. Calculate usmOut:
185185
uint adjShrinkFactor;
@@ -201,7 +201,7 @@ contract USM is IUSM, ERC20Permit, OptOutable {
201201
LoadedState memory ls = loadState();
202202

203203
// 2. Refresh the oracle price:
204-
(ls.ethUsdPrice,, ls.bidAskAdjustment) = checkForFreshOraclePrice(ls);
204+
(ls.ethUsdPrice, ls.bidAskAdjustment) = checkForFreshOraclePrice(ls);
205205

206206
// 3. Calculate ethOut:
207207
uint adjGrowthFactor;
@@ -225,7 +225,7 @@ contract USM is IUSM, ERC20Permit, OptOutable {
225225
ls.ethPool -= msg.value; // Backing out the ETH just received, which our calculations should ignore
226226

227227
// 2. Refresh the oracle price:
228-
(ls.ethUsdPrice,, ls.bidAskAdjustment) = checkForFreshOraclePrice(ls);
228+
(ls.ethUsdPrice, ls.bidAskAdjustment) = checkForFreshOraclePrice(ls);
229229

230230
// 3. Refresh timeSystemWentUnderwater, and replace ls.usmTotalSupply with the *effective* USM supply for FUM buys:
231231
uint debtRatio_;
@@ -253,7 +253,7 @@ contract USM is IUSM, ERC20Permit, OptOutable {
253253
LoadedState memory ls = loadState();
254254

255255
// 2. Refresh the oracle price:
256-
(ls.ethUsdPrice,, ls.bidAskAdjustment) = checkForFreshOraclePrice(ls);
256+
(ls.ethUsdPrice, ls.bidAskAdjustment) = checkForFreshOraclePrice(ls);
257257

258258
// 3. Calculate ethOut:
259259
uint fumSupply = fum.totalSupply();
@@ -276,10 +276,7 @@ contract USM is IUSM, ERC20Permit, OptOutable {
276276
}
277277

278278
/**
279-
* @notice Stores the current price, `bidAskAdjustment`, and `timeSystemWentUnderwater`. Note that whereas most calls to
280-
* this function store a fresh `bidAskAdjustmentTimestamp`, most calls do *not* store a fresh `ethUsdPriceTimestamp`: the
281-
* latter isn't updated every time this is called with a new price, but only when the *oracle's* price is refreshed. The
282-
* oracle price being "refreshed" is itself a subtle idea: see the comment in `Oracle.latestPrice()`.
279+
* @notice Stores the current price (and oracle price), `bidAskAdjustment`, and `timeSystemWentUnderwater`.
283280
*/
284281
function _storeState(LoadedState memory ls) internal {
285282
require(ls.bidAskAdjustmentTimestamp <= type(uint32).max, "bidAskAdjustmentTimestamp overflow");
@@ -322,8 +319,8 @@ contract USM is IUSM, ERC20Permit, OptOutable {
322319

323320
// ____________________ Public Oracle view functions ____________________
324321

325-
function latestPrice() public virtual override view returns (uint price, uint updateTime) {
326-
(price, updateTime,) = checkForFreshOraclePrice(loadState());
322+
function latestPrice() public virtual override view returns (uint price) {
323+
(price,) = checkForFreshOraclePrice(loadState());
327324
}
328325

329326
// ____________________ Public informational view functions ____________________
@@ -332,16 +329,11 @@ contract USM is IUSM, ERC20Permit, OptOutable {
332329
* @notice Checks the external oracle for a fresh ETH/USD price. If it has one, we take it as the new USM system price
333330
* (and update `bidAskAdjustment` as described below); if no fresh oracle price is available, we stick with our existing
334331
* system price, `ls.ethUsdPrice`, which may have been nudged around by mint/burn operations since the last oracle update.
335-
*
336-
* Note that our definition of whether an oracle price is "fresh" (`updateTime > ls.ethUsdPriceTimestamp`) isn't as simple
337-
* as "whether it's changed since our last call." Eg, we only consider a Uniswap TWAP price "fresh" when a new price
338-
* observation (trade) occurs, even though `price` may change without such an observation. See the comment in
339-
* `Oracle.latestPrice()`.
340332
*/
341333
function checkForFreshOraclePrice(LoadedState memory ls)
342-
public view returns (uint price, uint updateTime, uint adjustment)
334+
public view returns (uint price, uint adjustment)
343335
{
344-
(price, updateTime) = oracle.latestPrice();
336+
price = oracle.latestPrice();
345337
uint oraclePriceRounded = price + HALF_TRILLION; // Round for comparison below (we only store millionths precision)
346338
unchecked { oraclePriceRounded = oraclePriceRounded / TRILLION * TRILLION; } // Zeroing out the last 12 digits
347339

@@ -358,7 +350,7 @@ contract USM is IUSM, ERC20Permit, OptOutable {
358350
*
359351
* 1. storedPrice = $1,000, and bidAskAdjustment = 1.02. So, our current ETH buy price is $1,020, and our current
360352
* ETH sell price is $1,000 (mid).
361-
* 2. The oracle comes back with a fresh price (newer updateTime) of $990.
353+
* 2. The oracle comes back with a fresh price of $990.
362354
* 3. The currently adjusted price is buy price (ie, adj > 1). So, we want to:
363355
* a) Update storedPrice (mid) to $990.
364356
* b) Update bidAskAdj to ensure that buy price remains >= $1,020.

contracts/USMView.sol

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ contract USMView {
2222
* @return buffer ETH buffer
2323
*/
2424
function ethBuffer(bool roundUp) external view returns (int buffer) {
25-
(uint price, ) = usm.latestPrice();
26-
buffer = usm.ethBuffer(price, usm.ethPool(), usm.totalSupply(), roundUp);
25+
buffer = usm.ethBuffer(usm.latestPrice(), usm.ethPool(), usm.totalSupply(), roundUp);
2726
}
2827

2928
/**
@@ -32,8 +31,7 @@ contract USMView {
3231
* @return usmOut The amount of USM
3332
*/
3433
function ethToUsm(uint ethAmount, bool roundUp) external view returns (uint usmOut) {
35-
(uint price, ) = usm.latestPrice();
36-
usmOut = usm.ethToUsm(price, ethAmount, roundUp);
34+
usmOut = usm.ethToUsm(usm.latestPrice(), ethAmount, roundUp);
3735
}
3836

3937
/**
@@ -42,27 +40,24 @@ contract USMView {
4240
* @return ethOut The amount of ETH
4341
*/
4442
function usmToEth(uint usmAmount, bool roundUp) external view returns (uint ethOut) {
45-
(uint price, ) = usm.latestPrice();
46-
ethOut = usm.usmToEth(price, usmAmount, roundUp);
43+
ethOut = usm.usmToEth(usm.latestPrice(), usmAmount, roundUp);
4744
}
4845

4946
/**
5047
* @notice Calculate debt ratio.
5148
* @return ratio Debt ratio
5249
*/
5350
function debtRatio() external view returns (uint ratio) {
54-
(uint price, ) = usm.latestPrice();
55-
ratio = usm.debtRatio(price, usm.ethPool(), usm.totalSupply());
51+
ratio = usm.debtRatio(usm.latestPrice(), usm.ethPool(), usm.totalSupply());
5652
}
5753

5854
/**
5955
* @notice Calculate the *marginal* price of USM (in ETH terms) - that is, of the next unit, before price start sliding.
6056
* @return price USM price in ETH terms
6157
*/
6258
function usmPrice(IUSM.Side side) external view returns (uint price) {
63-
(uint ethUsdPrice, ) = usm.latestPrice();
6459
IUSM.Side ethSide = (side == IUSM.Side.Buy ? IUSM.Side.Sell : IUSM.Side.Buy); // Buying USM = selling ETH
65-
uint adjustedPrice = usm.adjustedEthUsdPrice(ethSide, ethUsdPrice, usm.bidAskAdjustment());
60+
uint adjustedPrice = usm.adjustedEthUsdPrice(ethSide, usm.latestPrice(), usm.bidAskAdjustment());
6661
price = usm.usmPrice(side, adjustedPrice);
6762
}
6863

@@ -81,7 +76,7 @@ contract USMView {
8176
* @return price FUM price in ETH terms
8277
*/
8378
function fumPrice(IUSM.Side side, bool prefund) public view returns (uint price) {
84-
(uint ethUsdPrice, ) = usm.latestPrice();
79+
uint ethUsdPrice = usm.latestPrice();
8580
uint adjustedPrice = usm.adjustedEthUsdPrice(side, ethUsdPrice, usm.bidAskAdjustment());
8681
uint ethPool = usm.ethPool();
8782
uint usmSupply = usm.totalSupply();

contracts/fuzzing/WETH9Fuzzing.sol

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// SPDX-License-Identifier: GPL-3.0-or-later
22
pragma solidity ^0.8.0;
33
import "../mocks/MockWETH9.sol";
4-
import "hardhat/console.sol";
54

65
contract WETH9Fuzzing {
76

contracts/mocks/GasMeasuredOracleWrapper.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ contract GasMeasuredOracleWrapper is Oracle {
1414
oracleName = name;
1515
}
1616

17-
function latestPrice() public virtual override view returns (uint price, uint updateTime) {
17+
function latestPrice() public virtual override view returns (uint price) {
1818
uint gasStart = gasleft();
19-
(price, updateTime) = measuredOracle.latestPrice();
19+
price = measuredOracle.latestPrice();
2020
uint gasEnd = gasleft();
2121
console.log(" ", oracleName, "oracle.latestPrice() cost: ", gasStart - gasEnd);
2222
}

contracts/mocks/MockChainlinkOracle.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import "../oracles/ChainlinkOracle.sol";
1212
contract MockChainlinkOracle is ChainlinkOracle, SettableOracle {
1313
constructor(AggregatorV3Interface aggregator_) ChainlinkOracle(aggregator_) {}
1414

15-
function latestPrice() public override(ChainlinkOracle, Oracle) view returns (uint price, uint updateTime) {
16-
(price, updateTime) = (savedPrice != 0) ? (savedPrice, savedUpdateTime) : super.latestPrice();
15+
function latestPrice() public override(ChainlinkOracle, Oracle) view returns (uint price) {
16+
price = (savedPrice != 0) ? savedPrice : super.latestPrice();
1717
}
1818
}

contracts/mocks/MockMedianOracle.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ contract MockMedianOracle is MedianOracle, SettableOracle {
1919
uniswapPool1, uniswapTokenToPrice1, uniswapDecimals1,
2020
uniswapPool2, uniswapTokenToPrice2, uniswapDecimals2) {}
2121

22-
function latestPrice() public override(MedianOracle, Oracle) view returns (uint price, uint updateTime) {
23-
(price, updateTime) = (savedPrice != 0) ? (savedPrice, savedUpdateTime) : super.latestPrice();
22+
function latestPrice() public override(MedianOracle, Oracle) view returns (uint price) {
23+
price = (savedPrice != 0) ? savedPrice : super.latestPrice();
2424
}
2525
}

contracts/mocks/MockUniswapV3Pool.sol

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,6 @@ contract MockUniswapV3Pool {
2121
lastObservationIndex = observationIndex;
2222
}
2323

24-
function slot0() public view
25-
returns (
26-
uint160 sqrtPriceX96,
27-
int24 tick,
28-
uint16 observationIndex,
29-
uint16 observationCardinality,
30-
uint16 observationCardinalityNext,
31-
uint8 feeProtocol,
32-
bool unlocked
33-
)
34-
{
35-
//Oracle.Observation memory lastObservation = observations[lastObservationIndex];
36-
//tick = int24(lastObservation.tickCumulative);
37-
tick = OracleLibrary.consult(address(this), 1); // 1 because any positive period should do here
38-
sqrtPriceX96 = TickMath.getSqrtRatioAtTick(tick);
39-
return (sqrtPriceX96, tick, lastObservationIndex, 0, 0, 0, true);
40-
}
41-
4224
/**
4325
* @notice See also
4426
* https://github.com/Uniswap/uniswap-v3-core/blob/main/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol, where

contracts/mocks/SettableOracle.sol

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@ import "../oracles/Oracle.sol";
55

66
abstract contract SettableOracle is Oracle {
77
uint public savedPrice;
8-
uint public savedUpdateTime;
98

109
function setPrice(uint p) public {
1110
savedPrice = p;
12-
savedUpdateTime = block.timestamp;
1311
}
1412
}

contracts/mocks/TestOracle.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ contract TestOracle is SettableOracle {
88
setPrice(p);
99
}
1010

11-
function latestPrice() public virtual override view returns (uint price, uint updateTime) {
12-
return (savedPrice, savedUpdateTime);
11+
function latestPrice() public virtual override view returns (uint price) {
12+
return savedPrice;
1313
}
1414
}

contracts/oracles/ChainlinkOracle.sol

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,8 @@ contract ChainlinkOracle is Oracle {
2222
* @notice Retrieve the latest price of the price oracle.
2323
* @return price
2424
*/
25-
function latestPrice() public virtual override view returns (uint price, uint updateTime) {
26-
int rawPrice;
27-
(, rawPrice,, updateTime,) = chainlinkAggregator.latestRoundData();
25+
function latestPrice() public virtual override view returns (uint price) {
26+
(, int rawPrice,,,) = chainlinkAggregator.latestRoundData();
2827
require(rawPrice > 0, "Chainlink price <= 0");
2928
price = uint(rawPrice) * CHAINLINK_SCALE_FACTOR;
3029
}

0 commit comments

Comments
 (0)