Skip to content

Commit 0d95dd1

Browse files
committed
rename twap packed data for better clarity
1 parent c7b7f12 commit 0d95dd1

File tree

6 files changed

+57
-52
lines changed

6 files changed

+57
-52
lines changed

packages/contracts/contracts/ActivePool.sol

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,8 @@ contract ActivePool is
206206

207207
uint256 cachedSystemDebt = systemDebt + _amount;
208208

209-
_setValue(uint128(cachedSystemDebt)); // @audit update TWAP spot value
210-
update(); // @audit update TWAP accumulator and weighted average
209+
_setValue(uint128(cachedSystemDebt)); // @audit update TWAP global spot value and accumulator variable along with a timestamp
210+
update(); // @audit update TWAP Observer accumulator and weighted average
211211

212212
systemDebt = cachedSystemDebt;
213213
emit ActivePoolEBTCDebtUpdated(cachedSystemDebt);
@@ -222,8 +222,8 @@ contract ActivePool is
222222

223223
uint256 cachedSystemDebt = systemDebt - _amount;
224224

225-
_setValue(uint128(cachedSystemDebt)); // @audit update TWAP spot value
226-
update(); // @audit update TWAP accumulator and weighted average
225+
_setValue(uint128(cachedSystemDebt)); // @audit update TWAP global spot value and accumulator variable along with a timestamp
226+
update(); // @audit update TWAP Observer accumulator and weighted average
227227

228228
systemDebt = cachedSystemDebt;
229229
emit ActivePoolEBTCDebtUpdated(cachedSystemDebt);

