@@ -6,6 +6,7 @@ import {Pool} from "./libraries/Pool.sol";
6
6
import {SafeCast} from "./libraries/SafeCast.sol " ;
7
7
import {Position} from "./libraries/Position.sol " ;
8
8
import {Currency, CurrencyLibrary} from "./libraries/CurrencyLibrary.sol " ;
9
+ import {LockDataLibrary} from "./libraries/LockDataLibrary.sol " ;
9
10
10
11
import {NoDelegateCall} from "./NoDelegateCall.sol " ;
11
12
import {Owned} from "./Owned.sol " ;
@@ -29,6 +30,7 @@ contract PoolManager is IPoolManager, Owned, NoDelegateCall, ERC1155, IERC1155Re
29
30
using Hooks for IHooks;
30
31
using Position for mapping (bytes32 => Position.Info);
31
32
using CurrencyLibrary for Currency;
33
+ using LockDataLibrary for IPoolManager.LockData;
32
34
using Fees for uint24 ;
33
35
34
36
/// @inheritdoc IPoolManager
@@ -45,18 +47,11 @@ contract PoolManager is IPoolManager, Owned, NoDelegateCall, ERC1155, IERC1155Re
45
47
IProtocolFeeController public protocolFeeController;
46
48
47
49
/// @inheritdoc IPoolManager
48
- address [] public override lockedBy ;
50
+ IPoolManager.LockData public override lockData ;
49
51
50
- /// @member nonzeroDeltaCount The number of entries in the currencyDelta mapping that have a non-zero value
51
- /// @member currencyDelta The amount owed to the locker (positive) or owed to the pool (negative) of the currency
52
- struct LockState {
53
- uint256 nonzeroDeltaCount;
54
- mapping (Currency currency => int256 ) currencyDelta;
55
- }
56
-
57
- /// @dev Represents the state of the locker at the given index. Each locker must have net 0 currencies owed before
58
- /// releasing their lock. Note this is private because the nested mappings cannot be exposed as a public variable.
59
- mapping (uint256 index = > LockState) private lockStates;
52
+ /// @dev Represents the currencies due/owed to each locker.
53
+ /// Must all net to zero when the last lock is released.
54
+ mapping (address locker = > mapping (Currency currency => int256 currencyDelta )) public currencyDelta;
60
55
61
56
/// @inheritdoc IPoolManager
62
57
mapping (Currency currency => uint256 ) public override reservesOf;
@@ -126,6 +121,11 @@ contract PoolManager is IPoolManager, Owned, NoDelegateCall, ERC1155, IERC1155Re
126
121
return pools[id].positions.get (owner, tickLower, tickUpper);
127
122
}
128
123
124
+ /// @inheritdoc IPoolManager
125
+ function getLock (uint256 i ) external view override returns (address locker ) {
126
+ return LockDataLibrary.getLock (i);
127
+ }
128
+
129
129
/// @inheritdoc IPoolManager
130
130
function initialize (PoolKey memory key , uint160 sqrtPriceX96 ) external override returns (int24 tick ) {
131
131
if (key.fee & Fees.STATIC_FEE_MASK >= 1000000 ) revert FeeTooLarge ();
@@ -155,53 +155,37 @@ contract PoolManager is IPoolManager, Owned, NoDelegateCall, ERC1155, IERC1155Re
155
155
emit Initialize (id, key.currency0, key.currency1, key.fee, key.tickSpacing, key.hooks);
156
156
}
157
157
158
- /// @inheritdoc IPoolManager
159
- function lockedByLength () external view returns (uint256 ) {
160
- return lockedBy.length ;
161
- }
162
-
163
- /// @inheritdoc IPoolManager
164
- function getNonzeroDeltaCount (uint256 id ) external view returns (uint256 ) {
165
- return lockStates[id].nonzeroDeltaCount;
166
- }
167
-
168
- /// @inheritdoc IPoolManager
169
- function getCurrencyDelta (uint256 id , Currency currency ) external view returns (int256 ) {
170
- return lockStates[id].currencyDelta[currency];
171
- }
172
-
173
158
/// @inheritdoc IPoolManager
174
159
function lock (bytes calldata data ) external override returns (bytes memory result ) {
175
- uint256 id = lockedBy.length ;
176
- lockedBy.push (msg .sender );
160
+ lockData.push (msg .sender );
177
161
178
162
// the caller does everything in this callback, including paying what they owe via calls to settle
179
- result = ILockCallback (msg .sender ).lockAcquired (id, data);
163
+ result = ILockCallback (msg .sender ).lockAcquired (data);
180
164
181
- unchecked {
182
- LockState storage lockState = lockStates[id];
183
- if (lockState.nonzeroDeltaCount != 0 ) revert CurrencyNotSettled ();
165
+ if (lockData.length == 1 ) {
166
+ if (lockData.nonzeroDeltaCount != 0 ) revert CurrencyNotSettled ();
167
+ delete lockData;
168
+ } else {
169
+ lockData.pop ();
184
170
}
185
-
186
- lockedBy.pop ();
187
171
}
188
172
189
173
function _accountDelta (Currency currency , int128 delta ) internal {
190
174
if (delta == 0 ) return ;
191
175
192
- LockState storage lockState = lockStates[lockedBy.length - 1 ];
193
- int256 current = lockState.currencyDelta[currency];
194
-
176
+ address locker = lockData.getActiveLock ();
177
+ int256 current = currencyDelta[locker][currency];
195
178
int256 next = current + delta;
179
+
196
180
unchecked {
197
181
if (next == 0 ) {
198
- lockState .nonzeroDeltaCount-- ;
182
+ lockData .nonzeroDeltaCount-- ;
199
183
} else if (current == 0 ) {
200
- lockState .nonzeroDeltaCount++ ;
184
+ lockData .nonzeroDeltaCount++ ;
201
185
}
202
186
}
203
187
204
- lockState. currencyDelta[currency] = next;
188
+ currencyDelta[locker] [currency] = next;
205
189
}
206
190
207
191
/// @dev Accumulates a balance change to a map of currency to balance changes
@@ -211,7 +195,7 @@ contract PoolManager is IPoolManager, Owned, NoDelegateCall, ERC1155, IERC1155Re
211
195
}
212
196
213
197
modifier onlyByLocker () {
214
- address locker = lockedBy[lockedBy. length - 1 ] ;
198
+ address locker = lockData. getActiveLock () ;
215
199
if (msg .sender != locker) revert LockedBy (locker);
216
200
_;
217
201
}
0 commit comments