@@ -11,11 +11,11 @@ contract TwapWeightedObserver is ITwapWeightedObserver {
11
11
12
12
constructor (uint128 initialValue ) {
13
13
PackedData memory cachedData = PackedData ({
14
- priceCumulative0 : initialValue,
14
+ observerCumuVal : initialValue,
15
15
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
19
19
});
20
20
21
21
valueToTrack = initialValue;
@@ -31,7 +31,7 @@ contract TwapWeightedObserver is ITwapWeightedObserver {
31
31
function _setValue (uint128 newValue ) internal {
32
32
uint128 _newAcc = _updateAcc (valueToTrack);
33
33
34
- data.lastUpdate = uint64 (block .timestamp );
34
+ data.lastTrackUpdTs = uint64 (block .timestamp );
35
35
emit NewTrackValue (valueToTrack, newValue, block .timestamp , _newAcc);
36
36
valueToTrack = newValue;
37
37
}
@@ -47,7 +47,7 @@ contract TwapWeightedObserver is ITwapWeightedObserver {
47
47
/// @return Duration since last update
48
48
/// @dev Safe from overflow for tens of thousands of years
49
49
function timeToAccrue () public view returns (uint64 ) {
50
- return uint64 (block .timestamp ) - data.lastUpdate ;
50
+ return uint64 (block .timestamp ) - data.lastTrackUpdTs ;
51
51
}
52
52
53
53
/// @notice Returns the accumulator value, adjusted according to the current value and block timestamp
@@ -77,55 +77,55 @@ contract TwapWeightedObserver is ITwapWeightedObserver {
77
77
function observe () external returns (uint256 ) {
78
78
// Here, we need to apply the new accumulator to skew the price in some way
79
79
// 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 ;
81
81
82
82
if (futureWeight == 0 ) {
83
- return data.avgValue ;
83
+ return data.avgSinceLastObs ;
84
84
}
85
85
86
86
// A reference period is 7 days
87
87
// For each second passed after update
88
88
// Let's virtally sync TWAP
89
89
// 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 ();
93
91
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
97
94
// Return virtual
98
95
return virtualAvgValue;
99
96
}
100
97
101
- uint256 weightedAvg = data.avgValue * (maxWeight - futureWeight);
98
+ uint256 weightedAvg = data.avgSinceLastObs * (PERIOD - futureWeight);
102
99
uint256 weightedVirtual = virtualAvgValue * (futureWeight);
103
100
104
101
uint256 weightedMean = (weightedAvg + weightedVirtual) / PERIOD;
105
102
106
103
return weightedMean;
107
104
}
108
105
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
+ }
113
112
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
+ }
119
118
120
- _update (avgValue, priceCum0, time0);
121
- }
119
+ function _checkUpdatePeriod () internal returns ( bool ) {
120
+ return block . timestamp >= (data.observerUpdTs + PERIOD);
122
121
}
123
122
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
+ }
129
129
}
130
130
131
131
function getData () external view returns (PackedData memory ) {
0 commit comments