@@ -3,15 +3,17 @@ pragma solidity ^0.8.19;
3
3
4
4
import {IOracle} from '../interfaces/IOracle.sol ' ;
5
5
6
+ import {IAccessModule} from '../interfaces/modules/access/IAccessModule.sol ' ;
6
7
import {IDisputeModule} from '../interfaces/modules/dispute/IDisputeModule.sol ' ;
7
-
8
8
import {IFinalityModule} from '../interfaces/modules/finality/IFinalityModule.sol ' ;
9
9
import {IRequestModule} from '../interfaces/modules/request/IRequestModule.sol ' ;
10
10
import {IResolutionModule} from '../interfaces/modules/resolution/IResolutionModule.sol ' ;
11
11
import {IResponseModule} from '../interfaces/modules/response/IResponseModule.sol ' ;
12
12
import {ValidatorLib} from '../libraries/ValidatorLib.sol ' ;
13
+ import {OracleAccessController} from './OracleAccessController.sol ' ;
14
+ import {OracleTypehash} from './utils/OracleTypehash.sol ' ;
13
15
14
- contract Oracle is IOracle {
16
+ contract Oracle is IOracle , OracleAccessController , OracleTypehash {
15
17
using ValidatorLib for * ;
16
18
17
19
/// @inheritdoc IOracle
@@ -44,31 +46,26 @@ contract Oracle is IOracle {
44
46
/// @inheritdoc IOracle
45
47
mapping (bytes32 _requestId = > mapping (address _user = > bool _isParticipant )) public isParticipant;
46
48
49
+ /// @inheritdoc IOracle
50
+ uint256 public totalRequestCount;
51
+
47
52
/**
48
53
* @notice The list of the response ids for each request
49
54
*/
50
55
mapping (bytes32 _requestId = > bytes _responseIds ) internal _responseIds;
51
56
52
57
/// @inheritdoc IOracle
53
- uint256 public totalRequestCount;
54
-
55
- /// @inheritdoc IOracle
56
- function createRequest (Request calldata _request , bytes32 _ipfsHash ) external returns (bytes32 _requestId ) {
57
- _requestId = _createRequest (_request, _ipfsHash);
58
- }
58
+ function getResponseIds (bytes32 _requestId ) public view returns (bytes32 [] memory _ids ) {
59
+ bytes memory _responses = _responseIds[_requestId];
60
+ uint256 _length = _responses.length / 32 ;
59
61
60
- /// @inheritdoc IOracle
61
- function createRequests (
62
- Request[] calldata _requestsData ,
63
- bytes32 [] calldata _ipfsHashes
64
- ) external returns (bytes32 [] memory _batchRequestsIds ) {
65
- uint256 _requestsAmount = _requestsData.length ;
66
- _batchRequestsIds = new bytes32 [](_requestsAmount);
62
+ assembly {
63
+ for { let _i := 0 } lt (_i, _length) { _i := add (_i, 1 ) } {
64
+ // Increase the size of the array
65
+ mstore (_ids, add (mload (_ids), 1 ))
67
66
68
- for (uint256 _i = 0 ; _i < _requestsAmount;) {
69
- _batchRequestsIds[_i] = _createRequest (_requestsData[_i], _ipfsHashes[_i]);
70
- unchecked {
71
- ++ _i;
67
+ // Store the response id in the array
68
+ mstore (add (_ids, add (32 , mul (_i, 32 ))), mload (add (_responses, add (32 , mul (_i, 32 )))))
72
69
}
73
70
}
74
71
}
@@ -98,11 +95,42 @@ contract Oracle is IOracle {
98
95
}
99
96
}
100
97
98
+ /// @inheritdoc IOracle
99
+ function createRequest (
100
+ Request calldata _request ,
101
+ bytes32 _ipfsHash ,
102
+ AccessControl calldata _accessControl
103
+ ) external returns (bytes32 _requestId ) {
104
+ _requestId = _createRequest (_request, _ipfsHash, _accessControl);
105
+ }
106
+
107
+ /// @inheritdoc IOracle
108
+ function createRequests (
109
+ Request[] calldata _requestsData ,
110
+ bytes32 [] calldata _ipfsHashes ,
111
+ AccessControl[] calldata _accessControl
112
+ ) external returns (bytes32 [] memory _batchRequestsIds ) {
113
+ uint256 _requestsAmount = _requestsData.length ;
114
+ _batchRequestsIds = new bytes32 [](_requestsAmount);
115
+
116
+ for (uint256 _i; _i < _requestsAmount;) {
117
+ _batchRequestsIds[_i] = _createRequest (_requestsData[_i], _ipfsHashes[_i], _accessControl[_i]);
118
+ unchecked {
119
+ ++ _i;
120
+ }
121
+ }
122
+ }
123
+
101
124
/// @inheritdoc IOracle
102
125
function proposeResponse (
103
126
Request calldata _request ,
104
- Response calldata _response
105
- ) external returns (bytes32 _responseId ) {
127
+ Response calldata _response ,
128
+ AccessControl calldata _accessControl
129
+ )
130
+ external
131
+ hasAccess (_request.accessModule, PROPOSE_TYPEHASH, abi.encode (_request, _response), _accessControl)
132
+ returns (bytes32 _responseId )
133
+ {
106
134
_responseId = ValidatorLib._validateResponse (_request, _response);
107
135
108
136
bytes32 _requestId = _response.requestId;
@@ -111,8 +139,8 @@ contract Oracle is IOracle {
111
139
revert Oracle_InvalidRequest ();
112
140
}
113
141
114
- // The caller must be the proposer, unless the response is coming from a dispute module
115
- if (msg . sender != _response.proposer && msg . sender != address ( _request.disputeModule) ) {
142
+ // The user must be the proposer unless response comes from the dispute module
143
+ if (_accessControl.user != _response.proposer && _accessControl.user != _request.disputeModule) {
116
144
revert Oracle_InvalidProposer ();
117
145
}
118
146
@@ -125,7 +153,7 @@ contract Oracle is IOracle {
125
153
revert Oracle_AlreadyFinalized (_requestId);
126
154
}
127
155
isParticipant[_requestId][_response.proposer] = true ;
128
- IResponseModule (_request.responseModule).propose (_request, _response, msg . sender );
156
+ IResponseModule (_request.responseModule).propose (_request, _response, _accessControl.user );
129
157
_responseIds[_requestId] = abi.encodePacked (_responseIds[_requestId], _responseId);
130
158
responseCreatedAt[_responseId] = block .timestamp ;
131
159
@@ -136,8 +164,13 @@ contract Oracle is IOracle {
136
164
function disputeResponse (
137
165
Request calldata _request ,
138
166
Response calldata _response ,
139
- Dispute calldata _dispute
140
- ) external returns (bytes32 _disputeId ) {
167
+ Dispute calldata _dispute ,
168
+ AccessControl calldata _accessControl
169
+ )
170
+ external
171
+ hasAccess (_request.accessModule, DISPUTE_TYPEHASH, abi.encode (_request, _response, _dispute), _accessControl)
172
+ returns (bytes32 _disputeId )
173
+ {
141
174
bytes32 _responseId;
142
175
(_responseId, _disputeId) = ValidatorLib._validateResponseAndDispute (_request, _response, _dispute);
143
176
@@ -151,7 +184,7 @@ contract Oracle is IOracle {
151
184
revert Oracle_InvalidProposer ();
152
185
}
153
186
154
- if (_dispute.disputer != msg . sender ) {
187
+ if (_dispute.disputer != _accessControl.user ) {
155
188
revert Oracle_InvalidDisputer ();
156
189
}
157
190
@@ -162,7 +195,7 @@ contract Oracle is IOracle {
162
195
if (disputeOf[_responseId] != bytes32 (0 )) {
163
196
revert Oracle_ResponseAlreadyDisputed (_responseId);
164
197
}
165
- isParticipant[_requestId][msg . sender ] = true ;
198
+ isParticipant[_requestId][_accessControl.user ] = true ;
166
199
disputeStatus[_disputeId] = DisputeStatus.Active;
167
200
disputeOf[_responseId] = _disputeId;
168
201
disputeCreatedAt[_disputeId] = block .timestamp ;
@@ -173,7 +206,15 @@ contract Oracle is IOracle {
173
206
}
174
207
175
208
/// @inheritdoc IOracle
176
- function escalateDispute (Request calldata _request , Response calldata _response , Dispute calldata _dispute ) external {
209
+ function escalateDispute (
210
+ Request calldata _request ,
211
+ Response calldata _response ,
212
+ Dispute calldata _dispute ,
213
+ AccessControl calldata _accessControl
214
+ )
215
+ external
216
+ hasAccess (_request.accessModule, ESCALATE_TYPEHASH, abi.encode (_request, _response, _dispute), _accessControl)
217
+ {
177
218
(bytes32 _responseId , bytes32 _disputeId ) = ValidatorLib._validateResponseAndDispute (_request, _response, _dispute);
178
219
179
220
if (disputeCreatedAt[_disputeId] == 0 ) {
@@ -194,16 +235,24 @@ contract Oracle is IOracle {
194
235
// Notify the dispute module about the escalation
195
236
IDisputeModule (_request.disputeModule).onDisputeStatusChange (_disputeId, _request, _response, _dispute);
196
237
197
- emit DisputeEscalated (msg . sender , _disputeId, _dispute);
238
+ emit DisputeEscalated (_accessControl.user , _disputeId, _dispute);
198
239
199
- if (address ( _request.resolutionModule) != address (0 )) {
240
+ if (_request.resolutionModule != address (0 )) {
200
241
// Initiate the resolution
201
242
IResolutionModule (_request.resolutionModule).startResolution (_disputeId, _request, _response, _dispute);
202
243
}
203
244
}
204
245
205
246
/// @inheritdoc IOracle
206
- function resolveDispute (Request calldata _request , Response calldata _response , Dispute calldata _dispute ) external {
247
+ function resolveDispute (
248
+ Request calldata _request ,
249
+ Response calldata _response ,
250
+ Dispute calldata _dispute ,
251
+ AccessControl calldata _accessControl
252
+ )
253
+ external
254
+ hasAccess (_request.accessModule, RESOLVE_TYPEHASH, abi.encode (_request, _response, _dispute), _accessControl)
255
+ {
207
256
(bytes32 _responseId , bytes32 _disputeId ) = ValidatorLib._validateResponseAndDispute (_request, _response, _dispute);
208
257
209
258
if (disputeCreatedAt[_disputeId] == 0 ) {
@@ -220,13 +269,13 @@ contract Oracle is IOracle {
220
269
revert Oracle_CannotResolve (_disputeId);
221
270
}
222
271
223
- if (address ( _request.resolutionModule) == address (0 )) {
272
+ if (_request.resolutionModule == address (0 )) {
224
273
revert Oracle_NoResolutionModule (_disputeId);
225
274
}
226
275
227
276
IResolutionModule (_request.resolutionModule).resolveDispute (_disputeId, _request, _response, _dispute);
228
277
229
- emit DisputeResolved (_disputeId, _dispute, msg . sender );
278
+ emit DisputeResolved (_disputeId, _dispute);
230
279
}
231
280
232
281
/// @inheritdoc IOracle
@@ -246,7 +295,7 @@ contract Oracle is IOracle {
246
295
revert Oracle_InvalidDisputeId (_disputeId);
247
296
}
248
297
249
- if (msg .sender != address ( _request.disputeModule) && msg .sender != address ( _request.resolutionModule) ) {
298
+ if (msg .sender != _request.disputeModule && msg .sender != _request.resolutionModule) {
250
299
revert Oracle_NotDisputeOrResolutionModule (msg .sender );
251
300
}
252
301
disputeStatus[_disputeId] = _status;
@@ -256,23 +305,11 @@ contract Oracle is IOracle {
256
305
}
257
306
258
307
/// @inheritdoc IOracle
259
- function getResponseIds (bytes32 _requestId ) public view returns (bytes32 [] memory _ids ) {
260
- bytes memory _responses = _responseIds[_requestId];
261
- uint256 _length = _responses.length / 32 ;
262
-
263
- assembly {
264
- for { let _i := 0 } lt (_i, _length) { _i := add (_i, 1 ) } {
265
- // Increase the size of the array
266
- mstore (_ids, add (mload (_ids), 1 ))
267
-
268
- // Store the response id in the array
269
- mstore (add (_ids, add (32 , mul (_i, 32 ))), mload (add (_responses, add (32 , mul (_i, 32 )))))
270
- }
271
- }
272
- }
273
-
274
- /// @inheritdoc IOracle
275
- function finalize (IOracle.Request calldata _request , IOracle.Response calldata _response ) external {
308
+ function finalize (
309
+ IOracle.Request calldata _request ,
310
+ IOracle.Response calldata _response ,
311
+ AccessControl calldata _accessControl
312
+ ) external hasAccess (_request.accessModule, FINALIZE_TYPEHASH, abi.encode (_request, _response), _accessControl) {
276
313
bytes32 _requestId;
277
314
bytes32 _responseId;
278
315
@@ -289,19 +326,23 @@ contract Oracle is IOracle {
289
326
290
327
finalizedAt[_requestId] = block .timestamp ;
291
328
292
- if (address ( _request.finalityModule) != address (0 )) {
293
- IFinalityModule (_request.finalityModule).finalizeRequest (_request, _response, msg . sender );
329
+ if (_request.finalityModule != address (0 )) {
330
+ IFinalityModule (_request.finalityModule).finalizeRequest (_request, _response, _accessControl.user );
294
331
}
295
332
296
- if (address ( _request.resolutionModule) != address (0 )) {
297
- IResolutionModule (_request.resolutionModule).finalizeRequest (_request, _response, msg . sender );
333
+ if (_request.resolutionModule != address (0 )) {
334
+ IResolutionModule (_request.resolutionModule).finalizeRequest (_request, _response, _accessControl.user );
298
335
}
299
336
300
- IDisputeModule (_request.disputeModule).finalizeRequest (_request, _response, msg .sender );
301
- IResponseModule (_request.responseModule).finalizeRequest (_request, _response, msg .sender );
302
- IRequestModule (_request.requestModule).finalizeRequest (_request, _response, msg .sender );
337
+ IDisputeModule (_request.disputeModule).finalizeRequest (_request, _response, _accessControl.user);
338
+ IResponseModule (_request.responseModule).finalizeRequest (_request, _response, _accessControl.user);
339
+ IRequestModule (_request.requestModule).finalizeRequest (_request, _response, _accessControl.user);
340
+
341
+ if (_request.accessModule != address (0 )) {
342
+ IAccessModule (_request.accessModule).finalizeRequest (_request, _response, _accessControl.user);
343
+ }
303
344
304
- emit OracleRequestFinalized (_requestId, _responseId, msg . sender );
345
+ emit OracleRequestFinalized (_requestId, _responseId);
305
346
}
306
347
307
348
/**
@@ -372,14 +413,23 @@ contract Oracle is IOracle {
372
413
*
373
414
* @param _request The request to be created
374
415
* @param _ipfsHash The hashed IPFS CID of the metadata json
416
+ * @param _accessControl The access control struct
375
417
* @return _requestId The id of the created request
376
418
*/
377
- function _createRequest (Request memory _request , bytes32 _ipfsHash ) internal returns (bytes32 _requestId ) {
419
+ function _createRequest (
420
+ Request memory _request ,
421
+ bytes32 _ipfsHash ,
422
+ AccessControl calldata _accessControl
423
+ )
424
+ internal
425
+ hasAccess (_request.accessModule, CREATE_TYPEHASH, abi.encode (_request), _accessControl)
426
+ returns (bytes32 _requestId )
427
+ {
378
428
uint256 _requestNonce = totalRequestCount++ ;
379
429
380
430
if (_request.nonce == 0 ) _request.nonce = uint96 (_requestNonce);
381
431
382
- if (msg . sender != _request.requester || _requestNonce != _request.nonce) {
432
+ if (_accessControl.user != _request.requester || _requestNonce != _request.nonce) {
383
433
revert Oracle_InvalidRequestBody ();
384
434
}
385
435
@@ -393,9 +443,9 @@ contract Oracle is IOracle {
393
443
allowedModule[_requestId][_request.resolutionModule] = true ;
394
444
allowedModule[_requestId][_request.finalityModule] = true ;
395
445
396
- isParticipant[_requestId][msg . sender ] = true ;
446
+ isParticipant[_requestId][_accessControl.user ] = true ;
397
447
398
- IRequestModule (_request.requestModule).createRequest (_requestId, _request.requestModuleData, msg . sender );
448
+ IRequestModule (_request.requestModule).createRequest (_requestId, _request.requestModuleData, _accessControl.user );
399
449
400
450
emit RequestCreated (_requestId, _request, _ipfsHash);
401
451
}
0 commit comments