@@ -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 ) {
0 commit comments