@rootzero/contracts 0.7.2 → 0.9.0
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/Commands.sol +15 -20
- package/Core.sol +3 -4
- package/Cursors.sol +3 -2
- package/Events.sol +1 -1
- package/Queries.sol +3 -3
- package/README.md +18 -19
- package/Utils.sol +3 -3
- package/blocks/Cursors.sol +937 -551
- package/blocks/Keys.sol +60 -34
- package/blocks/Schema.sol +112 -122
- package/blocks/Writers.sol +476 -301
- package/commands/Base.sol +32 -22
- package/commands/Burn.sol +14 -12
- package/commands/Credit.sol +16 -15
- package/commands/Debit.sol +14 -12
- package/commands/Deposit.sol +30 -37
- package/commands/Pipe.sol +14 -20
- package/commands/Provision.sol +19 -49
- package/commands/Transfer.sol +9 -18
- package/commands/Withdraw.sol +15 -14
- package/commands/admin/AllowAssets.sol +3 -3
- package/commands/admin/Allowance.sol +43 -0
- package/commands/admin/Authorize.sol +4 -4
- package/commands/admin/DenyAssets.sol +3 -3
- package/commands/admin/Destroy.sol +10 -8
- package/commands/admin/Execute.sol +38 -0
- package/commands/admin/Init.sol +10 -8
- package/commands/admin/Relocate.sol +5 -5
- package/commands/admin/Unauthorize.sol +4 -4
- package/core/Access.sol +38 -34
- package/core/Balances.sol +17 -18
- package/core/{Operation.sol → Calls.sol} +5 -8
- package/core/{CursorBase.sol → Context.sol} +11 -5
- package/core/Host.sol +11 -10
- package/core/Types.sol +86 -0
- package/docs/GETTING_STARTED.md +37 -29
- package/events/Asset.sol +1 -1
- package/events/Command.sol +10 -10
- package/events/Deposit.sol +3 -4
- package/events/Listing.sol +1 -1
- package/events/Peer.sol +3 -3
- package/events/Position.sol +21 -0
- package/events/Query.sol +3 -3
- package/events/Withdraw.sol +2 -3
- package/package.json +1 -1
- package/peer/AllowAssets.sol +1 -1
- package/peer/Allowance.sol +36 -0
- package/peer/AssetPull.sol +33 -31
- package/peer/Base.sol +8 -4
- package/peer/DenyAssets.sol +1 -1
- package/peer/Settle.sol +3 -4
- package/queries/Assets.sol +18 -16
- package/queries/Balances.sol +21 -19
- package/queries/Base.sol +2 -3
- package/queries/Positions.sol +32 -24
- package/utils/Accounts.sol +14 -13
- package/utils/Assets.sol +137 -62
- package/utils/Ids.sol +9 -9
- package/utils/Layout.sol +5 -3
- package/utils/Utils.sol +10 -0
- package/commands/Create.sol +0 -42
- package/commands/Remove.sol +0 -42
- package/commands/Settle.sol +0 -38
- package/commands/Stake.sol +0 -47
- package/commands/Supply.sol +0 -41
- package/commands/admin/Allocate.sol +0 -41
- package/core/HostBound.sol +0 -14
- package/events/Erc721.sol +0 -20
- package/peer/Pull.sol +0 -39
- package/peer/Push.sol +0 -45
- package/utils/State.sol +0 -22
package/blocks/Cursors.sol
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {AssetAmount, AccountAsset, AccountAmount, HostAmount, HostAccountAsset, Tx} from "../core/Types.sol";
|
|
5
|
+
import {Sizes} from "./Schema.sol";
|
|
6
|
+
import {Keys} from "./Keys.sol";
|
|
5
7
|
import {ALLOC_SCALE, Writer, Writers} from "./Writers.sol";
|
|
6
8
|
|
|
7
9
|
/// @notice Zero-copy view into a calldata block stream.
|
|
@@ -31,20 +33,22 @@ library Cursors {
|
|
|
31
33
|
error MalformedBlocks();
|
|
32
34
|
/// @dev Current block key does not match the expected key, or payload size is out of range.
|
|
33
35
|
error InvalidBlock();
|
|
34
|
-
/// @dev `primeRun` found zero blocks of the expected key; the cursor region is empty.
|
|
35
|
-
error ZeroCursor();
|
|
36
36
|
/// @dev `complete` called but the cursor has not consumed exactly up to `bound`.
|
|
37
37
|
error IncompleteCursor();
|
|
38
|
+
/// @dev `primeRun` found zero blocks of the expected key; the cursor region is empty.
|
|
39
|
+
error ZeroCursor();
|
|
38
40
|
/// @dev `primeRun` was called with a zero group size.
|
|
39
41
|
error ZeroGroup();
|
|
40
|
-
/// @dev
|
|
41
|
-
error
|
|
42
|
+
/// @dev An account field was required but the block or fallback was zero.
|
|
43
|
+
error ZeroAccount();
|
|
42
44
|
/// @dev A node field was required but the block or fallback was zero.
|
|
43
45
|
error ZeroNode();
|
|
44
46
|
/// @dev A field value did not match the expected value.
|
|
45
47
|
error UnexpectedValue();
|
|
46
48
|
/// @dev Input and output block counts are not proportional to their declared group sizes.
|
|
47
49
|
error BadRatio();
|
|
50
|
+
/// @dev A fixed-width low-level unpacker received an invalid final-word keep length.
|
|
51
|
+
error InvalidKeep();
|
|
48
52
|
|
|
49
53
|
// -------------------------------------------------------------------------
|
|
50
54
|
// Cursor construction and navigation
|
|
@@ -74,6 +78,18 @@ library Cursors {
|
|
|
74
78
|
return cur;
|
|
75
79
|
}
|
|
76
80
|
|
|
81
|
+
/// @notice Create a subcursor over the half-open range `[from, to)` within the source region.
|
|
82
|
+
/// The returned cursor starts at position zero within that sliced region.
|
|
83
|
+
/// @param cur Source cursor.
|
|
84
|
+
/// @param from Start byte offset within the source region (inclusive).
|
|
85
|
+
/// @param to End byte offset within the source region (exclusive).
|
|
86
|
+
/// @return out Cursor scoped to the requested sub-range.
|
|
87
|
+
function slice(Cur memory cur, uint from, uint to) internal pure returns (Cur memory out) {
|
|
88
|
+
if (from > to || to > cur.len) revert MalformedBlocks();
|
|
89
|
+
out.offset = cur.offset + from;
|
|
90
|
+
out.len = to - from;
|
|
91
|
+
}
|
|
92
|
+
|
|
77
93
|
/// @notice Read a block header at position `i` without advancing the cursor.
|
|
78
94
|
/// @param cur Source cursor.
|
|
79
95
|
/// @param i Byte offset of the block header within the source region.
|
|
@@ -87,6 +103,26 @@ library Cursors {
|
|
|
87
103
|
if (i + 8 + len > cur.len) revert MalformedBlocks();
|
|
88
104
|
}
|
|
89
105
|
|
|
106
|
+
/// @notice Return the byte offset immediately past the block at the current cursor position.
|
|
107
|
+
/// Does not advance the cursor.
|
|
108
|
+
/// @param cur Source cursor.
|
|
109
|
+
/// @return Byte offset immediately past the current block, relative to the source region.
|
|
110
|
+
function past(Cur memory cur) internal pure returns (uint) {
|
|
111
|
+
(, uint len) = peek(cur, cur.i);
|
|
112
|
+
return cur.i + Sizes.Header + len;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/// @notice Return true if the current cursor position contains a block header with the given key.
|
|
116
|
+
/// Returns false when `cur.i` is out of bounds or the key differs.
|
|
117
|
+
/// @param cur Source cursor.
|
|
118
|
+
/// @param key Expected block type identifier.
|
|
119
|
+
/// @return Whether the block header at `cur.i` uses `key`.
|
|
120
|
+
function has(Cur memory cur, bytes4 key) internal pure returns (bool) {
|
|
121
|
+
if (cur.i + 8 > cur.len) return false;
|
|
122
|
+
uint abs = cur.offset + cur.i;
|
|
123
|
+
return bytes4(msg.data[abs:abs + 4]) == key;
|
|
124
|
+
}
|
|
125
|
+
|
|
90
126
|
/// @notice Validate a block at position `i` and return its payload location.
|
|
91
127
|
/// Does not advance the cursor.
|
|
92
128
|
/// @param cur Source cursor.
|
|
@@ -141,7 +177,7 @@ library Cursors {
|
|
|
141
177
|
/// @return quotient Number of groups represented by the run (`count / group`).
|
|
142
178
|
function primeRun(Cur memory cur, uint group) internal pure returns (bytes4 key, uint count, uint quotient) {
|
|
143
179
|
if (group == 0) revert ZeroGroup();
|
|
144
|
-
key = cur.
|
|
180
|
+
key = cur.i + 4 > cur.len ? bytes4(0) : bytes4(msg.data[cur.offset + cur.i:cur.offset + cur.i + 4]);
|
|
145
181
|
(count, cur.bound) = countRun(cur, cur.i, key);
|
|
146
182
|
if (count == 0) revert ZeroCursor();
|
|
147
183
|
if (count % group != 0) revert BadRatio();
|
|
@@ -182,18 +218,71 @@ library Cursors {
|
|
|
182
218
|
cur.i = next;
|
|
183
219
|
}
|
|
184
220
|
|
|
185
|
-
/// @notice
|
|
186
|
-
///
|
|
187
|
-
/// @param
|
|
188
|
-
/// @return
|
|
189
|
-
function
|
|
190
|
-
(
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
221
|
+
/// @notice Load a payload word and mask away any omitted tail bytes on the right.
|
|
222
|
+
/// @param abs Absolute calldata offset of the word start.
|
|
223
|
+
/// @param tail Number of trailing bytes omitted from the logical payload (0..31).
|
|
224
|
+
/// @return value Decoded word with omitted tail bytes zeroed.
|
|
225
|
+
function mask(uint abs, uint tail) internal pure returns (bytes32 value) {
|
|
226
|
+
assembly ("memory-safe") {
|
|
227
|
+
value := calldataload(abs)
|
|
228
|
+
}
|
|
229
|
+
if (tail != 0) value &= bytes32(type(uint256).max << (tail * 8));
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/// @notice Enter a Bundle block at the current position and return the next offset.
|
|
233
|
+
/// Advances `cur.i` past the bundle header so the bundled members can be parsed
|
|
234
|
+
/// directly from the same cursor. The returned `next` is the byte offset
|
|
235
|
+
/// immediately after the bundle payload, relative to the current cursor region.
|
|
236
|
+
/// @param cur Cursor positioned at a bundle block; advanced past the 8-byte header.
|
|
237
|
+
/// @return next Byte offset immediately after the bundle payload.
|
|
238
|
+
function bundle(Cur memory cur) internal pure returns (uint next) {
|
|
239
|
+
(, next) = expect(cur, cur.i, Keys.Bundle, 0, 0);
|
|
240
|
+
cur.i += 8;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/// @notice Enter a List block at the current position and return the next offset.
|
|
244
|
+
/// Advances `cur.i` past the list header so the list members can be parsed
|
|
245
|
+
/// directly from the same cursor. The returned `next` is the byte offset
|
|
246
|
+
/// immediately after the list payload, relative to the current cursor region.
|
|
247
|
+
/// @param cur Cursor positioned at a list block; advanced past the 8-byte header.
|
|
248
|
+
/// @return next Byte offset immediately after the list payload.
|
|
249
|
+
function list(Cur memory cur) internal pure returns (uint next) {
|
|
250
|
+
(, next) = expect(cur, cur.i, Keys.List, 0, 0);
|
|
251
|
+
cur.i += 8;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/// @notice Consume a block with the given key at the current position and return a cursor over the full block slice.
|
|
255
|
+
/// Advances `cur.i` past the block while the returned cursor is scoped to the
|
|
256
|
+
/// full block bytes as a fresh zero-based region.
|
|
257
|
+
/// @param cur Cursor positioned at the expected block.
|
|
258
|
+
/// @param key Expected block type key.
|
|
259
|
+
/// @return out Cursor scoped to the full block.
|
|
260
|
+
function take(Cur memory cur, bytes4 key) internal pure returns (Cur memory out) {
|
|
261
|
+
(, uint next) = expect(cur, cur.i, key, 0, 0);
|
|
262
|
+
out = cur.slice(cur.i, next);
|
|
194
263
|
cur.i = next;
|
|
195
264
|
}
|
|
196
265
|
|
|
266
|
+
/// @notice Consume an optional ROUTE block at the current position and return a cursor over the full block slice.
|
|
267
|
+
/// If the current block is not ROUTE, returns an empty cursor and leaves `cur.i` unchanged.
|
|
268
|
+
/// Otherwise behaves like `take(cur, Keys.Route)`.
|
|
269
|
+
/// @param cur Cursor positioned at an optional ROUTE block.
|
|
270
|
+
/// @return out Cursor scoped to the full ROUTE block, or empty when no ROUTE block is present.
|
|
271
|
+
function maybeRoute(Cur memory cur) internal pure returns (Cur memory out) {
|
|
272
|
+
return cur.has(Keys.Route) ? take(cur, Keys.Route) : cur.slice(cur.i, cur.i);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/// @notice Enter a List block, prime its member run, and return the raw block count.
|
|
276
|
+
/// @param cur Cursor positioned at a list block; advanced past the 8-byte header.
|
|
277
|
+
/// @param group Expected block group size for the list item stream.
|
|
278
|
+
/// @return count Total number of blocks in the list payload (a multiple of `group`).
|
|
279
|
+
/// @return next Byte offset immediately after the list payload.
|
|
280
|
+
function list(Cur memory cur, uint group) internal pure returns (uint count, uint next) {
|
|
281
|
+
next = list(cur);
|
|
282
|
+
(, count, ) = cur.primeRun(group);
|
|
283
|
+
if (cur.bound != next) revert IncompleteCursor();
|
|
284
|
+
}
|
|
285
|
+
|
|
197
286
|
/// @notice Assert that the cursor has consumed exactly up to `bound`.
|
|
198
287
|
/// Reverts with `IncompleteCursor` if `bound` is zero or `cur.i != cur.bound`.
|
|
199
288
|
/// @param cur Cursor to check.
|
|
@@ -201,6 +290,32 @@ library Cursors {
|
|
|
201
290
|
if (cur.bound == 0 || cur.i != cur.bound) revert IncompleteCursor();
|
|
202
291
|
}
|
|
203
292
|
|
|
293
|
+
/// @notice Assert that the cursor has consumed its entire source region.
|
|
294
|
+
/// Reverts with `IncompleteCursor` when `cur.i != cur.len`.
|
|
295
|
+
/// @param cur Cursor to check.
|
|
296
|
+
function end(Cur memory cur) internal pure {
|
|
297
|
+
if (cur.i != cur.len) revert IncompleteCursor();
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/// @notice Resume parsing after a nested region delimited by `resumeAt`.
|
|
301
|
+
/// Reverts with `IncompleteCursor` if `cur.i` has advanced past `resumeAt` or `resumeAt`
|
|
302
|
+
/// exceeds the cursor region length. Otherwise moves `cur.i` to `end`.
|
|
303
|
+
/// @param cur Cursor to advance.
|
|
304
|
+
/// @param resumeAt Relative end offset of the nested region to resume after.
|
|
305
|
+
function resume(Cur memory cur, uint resumeAt) internal pure {
|
|
306
|
+
if (resumeAt > cur.len || cur.i > resumeAt) revert IncompleteCursor();
|
|
307
|
+
cur.i = resumeAt;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/// @notice Ensure that parsing has reached an exact nested-region boundary.
|
|
311
|
+
/// Reverts with `IncompleteCursor` if `ensureAt` exceeds the cursor region length
|
|
312
|
+
/// or `cur.i != ensureAt`.
|
|
313
|
+
/// @param cur Cursor to check.
|
|
314
|
+
/// @param ensureAt Relative offset that `cur.i` must match exactly.
|
|
315
|
+
function ensure(Cur memory cur, uint ensureAt) internal pure {
|
|
316
|
+
if (ensureAt > cur.len || cur.i != ensureAt) revert IncompleteCursor();
|
|
317
|
+
}
|
|
318
|
+
|
|
204
319
|
/// @notice Assert completion and finalise a writer in one step.
|
|
205
320
|
/// @param cur Cursor to check.
|
|
206
321
|
/// @param writer Writer to finalise.
|
|
@@ -218,45 +333,26 @@ library Cursors {
|
|
|
218
333
|
/// @param key Block type key.
|
|
219
334
|
/// @param value 32-byte payload.
|
|
220
335
|
/// @return Encoded block bytes.
|
|
221
|
-
function
|
|
336
|
+
function createBlock32(bytes4 key, bytes32 value) internal pure returns (bytes memory) {
|
|
222
337
|
return bytes.concat(key, bytes4(uint32(0x20)), value);
|
|
223
338
|
}
|
|
224
339
|
|
|
225
|
-
/// @notice Encode a block with a 32-byte fixed head followed by a variable-length tail.
|
|
226
|
-
/// @param key Block type key.
|
|
227
|
-
/// @param head Fixed 32-byte head payload.
|
|
228
|
-
/// @param tail Variable-length payload bytes appended after the head.
|
|
229
|
-
/// @return Encoded block bytes.
|
|
230
|
-
function createHead32(bytes4 key, bytes32 head, bytes memory tail) internal pure returns (bytes memory) {
|
|
231
|
-
return bytes.concat(key, bytes4(uint32(0x20 + tail.length)), head, tail);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
340
|
/// @notice Encode a block with two 32-byte payload words (64-byte payload).
|
|
235
341
|
/// @param key Block type key.
|
|
236
342
|
/// @param a First payload word.
|
|
237
343
|
/// @param b Second payload word.
|
|
238
344
|
/// @return Encoded block bytes.
|
|
239
|
-
function
|
|
345
|
+
function createBlock64(bytes4 key, bytes32 a, bytes32 b) internal pure returns (bytes memory) {
|
|
240
346
|
return bytes.concat(key, bytes4(uint32(0x40)), a, b);
|
|
241
347
|
}
|
|
242
348
|
|
|
243
|
-
/// @notice Encode a block with a 64-byte fixed head followed by a variable-length tail.
|
|
244
|
-
/// @param key Block type key.
|
|
245
|
-
/// @param a First fixed payload word.
|
|
246
|
-
/// @param b Second fixed payload word.
|
|
247
|
-
/// @param tail Variable-length payload bytes appended after the fixed head.
|
|
248
|
-
/// @return Encoded block bytes.
|
|
249
|
-
function createHead64(bytes4 key, bytes32 a, bytes32 b, bytes memory tail) internal pure returns (bytes memory) {
|
|
250
|
-
return bytes.concat(key, bytes4(uint32(0x40 + tail.length)), a, b, tail);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
349
|
/// @notice Encode a block with three 32-byte payload words (96-byte payload).
|
|
254
350
|
/// @param key Block type key.
|
|
255
351
|
/// @param a First payload word.
|
|
256
352
|
/// @param b Second payload word.
|
|
257
353
|
/// @param c Third payload word.
|
|
258
354
|
/// @return Encoded block bytes.
|
|
259
|
-
function
|
|
355
|
+
function createBlock96(bytes4 key, bytes32 a, bytes32 b, bytes32 c) internal pure returns (bytes memory) {
|
|
260
356
|
return bytes.concat(key, bytes4(uint32(0x60)), a, b, c);
|
|
261
357
|
}
|
|
262
358
|
|
|
@@ -267,39 +363,65 @@ library Cursors {
|
|
|
267
363
|
/// @param c Third payload word.
|
|
268
364
|
/// @param d Fourth payload word.
|
|
269
365
|
/// @return Encoded block bytes.
|
|
270
|
-
function
|
|
366
|
+
function createBlock128(
|
|
367
|
+
bytes4 key,
|
|
368
|
+
bytes32 a,
|
|
369
|
+
bytes32 b,
|
|
370
|
+
bytes32 c,
|
|
371
|
+
bytes32 d
|
|
372
|
+
) internal pure returns (bytes memory) {
|
|
271
373
|
return bytes.concat(key, bytes4(uint32(0x80)), a, b, c, d);
|
|
272
374
|
}
|
|
273
375
|
|
|
274
|
-
/// @notice Encode a
|
|
275
|
-
/// @param
|
|
276
|
-
/// @param
|
|
277
|
-
/// @
|
|
278
|
-
|
|
279
|
-
|
|
376
|
+
/// @notice Encode a block with five 32-byte payload words (160-byte payload).
|
|
377
|
+
/// @param key Block type key.
|
|
378
|
+
/// @param a First payload word.
|
|
379
|
+
/// @param b Second payload word.
|
|
380
|
+
/// @param c Third payload word.
|
|
381
|
+
/// @param d Fourth payload word.
|
|
382
|
+
/// @param e Fifth payload word.
|
|
383
|
+
/// @return Encoded block bytes.
|
|
384
|
+
function createBlock160(
|
|
385
|
+
bytes4 key,
|
|
386
|
+
bytes32 a,
|
|
387
|
+
bytes32 b,
|
|
388
|
+
bytes32 c,
|
|
389
|
+
bytes32 d,
|
|
390
|
+
bytes32 e
|
|
391
|
+
) internal pure returns (bytes memory) {
|
|
392
|
+
return bytes.concat(key, bytes4(uint32(0xa0)), a, b, c, d, e);
|
|
280
393
|
}
|
|
281
394
|
|
|
282
|
-
/// @notice Encode a
|
|
283
|
-
/// @param
|
|
284
|
-
/// @param
|
|
285
|
-
/// @
|
|
286
|
-
|
|
287
|
-
|
|
395
|
+
/// @notice Encode a block with a 32-byte fixed head followed by a variable-length tail.
|
|
396
|
+
/// @param key Block type key.
|
|
397
|
+
/// @param head Fixed 32-byte head payload.
|
|
398
|
+
/// @param tail Variable-length payload bytes appended after the head.
|
|
399
|
+
/// @return Encoded block bytes.
|
|
400
|
+
function createBlockHead32(bytes4 key, bytes32 head, bytes memory tail) internal pure returns (bytes memory) {
|
|
401
|
+
return bytes.concat(key, bytes4(uint32(0x20 + tail.length)), head, tail);
|
|
288
402
|
}
|
|
289
403
|
|
|
290
|
-
/// @notice Encode a
|
|
291
|
-
/// @param
|
|
292
|
-
/// @param
|
|
293
|
-
/// @
|
|
294
|
-
|
|
295
|
-
|
|
404
|
+
/// @notice Encode a block with a 64-byte fixed head followed by a variable-length tail.
|
|
405
|
+
/// @param key Block type key.
|
|
406
|
+
/// @param a First fixed payload word.
|
|
407
|
+
/// @param b Second fixed payload word.
|
|
408
|
+
/// @param tail Variable-length payload bytes appended after the fixed head.
|
|
409
|
+
/// @return Encoded block bytes.
|
|
410
|
+
function createBlockHead64(
|
|
411
|
+
bytes4 key,
|
|
412
|
+
bytes32 a,
|
|
413
|
+
bytes32 b,
|
|
414
|
+
bytes memory tail
|
|
415
|
+
) internal pure returns (bytes memory) {
|
|
416
|
+
return bytes.concat(key, bytes4(uint32(0x40 + tail.length)), a, b, tail);
|
|
296
417
|
}
|
|
297
418
|
|
|
298
|
-
/// @notice Encode a
|
|
299
|
-
/// @param
|
|
300
|
-
/// @
|
|
301
|
-
|
|
302
|
-
|
|
419
|
+
/// @notice Encode a BOUNTY block.
|
|
420
|
+
/// @param bounty Relayer reward amount.
|
|
421
|
+
/// @param relayer Relayer account identifier.
|
|
422
|
+
/// @return Encoded BOUNTY block bytes.
|
|
423
|
+
function toBountyBlock(uint bounty, bytes32 relayer) internal pure returns (bytes memory) {
|
|
424
|
+
return createBlock64(Keys.Bounty, bytes32(bounty), relayer);
|
|
303
425
|
}
|
|
304
426
|
|
|
305
427
|
/// @notice Encode a STEP block.
|
|
@@ -308,7 +430,16 @@ library Cursors {
|
|
|
308
430
|
/// @param request Variable-length nested request payload.
|
|
309
431
|
/// @return Encoded STEP block bytes.
|
|
310
432
|
function toStepBlock(uint target, uint value, bytes memory request) internal pure returns (bytes memory) {
|
|
311
|
-
return
|
|
433
|
+
return createBlockHead64(Keys.Step, bytes32(target), bytes32(value), request);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/// @notice Encode a CALL block.
|
|
437
|
+
/// @param target Target node identifier.
|
|
438
|
+
/// @param value Native value forwarded with the call.
|
|
439
|
+
/// @param data Raw calldata payload for the target.
|
|
440
|
+
/// @return Encoded CALL block bytes.
|
|
441
|
+
function toCallBlock(uint target, uint value, bytes memory data) internal pure returns (bytes memory) {
|
|
442
|
+
return createBlockHead64(Keys.Call, bytes32(target), bytes32(value), data);
|
|
312
443
|
}
|
|
313
444
|
|
|
314
445
|
/// @notice Encode a BALANCE block.
|
|
@@ -317,7 +448,7 @@ library Cursors {
|
|
|
317
448
|
/// @param amount Token amount.
|
|
318
449
|
/// @return Encoded BALANCE block bytes.
|
|
319
450
|
function toBalanceBlock(bytes32 asset, bytes32 meta, uint amount) internal pure returns (bytes memory) {
|
|
320
|
-
return
|
|
451
|
+
return createBlock96(Keys.Balance, asset, meta, bytes32(amount));
|
|
321
452
|
}
|
|
322
453
|
|
|
323
454
|
/// @notice Encode a CUSTODY block.
|
|
@@ -326,562 +457,699 @@ library Cursors {
|
|
|
326
457
|
/// @param meta Asset metadata slot.
|
|
327
458
|
/// @param amount Token amount.
|
|
328
459
|
/// @return Encoded CUSTODY block bytes.
|
|
329
|
-
function toCustodyBlock(
|
|
330
|
-
|
|
460
|
+
function toCustodyBlock(
|
|
461
|
+
uint host,
|
|
462
|
+
bytes32 asset,
|
|
463
|
+
bytes32 meta,
|
|
464
|
+
uint amount
|
|
465
|
+
) internal pure returns (bytes memory) {
|
|
466
|
+
return createBlock128(Keys.Custody, bytes32(host), asset, meta, bytes32(amount));
|
|
331
467
|
}
|
|
332
468
|
|
|
333
469
|
// -------------------------------------------------------------------------
|
|
334
|
-
//
|
|
470
|
+
// Raw calldata loaders
|
|
335
471
|
// -------------------------------------------------------------------------
|
|
336
472
|
|
|
337
|
-
/// @notice
|
|
338
|
-
///
|
|
339
|
-
/// @param
|
|
340
|
-
/// @
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
(uint abs, ) = expect(cur, i, Keys.Node, 32, 32);
|
|
347
|
-
return uint(bytes32(msg.data[abs:abs + 32]));
|
|
473
|
+
/// @notice Load one 32-byte word from calldata.
|
|
474
|
+
/// @dev Performs no bounds, key, length, or cursor checks.
|
|
475
|
+
/// @param abs Absolute calldata offset of the word start.
|
|
476
|
+
/// @return a Loaded word.
|
|
477
|
+
function load32(uint abs) internal pure returns (bytes32 a) {
|
|
478
|
+
assembly ("memory-safe") {
|
|
479
|
+
a := calldataload(abs)
|
|
480
|
+
}
|
|
348
481
|
}
|
|
349
482
|
|
|
350
|
-
/// @notice
|
|
351
|
-
///
|
|
352
|
-
/// @param
|
|
353
|
-
/// @
|
|
354
|
-
/// @return
|
|
355
|
-
function
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
return bytes32(msg.data[abs:abs + 32]);
|
|
483
|
+
/// @notice Load two 32-byte words from calldata.
|
|
484
|
+
/// @dev Performs no bounds, key, length, or cursor checks.
|
|
485
|
+
/// @param abs Absolute calldata offset of the first word.
|
|
486
|
+
/// @return a First loaded word.
|
|
487
|
+
/// @return b Second loaded word.
|
|
488
|
+
function load64(uint abs) internal pure returns (bytes32 a, bytes32 b) {
|
|
489
|
+
assembly ("memory-safe") {
|
|
490
|
+
a := calldataload(abs)
|
|
491
|
+
b := calldataload(add(abs, 0x20))
|
|
492
|
+
}
|
|
361
493
|
}
|
|
362
494
|
|
|
363
|
-
/// @notice
|
|
364
|
-
///
|
|
365
|
-
///
|
|
366
|
-
///
|
|
367
|
-
/// @
|
|
368
|
-
/// @
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
if (cur.len - cur.i < Sizes.Auth) revert MalformedBlocks();
|
|
495
|
+
/// @notice Load three 32-byte words from calldata.
|
|
496
|
+
/// @dev Performs no bounds, key, length, or cursor checks.
|
|
497
|
+
/// @param abs Absolute calldata offset of the first word.
|
|
498
|
+
/// @return a First loaded word.
|
|
499
|
+
/// @return b Second loaded word.
|
|
500
|
+
/// @return c Third loaded word.
|
|
501
|
+
function load96(uint abs) internal pure returns (bytes32 a, bytes32 b, bytes32 c) {
|
|
502
|
+
assembly ("memory-safe") {
|
|
503
|
+
a := calldataload(abs)
|
|
504
|
+
b := calldataload(add(abs, 0x20))
|
|
505
|
+
c := calldataload(add(abs, 0x40))
|
|
506
|
+
}
|
|
507
|
+
}
|
|
377
508
|
|
|
378
|
-
|
|
379
|
-
|
|
509
|
+
/// @notice Load four 32-byte words from calldata.
|
|
510
|
+
/// @dev Performs no bounds, key, length, or cursor checks.
|
|
511
|
+
/// @param abs Absolute calldata offset of the first word.
|
|
512
|
+
/// @return a First loaded word.
|
|
513
|
+
/// @return b Second loaded word.
|
|
514
|
+
/// @return c Third loaded word.
|
|
515
|
+
/// @return d Fourth loaded word.
|
|
516
|
+
function load128(uint abs) internal pure returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d) {
|
|
517
|
+
assembly ("memory-safe") {
|
|
518
|
+
a := calldataload(abs)
|
|
519
|
+
b := calldataload(add(abs, 0x20))
|
|
520
|
+
c := calldataload(add(abs, 0x40))
|
|
521
|
+
d := calldataload(add(abs, 0x60))
|
|
522
|
+
}
|
|
523
|
+
}
|
|
380
524
|
|
|
381
|
-
|
|
382
|
-
|
|
525
|
+
/// @notice Load five 32-byte words from calldata.
|
|
526
|
+
/// @dev Performs no bounds, key, length, or cursor checks.
|
|
527
|
+
/// @param abs Absolute calldata offset of the first word.
|
|
528
|
+
/// @return a First loaded word.
|
|
529
|
+
/// @return b Second loaded word.
|
|
530
|
+
/// @return c Third loaded word.
|
|
531
|
+
/// @return d Fourth loaded word.
|
|
532
|
+
/// @return e Fifth loaded word.
|
|
533
|
+
function load160(uint abs) internal pure returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e) {
|
|
534
|
+
assembly ("memory-safe") {
|
|
535
|
+
a := calldataload(abs)
|
|
536
|
+
b := calldataload(add(abs, 0x20))
|
|
537
|
+
c := calldataload(add(abs, 0x40))
|
|
538
|
+
d := calldataload(add(abs, 0x60))
|
|
539
|
+
e := calldataload(add(abs, 0x80))
|
|
540
|
+
}
|
|
383
541
|
}
|
|
384
542
|
|
|
385
543
|
// -------------------------------------------------------------------------
|
|
386
|
-
// unpack*
|
|
544
|
+
// unpack* - consume current block and decode payload fields
|
|
387
545
|
// -------------------------------------------------------------------------
|
|
388
546
|
|
|
389
|
-
|
|
390
|
-
/// @param cur Cursor; advanced past the block.
|
|
391
|
-
/// @return value Decoded asset, meta, and amount.
|
|
392
|
-
function unpackBalanceValue(Cur memory cur) internal pure returns (AssetAmount memory value) {
|
|
393
|
-
uint abs = consume(cur, Keys.Balance, 96, 96);
|
|
394
|
-
value.asset = bytes32(msg.data[abs:abs + 32]);
|
|
395
|
-
value.meta = bytes32(msg.data[abs + 32:abs + 64]);
|
|
396
|
-
value.amount = uint(bytes32(msg.data[abs + 64:abs + 96]));
|
|
397
|
-
}
|
|
547
|
+
// Generic fixed-width decoders
|
|
398
548
|
|
|
399
|
-
/// @notice Consume
|
|
549
|
+
/// @notice Consume a dynamic block with the given key and return the raw payload as a calldata slice.
|
|
550
|
+
/// The payload length is variable; the returned slice covers the entire payload.
|
|
400
551
|
/// @param cur Cursor; advanced past the block.
|
|
401
|
-
/// @
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
552
|
+
/// @param key Expected dynamic block key.
|
|
553
|
+
/// @return data Raw block payload bytes.
|
|
554
|
+
function unpackRaw(Cur memory cur, bytes4 key) internal pure returns (bytes calldata data) {
|
|
555
|
+
(uint abs, uint next) = expect(cur, cur.i, key, 0, 0);
|
|
556
|
+
data = msg.data[abs:cur.offset + next];
|
|
557
|
+
cur.i = next;
|
|
407
558
|
}
|
|
408
559
|
|
|
409
|
-
/// @notice Consume
|
|
560
|
+
/// @notice Consume a dynamic block with a single bytes32 payload.
|
|
410
561
|
/// @param cur Cursor; advanced past the block.
|
|
411
|
-
/// @
|
|
412
|
-
/// @return
|
|
413
|
-
/// @
|
|
414
|
-
function
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
562
|
+
/// @param key Expected dynamic block key.
|
|
563
|
+
/// @return value Decoded bytes32.
|
|
564
|
+
/// @param keep Number of bytes to keep from the final payload word (1..32).
|
|
565
|
+
function unpack32(Cur memory cur, bytes4 key, uint keep) internal pure returns (bytes32 value) {
|
|
566
|
+
if (keep == 0 || keep > 32) revert InvalidKeep();
|
|
567
|
+
uint len = keep;
|
|
568
|
+
uint abs = consume(cur, key, len, len);
|
|
569
|
+
value = mask(abs, 32 - keep);
|
|
419
570
|
}
|
|
420
571
|
|
|
421
|
-
/// @notice Consume a
|
|
572
|
+
/// @notice Consume a dynamic block with two bytes32 payload words.
|
|
422
573
|
/// @param cur Cursor; advanced past the block.
|
|
423
|
-
/// @
|
|
424
|
-
/// @return
|
|
425
|
-
/// @return
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
574
|
+
/// @param key Expected dynamic block key.
|
|
575
|
+
/// @return a First decoded bytes32.
|
|
576
|
+
/// @return b Second decoded bytes32.
|
|
577
|
+
/// @param keep Number of bytes to keep from the final payload word (1..32).
|
|
578
|
+
function unpack64(Cur memory cur, bytes4 key, uint keep) internal pure returns (bytes32 a, bytes32 b) {
|
|
579
|
+
if (keep == 0 || keep > 32) revert InvalidKeep();
|
|
580
|
+
uint len = 32 + keep;
|
|
581
|
+
uint abs = consume(cur, key, len, len);
|
|
582
|
+
a = bytes32(msg.data[abs:abs + 32]);
|
|
583
|
+
b = mask(abs + 32, 32 - keep);
|
|
431
584
|
}
|
|
432
585
|
|
|
433
|
-
/// @notice Consume a
|
|
586
|
+
/// @notice Consume a dynamic block with three bytes32 payload words.
|
|
434
587
|
/// @param cur Cursor; advanced past the block.
|
|
435
|
-
/// @
|
|
436
|
-
/// @return
|
|
437
|
-
/// @return
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
588
|
+
/// @param key Expected dynamic block key.
|
|
589
|
+
/// @return a First decoded bytes32.
|
|
590
|
+
/// @return b Second decoded bytes32.
|
|
591
|
+
/// @return c Third decoded bytes32.
|
|
592
|
+
/// @param keep Number of bytes to keep from the final payload word (1..32).
|
|
593
|
+
function unpack96(Cur memory cur, bytes4 key, uint keep) internal pure returns (bytes32 a, bytes32 b, bytes32 c) {
|
|
594
|
+
if (keep == 0 || keep > 32) revert InvalidKeep();
|
|
595
|
+
uint len = 64 + keep;
|
|
596
|
+
uint abs = consume(cur, key, len, len);
|
|
597
|
+
a = bytes32(msg.data[abs:abs + 32]);
|
|
598
|
+
b = bytes32(msg.data[abs + 32:abs + 64]);
|
|
599
|
+
c = mask(abs + 64, 32 - keep);
|
|
443
600
|
}
|
|
444
601
|
|
|
445
|
-
/// @notice Consume a
|
|
602
|
+
/// @notice Consume a dynamic block with a 128-byte payload (four 32-byte words).
|
|
446
603
|
/// @param cur Cursor; advanced past the block.
|
|
447
|
-
/// @
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
604
|
+
/// @param key Expected dynamic block key.
|
|
605
|
+
/// @return a First decoded bytes32.
|
|
606
|
+
/// @return b Second decoded bytes32.
|
|
607
|
+
/// @return c Third decoded bytes32.
|
|
608
|
+
/// @return d Fourth decoded bytes32.
|
|
609
|
+
/// @param keep Number of bytes to keep from the final payload word (1..32).
|
|
610
|
+
function unpack128(
|
|
611
|
+
Cur memory cur,
|
|
612
|
+
bytes4 key,
|
|
613
|
+
uint keep
|
|
614
|
+
) internal pure returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d) {
|
|
615
|
+
if (keep == 0 || keep > 32) revert InvalidKeep();
|
|
616
|
+
uint len = 96 + keep;
|
|
617
|
+
uint abs = consume(cur, key, len, len);
|
|
618
|
+
a = bytes32(msg.data[abs:abs + 32]);
|
|
619
|
+
b = bytes32(msg.data[abs + 32:abs + 64]);
|
|
620
|
+
c = bytes32(msg.data[abs + 64:abs + 96]);
|
|
621
|
+
d = mask(abs + 96, 32 - keep);
|
|
453
622
|
}
|
|
454
623
|
|
|
455
|
-
/// @notice Consume a
|
|
624
|
+
/// @notice Consume a dynamic block with a 160-byte payload (five 32-byte words).
|
|
456
625
|
/// @param cur Cursor; advanced past the block.
|
|
457
|
-
/// @
|
|
458
|
-
/// @return
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
626
|
+
/// @param key Expected dynamic block key.
|
|
627
|
+
/// @return a First decoded bytes32.
|
|
628
|
+
/// @return b Second decoded bytes32.
|
|
629
|
+
/// @return c Third decoded bytes32.
|
|
630
|
+
/// @return d Fourth decoded bytes32.
|
|
631
|
+
/// @return e Fifth decoded bytes32.
|
|
632
|
+
/// @param keep Number of bytes to keep from the final payload word (1..32).
|
|
633
|
+
function unpack160(
|
|
634
|
+
Cur memory cur,
|
|
635
|
+
bytes4 key,
|
|
636
|
+
uint keep
|
|
637
|
+
) internal pure returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e) {
|
|
638
|
+
if (keep == 0 || keep > 32) revert InvalidKeep();
|
|
639
|
+
uint len = 128 + keep;
|
|
640
|
+
uint abs = consume(cur, key, len, len);
|
|
641
|
+
a = bytes32(msg.data[abs:abs + 32]);
|
|
642
|
+
b = bytes32(msg.data[abs + 32:abs + 64]);
|
|
643
|
+
c = bytes32(msg.data[abs + 64:abs + 96]);
|
|
644
|
+
d = bytes32(msg.data[abs + 96:abs + 128]);
|
|
645
|
+
e = mask(abs + 128, 32 - keep);
|
|
463
646
|
}
|
|
464
647
|
|
|
465
|
-
/// @notice Consume a
|
|
648
|
+
/// @notice Consume a dynamic block with a single uint payload.
|
|
466
649
|
/// @param cur Cursor; advanced past the block.
|
|
467
|
-
/// @
|
|
468
|
-
/// @return
|
|
469
|
-
function
|
|
470
|
-
|
|
471
|
-
a = uint(bytes32(msg.data[abs:abs + 32]));
|
|
472
|
-
b = uint(bytes32(msg.data[abs + 32:abs + 64]));
|
|
650
|
+
/// @param key Expected dynamic block key.
|
|
651
|
+
/// @return value Decoded uint value.
|
|
652
|
+
function unpackUint(Cur memory cur, bytes4 key) internal pure returns (uint value) {
|
|
653
|
+
value = uint(unpack32(cur, key, 32));
|
|
473
654
|
}
|
|
474
655
|
|
|
475
|
-
/// @notice Consume a
|
|
656
|
+
/// @notice Consume a dynamic block with two uint payload words.
|
|
476
657
|
/// @param cur Cursor; advanced past the block.
|
|
477
|
-
/// @
|
|
478
|
-
/// @return
|
|
479
|
-
/// @return
|
|
480
|
-
function
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
meta = bytes32(msg.data[abs + 32:abs + 64]);
|
|
484
|
-
amount = uint(bytes32(msg.data[abs + 64:abs + 96]));
|
|
658
|
+
/// @param key Expected dynamic block key.
|
|
659
|
+
/// @return a First decoded uint.
|
|
660
|
+
/// @return b Second decoded uint.
|
|
661
|
+
function unpack2Uint(Cur memory cur, bytes4 key) internal pure returns (uint a, uint b) {
|
|
662
|
+
(bytes32 x, bytes32 y) = unpack64(cur, key, 32);
|
|
663
|
+
return (uint(x), uint(y));
|
|
485
664
|
}
|
|
486
665
|
|
|
487
|
-
/// @notice Consume a
|
|
666
|
+
/// @notice Consume a dynamic block with three uint payload words.
|
|
488
667
|
/// @param cur Cursor; advanced past the block.
|
|
489
|
-
/// @
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
668
|
+
/// @param key Expected dynamic block key.
|
|
669
|
+
/// @return a First decoded uint.
|
|
670
|
+
/// @return b Second decoded uint.
|
|
671
|
+
/// @return c Third decoded uint.
|
|
672
|
+
function unpack3Uint(Cur memory cur, bytes4 key) internal pure returns (uint a, uint b, uint c) {
|
|
673
|
+
(bytes32 x, bytes32 y, bytes32 z) = unpack96(cur, key, 32);
|
|
674
|
+
return (uint(x), uint(y), uint(z));
|
|
495
675
|
}
|
|
496
676
|
|
|
497
|
-
|
|
498
|
-
/// The `req` slice covers any additional payload bytes after the fixed head.
|
|
499
|
-
/// @param cur Cursor; advanced past the block.
|
|
500
|
-
/// @return target Destination node ID for the sub-command.
|
|
501
|
-
/// @return value Native value to forward with the call.
|
|
502
|
-
/// @return req Embedded request bytes for the sub-command.
|
|
503
|
-
function unpackStep(Cur memory cur) internal pure returns (uint target, uint value, bytes calldata req) {
|
|
504
|
-
uint abs = consume(cur, Keys.Step, 64, 0);
|
|
505
|
-
target = uint(bytes32(msg.data[abs:abs + 32]));
|
|
506
|
-
value = uint(bytes32(msg.data[abs + 32:abs + 64]));
|
|
507
|
-
req = msg.data[abs + 64:cur.offset + cur.i];
|
|
508
|
-
}
|
|
677
|
+
// Generic fixed-head decoders
|
|
509
678
|
|
|
510
|
-
/// @notice Consume a
|
|
679
|
+
/// @notice Consume a dynamic block with a 32-byte fixed head followed by a variable-length tail.
|
|
511
680
|
/// @param cur Cursor; advanced past the block.
|
|
512
|
-
/// @
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
681
|
+
/// @param key Expected dynamic block key.
|
|
682
|
+
/// @return head Fixed 32-byte head.
|
|
683
|
+
/// @return tail Variable-length payload bytes after the fixed head.
|
|
684
|
+
function unpackHead32(Cur memory cur, bytes4 key) internal pure returns (bytes32 head, bytes calldata tail) {
|
|
685
|
+
uint abs = consume(cur, key, 32, 0);
|
|
686
|
+
head = bytes32(msg.data[abs:abs + 32]);
|
|
687
|
+
tail = msg.data[abs + 32:cur.offset + cur.i];
|
|
516
688
|
}
|
|
517
689
|
|
|
518
|
-
/// @notice Consume a
|
|
690
|
+
/// @notice Consume a dynamic block with a 64-byte fixed head followed by a variable-length tail.
|
|
519
691
|
/// @param cur Cursor; advanced past the block.
|
|
520
|
-
/// @
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
692
|
+
/// @param key Expected dynamic block key.
|
|
693
|
+
/// @return a First fixed head word.
|
|
694
|
+
/// @return b Second fixed head word.
|
|
695
|
+
/// @return tail Variable-length payload bytes after the fixed head.
|
|
696
|
+
function unpackHead64(
|
|
697
|
+
Cur memory cur,
|
|
698
|
+
bytes4 key
|
|
699
|
+
) internal pure returns (bytes32 a, bytes32 b, bytes calldata tail) {
|
|
700
|
+
uint abs = consume(cur, key, 64, 0);
|
|
701
|
+
a = bytes32(msg.data[abs:abs + 32]);
|
|
702
|
+
b = bytes32(msg.data[abs + 32:abs + 64]);
|
|
703
|
+
tail = msg.data[abs + 64:cur.offset + cur.i];
|
|
524
704
|
}
|
|
525
705
|
|
|
526
|
-
/// @notice Consume a
|
|
706
|
+
/// @notice Consume a dynamic block with a 96-byte fixed head followed by a variable-length tail.
|
|
527
707
|
/// @param cur Cursor; advanced past the block.
|
|
528
|
-
/// @
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
708
|
+
/// @param key Expected dynamic block key.
|
|
709
|
+
/// @return a First fixed head word.
|
|
710
|
+
/// @return b Second fixed head word.
|
|
711
|
+
/// @return c Third fixed head word.
|
|
712
|
+
/// @return tail Variable-length payload bytes after the fixed head.
|
|
713
|
+
function unpackHead96(
|
|
714
|
+
Cur memory cur,
|
|
715
|
+
bytes4 key
|
|
716
|
+
) internal pure returns (bytes32 a, bytes32 b, bytes32 c, bytes calldata tail) {
|
|
717
|
+
uint abs = consume(cur, key, 96, 0);
|
|
718
|
+
a = bytes32(msg.data[abs:abs + 32]);
|
|
719
|
+
b = bytes32(msg.data[abs + 32:abs + 64]);
|
|
720
|
+
c = bytes32(msg.data[abs + 64:abs + 96]);
|
|
721
|
+
tail = msg.data[abs + 96:cur.offset + cur.i];
|
|
532
722
|
}
|
|
533
723
|
|
|
534
|
-
/// @notice Consume a
|
|
724
|
+
/// @notice Consume a dynamic block with a 128-byte fixed head followed by a variable-length tail.
|
|
535
725
|
/// @param cur Cursor; advanced past the block.
|
|
536
|
-
/// @
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
726
|
+
/// @param key Expected dynamic block key.
|
|
727
|
+
/// @return a First fixed head word.
|
|
728
|
+
/// @return b Second fixed head word.
|
|
729
|
+
/// @return c Third fixed head word.
|
|
730
|
+
/// @return d Fourth fixed head word.
|
|
731
|
+
/// @return tail Variable-length payload bytes after the fixed head.
|
|
732
|
+
function unpackHead128(
|
|
733
|
+
Cur memory cur,
|
|
734
|
+
bytes4 key
|
|
735
|
+
) internal pure returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes calldata tail) {
|
|
736
|
+
uint abs = consume(cur, key, 128, 0);
|
|
737
|
+
a = bytes32(msg.data[abs:abs + 32]);
|
|
738
|
+
b = bytes32(msg.data[abs + 32:abs + 64]);
|
|
739
|
+
c = bytes32(msg.data[abs + 64:abs + 96]);
|
|
740
|
+
d = bytes32(msg.data[abs + 96:abs + 128]);
|
|
741
|
+
tail = msg.data[abs + 128:cur.offset + cur.i];
|
|
540
742
|
}
|
|
541
743
|
|
|
542
|
-
|
|
543
|
-
/// @param cur Cursor; advanced past the block.
|
|
544
|
-
/// @return min Lower signed bound.
|
|
545
|
-
/// @return max Upper signed bound.
|
|
546
|
-
function unpackBounds(Cur memory cur) internal pure returns (int min, int max) {
|
|
547
|
-
uint abs = consume(cur, Keys.Bounds, 64, 64);
|
|
548
|
-
assembly ("memory-safe") {
|
|
549
|
-
min := calldataload(abs)
|
|
550
|
-
max := calldataload(add(abs, 0x20))
|
|
551
|
-
}
|
|
552
|
-
}
|
|
744
|
+
// Generic typed-shape decoders
|
|
553
745
|
|
|
554
|
-
/// @notice Consume
|
|
746
|
+
/// @notice Consume a fixed-size asset amount block and return asset, meta, and amount.
|
|
555
747
|
/// @param cur Cursor; advanced past the block.
|
|
748
|
+
/// @param key Expected block key.
|
|
556
749
|
/// @return asset Asset identifier.
|
|
557
750
|
/// @return meta Asset metadata slot.
|
|
558
|
-
|
|
559
|
-
|
|
751
|
+
/// @return amount Scalar amount value.
|
|
752
|
+
function unpackAssetAmount(
|
|
753
|
+
Cur memory cur,
|
|
754
|
+
bytes4 key
|
|
755
|
+
) internal pure returns (bytes32 asset, bytes32 meta, uint amount) {
|
|
756
|
+
uint abs = consume(cur, key, 96, 96);
|
|
560
757
|
asset = bytes32(msg.data[abs:abs + 32]);
|
|
561
758
|
meta = bytes32(msg.data[abs + 32:abs + 64]);
|
|
759
|
+
amount = uint(bytes32(msg.data[abs + 64:abs + 96]));
|
|
562
760
|
}
|
|
563
761
|
|
|
564
|
-
/// @notice Consume a
|
|
762
|
+
/// @notice Consume a fixed-size account amount block and return account, asset, meta, and amount.
|
|
565
763
|
/// @param cur Cursor; advanced past the block.
|
|
566
|
-
/// @
|
|
567
|
-
/// @return
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
amount = uint(bytes32(msg.data[abs:abs + 32]));
|
|
581
|
-
relayer = bytes32(msg.data[abs + 32:abs + 64]);
|
|
764
|
+
/// @param key Expected block key.
|
|
765
|
+
/// @return account Account identifier.
|
|
766
|
+
/// @return asset Asset identifier.
|
|
767
|
+
/// @return meta Asset metadata slot.
|
|
768
|
+
/// @return amount Scalar amount value.
|
|
769
|
+
function unpackAccountAmount(
|
|
770
|
+
Cur memory cur,
|
|
771
|
+
bytes4 key
|
|
772
|
+
) internal pure returns (bytes32 account, bytes32 asset, bytes32 meta, uint amount) {
|
|
773
|
+
uint abs = consume(cur, key, 128, 128);
|
|
774
|
+
account = bytes32(msg.data[abs:abs + 32]);
|
|
775
|
+
asset = bytes32(msg.data[abs + 32:abs + 64]);
|
|
776
|
+
meta = bytes32(msg.data[abs + 64:abs + 96]);
|
|
777
|
+
amount = uint(bytes32(msg.data[abs + 96:abs + 128]));
|
|
582
778
|
}
|
|
583
779
|
|
|
584
|
-
/// @notice Consume a
|
|
780
|
+
/// @notice Consume a fixed-size host amount block and return host, asset, meta, and amount.
|
|
585
781
|
/// @param cur Cursor; advanced past the block.
|
|
586
|
-
/// @
|
|
782
|
+
/// @param key Expected block key.
|
|
783
|
+
/// @return host Host node ID.
|
|
587
784
|
/// @return asset Asset identifier.
|
|
588
785
|
/// @return meta Asset metadata slot.
|
|
589
|
-
|
|
590
|
-
|
|
786
|
+
/// @return amount Scalar amount value.
|
|
787
|
+
function unpackHostAmount(
|
|
788
|
+
Cur memory cur,
|
|
789
|
+
bytes4 key
|
|
790
|
+
) internal pure returns (uint host, bytes32 asset, bytes32 meta, uint amount) {
|
|
791
|
+
uint abs = consume(cur, key, 128, 128);
|
|
591
792
|
host = uint(bytes32(msg.data[abs:abs + 32]));
|
|
592
793
|
asset = bytes32(msg.data[abs + 32:abs + 64]);
|
|
593
794
|
meta = bytes32(msg.data[abs + 64:abs + 96]);
|
|
795
|
+
amount = uint(bytes32(msg.data[abs + 96:abs + 128]));
|
|
594
796
|
}
|
|
595
797
|
|
|
596
|
-
/// @notice Consume a
|
|
798
|
+
/// @notice Consume a fixed-size host account asset block and return host, account, asset, and meta.
|
|
597
799
|
/// @param cur Cursor; advanced past the block.
|
|
598
|
-
/// @
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
800
|
+
/// @param key Expected block key.
|
|
801
|
+
/// @return host Host node ID.
|
|
802
|
+
/// @return account Account identifier.
|
|
803
|
+
/// @return asset Asset identifier.
|
|
804
|
+
/// @return meta Asset metadata slot.
|
|
805
|
+
function unpackHostAccountAsset(
|
|
806
|
+
Cur memory cur,
|
|
807
|
+
bytes4 key
|
|
808
|
+
) internal pure returns (uint host, bytes32 account, bytes32 asset, bytes32 meta) {
|
|
809
|
+
uint abs = consume(cur, key, 128, 128);
|
|
810
|
+
host = uint(bytes32(msg.data[abs:abs + 32]));
|
|
811
|
+
account = bytes32(msg.data[abs + 32:abs + 64]);
|
|
812
|
+
asset = bytes32(msg.data[abs + 64:abs + 96]);
|
|
813
|
+
meta = bytes32(msg.data[abs + 96:abs + 128]);
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
/// @notice Consume a fixed-size transaction block and return from, to, asset, meta, and amount.
|
|
817
|
+
/// @param cur Cursor; advanced past the block.
|
|
818
|
+
/// @param key Expected block key.
|
|
819
|
+
/// @return from Source account identifier.
|
|
820
|
+
/// @return to Destination account identifier.
|
|
821
|
+
/// @return asset Asset identifier.
|
|
822
|
+
/// @return meta Asset metadata slot.
|
|
823
|
+
/// @return amount Scalar amount value.
|
|
824
|
+
function unpackTransaction(
|
|
825
|
+
Cur memory cur,
|
|
826
|
+
bytes4 key
|
|
827
|
+
) internal pure returns (bytes32 from, bytes32 to, bytes32 asset, bytes32 meta, uint amount) {
|
|
828
|
+
uint abs = consume(cur, key, 160, 160);
|
|
829
|
+
from = bytes32(msg.data[abs:abs + 32]);
|
|
830
|
+
to = bytes32(msg.data[abs + 32:abs + 64]);
|
|
831
|
+
asset = bytes32(msg.data[abs + 64:abs + 96]);
|
|
832
|
+
meta = bytes32(msg.data[abs + 96:abs + 128]);
|
|
833
|
+
amount = uint(bytes32(msg.data[abs + 128:abs + 160]));
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
// Type-specific fixed-width decoders
|
|
837
|
+
|
|
838
|
+
/// @notice Consume an ACCOUNT block and return the account.
|
|
839
|
+
/// @param cur Cursor; advanced past the block.
|
|
840
|
+
/// @return account Account identifier.
|
|
841
|
+
function unpackAccount(Cur memory cur) internal pure returns (bytes32 account) {
|
|
842
|
+
account = unpack32(cur, Keys.Account, 32);
|
|
604
843
|
}
|
|
605
844
|
|
|
606
845
|
/// @notice Consume a NODE block and return the node ID.
|
|
607
846
|
/// @param cur Cursor; advanced past the block.
|
|
608
847
|
/// @return node Node identifier.
|
|
609
848
|
function unpackNode(Cur memory cur) internal pure returns (uint node) {
|
|
610
|
-
|
|
611
|
-
node = uint(bytes32(msg.data[abs:abs + 32]));
|
|
849
|
+
node = uint(unpack32(cur, Keys.Node, 32));
|
|
612
850
|
}
|
|
613
851
|
|
|
614
|
-
/// @notice Consume a
|
|
615
|
-
/// The payload length is variable; the returned slice covers the entire payload.
|
|
852
|
+
/// @notice Consume a RATE block and return the value.
|
|
616
853
|
/// @param cur Cursor; advanced past the block.
|
|
617
|
-
/// @return
|
|
618
|
-
function
|
|
619
|
-
|
|
620
|
-
data = msg.data[abs:cur.offset + next];
|
|
621
|
-
cur.i = next;
|
|
854
|
+
/// @return value Encoded ratio or rate.
|
|
855
|
+
function unpackRate(Cur memory cur) internal pure returns (uint value) {
|
|
856
|
+
value = uint(unpack32(cur, Keys.Rate, 32));
|
|
622
857
|
}
|
|
623
858
|
|
|
624
|
-
/// @notice Consume a
|
|
625
|
-
/// The payload length is variable; the returned slice covers the entire payload.
|
|
859
|
+
/// @notice Consume a QUANTITY block and return the amount.
|
|
626
860
|
/// @param cur Cursor; advanced past the block.
|
|
627
|
-
/// @return
|
|
628
|
-
function
|
|
629
|
-
|
|
630
|
-
data = msg.data[abs:cur.offset + next];
|
|
631
|
-
cur.i = next;
|
|
861
|
+
/// @return amount Scalar quantity value.
|
|
862
|
+
function unpackQuantity(Cur memory cur) internal pure returns (uint amount) {
|
|
863
|
+
amount = uint(unpack32(cur, Keys.Quantity, 32));
|
|
632
864
|
}
|
|
633
865
|
|
|
634
|
-
/// @notice Consume a
|
|
635
|
-
/// The payload length is variable; the returned slice covers the entire payload.
|
|
866
|
+
/// @notice Consume a FEE block and return the amount.
|
|
636
867
|
/// @param cur Cursor; advanced past the block.
|
|
637
|
-
/// @return
|
|
638
|
-
function
|
|
639
|
-
|
|
640
|
-
data = msg.data[abs:cur.offset + next];
|
|
641
|
-
cur.i = next;
|
|
868
|
+
/// @return amount Fee amount.
|
|
869
|
+
function unpackFee(Cur memory cur) internal pure returns (uint amount) {
|
|
870
|
+
amount = uint(unpack32(cur, Keys.Fee, 32));
|
|
642
871
|
}
|
|
643
872
|
|
|
644
|
-
/// @notice Consume
|
|
645
|
-
/// The payload length is variable; the returned slice covers the entire payload.
|
|
873
|
+
/// @notice Consume an ASSET block and return the asset descriptor fields.
|
|
646
874
|
/// @param cur Cursor; advanced past the block.
|
|
647
|
-
/// @return
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
cur.i = next;
|
|
875
|
+
/// @return asset Asset identifier.
|
|
876
|
+
/// @return meta Asset metadata slot.
|
|
877
|
+
function unpackAsset(Cur memory cur) internal pure returns (bytes32 asset, bytes32 meta) {
|
|
878
|
+
(asset, meta) = unpack64(cur, Keys.Asset, 32);
|
|
652
879
|
}
|
|
653
880
|
|
|
654
|
-
/// @notice Consume
|
|
881
|
+
/// @notice Consume an ACCOUNT_ASSET form block and return its fields as separate values.
|
|
655
882
|
/// @param cur Cursor; advanced past the block.
|
|
656
|
-
/// @return
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
883
|
+
/// @return account Account identifier.
|
|
884
|
+
/// @return asset Asset identifier.
|
|
885
|
+
/// @return meta Asset metadata slot.
|
|
886
|
+
function unpackAccountAsset(Cur memory cur) internal pure returns (bytes32 account, bytes32 asset, bytes32 meta) {
|
|
887
|
+
uint abs = consume(cur, Keys.AccountAsset, 96, 96);
|
|
888
|
+
account = bytes32(msg.data[abs:abs + 32]);
|
|
889
|
+
asset = bytes32(msg.data[abs + 32:abs + 64]);
|
|
890
|
+
meta = bytes32(msg.data[abs + 64:abs + 96]);
|
|
660
891
|
}
|
|
661
892
|
|
|
662
|
-
/// @notice Consume
|
|
893
|
+
/// @notice Consume an ACCOUNT_ASSET form block and return its fields as a struct.
|
|
663
894
|
/// @param cur Cursor; advanced past the block.
|
|
664
|
-
/// @return value Decoded
|
|
665
|
-
function
|
|
666
|
-
|
|
667
|
-
value = uint(bytes32(msg.data[abs:abs + 32]));
|
|
895
|
+
/// @return value Decoded account, asset, and meta.
|
|
896
|
+
function unpackAccountAssetValue(Cur memory cur) internal pure returns (AccountAsset memory value) {
|
|
897
|
+
(value.account, value.asset, value.meta) = unpackAccountAsset(cur);
|
|
668
898
|
}
|
|
669
899
|
|
|
670
|
-
/// @notice Consume a
|
|
900
|
+
/// @notice Consume a RELOCATION block and return the host and amount.
|
|
671
901
|
/// @param cur Cursor; advanced past the block.
|
|
672
|
-
/// @return
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
902
|
+
/// @return host Host node ID receiving the funding.
|
|
903
|
+
/// @return amount Funding amount.
|
|
904
|
+
function unpackRelocation(Cur memory cur) internal pure returns (uint host, uint amount) {
|
|
905
|
+
(host, amount) = unpack2Uint(cur, Keys.Relocation);
|
|
676
906
|
}
|
|
677
907
|
|
|
678
|
-
/// @notice Consume a
|
|
908
|
+
/// @notice Consume a BOUNTY block and return the reward amount and relayer.
|
|
679
909
|
/// @param cur Cursor; advanced past the block.
|
|
680
|
-
/// @return
|
|
681
|
-
/// @return
|
|
682
|
-
function
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
910
|
+
/// @return amount Relayer reward amount.
|
|
911
|
+
/// @return relayer Relayer account identifier.
|
|
912
|
+
function unpackBounty(Cur memory cur) internal pure returns (uint amount, bytes32 relayer) {
|
|
913
|
+
(bytes32 x, bytes32 y) = unpack64(cur, Keys.Bounty, 32);
|
|
914
|
+
amount = uint(x);
|
|
915
|
+
relayer = y;
|
|
686
916
|
}
|
|
687
917
|
|
|
688
|
-
/// @notice Consume a
|
|
918
|
+
/// @notice Consume a BOUNDS block and return the signed min and max values.
|
|
689
919
|
/// @param cur Cursor; advanced past the block.
|
|
690
|
-
/// @return
|
|
691
|
-
/// @return
|
|
692
|
-
function
|
|
693
|
-
uint abs = consume(cur, Keys.
|
|
694
|
-
|
|
695
|
-
|
|
920
|
+
/// @return min Lower signed bound.
|
|
921
|
+
/// @return max Upper signed bound.
|
|
922
|
+
function unpackBounds(Cur memory cur) internal pure returns (int min, int max) {
|
|
923
|
+
uint abs = consume(cur, Keys.Bounds, 64, 64);
|
|
924
|
+
assembly ("memory-safe") {
|
|
925
|
+
min := calldataload(abs)
|
|
926
|
+
max := calldataload(add(abs, 0x20))
|
|
927
|
+
}
|
|
696
928
|
}
|
|
697
929
|
|
|
698
|
-
/// @notice Consume
|
|
930
|
+
/// @notice Consume an AMOUNT block and return its fields as separate values.
|
|
699
931
|
/// @param cur Cursor; advanced past the block.
|
|
700
|
-
/// @return
|
|
701
|
-
/// @return
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
b = uint(bytes32(msg.data[abs + 32:abs + 64]));
|
|
932
|
+
/// @return asset Asset identifier.
|
|
933
|
+
/// @return meta Asset metadata slot.
|
|
934
|
+
/// @return amount Token amount.
|
|
935
|
+
function unpackAmount(Cur memory cur) internal pure returns (bytes32 asset, bytes32 meta, uint amount) {
|
|
936
|
+
return unpackAssetAmount(cur, Keys.Amount);
|
|
706
937
|
}
|
|
707
938
|
|
|
708
|
-
/// @notice Consume
|
|
939
|
+
/// @notice Consume an AMOUNT block and return its fields as a struct.
|
|
709
940
|
/// @param cur Cursor; advanced past the block.
|
|
710
|
-
/// @return
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
function unpackRoute3Uint(Cur memory cur) internal pure returns (uint a, uint b, uint c) {
|
|
714
|
-
uint abs = consume(cur, Keys.Route, 96, 96);
|
|
715
|
-
a = uint(bytes32(msg.data[abs:abs + 32]));
|
|
716
|
-
b = uint(bytes32(msg.data[abs + 32:abs + 64]));
|
|
717
|
-
c = uint(bytes32(msg.data[abs + 64:abs + 96]));
|
|
941
|
+
/// @return value Decoded asset, meta, and amount.
|
|
942
|
+
function unpackAmountValue(Cur memory cur) internal pure returns (AssetAmount memory value) {
|
|
943
|
+
(value.asset, value.meta, value.amount) = unpackAssetAmount(cur, Keys.Amount);
|
|
718
944
|
}
|
|
719
945
|
|
|
720
|
-
/// @notice Consume a
|
|
946
|
+
/// @notice Consume a BALANCE block and return its fields as separate values.
|
|
721
947
|
/// @param cur Cursor; advanced past the block.
|
|
722
|
-
/// @return
|
|
723
|
-
/// @return
|
|
724
|
-
/// @return
|
|
725
|
-
function
|
|
726
|
-
|
|
727
|
-
a = uint(bytes32(msg.data[abs:abs + 32]));
|
|
728
|
-
b = uint(bytes32(msg.data[abs + 32:abs + 64]));
|
|
729
|
-
c = uint(bytes32(msg.data[abs + 64:abs + 96]));
|
|
948
|
+
/// @return asset Asset identifier.
|
|
949
|
+
/// @return meta Asset metadata slot.
|
|
950
|
+
/// @return amount Token amount.
|
|
951
|
+
function unpackBalance(Cur memory cur) internal pure returns (bytes32 asset, bytes32 meta, uint amount) {
|
|
952
|
+
return unpackAssetAmount(cur, Keys.Balance);
|
|
730
953
|
}
|
|
731
954
|
|
|
732
|
-
/// @notice Consume a
|
|
955
|
+
/// @notice Consume a BALANCE block and return its fields as a struct.
|
|
733
956
|
/// @param cur Cursor; advanced past the block.
|
|
734
|
-
/// @return
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
function unpackResponse3Uint(Cur memory cur) internal pure returns (uint a, uint b, uint c) {
|
|
738
|
-
uint abs = consume(cur, Keys.Response, 96, 96);
|
|
739
|
-
a = uint(bytes32(msg.data[abs:abs + 32]));
|
|
740
|
-
b = uint(bytes32(msg.data[abs + 32:abs + 64]));
|
|
741
|
-
c = uint(bytes32(msg.data[abs + 64:abs + 96]));
|
|
957
|
+
/// @return value Decoded asset, meta, and amount.
|
|
958
|
+
function unpackBalanceValue(Cur memory cur) internal pure returns (AssetAmount memory value) {
|
|
959
|
+
(value.asset, value.meta, value.amount) = unpackAssetAmount(cur, Keys.Balance);
|
|
742
960
|
}
|
|
743
961
|
|
|
744
|
-
/// @notice Consume a
|
|
962
|
+
/// @notice Consume a MINIMUM block and return its fields as separate values.
|
|
745
963
|
/// @param cur Cursor; advanced past the block.
|
|
746
|
-
/// @return
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
964
|
+
/// @return asset Asset identifier.
|
|
965
|
+
/// @return meta Asset metadata slot.
|
|
966
|
+
/// @return amount Minimum acceptable amount.
|
|
967
|
+
function unpackMinimum(Cur memory cur) internal pure returns (bytes32 asset, bytes32 meta, uint amount) {
|
|
968
|
+
return unpackAssetAmount(cur, Keys.Minimum);
|
|
750
969
|
}
|
|
751
970
|
|
|
752
|
-
/// @notice Consume a
|
|
971
|
+
/// @notice Consume a MINIMUM block and return its fields as a struct.
|
|
753
972
|
/// @param cur Cursor; advanced past the block.
|
|
754
|
-
/// @return value Decoded
|
|
755
|
-
function
|
|
756
|
-
|
|
757
|
-
value = bytes32(msg.data[abs:abs + 32]);
|
|
973
|
+
/// @return value Decoded asset, meta, and minimum amount.
|
|
974
|
+
function unpackMinimumValue(Cur memory cur) internal pure returns (AssetAmount memory value) {
|
|
975
|
+
(value.asset, value.meta, value.amount) = unpackAssetAmount(cur, Keys.Minimum);
|
|
758
976
|
}
|
|
759
977
|
|
|
760
|
-
/// @notice Consume a
|
|
978
|
+
/// @notice Consume a MAXIMUM block and return its fields as separate values.
|
|
761
979
|
/// @param cur Cursor; advanced past the block.
|
|
762
|
-
/// @return
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
980
|
+
/// @return asset Asset identifier.
|
|
981
|
+
/// @return meta Asset metadata slot.
|
|
982
|
+
/// @return amount Maximum allowable spend.
|
|
983
|
+
function unpackMaximum(Cur memory cur) internal pure returns (bytes32 asset, bytes32 meta, uint amount) {
|
|
984
|
+
return unpackAssetAmount(cur, Keys.Maximum);
|
|
766
985
|
}
|
|
767
986
|
|
|
768
|
-
/// @notice Consume a
|
|
987
|
+
/// @notice Consume a MAXIMUM block and return its fields as a struct.
|
|
769
988
|
/// @param cur Cursor; advanced past the block.
|
|
770
|
-
/// @return
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
uint abs = consume(cur, Keys.Route, 64, 64);
|
|
774
|
-
a = bytes32(msg.data[abs:abs + 32]);
|
|
775
|
-
b = bytes32(msg.data[abs + 32:abs + 64]);
|
|
989
|
+
/// @return value Decoded asset, meta, and maximum amount.
|
|
990
|
+
function unpackMaximumValue(Cur memory cur) internal pure returns (AssetAmount memory value) {
|
|
991
|
+
(value.asset, value.meta, value.amount) = unpackAssetAmount(cur, Keys.Maximum);
|
|
776
992
|
}
|
|
777
993
|
|
|
778
|
-
/// @notice Consume a
|
|
994
|
+
/// @notice Consume a HOST_ACCOUNT_ASSET form block and return its fields as separate values.
|
|
779
995
|
/// @param cur Cursor; advanced past the block.
|
|
780
|
-
/// @return
|
|
781
|
-
/// @return
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
996
|
+
/// @return host Host node ID.
|
|
997
|
+
/// @return account Account identifier.
|
|
998
|
+
/// @return asset Asset identifier.
|
|
999
|
+
/// @return meta Asset metadata slot.
|
|
1000
|
+
function unpackHostAccountAsset(
|
|
1001
|
+
Cur memory cur
|
|
1002
|
+
) internal pure returns (uint host, bytes32 account, bytes32 asset, bytes32 meta) {
|
|
1003
|
+
return unpackHostAccountAsset(cur, Keys.HostAccountAsset);
|
|
786
1004
|
}
|
|
787
1005
|
|
|
788
|
-
/// @notice Consume a
|
|
1006
|
+
/// @notice Consume a HOST_ACCOUNT_ASSET form block and return its fields as a struct.
|
|
789
1007
|
/// @param cur Cursor; advanced past the block.
|
|
790
|
-
/// @return
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
uint abs = consume(cur, Keys.Response, 64, 64);
|
|
794
|
-
a = bytes32(msg.data[abs:abs + 32]);
|
|
795
|
-
b = bytes32(msg.data[abs + 32:abs + 64]);
|
|
1008
|
+
/// @return value Decoded host, account, asset, and meta.
|
|
1009
|
+
function unpackHostAccountAssetValue(Cur memory cur) internal pure returns (HostAccountAsset memory value) {
|
|
1010
|
+
(value.host, value.account, value.asset, value.meta) = unpackHostAccountAsset(cur, Keys.HostAccountAsset);
|
|
796
1011
|
}
|
|
797
1012
|
|
|
798
|
-
/// @notice Consume a
|
|
1013
|
+
/// @notice Consume a PAYOUT block and return its fields as separate values.
|
|
799
1014
|
/// @param cur Cursor; advanced past the block.
|
|
800
|
-
/// @return
|
|
801
|
-
/// @return
|
|
802
|
-
/// @return
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
1015
|
+
/// @return account Account identifier.
|
|
1016
|
+
/// @return asset Asset identifier.
|
|
1017
|
+
/// @return meta Asset metadata slot.
|
|
1018
|
+
/// @return amount Token amount.
|
|
1019
|
+
function unpackPayout(
|
|
1020
|
+
Cur memory cur
|
|
1021
|
+
) internal pure returns (bytes32 account, bytes32 asset, bytes32 meta, uint amount) {
|
|
1022
|
+
return unpackAccountAmount(cur, Keys.Payout);
|
|
808
1023
|
}
|
|
809
1024
|
|
|
810
|
-
/// @notice Consume a
|
|
1025
|
+
/// @notice Consume a PAYOUT block and return its fields as a struct.
|
|
811
1026
|
/// @param cur Cursor; advanced past the block.
|
|
812
|
-
/// @return
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
function unpackQuery96(Cur memory cur) internal pure returns (bytes32 a, bytes32 b, bytes32 c) {
|
|
816
|
-
uint abs = consume(cur, Keys.Query, 96, 96);
|
|
817
|
-
a = bytes32(msg.data[abs:abs + 32]);
|
|
818
|
-
b = bytes32(msg.data[abs + 32:abs + 64]);
|
|
819
|
-
c = bytes32(msg.data[abs + 64:abs + 96]);
|
|
1027
|
+
/// @return value Decoded account, asset, meta, and amount.
|
|
1028
|
+
function unpackPayoutValue(Cur memory cur) internal pure returns (AccountAmount memory value) {
|
|
1029
|
+
(value.account, value.asset, value.meta, value.amount) = unpackAccountAmount(cur, Keys.Payout);
|
|
820
1030
|
}
|
|
821
1031
|
|
|
822
|
-
/// @notice Consume
|
|
1032
|
+
/// @notice Consume an ACCOUNT_AMOUNT form block and return its fields as separate values.
|
|
823
1033
|
/// @param cur Cursor; advanced past the block.
|
|
824
|
-
/// @return
|
|
825
|
-
/// @return
|
|
826
|
-
/// @return
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
1034
|
+
/// @return account Account identifier.
|
|
1035
|
+
/// @return asset Asset identifier.
|
|
1036
|
+
/// @return meta Asset metadata slot.
|
|
1037
|
+
/// @return amount Token amount.
|
|
1038
|
+
function unpackAccountAmount(
|
|
1039
|
+
Cur memory cur
|
|
1040
|
+
) internal pure returns (bytes32 account, bytes32 asset, bytes32 meta, uint amount) {
|
|
1041
|
+
return unpackAccountAmount(cur, Keys.AccountAmount);
|
|
832
1042
|
}
|
|
833
1043
|
|
|
834
|
-
/// @notice Consume
|
|
1044
|
+
/// @notice Consume an ACCOUNT_AMOUNT form block and return its fields as a struct.
|
|
835
1045
|
/// @param cur Cursor; advanced past the block.
|
|
836
|
-
/// @return value Decoded
|
|
837
|
-
function
|
|
838
|
-
|
|
839
|
-
value.host = uint(bytes32(msg.data[abs:abs + 32]));
|
|
840
|
-
value.asset = bytes32(msg.data[abs + 32:abs + 64]);
|
|
841
|
-
value.meta = bytes32(msg.data[abs + 64:abs + 96]);
|
|
842
|
-
value.amount = uint(bytes32(msg.data[abs + 96:abs + 128]));
|
|
1046
|
+
/// @return value Decoded account, asset, meta, and amount.
|
|
1047
|
+
function unpackAccountAmountValue(Cur memory cur) internal pure returns (AccountAmount memory value) {
|
|
1048
|
+
(value.account, value.asset, value.meta, value.amount) = unpackAccountAmount(cur, Keys.AccountAmount);
|
|
843
1049
|
}
|
|
844
1050
|
|
|
845
1051
|
/// @notice Consume an ALLOCATION block and return its fields as separate values.
|
|
846
1052
|
/// @param cur Cursor; advanced past the block.
|
|
847
|
-
/// @return host Host node ID
|
|
1053
|
+
/// @return host Host node ID.
|
|
848
1054
|
/// @return asset Asset identifier.
|
|
849
1055
|
/// @return meta Asset metadata slot.
|
|
850
|
-
/// @return amount
|
|
851
|
-
function unpackAllocation(
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
meta = bytes32(msg.data[abs + 64:abs + 96]);
|
|
856
|
-
amount = uint(bytes32(msg.data[abs + 96:abs + 128]));
|
|
1056
|
+
/// @return amount Token amount.
|
|
1057
|
+
function unpackAllocation(
|
|
1058
|
+
Cur memory cur
|
|
1059
|
+
) internal pure returns (uint host, bytes32 asset, bytes32 meta, uint amount) {
|
|
1060
|
+
return unpackHostAmount(cur, Keys.Allocation);
|
|
857
1061
|
}
|
|
858
1062
|
|
|
859
1063
|
/// @notice Consume an ALLOCATION block and return its fields as a struct.
|
|
860
1064
|
/// @param cur Cursor; advanced past the block.
|
|
861
1065
|
/// @return value Decoded host, asset, meta, and amount.
|
|
862
1066
|
function unpackAllocationValue(Cur memory cur) internal pure returns (HostAmount memory value) {
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
1067
|
+
(value.host, value.asset, value.meta, value.amount) = unpackHostAmount(cur, Keys.Allocation);
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
/// @notice Consume an ALLOWANCE block and return its fields as separate values.
|
|
1071
|
+
/// @param cur Cursor; advanced past the block.
|
|
1072
|
+
/// @return host Host node ID.
|
|
1073
|
+
/// @return asset Asset identifier.
|
|
1074
|
+
/// @return meta Asset metadata slot.
|
|
1075
|
+
/// @return amount Token amount.
|
|
1076
|
+
function unpackAllowance(
|
|
1077
|
+
Cur memory cur
|
|
1078
|
+
) internal pure returns (uint host, bytes32 asset, bytes32 meta, uint amount) {
|
|
1079
|
+
return unpackHostAmount(cur, Keys.Allowance);
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
/// @notice Consume an ALLOWANCE block and return its fields as a struct.
|
|
1083
|
+
/// @param cur Cursor; advanced past the block.
|
|
1084
|
+
/// @return value Decoded host, asset, meta, and amount.
|
|
1085
|
+
function unpackAllowanceValue(Cur memory cur) internal pure returns (HostAmount memory value) {
|
|
1086
|
+
(value.host, value.asset, value.meta, value.amount) = unpackHostAmount(cur, Keys.Allowance);
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
/// @notice Consume a CUSTODY block and return its fields as separate values.
|
|
1090
|
+
/// @param cur Cursor; advanced past the block.
|
|
1091
|
+
/// @return host Host node ID.
|
|
1092
|
+
/// @return asset Asset identifier.
|
|
1093
|
+
/// @return meta Asset metadata slot.
|
|
1094
|
+
/// @return amount Token amount.
|
|
1095
|
+
function unpackCustody(
|
|
1096
|
+
Cur memory cur
|
|
1097
|
+
) internal pure returns (uint host, bytes32 asset, bytes32 meta, uint amount) {
|
|
1098
|
+
return unpackHostAmount(cur, Keys.Custody);
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
/// @notice Consume a CUSTODY block and return its fields as a struct.
|
|
1102
|
+
/// @param cur Cursor; advanced past the block.
|
|
1103
|
+
/// @return value Decoded host, asset, meta, and amount.
|
|
1104
|
+
function unpackCustodyValue(Cur memory cur) internal pure returns (HostAmount memory value) {
|
|
1105
|
+
(value.host, value.asset, value.meta, value.amount) = unpackHostAmount(cur, Keys.Custody);
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
/// @notice Consume a TRANSACTION block and return its fields as separate values.
|
|
1109
|
+
/// @param cur Cursor; advanced past the block.
|
|
1110
|
+
/// @return from Source account identifier.
|
|
1111
|
+
/// @return to Destination account identifier.
|
|
1112
|
+
/// @return asset Asset identifier.
|
|
1113
|
+
/// @return meta Asset metadata slot.
|
|
1114
|
+
/// @return amount Token amount.
|
|
1115
|
+
function unpackTransaction(
|
|
1116
|
+
Cur memory cur
|
|
1117
|
+
) internal pure returns (bytes32 from, bytes32 to, bytes32 asset, bytes32 meta, uint amount) {
|
|
1118
|
+
return unpackTransaction(cur, Keys.Transaction);
|
|
868
1119
|
}
|
|
869
1120
|
|
|
870
1121
|
/// @notice Consume a TRANSACTION block and return all fields as a struct.
|
|
871
1122
|
/// @param cur Cursor; advanced past the block.
|
|
872
1123
|
/// @return value Decoded from, to, asset, meta, and amount.
|
|
873
1124
|
function unpackTxValue(Cur memory cur) internal pure returns (Tx memory value) {
|
|
874
|
-
|
|
875
|
-
value.from = bytes32(msg.data[abs:abs + 32]);
|
|
876
|
-
value.to = bytes32(msg.data[abs + 32:abs + 64]);
|
|
877
|
-
value.asset = bytes32(msg.data[abs + 64:abs + 96]);
|
|
878
|
-
value.meta = bytes32(msg.data[abs + 96:abs + 128]);
|
|
879
|
-
value.amount = uint(bytes32(msg.data[abs + 128:abs + 160]));
|
|
1125
|
+
(value.from, value.to, value.asset, value.meta, value.amount) = unpackTransaction(cur);
|
|
880
1126
|
}
|
|
881
1127
|
|
|
882
|
-
//
|
|
883
|
-
|
|
884
|
-
|
|
1128
|
+
// Type-specific dynamic decoders
|
|
1129
|
+
|
|
1130
|
+
/// @notice Consume a STEP block and return its sub-command invocation fields.
|
|
1131
|
+
/// The `req` slice covers any additional payload bytes after the fixed head.
|
|
1132
|
+
/// @param cur Cursor; advanced past the block.
|
|
1133
|
+
/// @return target Destination node ID for the sub-command.
|
|
1134
|
+
/// @return value Native value to forward with the call.
|
|
1135
|
+
/// @return req Embedded request bytes for the sub-command.
|
|
1136
|
+
function unpackStep(Cur memory cur) internal pure returns (uint target, uint value, bytes calldata req) {
|
|
1137
|
+
(bytes32 a, bytes32 b, bytes calldata tail) = unpackHead64(cur, Keys.Step);
|
|
1138
|
+
return (uint(a), uint(b), tail);
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
/// @notice Consume a CALL block and return its target invocation fields.
|
|
1142
|
+
/// The `data` slice covers any additional payload bytes after the fixed head.
|
|
1143
|
+
/// @param cur Cursor; advanced past the block.
|
|
1144
|
+
/// @return target Target node ID to call.
|
|
1145
|
+
/// @return value Native value to forward with the call.
|
|
1146
|
+
/// @return data Raw calldata payload for the target.
|
|
1147
|
+
function unpackCall(Cur memory cur) internal pure returns (uint target, uint value, bytes calldata data) {
|
|
1148
|
+
(bytes32 a, bytes32 b, bytes calldata tail) = unpackHead64(cur, Keys.Call);
|
|
1149
|
+
return (uint(a), uint(b), tail);
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
// Type-specific validators
|
|
885
1153
|
|
|
886
1154
|
/// @notice Validate an AUTH block at position `i` and extract deadline and proof.
|
|
887
1155
|
/// Does not advance the cursor.
|
|
@@ -897,155 +1165,273 @@ library Cursors {
|
|
|
897
1165
|
proof = msg.data[abs + 64:cur.offset + next];
|
|
898
1166
|
}
|
|
899
1167
|
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
1168
|
+
// -------------------------------------------------------------------------
|
|
1169
|
+
// require* - validate + advance (like consume with content checks)
|
|
1170
|
+
// -------------------------------------------------------------------------
|
|
1171
|
+
|
|
1172
|
+
/// @notice Consume an asset block and assert it matches the expected asset.
|
|
1173
|
+
/// @param cur Cursor; advanced past the block.
|
|
1174
|
+
/// @param key Expected block type key.
|
|
904
1175
|
/// @param asset Expected asset identifier.
|
|
905
|
-
/// @
|
|
906
|
-
/// @return amount
|
|
907
|
-
function
|
|
908
|
-
|
|
1176
|
+
/// @return meta Metadata slot from the block.
|
|
1177
|
+
/// @return amount Amount from the block.
|
|
1178
|
+
function requireAssetAmount(
|
|
1179
|
+
Cur memory cur,
|
|
1180
|
+
bytes4 key,
|
|
1181
|
+
bytes32 asset
|
|
1182
|
+
) internal pure returns (bytes32 meta, uint amount) {
|
|
1183
|
+
uint abs = consume(cur, key, 96, 96);
|
|
909
1184
|
if (bytes32(msg.data[abs:abs + 32]) != asset) revert UnexpectedValue();
|
|
910
|
-
|
|
1185
|
+
meta = bytes32(msg.data[abs + 32:abs + 64]);
|
|
911
1186
|
amount = uint(bytes32(msg.data[abs + 64:abs + 96]));
|
|
912
1187
|
}
|
|
913
1188
|
|
|
914
|
-
/// @notice
|
|
915
|
-
///
|
|
916
|
-
/// @param
|
|
917
|
-
/// @param i Byte offset of the BALANCE block.
|
|
1189
|
+
/// @notice Consume an asset amount block and assert it matches the expected asset and meta.
|
|
1190
|
+
/// @param cur Cursor; advanced past the block.
|
|
1191
|
+
/// @param key Expected block type key.
|
|
918
1192
|
/// @param asset Expected asset identifier.
|
|
919
1193
|
/// @param meta Expected metadata slot.
|
|
920
|
-
/// @return amount
|
|
921
|
-
function
|
|
922
|
-
|
|
1194
|
+
/// @return amount Amount from the block.
|
|
1195
|
+
function requireAssetAmount(
|
|
1196
|
+
Cur memory cur,
|
|
1197
|
+
bytes4 key,
|
|
1198
|
+
bytes32 asset,
|
|
1199
|
+
bytes32 meta
|
|
1200
|
+
) internal pure returns (uint amount) {
|
|
1201
|
+
uint abs = consume(cur, key, 96, 96);
|
|
923
1202
|
if (bytes32(msg.data[abs:abs + 32]) != asset) revert UnexpectedValue();
|
|
924
1203
|
if (bytes32(msg.data[abs + 32:abs + 64]) != meta) revert UnexpectedValue();
|
|
925
1204
|
amount = uint(bytes32(msg.data[abs + 64:abs + 96]));
|
|
926
1205
|
}
|
|
927
1206
|
|
|
928
|
-
/// @notice
|
|
929
|
-
///
|
|
930
|
-
/// @param
|
|
931
|
-
/// @param i Byte offset of the MINIMUM block.
|
|
1207
|
+
/// @notice Consume an asset amount block, assert it matches the expected asset, and require the amount to be 1.
|
|
1208
|
+
/// @param cur Cursor; advanced past the block.
|
|
1209
|
+
/// @param key Expected block type key.
|
|
932
1210
|
/// @param asset Expected asset identifier.
|
|
933
|
-
/// @
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
(uint abs, ) = expect(cur, i, Keys.Minimum, 96, 96);
|
|
1211
|
+
/// @return meta Metadata slot from the block.
|
|
1212
|
+
function requireUnitAssetAmount(Cur memory cur, bytes4 key, bytes32 asset) internal pure returns (bytes32 meta) {
|
|
1213
|
+
uint abs = consume(cur, key, 96, 96);
|
|
937
1214
|
if (bytes32(msg.data[abs:abs + 32]) != asset) revert UnexpectedValue();
|
|
938
|
-
|
|
939
|
-
|
|
1215
|
+
meta = bytes32(msg.data[abs + 32:abs + 64]);
|
|
1216
|
+
if (uint(bytes32(msg.data[abs + 64:abs + 96])) != 1) revert UnexpectedValue();
|
|
940
1217
|
}
|
|
941
1218
|
|
|
942
|
-
/// @notice
|
|
943
|
-
///
|
|
944
|
-
/// @param cur Source cursor.
|
|
945
|
-
/// @param i Byte offset of the MAXIMUM block.
|
|
1219
|
+
/// @notice Consume a MINIMUM block and assert it matches the expected asset and meta.
|
|
1220
|
+
/// @param cur Cursor; advanced past the block.
|
|
946
1221
|
/// @param asset Expected asset identifier.
|
|
947
1222
|
/// @param meta Expected metadata slot.
|
|
948
|
-
/// @return amount
|
|
949
|
-
function
|
|
950
|
-
|
|
951
|
-
if (bytes32(msg.data[abs:abs + 32]) != asset) revert UnexpectedValue();
|
|
952
|
-
if (bytes32(msg.data[abs + 32:abs + 64]) != meta) revert UnexpectedValue();
|
|
953
|
-
amount = uint(bytes32(msg.data[abs + 64:abs + 96]));
|
|
1223
|
+
/// @return amount Minimum amount from the block.
|
|
1224
|
+
function requireMinimum(Cur memory cur, bytes32 asset, bytes32 meta) internal pure returns (uint amount) {
|
|
1225
|
+
return requireAssetAmount(cur, Keys.Minimum, asset, meta);
|
|
954
1226
|
}
|
|
955
1227
|
|
|
956
|
-
/// @notice
|
|
957
|
-
///
|
|
958
|
-
/// @param
|
|
959
|
-
/// @param i Byte offset of the CUSTODY block.
|
|
1228
|
+
/// @notice Consume a host amount block and assert it matches the expected host.
|
|
1229
|
+
/// @param cur Cursor; advanced past the block.
|
|
1230
|
+
/// @param key Expected block type key.
|
|
960
1231
|
/// @param host Expected host node ID.
|
|
961
|
-
/// @return
|
|
962
|
-
|
|
963
|
-
|
|
1232
|
+
/// @return asset Asset identifier from the block.
|
|
1233
|
+
/// @return meta Metadata slot from the block.
|
|
1234
|
+
/// @return amount Amount from the block.
|
|
1235
|
+
function requireHostAmount(
|
|
1236
|
+
Cur memory cur,
|
|
1237
|
+
bytes4 key,
|
|
1238
|
+
uint host
|
|
1239
|
+
) internal pure returns (bytes32 asset, bytes32 meta, uint amount) {
|
|
1240
|
+
uint abs = consume(cur, key, 128, 128);
|
|
964
1241
|
if (uint(bytes32(msg.data[abs:abs + 32])) != host) revert UnexpectedValue();
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
1242
|
+
asset = bytes32(msg.data[abs + 32:abs + 64]);
|
|
1243
|
+
meta = bytes32(msg.data[abs + 64:abs + 96]);
|
|
1244
|
+
amount = uint(bytes32(msg.data[abs + 96:abs + 128]));
|
|
968
1245
|
}
|
|
969
1246
|
|
|
970
|
-
|
|
971
|
-
// require* — validate + advance (like consume with content checks)
|
|
972
|
-
// -------------------------------------------------------------------------
|
|
973
|
-
|
|
974
|
-
/// @notice Consume an AUTH block at the current position and verify the command ID.
|
|
1247
|
+
/// @notice Consume a host amount block and assert it matches the expected host and asset.
|
|
975
1248
|
/// @param cur Cursor; advanced past the block.
|
|
976
|
-
/// @param
|
|
977
|
-
/// @
|
|
978
|
-
/// @
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
1249
|
+
/// @param key Expected block type key.
|
|
1250
|
+
/// @param host Expected host node ID.
|
|
1251
|
+
/// @param asset Expected asset identifier.
|
|
1252
|
+
/// @return meta Metadata slot from the block.
|
|
1253
|
+
/// @return amount Amount from the block.
|
|
1254
|
+
function requireHostAmount(
|
|
1255
|
+
Cur memory cur,
|
|
1256
|
+
bytes4 key,
|
|
1257
|
+
uint host,
|
|
1258
|
+
bytes32 asset
|
|
1259
|
+
) internal pure returns (bytes32 meta, uint amount) {
|
|
1260
|
+
uint abs = consume(cur, key, 128, 128);
|
|
1261
|
+
if (uint(bytes32(msg.data[abs:abs + 32])) != host) revert UnexpectedValue();
|
|
1262
|
+
if (bytes32(msg.data[abs + 32:abs + 64]) != asset) revert UnexpectedValue();
|
|
1263
|
+
meta = bytes32(msg.data[abs + 64:abs + 96]);
|
|
1264
|
+
amount = uint(bytes32(msg.data[abs + 96:abs + 128]));
|
|
982
1265
|
}
|
|
983
1266
|
|
|
984
|
-
/// @notice Consume
|
|
1267
|
+
/// @notice Consume a host amount block, assert it matches the expected host and asset, and require the amount to be 1.
|
|
985
1268
|
/// @param cur Cursor; advanced past the block.
|
|
1269
|
+
/// @param key Expected block type key.
|
|
1270
|
+
/// @param host Expected host node ID.
|
|
986
1271
|
/// @param asset Expected asset identifier.
|
|
987
|
-
/// @
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1272
|
+
/// @return meta Metadata slot from the block.
|
|
1273
|
+
function requireUnitHostAmount(
|
|
1274
|
+
Cur memory cur,
|
|
1275
|
+
bytes4 key,
|
|
1276
|
+
uint host,
|
|
1277
|
+
bytes32 asset
|
|
1278
|
+
) internal pure returns (bytes32 meta) {
|
|
1279
|
+
uint abs = consume(cur, key, 128, 128);
|
|
1280
|
+
if (uint(bytes32(msg.data[abs:abs + 32])) != host) revert UnexpectedValue();
|
|
1281
|
+
if (bytes32(msg.data[abs + 32:abs + 64]) != asset) revert UnexpectedValue();
|
|
1282
|
+
meta = bytes32(msg.data[abs + 64:abs + 96]);
|
|
1283
|
+
if (uint(bytes32(msg.data[abs + 96:abs + 128])) != 1) revert UnexpectedValue();
|
|
992
1284
|
}
|
|
993
1285
|
|
|
994
|
-
/// @notice Consume a
|
|
1286
|
+
/// @notice Consume a host account asset block and assert it matches the expected host and account.
|
|
995
1287
|
/// @param cur Cursor; advanced past the block.
|
|
996
|
-
/// @param
|
|
997
|
-
/// @param
|
|
998
|
-
/// @
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1288
|
+
/// @param key Expected block key.
|
|
1289
|
+
/// @param host Expected host node ID.
|
|
1290
|
+
/// @param account Expected account identifier.
|
|
1291
|
+
/// @return asset Asset identifier from the block.
|
|
1292
|
+
/// @return meta Metadata slot from the block.
|
|
1293
|
+
function requireHostAccountAsset(
|
|
1294
|
+
Cur memory cur,
|
|
1295
|
+
bytes4 key,
|
|
1296
|
+
uint host,
|
|
1297
|
+
bytes32 account
|
|
1298
|
+
) internal pure returns (bytes32 asset, bytes32 meta) {
|
|
1299
|
+
uint abs = consume(cur, key, 128, 128);
|
|
1300
|
+
if (uint(bytes32(msg.data[abs:abs + 32])) != host) revert UnexpectedValue();
|
|
1301
|
+
if (bytes32(msg.data[abs + 32:abs + 64]) != account) revert UnexpectedValue();
|
|
1302
|
+
asset = bytes32(msg.data[abs + 64:abs + 96]);
|
|
1303
|
+
meta = bytes32(msg.data[abs + 96:abs + 128]);
|
|
1002
1304
|
}
|
|
1003
1305
|
|
|
1004
|
-
/// @notice Consume a
|
|
1306
|
+
/// @notice Consume a host account asset block, assert it targets the expected host, and return account, asset, and meta.
|
|
1005
1307
|
/// @param cur Cursor; advanced past the block.
|
|
1006
|
-
/// @param
|
|
1007
|
-
/// @param
|
|
1008
|
-
/// @return
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1308
|
+
/// @param key Expected block key.
|
|
1309
|
+
/// @param host Expected host node ID.
|
|
1310
|
+
/// @return account Account identifier from the block.
|
|
1311
|
+
/// @return asset Asset identifier from the block.
|
|
1312
|
+
/// @return meta Metadata slot from the block.
|
|
1313
|
+
function requireHostAccountAsset(
|
|
1314
|
+
Cur memory cur,
|
|
1315
|
+
bytes4 key,
|
|
1316
|
+
uint host
|
|
1317
|
+
) internal pure returns (bytes32 account, bytes32 asset, bytes32 meta) {
|
|
1318
|
+
uint abs = consume(cur, key, 128, 128);
|
|
1319
|
+
if (uint(bytes32(msg.data[abs:abs + 32])) != host) revert UnexpectedValue();
|
|
1320
|
+
account = bytes32(msg.data[abs + 32:abs + 64]);
|
|
1321
|
+
asset = bytes32(msg.data[abs + 64:abs + 96]);
|
|
1322
|
+
meta = bytes32(msg.data[abs + 96:abs + 128]);
|
|
1012
1323
|
}
|
|
1013
1324
|
|
|
1014
|
-
/// @notice Consume a
|
|
1325
|
+
/// @notice Consume a HOST_ACCOUNT_ASSET form block, assert it targets the expected host, and return account, asset, and meta.
|
|
1015
1326
|
/// @param cur Cursor; advanced past the block.
|
|
1016
|
-
/// @param
|
|
1017
|
-
/// @
|
|
1018
|
-
/// @
|
|
1019
|
-
|
|
1020
|
-
|
|
1327
|
+
/// @param host Expected host node ID.
|
|
1328
|
+
/// @return account Account identifier from the block.
|
|
1329
|
+
/// @return asset Asset identifier from the block.
|
|
1330
|
+
/// @return meta Metadata slot from the block.
|
|
1331
|
+
function requireHostAccountAsset(
|
|
1332
|
+
Cur memory cur,
|
|
1333
|
+
uint host
|
|
1334
|
+
) internal pure returns (bytes32 account, bytes32 asset, bytes32 meta) {
|
|
1335
|
+
return requireHostAccountAsset(cur, Keys.HostAccountAsset, host);
|
|
1021
1336
|
}
|
|
1022
1337
|
|
|
1023
|
-
/// @notice Consume
|
|
1338
|
+
/// @notice Consume an AUTH block at the current position and verify the command ID.
|
|
1024
1339
|
/// @param cur Cursor; advanced past the block.
|
|
1025
|
-
/// @param
|
|
1026
|
-
/// @
|
|
1027
|
-
/// @return
|
|
1028
|
-
function
|
|
1029
|
-
|
|
1030
|
-
cur.i +=
|
|
1340
|
+
/// @param cid Expected command ID.
|
|
1341
|
+
/// @return deadline Expiry timestamp.
|
|
1342
|
+
/// @return proof Raw proof bytes.
|
|
1343
|
+
function requireAuth(Cur memory cur, uint cid) internal pure returns (uint deadline, bytes calldata proof) {
|
|
1344
|
+
(deadline, proof) = expectAuth(cur, cur.i, cid);
|
|
1345
|
+
cur.i += Sizes.Header + 64 + proof.length;
|
|
1031
1346
|
}
|
|
1032
1347
|
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
/// @
|
|
1038
|
-
|
|
1039
|
-
|
|
1348
|
+
// -------------------------------------------------------------------------
|
|
1349
|
+
// Trailing-block helpers (search after bound)
|
|
1350
|
+
// -------------------------------------------------------------------------
|
|
1351
|
+
|
|
1352
|
+
/// @notice Look for a NODE block anywhere in a calldata source and return its value.
|
|
1353
|
+
/// Scans from the start of `source` to the end.
|
|
1354
|
+
/// @param source Calldata block stream to search.
|
|
1355
|
+
/// @param backup Value to return if no NODE block is found.
|
|
1356
|
+
/// @return node Node ID from the NODE block, or `backup` if absent.
|
|
1357
|
+
function resolveNode(bytes calldata source, uint backup) internal pure returns (uint node) {
|
|
1358
|
+
Cur memory cur = open(source);
|
|
1359
|
+
uint i = find(cur, 0, Keys.Node);
|
|
1360
|
+
if (i == cur.len) return backup;
|
|
1361
|
+
|
|
1362
|
+
(uint abs, ) = expect(cur, i, Keys.Node, 32, 32);
|
|
1363
|
+
return uint(bytes32(msg.data[abs:abs + 32]));
|
|
1040
1364
|
}
|
|
1041
1365
|
|
|
1042
|
-
/// @notice
|
|
1043
|
-
///
|
|
1044
|
-
/// @param
|
|
1045
|
-
/// @
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1366
|
+
/// @notice Look for a NODE block anywhere in a calldata source and require a non-zero result.
|
|
1367
|
+
/// Scans from the start of `source` to the end.
|
|
1368
|
+
/// @param source Calldata block stream to search.
|
|
1369
|
+
/// @param backup Value to use if no NODE block is found.
|
|
1370
|
+
/// @return node Node ID from the NODE block, or `backup` if absent.
|
|
1371
|
+
function resolveNodeOrRevert(bytes calldata source, uint backup) internal pure returns (uint node) {
|
|
1372
|
+
node = resolveNode(source, backup);
|
|
1373
|
+
if (node == 0) revert ZeroNode();
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
/// @notice Look for an ACCOUNT block anywhere in a calldata source and return its value.
|
|
1377
|
+
/// Scans from the start of `source` to the end.
|
|
1378
|
+
/// @param source Calldata block stream to search.
|
|
1379
|
+
/// @param backup Account to return if no ACCOUNT block is found.
|
|
1380
|
+
/// @return account Account from the ACCOUNT block, or `backup` if absent.
|
|
1381
|
+
function resolveAccount(bytes calldata source, bytes32 backup) internal pure returns (bytes32 account) {
|
|
1382
|
+
Cur memory cur = open(source);
|
|
1383
|
+
uint i = find(cur, 0, Keys.Account);
|
|
1384
|
+
if (i == cur.len) return backup;
|
|
1385
|
+
|
|
1386
|
+
(uint abs, ) = expect(cur, i, Keys.Account, 32, 32);
|
|
1387
|
+
return bytes32(msg.data[abs:abs + 32]);
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
/// @notice Look for a NODE block after the current run boundary and return its value.
|
|
1391
|
+
/// Searches from `cur.bound` to the end of the source region.
|
|
1392
|
+
/// @param cur Source cursor; `bound` marks the end of the primary run.
|
|
1393
|
+
/// @param backup Value to return if no NODE block is found.
|
|
1394
|
+
/// @return node Node ID from the NODE block, or `backup` if absent.
|
|
1395
|
+
function nodeAfter(Cur memory cur, uint backup) internal pure returns (uint node) {
|
|
1396
|
+
uint i = find(cur, cur.bound, Keys.Node);
|
|
1397
|
+
if (i == cur.len) return backup;
|
|
1398
|
+
|
|
1399
|
+
(uint abs, ) = expect(cur, i, Keys.Node, 32, 32);
|
|
1400
|
+
return uint(bytes32(msg.data[abs:abs + 32]));
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
/// @notice Look for an ACCOUNT block after the current run boundary and return its value.
|
|
1404
|
+
/// Searches from `cur.bound` to the end of the source region.
|
|
1405
|
+
/// @param cur Source cursor; `bound` marks the end of the primary run.
|
|
1406
|
+
/// @param backup Account to return if no ACCOUNT block is found.
|
|
1407
|
+
/// @return account Account from the ACCOUNT block, or `backup` if absent.
|
|
1408
|
+
function accountAfter(Cur memory cur, bytes32 backup) internal pure returns (bytes32 account) {
|
|
1409
|
+
uint i = find(cur, cur.bound, Keys.Account);
|
|
1410
|
+
if (i == cur.len) return backup;
|
|
1411
|
+
|
|
1412
|
+
(uint abs, ) = expect(cur, i, Keys.Account, 32, 32);
|
|
1413
|
+
return bytes32(msg.data[abs:abs + 32]);
|
|
1049
1414
|
}
|
|
1050
1415
|
|
|
1416
|
+
/// @notice Parse the trailing AUTH block and compute the signed message hash.
|
|
1417
|
+
/// The AUTH block must occupy the final `Sizes.Auth` bytes of the source region
|
|
1418
|
+
/// and must begin after `cur.bound`.
|
|
1419
|
+
/// The signed slice covers from `cur.i` up to (but not including) the AUTH proof bytes.
|
|
1420
|
+
/// @param cur Source cursor; `bound` marks the end of the primary data region.
|
|
1421
|
+
/// @param cid Command ID that the signature must be bound to.
|
|
1422
|
+
/// @return hash keccak256 of the signed message slice.
|
|
1423
|
+
/// @return deadline Expiry timestamp from the AUTH block.
|
|
1424
|
+
/// @return proof Raw proof bytes (layout: `[bytes20 signer][bytes65 sig]`).
|
|
1425
|
+
function authLast(
|
|
1426
|
+
Cur memory cur,
|
|
1427
|
+
uint cid
|
|
1428
|
+
) internal pure returns (bytes32 hash, uint deadline, bytes calldata proof) {
|
|
1429
|
+
if (cur.len - cur.i < Sizes.Auth) revert MalformedBlocks();
|
|
1430
|
+
|
|
1431
|
+
uint i = cur.len - Sizes.Auth;
|
|
1432
|
+
if (i < cur.bound) revert MalformedBlocks();
|
|
1433
|
+
|
|
1434
|
+
(deadline, proof) = expectAuth(cur, i, cid);
|
|
1435
|
+
hash = keccak256(msg.data[cur.offset + cur.i:cur.offset + cur.len - Sizes.Proof]);
|
|
1436
|
+
}
|
|
1051
1437
|
}
|