packages/contracts/contracts/Dependencies/TwapWeightedObserver.sol

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ contract TwapWeightedObserver is ITwapWeightedObserver {
1111

1212
constructor(uint128 initialValue) {
1313
PackedData memory cachedData = PackedData({
14-
priceCumulative0: initialValue,
14+
observerCumuVal: initialValue,
1515
accumulator: initialValue,
16-
t0: uint64(block.timestamp),
17-
lastUpdate: uint64(block.timestamp),
18-
avgValue: initialValue
16+
observerUpdTs: uint64(block.timestamp),
17+
lastTrackUpdTs: uint64(block.timestamp),
18+
avgSinceLastObs: initialValue
1919
});
2020

2121
valueToTrack = initialValue;
@@ -31,7 +31,7 @@ contract TwapWeightedObserver is ITwapWeightedObserver {
3131
function _setValue(uint128 newValue) internal {
3232
uint128 _newAcc = _updateAcc(valueToTrack);
3333

34-
data.lastUpdate = uint64(block.timestamp);
34+
data.lastTrackUpdTs = uint64(block.timestamp);
3535
emit NewTrackValue(valueToTrack, newValue, block.timestamp, _newAcc);
3636
valueToTrack = newValue;
3737
}
@@ -47,7 +47,7 @@ contract TwapWeightedObserver is ITwapWeightedObserver {
4747
/// @return Duration since last update
4848
/// @dev Safe from overflow for tens of thousands of years
4949
function timeToAccrue() public view returns (uint64) {
50-
return uint64(block.timestamp) - data.lastUpdate;
50+
return uint64(block.timestamp) - data.lastTrackUpdTs;
5151
}
5252

5353
/// @notice Returns the accumulator value, adjusted according to the current value and block timestamp
@@ -77,55 +77,55 @@ contract TwapWeightedObserver is ITwapWeightedObserver {
7777
function observe() external returns (uint256) {
7878
// Here, we need to apply the new accumulator to skew the price in some way
7979
// The weight of the skew should be proportional to the time passed
80-
uint256 futureWeight = block.timestamp - data.t0;
80+
uint256 futureWeight = block.timestamp - data.observerUpdTs;
8181

8282
if (futureWeight == 0) {
83-
return data.avgValue;
83+
return data.avgSinceLastObs;
8484
}
8585

8686
// A reference period is 7 days
8787
// For each second passed after update
8888
// Let's virtally sync TWAP
8989
// With a weight, that is higher, the more time has passed
90-
uint128 priceCum0 = getLatestAccumulator();
91-
uint128 virtualAvgValue = (priceCum0 - data.priceCumulative0) /
92-
(uint64(block.timestamp) - data.t0);
90+
(uint128 virtualAvgValue, uint128 obsAcc) = _calcUpdatedAvg();
9391

94-
uint256 maxWeight = PERIOD;
95-
if (futureWeight > maxWeight) {
96-
_update(virtualAvgValue, priceCum0, uint64(block.timestamp)); // May as well update
92+
if (_checkUpdatePeriod()) {
93+
_update(virtualAvgValue, obsAcc); // May as well update
9794
// Return virtual
9895
return virtualAvgValue;
9996
}
10097

101-
uint256 weightedAvg = data.avgValue * (maxWeight - futureWeight);
98+
uint256 weightedAvg = data.avgSinceLastObs * (PERIOD - futureWeight);
10299
uint256 weightedVirtual = virtualAvgValue * (futureWeight);
103100

104101
uint256 weightedMean = (weightedAvg + weightedVirtual) / PERIOD;
105102

106103
return weightedMean;
107104
}
108105

109-
function update() public {
110-
// On epoch flip, we update as intended
111-
if (block.timestamp >= data.t0 + PERIOD) {
112-
uint128 latestAcc = getLatestAccumulator();
106+
function _calcUpdatedAvg() internal view returns (uint128, uint128) {
107+
uint128 latestAcc = getLatestAccumulator();
108+
uint128 avgValue = (latestAcc - data.observerCumuVal) /
109+
(uint64(block.timestamp) - data.observerUpdTs);
110+
return (avgValue, latestAcc);
111+
}
113112

114-
// Compute based on delta
115-
uint128 avgValue = (latestAcc - data.priceCumulative0) /
116-
(uint64(block.timestamp) - data.t0);
117-
uint128 priceCum0 = latestAcc;
118-
uint64 time0 = uint64(block.timestamp);
113+
function _update(uint128 avgValue, uint128 obsAcc) internal {
114+
data.avgSinceLastObs = avgValue;
115+
data.observerCumuVal = obsAcc;
116+
data.observerUpdTs = uint64(block.timestamp);
117+
}
119118

120-
_update(avgValue, priceCum0, time0);
121-
}
119+
function _checkUpdatePeriod() internal returns (bool) {
120+
return block.timestamp >= (data.observerUpdTs + PERIOD);
122121
}
123122

124-
/// Internal update so we can call it both in _update and in observe
125-
function _update(uint128 avgValue, uint128 priceCum0, uint64 time0) internal {
126-
data.avgValue = avgValue;
127-
data.priceCumulative0 = priceCum0;
128-
data.t0 = time0;
123+
/// @dev update time-weighted Observer
124+
function update() public {
125+
if (_checkUpdatePeriod()) {
126+
(uint128 avgValue, uint128 latestAcc) = _calcUpdatedAvg();
127+
_update(avgValue, latestAcc);
128+
}
129129
}
130130

131131
function getData() external view returns (PackedData memory) {

packages/contracts/contracts/Interfaces/IBaseTwapWeightedObserver.sol

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,22 @@ interface IBaseTwapWeightedObserver {
66
struct PackedData {
77
// Slot 0
88
// Seconds in a year: 3.154e+7
9-
uint128 priceCumulative0; // 3.154e+7 * 80 * 100e27 = 2.5232e+38 | log_2(100e27 * 3.154e+7 * 80) = 127.568522171
9+
/// @dev Accumulator value recorded for TWAP Observer until last update
10+
uint128 observerCumuVal; // 3.154e+7 * 80 * 100e27 = 2.5232e+38 | log_2(100e27 * 3.154e+7 * 80) = 127.568522171
11+
/// @dev Accumulator for TWAP globally
1012
uint128 accumulator; // 3.154e+7 * 80 * 100e27 = 2.5232e+38 | log_2(100e27 * 3.154e+7 * 80) = 127.568522171
1113
// NOTE: We can further compress this slot but we will not be able to use only one (see u72 impl)
1214
/// So what's the point of making the code more complex?
1315

1416
// Slot 1
15-
uint64 t0; // Thousands of Years, if we use relative time we can use u32 | Relative to deploy time (as immutable)
16-
uint64 lastUpdate; // Thousands of years
17+
/// @dev last update timestamp for TWAP Observer
18+
uint64 observerUpdTs; // Thousands of Years, if we use relative time we can use u32 | Relative to deploy time (as immutable)
19+
/// @dev last update timestamp for TWAP global track(spot) value
20+
uint64 lastTrackUpdTs; // Thousands of years
1721
// Expect eBTC debt to never surpass 100e27, which is 100 BILLION eBTC
1822
// log_2(100e27) = 96.3359147517 | log_2(100e27 / 1e18) = 36.5412090438
1923
// We could use a u64
20-
uint128 avgValue;
24+
/// @dev average value since last observe
25+
uint128 avgSinceLastObs;
2126
}
2227
}

packages/contracts/foundry_test/ActivePool.twapAcc.t.sol

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ contract ActivePoolTwapAccTest is eBTCBaseFixture {
2323

2424
function testBasicTwap() public {
2525
uint256 entropy = 67842918170911949682054359726922204181906323355453850;
26-
vm.warp((apTester.getData()).lastUpdate + apTester.PERIOD());
26+
vm.warp((apTester.getData()).lastTrackUpdTs + apTester.PERIOD());
2727
apTester.unprotectedSetTwapTrackVal(100);
2828

2929
while (entropy > 0) {
@@ -45,8 +45,8 @@ contract ActivePoolTwapAccTest is eBTCBaseFixture {
4545
assertEq(_val, apTester.valueToTrack());
4646

4747
uint256 _accBefore = apTester.getLatestAccumulator();
48-
vm.warp((apTester.getData()).lastUpdate + apTester.PERIOD());
49-
uint256 _duration = block.timestamp - (apTester.getData()).lastUpdate;
48+
vm.warp((apTester.getData()).lastTrackUpdTs + apTester.PERIOD());
49+
uint256 _duration = block.timestamp - (apTester.getData()).lastTrackUpdTs;
5050
uint256 _accAfter = apTester.getLatestAccumulator();
5151
assertEq(_duration * _val, _accAfter - _accBefore);
5252
}
@@ -63,7 +63,7 @@ contract ActivePoolTwapAccTest is eBTCBaseFixture {
6363

6464
uint256 _accBefore = apTester.getLatestAccumulator();
6565
vm.warp(MANY_YEARS);
66-
uint256 _duration = block.timestamp - (apTester.getData()).lastUpdate;
66+
uint256 _duration = block.timestamp - (apTester.getData()).lastTrackUpdTs;
6767
uint256 _accAfter = apTester.getLatestAccumulator();
6868
assertEq(TEN_BILLION_USD * _duration, _accAfter - _accBefore);
6969
}
@@ -74,7 +74,7 @@ contract ActivePoolTwapAccTest is eBTCBaseFixture {
7474
assertEq(NORMAL_VALUE, apTester.valueToTrack());
7575

7676
// update the accumulator normally after period
77-
vm.warp((apTester.getData()).t0 + apTester.PERIOD() + 123);
77+
vm.warp((apTester.getData()).observerUpdTs + apTester.PERIOD() + 123);
7878
apTester.update();
7979
assertEq(NORMAL_VALUE, apTester.valueToTrack());
8080
uint256 _obsv = apTester.observe();

packages/contracts/foundry_test/BaseFixture.sol

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -634,11 +634,11 @@ contract eBTCBaseFixture is
634634
console.log("getLatestAccumulator: ", getLatestAccumulator.pretty());
635635
console.log("observe: ", observe.pretty());
636636
console.log("");
637-
console.log("data.priceCumulative0: ", data.priceCumulative0);
637+
console.log("data.priceCumulative0: ", data.observerCumuVal);
638638
console.log("data.accumulator: ", data.accumulator);
639-
console.log("data.t0: ", data.t0);
640-
console.log("data.lastUpdate: ", data.lastUpdate);
641-
console.log("data.avgValue: ", data.avgValue);
639+
console.log("data.t0: ", data.observerUpdTs);
640+
console.log("data.lastUpdate: ", data.lastTrackUpdTs);
641+
console.log("data.avgValue: ", data.avgSinceLastObs);
642642
console.log("");
643643
}
644644

packages/contracts/utils/testHelpers.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -321,15 +321,15 @@ class TestHelper {
321321
let _valToCheck = await contracts.activePool.valueToTrack();
322322
console.log('twap valToCheck=' + _valToCheck);
323323
let _period = await contracts.activePool.PERIOD();
324-
let _diffTime = this.toBN(blockTimestampStart + diffTimeBtwBlocks - _twapDebtData["lastUpdate"])
324+
let _diffTime = this.toBN(blockTimestampStart + diffTimeBtwBlocks - _twapDebtData["lastTrackUpdTs"])
325325
console.log('twap diffTime=' + _diffTime);
326326
let _acc = this.toBN(_twapDebtData["accumulator"]).add(this.toBN(_valToCheck).mul(_diffTime))
327327
console.log('twap acc=' + _acc);
328-
let _diffTimeT0 = this.toBN(blockTimestampStart + diffTimeBtwBlocks - _twapDebtData["t0"])
328+
let _diffTimeT0 = this.toBN(blockTimestampStart + diffTimeBtwBlocks - _twapDebtData["observerUpdTs"])
329329
console.log('twap diffTimeT0=' + _diffTimeT0);
330-
let _avg = _acc.sub(this.toBN(_twapDebtData["priceCumulative0"])).div(_diffTimeT0);
330+
let _avg = _acc.sub(this.toBN(_twapDebtData["observerCumuVal"])).div(_diffTimeT0);
331331
console.log('twap _avg=' + _avg);
332-
let _weightedMean = (this.toBN(_twapDebtData["avgValue"]).mul(_period.sub(_diffTimeT0)).add(_avg.mul(_diffTimeT0))).div(_period);
332+
let _weightedMean = (this.toBN(_twapDebtData["avgSinceLastObs"]).mul(_period.sub(_diffTimeT0)).add(_avg.mul(_diffTimeT0))).div(_period);
333333
console.log('twap _weightedMean=' + _weightedMean);
334334
return _weightedMean;
335335
}

0 commit comments

Comments
 (0)