2
2
pragma solidity ^ 0.8.0 ;
3
3
4
4
import { SafeCast } from "@openzeppelin/utils/math/SafeCast.sol " ;
5
+ import { ReentrancyGuardTransient } from "@openzeppelin/utils/ReentrancyGuardTransient.sol " ;
5
6
import { FixedPointMathLib } from "solady/utils/FixedPointMathLib.sol " ;
6
7
import { SafeTransferLib } from "solady/utils/SafeTransferLib.sol " ;
7
8
@@ -19,7 +20,7 @@ import { Observation } from "src/structs/Observation.sol";
19
20
import { Slot0 } from "src/structs/Slot0.sol " ;
20
21
import { ReservoirERC20 } from "src/ReservoirERC20.sol " ;
21
22
22
- abstract contract ReservoirPair is IAssetManagedPair , ReservoirERC20 {
23
+ abstract contract ReservoirPair is IAssetManagedPair , ReservoirERC20 , ReentrancyGuardTransient {
23
24
using FactoryStoreLib for IGenericFactory;
24
25
using Bytes32Lib for bytes32 ;
25
26
using SafeCast for uint256 ;
@@ -96,48 +97,23 @@ abstract contract ReservoirPair is IAssetManagedPair, ReservoirERC20 {
96
97
97
98
//////////////////////////////////////////////////////////////////////////*/
98
99
99
- Slot0 internal _slot0 = Slot0 ({ reserve0: 0 , reserve1: 0 , packedTimestamp : 0 , index: Buffer.SIZE - 1 });
100
+ Slot0 internal _slot0 = Slot0 ({ reserve0: 0 , reserve1: 0 , timestamp : 0 , index: Buffer.SIZE - 1 });
100
101
101
- function _currentTime () internal view returns (uint32 ) {
102
- return uint32 (block .timestamp & 0x7FFFFFFF );
103
- }
104
-
105
- function _splitSlot0Timestamp (uint32 aPackedTimestamp ) internal pure returns (uint32 rTimestamp , bool rLocked ) {
106
- rLocked = aPackedTimestamp >> 31 == 1 ;
107
- rTimestamp = aPackedTimestamp & 0x7FFFFFFF ;
108
- }
109
-
110
- /// @notice Writes the packed timestamp & re-entrancy guard into slot0.
111
- /// @dev The timestamp argument must not exceed 2**31.
112
- function _writeSlot0Timestamp (Slot0 storage sSlot0 , uint32 aTimestamp , bool aLocked ) internal {
113
- uint32 lLocked = aLocked ? uint32 (1 << 31 ) : uint32 (0 );
114
- sSlot0.packedTimestamp = aTimestamp | lLocked;
115
- }
116
-
117
- function _lockAndLoad ()
102
+ function _load ()
118
103
internal
119
104
returns (Slot0 storage , uint104 rReserve0 , uint104 rReserve1 , uint32 rBlockTimestampLast , uint16 rIndex )
120
105
{
121
106
Slot0 storage sSlot0 = _slot0;
122
107
123
108
// Load slot0 values.
124
- bool lLock;
125
109
rReserve0 = sSlot0.reserve0;
126
110
rReserve1 = sSlot0.reserve1;
127
- ( rBlockTimestampLast, lLock) = _splitSlot0Timestamp ( sSlot0.packedTimestamp) ;
111
+ rBlockTimestampLast = sSlot0.timestamp ;
128
112
rIndex = sSlot0.index;
129
113
130
- // Acquire reentrancy lock.
131
- require (! lLock, "REENTRANCY " );
132
- _writeSlot0Timestamp (sSlot0, rBlockTimestampLast, true );
133
-
134
114
return (sSlot0, rReserve0, rReserve1, rBlockTimestampLast, rIndex);
135
115
}
136
116
137
- function _unlock (Slot0 storage sSlot0 , uint32 aBlockTimestampLast ) internal {
138
- _writeSlot0Timestamp (sSlot0, aBlockTimestampLast, false );
139
- }
140
-
141
117
/// @notice Updates reserves with new balances.
142
118
/// @notice On the first call per block, accumulate price oracle using previous instant prices and write the new instant prices.
143
119
/// @dev The price is not updated on subsequent swaps as manipulating
@@ -153,7 +129,7 @@ abstract contract ReservoirPair is IAssetManagedPair, ReservoirERC20 {
153
129
require (aBalance0 <= type (uint104 ).max && aBalance1 <= type (uint104 ).max, "RP: OVERFLOW " );
154
130
require (aReserve0 <= type (uint104 ).max && aReserve1 <= type (uint104 ).max, "RP: OVERFLOW " );
155
131
156
- uint32 lBlockTimestamp = _currentTime ();
132
+ uint32 lBlockTimestamp = uint32 ( block . timestamp ); // invalid after year 2106
157
133
uint32 lTimeElapsed;
158
134
unchecked {
159
135
// underflow is desired
@@ -199,7 +175,7 @@ abstract contract ReservoirPair is IAssetManagedPair, ReservoirERC20 {
199
175
// update reserves to match latest balances
200
176
sSlot0.reserve0 = uint104 (aBalance0);
201
177
sSlot0.reserve1 = uint104 (aBalance1);
202
- _writeSlot0Timestamp ( sSlot0, lBlockTimestamp, false ) ;
178
+ sSlot0.timestamp = lBlockTimestamp ;
203
179
204
180
emit Sync (uint104 (aBalance0), uint104 (aBalance1));
205
181
}
@@ -213,25 +189,26 @@ abstract contract ReservoirPair is IAssetManagedPair, ReservoirERC20 {
213
189
214
190
rReserve0 = lSlot0.reserve0;
215
191
rReserve1 = lSlot0.reserve1;
216
- ( rBlockTimestampLast,) = _splitSlot0Timestamp ( lSlot0.packedTimestamp) ;
192
+ rBlockTimestampLast = lSlot0.timestamp ;
217
193
rIndex = lSlot0.index;
218
194
}
219
195
220
196
/// @notice Force reserves to match balances.
221
- function sync () external {
222
- (Slot0 storage sSlot0 , uint256 lReserve0 , uint256 lReserve1 , uint32 lBlockTimestampLast ,) = _lockAndLoad ();
197
+ function sync () external nonReentrant {
198
+ (Slot0 storage sSlot0 , uint256 lReserve0 , uint256 lReserve1 , uint32 lBlockTimestampLast ,) = _load ();
223
199
(lReserve0, lReserve1) = _syncManaged (lReserve0, lReserve1);
224
200
225
201
_updateAndUnlock (sSlot0, _totalToken0 (), _totalToken1 (), lReserve0, lReserve1, lBlockTimestampLast);
226
202
}
227
203
228
204
/// @notice Force balances to match reserves.
229
- function skim (address aTo ) external {
230
- (Slot0 storage sSlot0 , uint256 lReserve0 , uint256 lReserve1 , uint32 lBlockTimestampLast ,) = _lockAndLoad ();
205
+ function skim (address aTo ) external nonReentrant {
206
+ (Slot0 storage sSlot0 , uint256 lReserve0 , uint256 lReserve1 , uint32 lBlockTimestampLast ,) = _load ();
231
207
232
208
_checkedTransfer (token0 (), aTo, _totalToken0 () - lReserve0, lReserve0, lReserve1);
233
209
_checkedTransfer (token1 (), aTo, _totalToken1 () - lReserve1, lReserve0, lReserve1);
234
- _unlock (sSlot0, lBlockTimestampLast);
210
+
211
+ // might need to do an update here
235
212
}
236
213
237
214
/*//////////////////////////////////////////////////////////////////////////
0 commit comments