@towns-protocol/contracts 0.0.450 → 0.0.451

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@towns-protocol/contracts",
3
- "version": "0.0.450",
3
+ "version": "0.0.451",
4
4
  "scripts": {
5
5
  "clean": "forge clean",
6
6
  "compile": "forge build",
@@ -33,7 +33,7 @@
33
33
  "@layerzerolabs/oapp-evm": "^0.3.2",
34
34
  "@openzeppelin/merkle-tree": "^1.0.8",
35
35
  "@prb/test": "^0.6.4",
36
- "@towns-protocol/prettier-config": "^0.0.450",
36
+ "@towns-protocol/prettier-config": "^0.0.451",
37
37
  "@wagmi/cli": "^2.2.0",
38
38
  "forge-std": "github:foundry-rs/forge-std#v1.10.0",
39
39
  "prettier": "^3.5.3",
@@ -50,5 +50,5 @@
50
50
  "publishConfig": {
51
51
  "access": "public"
52
52
  },
53
- "gitHead": "cbbeb47f3b927004f889268ab727858eab3f1cf9"
53
+ "gitHead": "ad68c0f2514e44f51293824ebba5ccc2f8a6494c"
54
54
  }
@@ -19,26 +19,23 @@ import {Facet} from "@towns-protocol/diamond/src/facets/Facet.sol";
19
19
 
20
20
  contract EntitlementChecker is IEntitlementChecker, Facet {
21
21
  using EnumerableSet for EnumerableSet.AddressSet;
22
- using EnumerableSet for EnumerableSet.UintSet;
23
22
  using EnumerableSet for EnumerableSet.Bytes32Set;
23
+ using EnumerableSet for EnumerableSet.UintSet;
24
24
  using CustomRevert for bytes4;
25
25
  using SafeTransferLib for address;
26
26
 
27
- // =============================================================
28
- // Initializer
29
- // =============================================================
30
-
31
27
  function __EntitlementChecker_init() external onlyInitializing {
32
28
  _addInterface(type(IEntitlementChecker).interfaceId);
33
29
  }
34
30
 
35
- // =============================================================
36
- // Modifiers
37
- // =============================================================
38
- modifier onlyNodeOperator(address node, address operator) {
39
- EntitlementCheckerStorage.Layout storage layout = EntitlementCheckerStorage.layout();
31
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
32
+ /* MODIFIERS */
33
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
40
34
 
41
- if (layout.operatorByNode[node] != operator) {
35
+ modifier onlyNodeOperator(address node) {
36
+ EntitlementCheckerStorage.Layout storage $ = EntitlementCheckerStorage.layout();
37
+
38
+ if (msg.sender != $.operatorByNode[node]) {
42
39
  EntitlementChecker_InvalidNodeOperator.selector.revertWith();
43
40
  }
44
41
  _;
@@ -50,95 +47,73 @@ contract EntitlementChecker is IEntitlementChecker, Facet {
50
47
  if (!nodeOperatorLayout.operators.contains(msg.sender)) {
51
48
  EntitlementChecker_InvalidOperator.selector.revertWith();
52
49
  }
53
- _;
54
-
55
50
  if (nodeOperatorLayout.statusByOperator[msg.sender] != NodeOperatorStatus.Approved) {
56
51
  EntitlementChecker_OperatorNotActive.selector.revertWith();
57
52
  }
53
+ _;
58
54
  }
59
55
 
60
- // =============================================================
61
- // External
62
- // =============================================================
56
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
57
+ /* ADMIN FUNCTIONS */
58
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
63
59
 
64
60
  /// @inheritdoc IEntitlementChecker
65
61
  function registerNode(address node) external onlyRegisteredApprovedOperator {
66
- EntitlementCheckerStorage.Layout storage layout = EntitlementCheckerStorage.layout();
62
+ EntitlementCheckerStorage.Layout storage $ = EntitlementCheckerStorage.layout();
67
63
 
68
- if (layout.nodes.contains(node)) {
64
+ if ($.nodes.contains(node)) {
69
65
  EntitlementChecker_NodeAlreadyRegistered.selector.revertWith();
70
66
  }
71
67
 
72
- layout.nodes.add(node);
73
- layout.operatorByNode[node] = msg.sender;
68
+ $.nodes.add(node);
69
+ $.operatorByNode[node] = msg.sender;
74
70
 
75
71
  emit NodeRegistered(node);
76
72
  }
77
73
 
78
74
  /// @inheritdoc IEntitlementChecker
79
- function unregisterNode(address node) external onlyNodeOperator(node, msg.sender) {
80
- EntitlementCheckerStorage.Layout storage layout = EntitlementCheckerStorage.layout();
75
+ function unregisterNode(address node) external onlyNodeOperator(node) {
76
+ EntitlementCheckerStorage.Layout storage $ = EntitlementCheckerStorage.layout();
81
77
 
82
- if (!layout.nodes.contains(node)) {
78
+ if (!$.nodes.contains(node)) {
83
79
  EntitlementChecker_NodeNotRegistered.selector.revertWith();
84
80
  }
85
81
 
86
- layout.nodes.remove(node);
87
- delete layout.operatorByNode[node];
82
+ $.nodes.remove(node);
83
+ delete $.operatorByNode[node];
88
84
 
89
85
  emit NodeUnregistered(node);
90
86
  }
91
87
 
92
- /// @inheritdoc IEntitlementChecker
93
- function isValidNode(address node) external view returns (bool) {
94
- EntitlementCheckerStorage.Layout storage layout = EntitlementCheckerStorage.layout();
95
- return layout.nodes.contains(node);
96
- }
97
-
98
- /// @inheritdoc IEntitlementChecker
99
- function getNodeCount() external view returns (uint256) {
100
- EntitlementCheckerStorage.Layout storage layout = EntitlementCheckerStorage.layout();
101
- return layout.nodes.length();
102
- }
103
-
104
- /// @inheritdoc IEntitlementChecker
105
- function getNodeAtIndex(uint256 index) external view returns (address) {
106
- EntitlementCheckerStorage.Layout storage layout = EntitlementCheckerStorage.layout();
107
-
108
- require(index < layout.nodes.length(), "Index out of bounds");
109
- return layout.nodes.at(index);
110
- }
111
-
112
- /// @inheritdoc IEntitlementChecker
113
- function getRandomNodes(uint256 count) external view returns (address[] memory) {
114
- return _getRandomNodes(count);
115
- }
88
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
89
+ /* ENTITLEMENT */
90
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
116
91
 
117
92
  /// @inheritdoc IEntitlementChecker
118
93
  function requestEntitlementCheck(
119
- address walletAddress,
94
+ address receiver,
120
95
  bytes32 transactionId,
121
96
  uint256 roleId,
122
97
  address[] memory nodes
123
98
  ) external {
124
- emit EntitlementCheckRequested(walletAddress, msg.sender, transactionId, roleId, nodes);
99
+ emit EntitlementCheckRequested(receiver, msg.sender, transactionId, roleId, nodes);
125
100
  }
126
101
 
127
102
  /// @inheritdoc IEntitlementChecker
128
103
  function requestEntitlementCheckV2(
129
- address walletAddress,
104
+ address receiver,
130
105
  bytes32 transactionId,
131
106
  uint256 requestId,
132
107
  bytes memory extraData
133
108
  ) external payable {
134
- address senderAddress = abi.decode(extraData, (address));
109
+ address sender = abi.decode(extraData, (address));
135
110
  _requestEntitlementCheck(
136
- walletAddress,
111
+ receiver,
137
112
  transactionId,
138
113
  requestId,
139
114
  CurrencyTransfer.NATIVE_TOKEN,
140
115
  msg.value,
141
- senderAddress
116
+ sender
142
117
  );
143
118
  }
144
119
 
@@ -146,68 +121,104 @@ contract EntitlementChecker is IEntitlementChecker, Facet {
146
121
  function requestEntitlementCheck(CheckType checkType, bytes calldata data) external payable {
147
122
  if (checkType == CheckType.V1) {
148
123
  if (msg.value != 0) EntitlementChecker_InvalidValue.selector.revertWith();
149
- (
150
- address walletAddress,
151
- bytes32 transactionId,
152
- uint256 roleId,
153
- address[] memory nodes
154
- ) = abi.decode(data, (address, bytes32, uint256, address[]));
155
- emit EntitlementCheckRequested(walletAddress, msg.sender, transactionId, roleId, nodes);
124
+ (address receiver, bytes32 transactionId, uint256 roleId, address[] memory nodes) = abi
125
+ .decode(data, (address, bytes32, uint256, address[]));
126
+ emit EntitlementCheckRequested(receiver, msg.sender, transactionId, roleId, nodes);
156
127
  } else if (checkType == CheckType.V2) {
157
128
  (
158
- address walletAddress,
129
+ address receiver,
159
130
  bytes32 transactionId,
160
131
  uint256 requestId,
161
132
  bytes memory extraData
162
133
  ) = abi.decode(data, (address, bytes32, uint256, bytes));
163
- address senderAddress = abi.decode(extraData, (address));
134
+ address sender = abi.decode(extraData, (address));
164
135
  _requestEntitlementCheck(
165
- walletAddress,
136
+ receiver,
166
137
  transactionId,
167
138
  requestId,
168
139
  CurrencyTransfer.NATIVE_TOKEN,
169
140
  msg.value,
170
- senderAddress
141
+ sender
171
142
  );
172
143
  } else if (checkType == CheckType.V3) {
173
144
  (
174
- address walletAddress,
145
+ address receiver,
175
146
  bytes32 transactionId,
176
147
  uint256 requestId,
177
148
  address currency,
178
149
  uint256 amount,
179
- address senderAddress
150
+ address sender
180
151
  ) = abi.decode(data, (address, bytes32, uint256, address, uint256, address));
181
- _requestEntitlementCheck(
182
- walletAddress,
183
- transactionId,
184
- requestId,
185
- currency,
186
- amount,
187
- senderAddress
188
- );
152
+ _requestEntitlementCheck(receiver, transactionId, requestId, currency, amount, sender);
189
153
  } else {
190
154
  EntitlementChecker_InvalidCheckType.selector.revertWith();
191
155
  }
192
156
  }
193
157
 
194
- // =============================================================
195
- // Internal
196
- // =============================================================
158
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
159
+ /* GETTERS */
160
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
161
+
162
+ /// @inheritdoc IEntitlementChecker
163
+ function isValidNode(address node) external view returns (bool) {
164
+ return EntitlementCheckerStorage.layout().nodes.contains(node);
165
+ }
166
+
167
+ /// @inheritdoc IEntitlementChecker
168
+ function getNodeCount() external view returns (uint256) {
169
+ return EntitlementCheckerStorage.layout().nodes.length();
170
+ }
171
+
172
+ /// @inheritdoc IEntitlementChecker
173
+ function getNodeAtIndex(uint256 index) external view returns (address) {
174
+ EntitlementCheckerStorage.Layout storage $ = EntitlementCheckerStorage.layout();
175
+
176
+ require(index < $.nodes.length(), "Index out of bounds");
177
+ return $.nodes.at(index);
178
+ }
179
+
180
+ /// @inheritdoc IEntitlementChecker
181
+ function getRandomNodes(uint256 count) external view returns (address[] memory) {
182
+ return _getRandomNodes(count);
183
+ }
184
+
185
+ /// @inheritdoc IEntitlementChecker
186
+ function getNodesByOperator(address operator) external view returns (address[] memory nodes) {
187
+ EntitlementCheckerStorage.Layout storage $ = EntitlementCheckerStorage.layout();
188
+ address[] memory allNodes = $.nodes.values();
189
+ uint256 totalNodeCount = allNodes.length;
190
+ nodes = new address[](totalNodeCount);
191
+ uint256 nodeCount;
192
+ for (uint256 i; i < totalNodeCount; ++i) {
193
+ address node = allNodes[i];
194
+ if ($.operatorByNode[node] == operator) {
195
+ unchecked {
196
+ nodes[nodeCount++] = node;
197
+ }
198
+ }
199
+ }
200
+ assembly ("memory-safe") {
201
+ mstore(nodes, nodeCount)
202
+ }
203
+ }
204
+
205
+ /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
206
+ /* INTERNAL */
207
+ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
197
208
 
198
209
  function _requestEntitlementCheck(
199
- address walletAddress,
210
+ address receiver,
200
211
  bytes32 transactionId,
201
212
  uint256 requestId,
202
213
  address currency,
203
214
  uint256 amount,
204
- address senderAddress
215
+ address sender
205
216
  ) internal {
206
217
  address space = msg.sender;
207
218
 
208
219
  XChainLib.Layout storage layout = XChainLib.layout();
209
220
 
210
- layout.requestsBySender[senderAddress].add(transactionId);
221
+ layout.requestsBySender[sender].add(transactionId);
211
222
 
212
223
  // Only create the request if it doesn't exist yet
213
224
  XChainLib.Request storage request = layout.requests[transactionId];
@@ -215,7 +226,7 @@ contract EntitlementChecker is IEntitlementChecker, Facet {
215
226
  request.caller = space;
216
227
  request.blockNumber = block.number;
217
228
  request.value = amount;
218
- request.receiver = walletAddress;
229
+ request.receiver = receiver;
219
230
  request.currency = currency;
220
231
 
221
232
  if (currency == CurrencyTransfer.NATIVE_TOKEN) {
@@ -252,7 +263,7 @@ contract EntitlementChecker is IEntitlementChecker, Facet {
252
263
  }
253
264
 
254
265
  emit EntitlementCheckRequestedV2(
255
- walletAddress,
266
+ receiver,
256
267
  space,
257
268
  address(this),
258
269
  transactionId,
@@ -261,36 +272,12 @@ contract EntitlementChecker is IEntitlementChecker, Facet {
261
272
  );
262
273
  }
263
274
 
264
- /// @inheritdoc IEntitlementChecker
265
- function getNodesByOperator(address operator) external view returns (address[] memory nodes) {
266
- EntitlementCheckerStorage.Layout storage layout = EntitlementCheckerStorage.layout();
267
- uint256 totalNodeCount = layout.nodes.length();
268
- nodes = new address[](totalNodeCount);
269
- uint256 nodeCount;
270
- for (uint256 i; i < totalNodeCount; ++i) {
271
- address node = layout.nodes.at(i);
272
- if (layout.operatorByNode[node] == operator) {
273
- unchecked {
274
- nodes[nodeCount++] = node;
275
- }
276
- }
277
- }
278
- assembly ("memory-safe") {
279
- mstore(nodes, nodeCount) // Update the length of the array
280
- }
281
- }
282
-
283
- // =============================================================
284
- // Internal
285
- // =============================================================
286
275
  function _getRandomNodes(uint256 count) internal view returns (address[] memory randomNodes) {
287
- EntitlementCheckerStorage.Layout storage layout = EntitlementCheckerStorage.layout();
276
+ EntitlementCheckerStorage.Layout storage $ = EntitlementCheckerStorage.layout();
288
277
 
289
- uint256 nodeCount = layout.nodes.length();
278
+ uint256 nodeCount = $.nodes.length();
290
279
 
291
- if (count > nodeCount) {
292
- EntitlementChecker_InsufficientNumberOfNodes.selector.revertWith();
293
- }
280
+ if (count > nodeCount) EntitlementChecker_InsufficientNumberOfNodes.selector.revertWith();
294
281
 
295
282
  randomNodes = new address[](count);
296
283
  uint256[] memory indices = new uint256[](nodeCount);
@@ -303,7 +290,7 @@ contract EntitlementChecker is IEntitlementChecker, Facet {
303
290
  for (uint256 i; i < count; ++i) {
304
291
  // Adjust random function to generate within range 0 to n-1
305
292
  uint256 rand = _pseudoRandom(i, nodeCount);
306
- randomNodes[i] = layout.nodes.at(indices[rand]);
293
+ randomNodes[i] = $.nodes.at(indices[rand]);
307
294
  // Move the last element to the used slot and reduce the pool size
308
295
  indices[rand] = indices[--nodeCount];
309
296
  }
@@ -6,12 +6,12 @@ interface IEntitlementCheckerBase {
6
6
  /// @dev To encode data for each type:
7
7
  /// switch (checkType) {
8
8
  /// case CheckType.V1:
9
- /// data = abi.encode(walletAddress, transactionId, roleId, nodes);
9
+ /// data = abi.encode(receiver, transactionId, roleId, nodes);
10
10
  /// case CheckType.V2:
11
- /// data = abi.encode(walletAddress, transactionId, requestId, extraData);
12
- /// // where extraData = abi.encode(senderAddress)
11
+ /// data = abi.encode(receiver, transactionId, requestId, extraData);
12
+ /// // where extraData = abi.encode(sender)
13
13
  /// case CheckType.V3:
14
- /// data = abi.encode(walletAddress, transactionId, requestId, currency, amount, senderAddress);
14
+ /// data = abi.encode(receiver, transactionId, requestId, currency, amount, sender);
15
15
  /// }
16
16
  enum CheckType {
17
17
  V1, // Legacy check with explicit nodes
@@ -38,17 +38,17 @@ interface IEntitlementCheckerBase {
38
38
 
39
39
  /// @notice Event emitted when an entitlement check is requested
40
40
  event EntitlementCheckRequested(
41
- address callerAddress,
42
- address contractAddress,
41
+ address receiver,
42
+ address space,
43
43
  bytes32 transactionId,
44
44
  uint256 roleId,
45
45
  address[] selectedNodes
46
46
  );
47
47
 
48
48
  event EntitlementCheckRequestedV2(
49
- address walletAddress,
50
- address spaceAddress,
51
- address resolverAddress,
49
+ address receiver,
50
+ address space,
51
+ address resolver,
52
52
  bytes32 transactionId,
53
53
  uint256 roleId,
54
54
  address[] selectedNodes
@@ -64,44 +64,25 @@ interface IEntitlementChecker is IEntitlementCheckerBase {
64
64
  /// @param node The address of the node to unregister
65
65
  function unregisterNode(address node) external;
66
66
 
67
- /// @notice Check if a node address is registered and valid
68
- /// @param node The address of the node to check
69
- /// @return bool True if the node is valid, false otherwise
70
- function isValidNode(address node) external view returns (bool);
71
-
72
- /// @notice Get the total number of registered nodes
73
- /// @return uint256 The count of registered nodes
74
- function getNodeCount() external view returns (uint256);
75
-
76
- /// @notice Get the node address at a specific index
77
- /// @param index The index of the node to retrieve
78
- /// @return address The address of the node at the given index
79
- function getNodeAtIndex(uint256 index) external view returns (address);
80
-
81
- /// @notice Get a random selection of registered nodes
82
- /// @param count The number of random nodes to return
83
- /// @return address[] Array of randomly selected node addresses
84
- function getRandomNodes(uint256 count) external view returns (address[] memory);
85
-
86
67
  /// @notice Request an entitlement check for a transaction
87
- /// @param callerAddress The address initiating the check
68
+ /// @param receiver The address to check entitlements for (membership recipient)
88
69
  /// @param transactionId The unique identifier of the transaction
89
70
  /// @param roleId The role ID to check entitlements against
90
71
  /// @param nodes Array of node addresses that will perform the check
91
72
  function requestEntitlementCheck(
92
- address callerAddress,
73
+ address receiver,
93
74
  bytes32 transactionId,
94
75
  uint256 roleId,
95
76
  address[] memory nodes
96
77
  ) external;
97
78
 
98
79
  /// @notice Request an entitlement check with additional data (V2)
99
- /// @param walletAddress The wallet address to check entitlements for
80
+ /// @param receiver The address to check entitlements for (membership recipient)
100
81
  /// @param transactionId The unique identifier of the transaction
101
82
  /// @param requestId The unique identifier for this specific request
102
83
  /// @param extraData Additional data required for the check
103
84
  function requestEntitlementCheckV2(
104
- address walletAddress,
85
+ address receiver,
105
86
  bytes32 transactionId,
106
87
  uint256 requestId,
107
88
  bytes memory extraData
@@ -112,6 +93,25 @@ interface IEntitlementChecker is IEntitlementCheckerBase {
112
93
  /// @param data Encoded parameters specific to the check type (see CheckType enum docs)
113
94
  function requestEntitlementCheck(CheckType checkType, bytes calldata data) external payable;
114
95
 
96
+ /// @notice Check if a node address is registered and valid
97
+ /// @param node The address of the node to check
98
+ /// @return bool True if the node is valid, false otherwise
99
+ function isValidNode(address node) external view returns (bool);
100
+
101
+ /// @notice Get the total number of registered nodes
102
+ /// @return uint256 The count of registered nodes
103
+ function getNodeCount() external view returns (uint256);
104
+
105
+ /// @notice Get the node address at a specific index
106
+ /// @param index The index of the node to retrieve
107
+ /// @return address The address of the node at the given index
108
+ function getNodeAtIndex(uint256 index) external view returns (address);
109
+
110
+ /// @notice Get a random selection of registered nodes
111
+ /// @param count The number of random nodes to return
112
+ /// @return address[] Array of randomly selected node addresses
113
+ function getRandomNodes(uint256 count) external view returns (address[] memory);
114
+
115
115
  /// @notice Get all nodes registered to a specific operator
116
116
  /// @param operator The address of the operator
117
117
  /// @return address[] Array of node addresses registered to the operator