@rootzero/contracts 1.25.0 → 1.26.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.
Files changed (68) hide show
  1. package/CHANGELOG.md +101 -0
  2. package/Codec.sol +1 -2
  3. package/Endpoints.sol +2 -0
  4. package/README.md +61 -51
  5. package/Utils.sol +2 -1
  6. package/codec/Blocks.sol +276 -88
  7. package/codec/Buffers.sol +24 -20
  8. package/codec/Decoders.sol +35 -37
  9. package/codec/Descriptors.sol +75 -72
  10. package/codec/Keys.sol +5 -1
  11. package/codec/Schema.sol +5 -1
  12. package/codec/Specs.sol +19 -9
  13. package/codec/Writers.sol +14 -19
  14. package/commands/Allocate.sol +8 -7
  15. package/commands/Base.sol +14 -49
  16. package/commands/Bootstrap.sol +95 -0
  17. package/commands/Burn.sol +7 -7
  18. package/commands/Cashout.sol +85 -0
  19. package/commands/Credit.sol +18 -16
  20. package/commands/Debit.sol +23 -19
  21. package/commands/Deposit.sol +13 -13
  22. package/commands/Payout.sol +8 -8
  23. package/commands/Provision.sol +13 -13
  24. package/commands/Recover.sol +7 -7
  25. package/commands/Relay.sol +22 -23
  26. package/commands/Repay.sol +36 -34
  27. package/commands/Settle.sol +24 -22
  28. package/commands/Withdraw.sol +7 -7
  29. package/commands/admin/AllowAssets.sol +7 -7
  30. package/commands/admin/Allowance.sol +7 -7
  31. package/commands/admin/Annotate.sol +7 -7
  32. package/commands/admin/Appoint.sol +7 -7
  33. package/commands/admin/Authorize.sol +7 -7
  34. package/commands/admin/Base.sol +5 -8
  35. package/commands/admin/DenyAssets.sol +7 -7
  36. package/commands/admin/Dismiss.sol +7 -7
  37. package/commands/admin/Execute.sol +8 -8
  38. package/commands/admin/Unauthorize.sol +7 -7
  39. package/core/Calls.sol +3 -3
  40. package/core/Endpoint.sol +7 -7
  41. package/core/Pipeline.sol +19 -20
  42. package/execution/Budget.sol +2 -3
  43. package/execution/Execution.sol +271 -509
  44. package/guards/Base.sol +1 -1
  45. package/guards/Revoke.sol +7 -7
  46. package/package.json +1 -1
  47. package/ports/Allowance.sol +3 -3
  48. package/ports/Assets.sol +7 -7
  49. package/ports/Base.sol +1 -1
  50. package/ports/Credit.sol +3 -3
  51. package/ports/Debit.sol +3 -3
  52. package/ports/Dispatch.sol +3 -3
  53. package/ports/Pipe.sol +3 -3
  54. package/ports/Post.sol +3 -3
  55. package/ports/Redeem.sol +3 -3
  56. package/queries/Assets.sol +3 -3
  57. package/queries/Balances.sol +3 -3
  58. package/queries/Base.sol +1 -1
  59. package/utils/Accounts.sol +1 -3
  60. package/utils/Actions.sol +2 -0
  61. package/utils/Assets.sol +1 -10
  62. package/utils/Cursors.sol +60 -116
  63. package/utils/Errors.sol +50 -0
  64. package/utils/Ids.sol +2 -5
  65. package/utils/Lanes.sol +0 -2
  66. package/utils/Nodes.sol +1 -3
  67. package/utils/Utils.sol +2 -9
  68. package/codec/Readers.sol +0 -190
@@ -5,11 +5,10 @@ import {AssetAmount, AccountAsset, HostAsset, AccountAmount, HostAmount, HostAcc
5
5
  import {Blocks} from "../codec/Blocks.sol";
6
6
  import {Buffers} from "../codec/Buffers.sol";
7
7
  import {Sizes, Specs} from "../codec/Specs.sol";
8
- import {Descriptors} from "../codec/Descriptors.sol";
9
8
  import {Cursors, Cur} from "../utils/Cursors.sol";
9
+ import {InsufficientValue, UnconsumedData} from "../utils/Errors.sol";
10
10
  import {Lanes} from "../utils/Lanes.sol";
11
11
  import {Budget} from "./Budget.sol";
12
- import {max16} from "../utils/Utils.sol";
13
12
 
14
13
  /// @notice Mutable state shared across one endpoint execution.
15
14
  /// @dev `decoders` contains tagged input and state cursor lanes. Cursor operations
@@ -18,165 +17,31 @@ struct Execution {
18
17
  bytes32 account;
19
18
  uint budget;
20
19
  uint decoders;
21
- uint writers;
22
- bytes transactions;
20
+ uint writer;
23
21
  bytes output;
24
22
  }
25
23
 
26
24
  /// @title Executions
27
- /// @notice Opening, decoding, output, transaction, and value helpers for executions.
25
+ /// @notice Opening, decoding, output, and value helpers for executions.
28
26
  /// @dev `output*` helpers consume memory inputs; `outputCopy*` helpers copy
29
27
  /// calldata inputs directly to the output lane.
30
28
  library Executions {
31
29
  using Cursors for uint;
32
30
 
33
- /// @dev Thrown when an execution attempts to spend more value than remains in its budget.
34
- error InsufficientValue();
35
- /// @dev Decoder block counts do not form compatible descriptor groups.
36
- error BadRatio();
37
- /// @dev A descriptor-empty lane received a non-empty block source.
31
+ /// @dev Command-defined lane policy rejected data in an expected-empty lane.
38
32
  error ZeroStride();
39
33
 
40
34
  // -------------------------------------------------------------------------
41
35
  // Opening
42
36
  // -------------------------------------------------------------------------
43
37
 
44
- /// @dev A lane with stride zero accepts only an empty source and returns the zero cursor.
45
- /// @param source Calldata source for the decoder lane.
46
- /// @param descriptor Packed endpoint descriptor.
47
- /// @param lane Input or state lane identifier.
48
- /// @return cur Tagged packed decoder cursor carrying its raw block count, or zero for an absent lane.
49
- function openDecoder(bytes calldata source, uint descriptor, uint8 lane) private pure returns (uint cur) {
50
- uint stride = Descriptors.stride(descriptor, lane);
51
- (uint abs, uint limit) = Cursors.bounds(source);
52
- if (stride == 0 && abs == limit) return 0;
53
- if (stride == 0) revert ZeroStride();
54
-
55
- bytes4 key = Descriptors.key(descriptor, lane);
56
- (uint count, uint end) = Blocks.runExact(abs, limit, key);
57
- if (count == 0) revert Blocks.EmptyRun();
58
- cur = Cursors.create(abs, end - abs, count, 0, lane);
59
- }
60
-
61
- /// @dev Convert one decoder lane's raw block count into descriptor groups.
62
- function groupCount(uint decoders, uint descriptor, uint8 lane) private pure returns (uint groups) {
63
- uint stride = Descriptors.stride(descriptor, lane);
64
- if (stride == 0) return 0;
65
-
66
- uint count = decoders.select(lane).count();
67
- if (count % stride != 0) revert BadRatio();
68
- groups = count / stride;
69
- }
70
-
71
- /// @dev Reconcile decoder lane groups once at endpoint execution opening.
72
- function reconcile(uint decoders, uint descriptor, uint expected) private pure returns (uint groups) {
73
- uint input = groupCount(decoders, descriptor, Lanes.Input);
74
- uint state = groupCount(decoders, descriptor, Lanes.State);
75
- if (input != 0 && state != 0 && input != state) revert BadRatio();
76
-
77
- groups = input != 0 ? input : state;
78
- if (groups != 0 && expected != 0 && groups != expected) revert BadRatio();
79
- if (groups == 0) groups = expected;
80
- max16(groups);
81
- }
82
-
83
- /// @dev Initialize one tagged writer cursor from a descriptor lane.
84
- /// @param descriptor Packed endpoint descriptor.
85
- /// @param batches Reconciled execution batch count.
86
- /// @param lane Output or transaction lane identifier.
87
- /// @param padding Additional logical capacity reserved for the lane.
88
- /// @return cur Tagged packed writer cursor, or zero for an absent lane.
89
- function initWriter(uint descriptor, uint batches, uint8 lane, uint padding) private pure returns (uint cur) {
90
- (uint capacity, bool growable) = Descriptors.allocation(descriptor, lane, batches);
91
- if (capacity == 0) return 0;
92
-
93
- uint count = batches * Descriptors.stride(descriptor, lane);
94
- if (padding != 0) count += padding / Sizes.Transaction;
95
- cur = Buffers.cursor(capacity + padding, count, growable, lane);
96
- }
97
-
98
- /// @dev Open and pair the input and state decoder cursors.
99
- /// @param state State calldata source.
100
- /// @param input Input calldata source.
101
- /// @param descriptor Packed endpoint descriptor.
102
- /// @return Paired decoder cursors.
103
- function decodeCursors(bytes calldata state, bytes calldata input, uint descriptor) private pure returns (uint) {
104
- return
105
- Cursors.pair(openDecoder(input, descriptor, Lanes.Input), openDecoder(state, descriptor, Lanes.State));
106
- }
107
-
108
- /// @dev Initialize and pair the output and transaction writer cursors.
109
- /// @param descriptor Packed endpoint descriptor.
110
- /// @param batches Reconciled execution batch count.
111
- /// @return Paired writer cursors.
112
- function writerCursors(uint descriptor, uint batches) private pure returns (uint) {
113
- return
114
- Cursors.pair(
115
- initWriter(descriptor, batches, Lanes.Output, 0),
116
- initWriter(descriptor, batches, Lanes.Transactions, Sizes.Transaction)
117
- );
118
- }
119
-
120
- /// @dev Complete execution initialization from pre-opened decoder cursors.
121
- /// @param decoders Packed decoder cursor or pair.
122
- /// @param descriptor Packed endpoint descriptor.
123
- /// @param batches Expected batch count; zero derives it from the decoders.
124
- /// @return exec Initialized execution.
125
- function open(uint decoders, uint descriptor, uint batches) private view returns (Execution memory exec) {
126
- exec.budget = msg.value;
127
- exec.decoders = decoders;
128
- batches = reconcile(decoders, descriptor, batches);
129
- exec.writers = writerCursors(descriptor, batches);
130
- }
131
-
132
38
  /// @notice Open an execution containing only the current call-value budget.
133
- /// @dev Decoders, writers, output, and transactions remain empty.
39
+ /// @dev Decoders, writer, and output remain empty.
134
40
  /// @return exec Budget-only execution initialized with `msg.value`.
135
41
  function open() internal view returns (Execution memory exec) {
136
42
  exec.budget = msg.value;
137
43
  }
138
44
 
139
- /// @notice Open an execution with an input decoder and descriptor writers.
140
- /// @param input Input block stream.
141
- /// @param descriptor Packed endpoint descriptor.
142
- /// @param batches Expected batch count; zero derives it from the input run.
143
- /// @return exec Initialized execution.
144
- function openInput(
145
- bytes calldata input,
146
- uint descriptor,
147
- uint batches
148
- ) internal view returns (Execution memory exec) {
149
- return open(openDecoder(input, descriptor, Lanes.Input), descriptor, batches);
150
- }
151
-
152
- /// @notice Open an execution with a state decoder and descriptor writers.
153
- /// @param state State block stream.
154
- /// @param descriptor Packed endpoint descriptor.
155
- /// @param batches Expected batch count; zero derives it from the state run.
156
- /// @return exec Initialized execution.
157
- function openState(
158
- bytes calldata state,
159
- uint descriptor,
160
- uint batches
161
- ) internal view returns (Execution memory exec) {
162
- return open(openDecoder(state, descriptor, Lanes.State), descriptor, batches);
163
- }
164
-
165
- /// @notice Open an execution with paired state and input decoders.
166
- /// @param state State block stream.
167
- /// @param input Input block stream.
168
- /// @param descriptor Packed endpoint descriptor.
169
- /// @param batches Expected batch count; zero derives it from the decoder runs.
170
- /// @return exec Initialized execution.
171
- function open(
172
- bytes calldata state,
173
- bytes calldata input,
174
- uint descriptor,
175
- uint batches
176
- ) internal view returns (Execution memory exec) {
177
- return open(decodeCursors(state, input, descriptor), descriptor, batches);
178
- }
179
-
180
45
  // -------------------------------------------------------------------------
181
46
  // Traversal
182
47
  // -------------------------------------------------------------------------
@@ -188,99 +53,134 @@ library Executions {
188
53
  return exec.decoders.any();
189
54
  }
190
55
 
191
- /// @notice Return a decoder lane's current absolute calldata position.
56
+ /// @notice Make the input decoder the active low lane.
57
+ /// @return exec The same execution, allowing chained decoding.
58
+ function oninput(Execution memory exec) internal pure returns (Execution memory) {
59
+ exec.decoders = exec.decoders.select(Lanes.Input);
60
+ return exec;
61
+ }
62
+
63
+ /// @notice Make the state decoder the active low lane.
64
+ /// @return exec The same execution, allowing chained decoding.
65
+ function onstate(Execution memory exec) internal pure returns (Execution memory) {
66
+ exec.decoders = exec.decoders.select(Lanes.State);
67
+ return exec;
68
+ }
69
+
70
+ /// @notice Return the active decoder's current absolute calldata position.
192
71
  /// @param exec Execution whose decoder is inspected.
193
- /// @param lane Decoder lane to select.
194
- /// @return Current absolute calldata position of the selected lane.
195
- function absolute(Execution memory exec, uint8 lane) internal pure returns (uint) {
196
- return exec.decoders.select(lane).absolute();
72
+ /// @return Current absolute calldata position of the active lane.
73
+ function absolute(Execution memory exec) internal pure returns (uint) {
74
+ return exec.decoders.absolute();
197
75
  }
198
76
 
199
- /// @dev Return the complete validated calldata source for a decoder lane.
77
+ /// @dev Return the complete bounded calldata source for a decoder lane.
200
78
  /// @dev Does not consume or depend on the lane's current position. A lane
201
79
  /// absent because its descriptor is EMPTY returns an empty calldata slice.
202
80
  /// @param exec Execution whose input or state source is requested.
203
- /// @param lane Input or state decoder lane.
204
81
  /// @return data Complete calldata region represented by the lane.
205
82
  function raw(Execution memory exec, uint8 lane) private pure returns (bytes calldata data) {
206
83
  if (!exec.decoders.contains(lane)) return msg.data[0:0];
207
84
 
208
85
  uint cur = exec.decoders.select(lane);
209
- (, uint offset, uint len) = cur.decode();
210
- if (len > msg.data.length || offset > msg.data.length - len) revert Blocks.MalformedBlocks();
211
- return msg.data[offset:offset + len];
86
+ if (uint8(cur >> 96) == 0) return msg.data[0:0];
87
+ (uint abs, uint end) = cur.bounds();
88
+ if (end > msg.data.length) revert Blocks.MalformedBlocks();
89
+ return msg.data[abs:end];
212
90
  }
213
91
 
214
- /// @notice Return the complete validated command state without consuming it.
92
+ /// @notice Return the complete bounded command state without consuming it.
215
93
  /// @dev Remains the complete original state after the state cursor advances.
216
94
  function rawState(Execution memory exec) internal pure returns (bytes calldata) {
217
95
  return raw(exec, Lanes.State);
218
96
  }
219
97
 
220
- /// @notice Return the complete validated endpoint input without consuming it.
98
+ /// @notice Return the complete state lane and mark it fully consumed.
99
+ /// @dev Intended for commands that forward their state intact without decoding it.
100
+ /// A lane declared EMPTY is returned empty and remains unconsumed so close
101
+ /// still rejects any state supplied against the descriptor.
102
+ function takeRawState(Execution memory exec) internal pure returns (bytes calldata data) {
103
+ data = raw(exec, Lanes.State);
104
+ if (!exec.decoders.contains(Lanes.State)) return data;
105
+
106
+ uint cur = exec.decoders.select(Lanes.State);
107
+ if (uint8(cur >> 96) == 0) return data;
108
+ (, , uint len) = cur.decode();
109
+ exec.decoders = cur.seek(len);
110
+ }
111
+
112
+ /// @notice Return the complete bounded endpoint input without consuming it.
221
113
  /// @dev Remains the complete original input after the input cursor advances.
222
114
  function rawInput(Execution memory exec) internal pure returns (bytes calldata) {
223
115
  return raw(exec, Lanes.Input);
224
116
  }
225
117
 
118
+ /// @notice Return the complete input lane and mark it fully consumed.
119
+ /// @dev Intended for endpoints that forward their input intact without decoding it.
120
+ /// A lane declared EMPTY is returned empty and remains unconsumed so close
121
+ /// still rejects any input supplied against the descriptor.
122
+ function takeRawInput(Execution memory exec) internal pure returns (bytes calldata data) {
123
+ data = raw(exec, Lanes.Input);
124
+ if (!exec.decoders.contains(Lanes.Input)) return data;
125
+
126
+ uint cur = exec.decoders.select(Lanes.Input);
127
+ if (uint8(cur >> 96) == 0) return data;
128
+ (, , uint len) = cur.decode();
129
+ exec.decoders = cur.seek(len);
130
+ }
131
+
226
132
  /// @notice Return whether the next block on `lane` has `key` and an empty payload.
227
133
  /// @param exec Execution whose decoder is inspected without advancing.
228
- /// @param lane Decoder lane to inspect.
229
134
  /// @param key Expected block key.
230
135
  /// @return Whether a complete matching empty block header occurs next.
231
- function isEmpty(Execution memory exec, uint8 lane, bytes4 key) internal pure returns (bool) {
232
- uint cur = exec.decoders.select(lane);
136
+ function isEmpty(Execution memory exec, bytes4 key) internal pure returns (bool) {
137
+ uint cur = exec.decoders;
233
138
  (uint i, uint offset, uint len) = cur.decode();
234
139
  return Blocks.isEmpty(offset + i, offset + len, key);
235
140
  }
236
141
 
237
142
  /// @notice Validate and consume the next block from an execution decoder lane.
238
- /// @param exec Execution whose selected decoder cursor is advanced over the complete block.
239
- /// @param lane Execution decoder lane to select.
143
+ /// @param exec Execution whose active decoder cursor is advanced over the complete block.
240
144
  /// @param spec Expected block specification.
241
145
  /// @return abs Absolute position of the first payload byte.
242
146
  /// @return end Absolute position immediately after the payload.
243
- function consume(Execution memory exec, uint8 lane, uint spec) internal pure returns (uint abs, uint end) {
244
- uint cur = exec.decoders.select(lane);
147
+ function consume(Execution memory exec, uint spec) internal pure returns (uint abs, uint end) {
148
+ uint cur = exec.decoders;
245
149
  (abs, end) = Blocks.expect(cur.absolute(), spec);
246
150
  exec.decoders = cur.seekAbs(end);
247
151
  }
248
152
 
249
153
  /// @notice Validate a known key and consume the next block from an execution decoder lane.
250
154
  /// @dev Validates no payload-size constraint beyond proving the complete block
251
- /// lies within the selected lane's logical region.
252
- /// @param exec Execution whose selected decoder cursor is advanced over the complete block.
253
- /// @param lane Execution decoder lane to select.
155
+ /// lies within the active lane's logical region.
156
+ /// @param exec Execution whose active decoder cursor is advanced over the complete block.
254
157
  /// @param key Expected block key.
255
158
  /// @return abs Absolute position of the first payload byte.
256
159
  /// @return end Absolute position immediately after the payload.
257
- function consume(Execution memory exec, uint8 lane, bytes4 key) internal pure returns (uint abs, uint end) {
258
- uint cur = exec.decoders.select(lane);
160
+ function consume(Execution memory exec, bytes4 key) internal pure returns (uint abs, uint end) {
161
+ uint cur = exec.decoders;
259
162
  (abs, end) = Blocks.expectKey(cur.absolute(), key);
260
163
  exec.decoders = cur.seekAbs(end);
261
164
  }
262
165
 
263
166
  /// @notice Validate and consume one block from a decoder lane, returning its complete encoding.
264
- /// @param exec Execution whose selected decoder cursor is advanced past the block.
265
- /// @param lane Execution decoder lane to select.
167
+ /// @param exec Execution whose active decoder cursor is advanced past the block.
266
168
  /// @param key Expected block key.
267
169
  /// @return data Calldata view of the complete block, including its header.
268
170
  function takeBlock(
269
171
  Execution memory exec,
270
- uint8 lane,
271
172
  bytes4 key
272
173
  ) internal pure returns (bytes calldata data) {
273
- (uint abs, uint end) = consume(exec, lane, key);
174
+ (uint abs, uint end) = consume(exec, key);
274
175
  data = msg.data[abs - Sizes.Header:end];
275
176
  }
276
177
 
277
178
  /// @notice Consume a matching empty block from an execution decoder lane when present.
278
- /// @param exec Execution whose selected decoder advances only for a matching empty block.
279
- /// @param lane Decoder lane to consume.
179
+ /// @param exec Execution whose active decoder advances only for a matching empty block.
280
180
  /// @param key Expected block key.
281
181
  /// @return Whether an empty block was consumed.
282
- function tryConsumeEmpty(Execution memory exec, uint8 lane, bytes4 key) internal pure returns (bool) {
283
- uint cur = exec.decoders.select(lane);
182
+ function tryConsumeEmpty(Execution memory exec, bytes4 key) internal pure returns (bool) {
183
+ uint cur = exec.decoders;
284
184
  (uint i, uint offset, uint size) = cur.decode();
285
185
  (bytes4 current, uint len) = Blocks.peek(offset + i, offset + size);
286
186
  if (current != key || len != 0) return false;
@@ -289,34 +189,31 @@ library Executions {
289
189
  }
290
190
 
291
191
  /// @notice Validate and enter the payload of the next block in an execution decoder lane.
292
- /// @dev The selected lane remains in its existing frame so callers can decode
192
+ /// @dev The active lane remains in its existing frame so callers can decode
293
193
  /// child blocks in place. Callers should prove complete payload consumption
294
194
  /// with `exec.expectAbs(end)` after decoding the children from the same lane.
295
- /// @param exec Execution whose selected decoder cursor advances over the block header.
296
- /// @param lane Execution decoder lane to select.
195
+ /// @param exec Execution whose active decoder cursor advances over the block header.
297
196
  /// @param spec Expected parent block specification.
298
197
  /// @return abs Absolute position of the first payload byte.
299
198
  /// @return end Absolute position immediately after the payload.
300
- function enter(Execution memory exec, uint8 lane, uint spec) internal pure returns (uint abs, uint end) {
301
- return enter(exec, lane, spec, 0);
199
+ function enter(Execution memory exec, uint spec) internal pure returns (uint abs, uint end) {
200
+ return enter(exec, spec, 0);
302
201
  }
303
202
 
304
203
  /// @notice Validate a parent block and advance over a fixed payload prefix.
305
204
  /// @dev `amount` is relative to the payload start and cannot exceed the
306
205
  /// current parent payload. The returned `abs` remains the payload start.
307
- /// @param exec Execution whose selected decoder advances over the header and fixed prefix.
308
- /// @param lane Execution decoder lane to select.
206
+ /// @param exec Execution whose active decoder advances over the header and fixed prefix.
309
207
  /// @param spec Expected parent block specification.
310
208
  /// @param amount Number of initial payload bytes to advance over.
311
209
  /// @return abs Absolute position of the first payload byte.
312
210
  /// @return end Absolute position immediately after the payload.
313
211
  function enter(
314
212
  Execution memory exec,
315
- uint8 lane,
316
213
  uint spec,
317
214
  uint amount
318
215
  ) internal pure returns (uint abs, uint end) {
319
- uint cur = exec.decoders.select(lane);
216
+ uint cur = exec.decoders;
320
217
  (abs, end) = Blocks.expect(cur.absolute(), spec);
321
218
  if (amount > end - abs) revert Blocks.InvalidBlock();
322
219
  exec.decoders = cur.seekAbs(abs + amount);
@@ -324,26 +221,24 @@ library Executions {
324
221
 
325
222
  /// @notice Advance an execution decoder lane by a raw byte count.
326
223
  /// @dev No block header or schema is validated.
327
- /// @param exec Execution whose selected decoder cursor is advanced.
328
- /// @param lane Decoder lane to select.
224
+ /// @param exec Execution whose active decoder cursor is advanced.
329
225
  /// @param amount Number of bytes to advance.
330
- function advance(Execution memory exec, uint8 lane, uint amount) internal pure {
331
- uint cur = exec.decoders.select(lane);
226
+ function advance(Execution memory exec, uint amount) internal pure {
227
+ uint cur = exec.decoders;
332
228
  exec.decoders = cur.advance(amount);
333
229
  }
334
230
 
335
231
  /// @notice Take a raw byte range from an execution decoder lane.
336
232
  /// @dev No block header or schema is validated.
337
- /// @param exec Execution whose selected decoder cursor is advanced.
338
- /// @param lane Decoder lane to select.
233
+ /// @param exec Execution whose active decoder cursor is advanced.
339
234
  /// @param amount Number of bytes to take.
340
235
  /// @return abs Absolute position of the first taken byte.
341
- function take(Execution memory exec, uint8 lane, uint amount) internal pure returns (uint abs) {
342
- (exec.decoders, abs) = exec.decoders.consume(lane, amount);
236
+ function take(Execution memory exec, uint amount) internal pure returns (uint abs) {
237
+ (exec.decoders, abs) = exec.decoders.consume(amount);
343
238
  }
344
239
 
345
240
  /// @notice Require the active execution decoder to be at absolute position `abs`.
346
- /// @dev The most recent lane-aware decoder operation determines the active lane.
241
+ /// @dev `oninput()` and `onstate()` determine the active lane.
347
242
  /// @param exec Execution whose active decoder position is validated.
348
243
  /// @param abs Expected absolute position.
349
244
  function expectAbs(Execution memory exec, uint abs) internal pure {
@@ -352,19 +247,17 @@ library Executions {
352
247
 
353
248
  /// @notice Consume a LIST block and return a cursor scoped to its payload.
354
249
  /// @param exec Execution whose decoder is advanced.
355
- /// @param lane Decoder lane containing the LIST block.
356
250
  /// @return items Cursor over the nested list items.
357
- function list(Execution memory exec, uint8 lane) internal pure returns (Cur memory items) {
358
- return list(exec, Specs.List, lane);
251
+ function list(Execution memory exec) internal pure returns (Cur memory items) {
252
+ return list(exec, Specs.List);
359
253
  }
360
254
 
361
255
  /// @notice Consume a list block described by `spec` and return a cursor scoped to its payload.
362
256
  /// @param exec Execution whose decoder is advanced.
363
257
  /// @param spec Custom list block specification.
364
- /// @param lane Decoder lane containing the list block.
365
258
  /// @return items Cursor over the nested list items.
366
- function list(Execution memory exec, uint spec, uint8 lane) internal pure returns (Cur memory items) {
367
- (uint abs, uint end) = consume(exec, lane, spec);
259
+ function list(Execution memory exec, uint spec) internal pure returns (Cur memory items) {
260
+ (uint abs, uint end) = consume(exec, spec);
368
261
  items.state = Cursors.create(abs, end - abs, 0, 0, 0);
369
262
  }
370
263
 
@@ -372,400 +265,350 @@ library Executions {
372
265
  // Fixed-width block decoding
373
266
  // -------------------------------------------------------------------------
374
267
 
375
- /// @dev Return the next raw calldata word from `lane` and advance by `size` bytes.
376
- function next(Execution memory exec, uint8 lane, uint size) private pure returns (bytes32 value) {
377
- value = Blocks.read32(take(exec, lane, size));
268
+ /// @dev Return the next raw calldata word from the active lane and advance by `size` bytes.
269
+ function next(Execution memory exec, uint size) private pure returns (bytes32 value) {
270
+ value = Blocks.read32(take(exec, size));
378
271
  }
379
272
 
380
273
  /// @notice Return the next raw byte from a decoder lane and advance it by one byte.
381
- function next1(Execution memory exec, uint8 lane) internal pure returns (bytes1 value) {
382
- value = bytes1(next(exec, lane, 1));
274
+ function next1(Execution memory exec) internal pure returns (bytes1 value) {
275
+ value = bytes1(next(exec, 1));
383
276
  }
384
277
 
385
278
  /// @notice Return the next two raw bytes from a decoder lane and advance it by two bytes.
386
- function next2(Execution memory exec, uint8 lane) internal pure returns (bytes2 value) {
387
- value = bytes2(next(exec, lane, 2));
279
+ function next2(Execution memory exec) internal pure returns (bytes2 value) {
280
+ value = bytes2(next(exec, 2));
388
281
  }
389
282
 
390
283
  /// @notice Return the next four raw bytes from a decoder lane and advance it by four bytes.
391
- function next4(Execution memory exec, uint8 lane) internal pure returns (bytes4 value) {
392
- value = bytes4(next(exec, lane, 4));
284
+ function next4(Execution memory exec) internal pure returns (bytes4 value) {
285
+ value = bytes4(next(exec, 4));
393
286
  }
394
287
 
395
288
  /// @notice Return the next eight raw bytes from a decoder lane and advance it by eight bytes.
396
- function next8(Execution memory exec, uint8 lane) internal pure returns (bytes8 value) {
397
- value = bytes8(next(exec, lane, 8));
289
+ function next8(Execution memory exec) internal pure returns (bytes8 value) {
290
+ value = bytes8(next(exec, 8));
398
291
  }
399
292
 
400
293
  /// @notice Return the next sixteen raw bytes from a decoder lane and advance it by sixteen bytes.
401
- function next16(Execution memory exec, uint8 lane) internal pure returns (bytes16 value) {
402
- value = bytes16(next(exec, lane, 16));
294
+ function next16(Execution memory exec) internal pure returns (bytes16 value) {
295
+ value = bytes16(next(exec, 16));
403
296
  }
404
297
 
405
298
  /// @notice Return the next raw calldata word from a decoder lane and advance it.
406
- /// @param exec Execution whose selected decoder cursor advances by one word.
407
- /// @param lane Execution decoder lane to select.
408
- /// @return value Raw word at the selected lane's previous position.
409
- function next32(Execution memory exec, uint8 lane) internal pure returns (bytes32 value) {
410
- value = next(exec, lane, Sizes.Word);
299
+ /// @param exec Execution whose active decoder cursor advances by one word.
300
+ /// @return value Raw word at the active lane's previous position.
301
+ function next32(Execution memory exec) internal pure returns (bytes32 value) {
302
+ value = next(exec, Sizes.Word);
411
303
  }
412
304
 
413
- /// @notice Decode one fixed 32-byte payload from `lane`.
305
+ /// @notice Decode one fixed 32-byte payload from the active lane.
414
306
  /// @param exec Execution whose decoder is advanced.
415
- /// @param lane Decoder lane to consume.
416
307
  /// @param spec Expected fixed block specification.
417
308
  /// @return value Decoded payload word.
418
- function unpack32(Execution memory exec, uint8 lane, uint spec) internal pure returns (bytes32 value) {
309
+ function unpack32(Execution memory exec, uint spec) internal pure returns (bytes32 value) {
419
310
  uint abs;
420
- (exec.decoders, abs) = exec.decoders.consume(lane, Sizes.B32);
311
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.B32);
421
312
  if (Blocks.header(abs, Specs.key(spec)) != 32) revert Blocks.InvalidBlock();
422
313
  assembly ("memory-safe") {
423
314
  value := calldataload(add(abs, 0x08))
424
315
  }
425
316
  }
426
317
 
427
- /// @notice Decode and consume one ACCOUNT block from `lane`.
318
+ /// @notice Decode and consume one ACCOUNT block from the active lane.
428
319
  /// @param exec Execution whose decoder is advanced.
429
- /// @param lane Decoder lane to consume.
430
320
  /// @return account Decoded account identifier.
431
- function unpackAccount(Execution memory exec, uint8 lane) internal pure returns (bytes32 account) {
321
+ function unpackAccount(Execution memory exec) internal pure returns (bytes32 account) {
432
322
  uint abs;
433
- (exec.decoders, abs) = exec.decoders.consume(lane, Sizes.B32);
323
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.B32);
434
324
  account = Blocks.unpackAccount(abs);
435
325
  }
436
326
 
437
- /// @notice Decode and consume one NODE block from `lane`.
327
+ /// @notice Decode and consume one NODE block from the active lane.
438
328
  /// @param exec Execution whose decoder is advanced.
439
- /// @param lane Decoder lane to consume.
440
329
  /// @return node Decoded node identifier.
441
- function unpackNode(Execution memory exec, uint8 lane) internal pure returns (uint node) {
330
+ function unpackNode(Execution memory exec) internal pure returns (uint node) {
442
331
  uint abs;
443
- (exec.decoders, abs) = exec.decoders.consume(lane, Sizes.B32);
332
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.B32);
444
333
  node = Blocks.unpackNode(abs);
445
334
  }
446
335
 
447
- /// @notice Decode and consume one ASSET block from `lane`.
336
+ /// @notice Decode and consume one CASHOUT block from the active lane.
337
+ /// @param exec Execution whose decoder is advanced.
338
+ /// @return amount Native-asset amount to withdraw.
339
+ function unpackCashout(Execution memory exec) internal pure returns (uint amount) {
340
+ uint abs;
341
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.Cashout);
342
+ amount = Blocks.unpackCashout(abs);
343
+ }
344
+
345
+ /// @notice Decode and consume one BOOTSTRAP block from the active lane.
448
346
  /// @param exec Execution whose decoder is advanced.
449
- /// @param lane Decoder lane to consume.
450
347
  /// @return asset Decoded asset identifier.
451
- function unpackAsset(Execution memory exec, uint8 lane) internal pure returns (bytes32 asset) {
348
+ /// @return amount Decoded balance amount.
349
+ /// @return budget Decoded native-value budget contribution.
350
+ function unpackBootstrap(
351
+ Execution memory exec
352
+ ) internal pure returns (bytes32 asset, uint amount, uint budget) {
452
353
  uint abs;
453
- (exec.decoders, abs) = exec.decoders.consume(lane, Sizes.B32);
354
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.Bootstrap);
355
+ return Blocks.unpackBootstrap(abs);
356
+ }
357
+
358
+ /// @notice Decode and consume one ASSET block from the active lane.
359
+ /// @param exec Execution whose decoder is advanced.
360
+ /// @return asset Decoded asset identifier.
361
+ function unpackAsset(Execution memory exec) internal pure returns (bytes32 asset) {
362
+ uint abs;
363
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.B32);
454
364
  asset = Blocks.unpackAsset(abs);
455
365
  }
456
366
 
457
- /// @notice Decode and consume one ACCOUNT_ASSET block from `lane`.
367
+ /// @notice Decode and consume one ACCOUNT_ASSET block from the active lane.
458
368
  /// @param exec Execution whose decoder is advanced.
459
- /// @param lane Decoder lane to consume.
460
369
  /// @return account Decoded account identifier.
461
370
  /// @return asset Decoded asset identifier.
462
- function unpackAccountAsset(
463
- Execution memory exec,
464
- uint8 lane
465
- ) internal pure returns (bytes32 account, bytes32 asset) {
371
+ function unpackAccountAsset(Execution memory exec) internal pure returns (bytes32 account, bytes32 asset) {
466
372
  uint abs;
467
- (exec.decoders, abs) = exec.decoders.consume(lane, Sizes.B64);
373
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.B64);
468
374
  (account, asset) = Blocks.unpackAccountAsset(abs);
469
375
  }
470
376
 
471
377
  /// @notice Decode one ACCOUNT_ASSET block into its structured value.
472
378
  /// @param exec Execution whose decoder is advanced.
473
- /// @param lane Decoder lane to consume.
474
379
  /// @return value Decoded account and asset.
475
- function unpackAccountAssetValue(
476
- Execution memory exec,
477
- uint8 lane
478
- ) internal pure returns (AccountAsset memory value) {
479
- (value.account, value.asset) = unpackAccountAsset(exec, lane);
380
+ function unpackAccountAssetValue(Execution memory exec) internal pure returns (AccountAsset memory value) {
381
+ (value.account, value.asset) = unpackAccountAsset(exec);
480
382
  }
481
383
 
482
- /// @notice Decode and consume one HOST_ASSET block from `lane`.
384
+ /// @notice Decode and consume one HOST_ASSET block from the active lane.
483
385
  /// @param exec Execution whose decoder is advanced.
484
- /// @param lane Decoder lane to consume.
485
386
  /// @return host Decoded host identifier.
486
387
  /// @return asset Decoded asset identifier.
487
- function unpackHostAsset(
488
- Execution memory exec,
489
- uint8 lane
490
- ) internal pure returns (uint host, bytes32 asset) {
388
+ function unpackHostAsset(Execution memory exec) internal pure returns (uint host, bytes32 asset) {
491
389
  uint abs;
492
- (exec.decoders, abs) = exec.decoders.consume(lane, Sizes.HostAsset);
390
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.HostAsset);
493
391
  (host, asset) = Blocks.unpackHostAsset(abs);
494
392
  }
495
393
 
496
394
  /// @notice Decode one HOST_ASSET block into its structured value.
497
395
  /// @param exec Execution whose decoder is advanced.
498
- /// @param lane Decoder lane to consume.
499
396
  /// @return value Decoded host and asset.
500
- function unpackHostAssetValue(
501
- Execution memory exec,
502
- uint8 lane
503
- ) internal pure returns (HostAsset memory value) {
504
- (value.host, value.asset) = unpackHostAsset(exec, lane);
397
+ function unpackHostAssetValue(Execution memory exec) internal pure returns (HostAsset memory value) {
398
+ (value.host, value.asset) = unpackHostAsset(exec);
505
399
  }
506
400
 
507
- /// @notice Decode and consume one AMOUNT block from `lane`.
401
+ /// @notice Decode and consume one AMOUNT block from the active lane.
508
402
  /// @param exec Execution whose decoder is advanced.
509
- /// @param lane Decoder lane to consume.
510
403
  /// @return asset Decoded asset identifier.
511
404
  /// @return amount Decoded amount.
512
- function unpackAmount(Execution memory exec, uint8 lane) internal pure returns (bytes32 asset, uint amount) {
405
+ function unpackAmount(Execution memory exec) internal pure returns (bytes32 asset, uint amount) {
513
406
  uint abs;
514
- (exec.decoders, abs) = exec.decoders.consume(lane, Sizes.Amount);
407
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.Amount);
515
408
  (asset, amount) = Blocks.unpackAmount(abs);
516
409
  }
517
410
 
518
411
  /// @notice Decode one AMOUNT block into its structured value.
519
412
  /// @param exec Execution whose decoder is advanced.
520
- /// @param lane Decoder lane to consume.
521
413
  /// @return value Decoded asset and amount.
522
- function unpackAmountValue(Execution memory exec, uint8 lane) internal pure returns (AssetAmount memory value) {
523
- (value.asset, value.amount) = unpackAmount(exec, lane);
414
+ function unpackAmountValue(Execution memory exec) internal pure returns (AssetAmount memory value) {
415
+ (value.asset, value.amount) = unpackAmount(exec);
524
416
  }
525
417
 
526
- /// @notice Decode and consume one BALANCE block from `lane`.
418
+ /// @notice Decode and consume one BALANCE block from the active lane.
527
419
  /// @param exec Execution whose decoder is advanced.
528
- /// @param lane Decoder lane to consume.
529
420
  /// @return asset Decoded asset identifier.
530
421
  /// @return amount Decoded balance amount.
531
- function unpackBalance(Execution memory exec, uint8 lane) internal pure returns (bytes32 asset, uint amount) {
422
+ function unpackBalance(Execution memory exec) internal pure returns (bytes32 asset, uint amount) {
532
423
  uint abs;
533
- (exec.decoders, abs) = exec.decoders.consume(lane, Sizes.Balance);
424
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.Balance);
534
425
  (asset, amount) = Blocks.unpackBalance(abs);
535
426
  }
536
427
 
537
428
  /// @notice Decode one BALANCE block into its structured value.
538
429
  /// @param exec Execution whose decoder is advanced.
539
- /// @param lane Decoder lane to consume.
540
430
  /// @return value Decoded asset and balance amount.
541
- function unpackBalanceValue(Execution memory exec, uint8 lane) internal pure returns (AssetAmount memory value) {
542
- (value.asset, value.amount) = unpackBalance(exec, lane);
431
+ function unpackBalanceValue(Execution memory exec) internal pure returns (AssetAmount memory value) {
432
+ (value.asset, value.amount) = unpackBalance(exec);
543
433
  }
544
434
 
545
- /// @notice Decode and consume one DEBT block from `lane`.
546
- function unpackDebt(Execution memory exec, uint8 lane) internal pure returns (bytes32 liability, uint debt) {
435
+ /// @notice Decode and consume one DEBT block from the active lane.
436
+ function unpackDebt(Execution memory exec) internal pure returns (bytes32 liability, uint debt) {
547
437
  uint abs;
548
- (exec.decoders, abs) = exec.decoders.consume(lane, Sizes.Debt);
438
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.Debt);
549
439
  (liability, debt) = Blocks.unpackDebt(abs);
550
440
  }
551
441
 
552
442
  /// @notice Decode one DEBT block into its structured value.
553
- function unpackDebtValue(Execution memory exec, uint8 lane) internal pure returns (Debt memory value) {
554
- (value.liability, value.debt) = unpackDebt(exec, lane);
443
+ function unpackDebtValue(Execution memory exec) internal pure returns (Debt memory value) {
444
+ (value.liability, value.debt) = unpackDebt(exec);
555
445
  }
556
446
 
557
- /// @notice Decode and consume one POSITION block from `lane`.
558
- function unpackPosition(
559
- Execution memory exec,
560
- uint8 lane
561
- ) internal pure returns (bytes32 asset, uint amount, bytes32 liability, uint debt) {
447
+ /// @notice Decode and consume one POSITION block from the active lane.
448
+ function unpackPosition(Execution memory exec) internal pure returns (bytes32 asset, uint amount, bytes32 liability, uint debt) {
562
449
  uint abs;
563
- (exec.decoders, abs) = exec.decoders.consume(lane, Sizes.Position);
450
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.Position);
564
451
  (asset, amount, liability, debt) = Blocks.unpackPosition(abs);
565
452
  }
566
453
 
567
454
  /// @notice Decode one POSITION block into its structured value.
568
- function unpackPositionValue(
569
- Execution memory exec,
570
- uint8 lane
571
- ) internal pure returns (Position memory value) {
572
- (value.asset, value.amount, value.liability, value.debt) = unpackPosition(exec, lane);
455
+ function unpackPositionValue(Execution memory exec) internal pure returns (Position memory value) {
456
+ (value.asset, value.amount, value.liability, value.debt) = unpackPosition(exec);
573
457
  }
574
458
 
575
459
  /// @notice Decode one BALANCE block and associate it with `host`.
576
460
  /// @param exec Execution whose decoder is advanced.
577
- /// @param lane Decoder lane to consume.
578
461
  /// @param host Host associated with the decoded balance.
579
462
  /// @return value Host-scoped asset amount.
580
463
  function unpackBalanceForHost(
581
464
  Execution memory exec,
582
- uint8 lane,
583
465
  uint host
584
466
  ) internal pure returns (HostAmount memory value) {
585
467
  uint abs;
586
- (exec.decoders, abs) = exec.decoders.consume(lane, Sizes.Balance);
468
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.Balance);
587
469
  value.host = host;
588
470
  (value.asset, value.amount) = Blocks.unpackBalance(abs);
589
471
  }
590
472
 
591
- /// @notice Decode and consume one ACCOUNT_AMOUNT block from `lane`.
473
+ /// @notice Decode and consume one ACCOUNT_AMOUNT block from the active lane.
592
474
  /// @param exec Execution whose decoder is advanced.
593
- /// @param lane Decoder lane to consume.
594
475
  /// @return account Decoded account identifier.
595
476
  /// @return asset Decoded asset identifier.
596
477
  /// @return amount Decoded amount.
597
- function unpackAccountAmount(
598
- Execution memory exec,
599
- uint8 lane
600
- ) internal pure returns (bytes32 account, bytes32 asset, uint amount) {
478
+ function unpackAccountAmount(Execution memory exec) internal pure returns (bytes32 account, bytes32 asset, uint amount) {
601
479
  uint abs;
602
- (exec.decoders, abs) = exec.decoders.consume(lane, Sizes.B96);
480
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.B96);
603
481
  (account, asset, amount) = Blocks.unpackAccountAmount(abs);
604
482
  }
605
483
 
606
484
  /// @notice Decode one ACCOUNT_AMOUNT block into its structured value.
607
485
  /// @param exec Execution whose decoder is advanced.
608
- /// @param lane Decoder lane to consume.
609
486
  /// @return value Decoded account, asset, and amount.
610
- function unpackAccountAmountValue(
611
- Execution memory exec,
612
- uint8 lane
613
- ) internal pure returns (AccountAmount memory value) {
614
- (value.account, value.asset, value.amount) = unpackAccountAmount(exec, lane);
487
+ function unpackAccountAmountValue(Execution memory exec) internal pure returns (AccountAmount memory value) {
488
+ (value.account, value.asset, value.amount) = unpackAccountAmount(exec);
615
489
  }
616
490
 
617
- /// @notice Decode and consume one ALLOCATION block from `lane`.
491
+ /// @notice Decode and consume one ALLOCATION block from the active lane.
618
492
  /// @param exec Execution whose decoder is advanced.
619
- /// @param lane Decoder lane to consume.
620
493
  /// @return host Decoded host identifier.
621
494
  /// @return asset Decoded asset identifier.
622
495
  /// @return amount Decoded amount.
623
- function unpackAllocation(
624
- Execution memory exec,
625
- uint8 lane
626
- ) internal pure returns (uint host, bytes32 asset, uint amount) {
496
+ function unpackAllocation(Execution memory exec) internal pure returns (uint host, bytes32 asset, uint amount) {
627
497
  uint abs;
628
- (exec.decoders, abs) = exec.decoders.consume(lane, Sizes.B96);
498
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.B96);
629
499
  (host, asset, amount) = Blocks.unpackAllocation(abs);
630
500
  }
631
501
 
632
502
  /// @notice Decode one ALLOCATION block into its structured value.
633
503
  /// @param exec Execution whose decoder is advanced.
634
- /// @param lane Decoder lane to consume.
635
504
  /// @return value Decoded host, asset, and amount.
636
- function unpackAllocationValue(Execution memory exec, uint8 lane) internal pure returns (HostAmount memory value) {
637
- (value.host, value.asset, value.amount) = unpackAllocation(exec, lane);
505
+ function unpackAllocationValue(Execution memory exec) internal pure returns (HostAmount memory value) {
506
+ (value.host, value.asset, value.amount) = unpackAllocation(exec);
638
507
  }
639
508
 
640
- /// @notice Decode and consume one ALLOWANCE block from `lane`.
509
+ /// @notice Decode and consume one ALLOWANCE block from the active lane.
641
510
  /// @param exec Execution whose decoder is advanced.
642
- /// @param lane Decoder lane to consume.
643
511
  /// @return host Decoded host identifier.
644
512
  /// @return asset Decoded asset identifier.
645
513
  /// @return amount Decoded allowance amount.
646
- function unpackAllowance(
647
- Execution memory exec,
648
- uint8 lane
649
- ) internal pure returns (uint host, bytes32 asset, uint amount) {
514
+ function unpackAllowance(Execution memory exec) internal pure returns (uint host, bytes32 asset, uint amount) {
650
515
  uint abs;
651
- (exec.decoders, abs) = exec.decoders.consume(lane, Sizes.B96);
516
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.B96);
652
517
  (host, asset, amount) = Blocks.unpackAllowance(abs);
653
518
  }
654
519
 
655
520
  /// @notice Decode one ALLOWANCE block into its structured value.
656
521
  /// @param exec Execution whose decoder is advanced.
657
- /// @param lane Decoder lane to consume.
658
522
  /// @return value Decoded host, asset, and allowance amount.
659
- function unpackAllowanceValue(Execution memory exec, uint8 lane) internal pure returns (HostAmount memory value) {
660
- (value.host, value.asset, value.amount) = unpackAllowance(exec, lane);
523
+ function unpackAllowanceValue(Execution memory exec) internal pure returns (HostAmount memory value) {
524
+ (value.host, value.asset, value.amount) = unpackAllowance(exec);
661
525
  }
662
526
 
663
- /// @notice Decode and consume one CUSTODY block from `lane`.
527
+ /// @notice Decode and consume one CUSTODY block from the active lane.
664
528
  /// @param exec Execution whose decoder is advanced.
665
- /// @param lane Decoder lane to consume.
666
529
  /// @return host Decoded host identifier.
667
530
  /// @return asset Decoded asset identifier.
668
531
  /// @return amount Decoded custody amount.
669
- function unpackCustody(
670
- Execution memory exec,
671
- uint8 lane
672
- ) internal pure returns (uint host, bytes32 asset, uint amount) {
532
+ function unpackCustody(Execution memory exec) internal pure returns (uint host, bytes32 asset, uint amount) {
673
533
  uint abs;
674
- (exec.decoders, abs) = exec.decoders.consume(lane, Sizes.B96);
534
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.B96);
675
535
  (host, asset, amount) = Blocks.unpackCustody(abs);
676
536
  }
677
537
 
678
538
  /// @notice Decode one CUSTODY block into its structured value.
679
539
  /// @param exec Execution whose decoder is advanced.
680
- /// @param lane Decoder lane to consume.
681
540
  /// @return value Decoded host, asset, and custody amount.
682
- function unpackCustodyValue(Execution memory exec, uint8 lane) internal pure returns (HostAmount memory value) {
683
- (value.host, value.asset, value.amount) = unpackCustody(exec, lane);
541
+ function unpackCustodyValue(Execution memory exec) internal pure returns (HostAmount memory value) {
542
+ (value.host, value.asset, value.amount) = unpackCustody(exec);
684
543
  }
685
544
 
686
- /// @notice Decode and consume one HOST_ACCOUNT_ASSET block from `lane`.
545
+ /// @notice Decode and consume one HOST_ACCOUNT_ASSET block from the active lane.
687
546
  /// @param exec Execution whose decoder is advanced.
688
- /// @param lane Decoder lane to consume.
689
547
  /// @return host Decoded host identifier.
690
548
  /// @return account Decoded account identifier.
691
549
  /// @return asset Decoded asset identifier.
692
- function unpackHostAccountAsset(
693
- Execution memory exec,
694
- uint8 lane
695
- ) internal pure returns (uint host, bytes32 account, bytes32 asset) {
550
+ function unpackHostAccountAsset(Execution memory exec) internal pure returns (uint host, bytes32 account, bytes32 asset) {
696
551
  uint abs;
697
- (exec.decoders, abs) = exec.decoders.consume(lane, Sizes.B96);
552
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.B96);
698
553
  (host, account, asset) = Blocks.unpackHostAccountAsset(abs);
699
554
  }
700
555
 
701
556
  /// @notice Decode one HOST_ACCOUNT_ASSET block into its structured value.
702
557
  /// @param exec Execution whose decoder is advanced.
703
- /// @param lane Decoder lane to consume.
704
558
  /// @return value Decoded host, account, and asset.
705
- function unpackHostAccountAssetValue(
706
- Execution memory exec,
707
- uint8 lane
708
- ) internal pure returns (HostAccountAsset memory value) {
709
- (value.host, value.account, value.asset) = unpackHostAccountAsset(exec, lane);
559
+ function unpackHostAccountAssetValue(Execution memory exec) internal pure returns (HostAccountAsset memory value) {
560
+ (value.host, value.account, value.asset) = unpackHostAccountAsset(exec);
710
561
  }
711
562
 
712
- /// @notice Decode and consume one TRANSACTION block from `lane`.
563
+ /// @notice Decode and consume one TRANSACTION block from the active lane.
713
564
  /// @param exec Execution whose decoder is advanced.
714
- /// @param lane Decoder lane to consume.
715
565
  /// @return from Decoded debit account.
716
566
  /// @return to Decoded credit account.
717
567
  /// @return asset Decoded asset identifier.
718
568
  /// @return amount Decoded transaction amount.
719
- function unpackTransaction(
720
- Execution memory exec,
721
- uint8 lane
722
- ) internal pure returns (bytes32 from, bytes32 to, bytes32 asset, uint amount) {
569
+ function unpackTransaction(Execution memory exec) internal pure returns (bytes32 from, bytes32 to, bytes32 asset, uint amount) {
723
570
  uint abs;
724
- (exec.decoders, abs) = exec.decoders.consume(lane, Sizes.Transaction);
571
+ (exec.decoders, abs) = exec.decoders.consume(Sizes.Transaction);
725
572
  (from, to, asset, amount) = Blocks.unpackTransaction(abs);
726
573
  }
727
574
 
728
575
  /// @notice Decode one TRANSACTION block into its structured value.
729
576
  /// @param exec Execution whose decoder is advanced.
730
- /// @param lane Decoder lane to consume.
731
577
  /// @return value Decoded transaction.
732
- function unpackTransactionValue(Execution memory exec, uint8 lane) internal pure returns (Tx memory value) {
733
- (value.from, value.to, value.asset, value.amount) = unpackTransaction(exec, lane);
578
+ function unpackTransactionValue(Execution memory exec) internal pure returns (Tx memory value) {
579
+ (value.from, value.to, value.asset, value.amount) = unpackTransaction(exec);
734
580
  }
735
581
 
736
582
  // -------------------------------------------------------------------------
737
583
  // Dynamic block decoding
738
584
  // -------------------------------------------------------------------------
739
585
 
740
- /// @notice Decode and consume a block described by `spec` from `lane`.
586
+ /// @notice Decode and consume a block described by `spec` from the active lane.
741
587
  /// @param exec Execution whose decoder is advanced.
742
- /// @param lane Decoder lane to consume.
743
588
  /// @param spec Expected block specification.
744
589
  /// @return data Calldata view of the decoded payload.
745
- function unpackRaw(Execution memory exec, uint8 lane, uint spec) internal pure returns (bytes calldata data) {
746
- uint cur = exec.decoders.select(lane);
590
+ function unpackRaw(Execution memory exec, uint spec) internal pure returns (bytes calldata data) {
591
+ uint cur = exec.decoders;
747
592
  uint end;
748
593
  (data, end) = Blocks.unpackRaw(cur.absolute(), spec);
749
594
  exec.decoders = cur.seekAbs(end);
750
595
  }
751
596
 
752
- /// @notice Decode and consume one BYTES block from `lane`.
597
+ /// @notice Decode and consume one BYTES block from the active lane.
753
598
  /// @param exec Execution whose decoder is advanced.
754
- /// @param lane Decoder lane to consume.
755
599
  /// @return data Decoded byte payload.
756
- function unpackBytes(Execution memory exec, uint8 lane) internal pure returns (bytes calldata data) {
757
- uint cur = exec.decoders.select(lane);
600
+ function unpackBytes(Execution memory exec) internal pure returns (bytes calldata data) {
601
+ uint cur = exec.decoders;
758
602
  uint end;
759
603
  (data, end) = Blocks.unpackBytes(cur.absolute());
760
604
  exec.decoders = cur.seekAbs(end);
761
605
  }
762
606
 
763
- /// @notice Decode and consume one STRING block from `lane`.
607
+ /// @notice Decode and consume one STRING block from the active lane.
764
608
  /// @param exec Execution whose decoder is advanced.
765
- /// @param lane Decoder lane to consume.
766
609
  /// @return data Decoded string payload.
767
- function unpackString(Execution memory exec, uint8 lane) internal pure returns (string memory data) {
768
- uint cur = exec.decoders.select(lane);
610
+ function unpackString(Execution memory exec) internal pure returns (string memory data) {
611
+ uint cur = exec.decoders;
769
612
  bytes calldata value;
770
613
  uint end;
771
614
  (value, end) = Blocks.unpackString(cur.absolute());
@@ -773,149 +616,113 @@ library Executions {
773
616
  data = string(value);
774
617
  }
775
618
 
776
- /// @notice Decode and consume one STEP block from `lane`.
619
+ /// @notice Decode and consume one STEP block from the active lane.
777
620
  /// @param exec Execution whose decoder is advanced.
778
- /// @param lane Decoder lane to consume.
779
621
  /// @return cmd Decoded command identifier.
780
- /// @return resources Decoded packed resources.
622
+ /// @return value Decoded native value.
781
623
  /// @return input Decoded nested input.
782
- function unpackStep(
783
- Execution memory exec,
784
- uint8 lane
785
- ) internal pure returns (uint cmd, uint resources, bytes calldata input) {
786
- uint cur = exec.decoders.select(lane);
624
+ function unpackStep(Execution memory exec) internal pure returns (uint cmd, uint128 value, bytes calldata input) {
625
+ uint cur = exec.decoders;
787
626
  uint end;
788
- (cmd, resources, input, end) = Blocks.unpackStep(cur.absolute());
627
+ (cmd, value, input, end) = Blocks.unpackStep(cur.absolute());
789
628
  exec.decoders = cur.seekAbs(end);
790
629
  }
791
630
 
792
- /// @notice Decode and consume one CALL block from `lane`.
631
+ /// @notice Decode and consume one CALL block from the active lane.
793
632
  /// @param exec Execution whose decoder is advanced.
794
- /// @param lane Decoder lane to consume.
795
633
  /// @return target Decoded call target.
796
634
  /// @return resources Decoded packed resources.
797
635
  /// @return data Decoded call payload.
798
- function unpackCall(
799
- Execution memory exec,
800
- uint8 lane
801
- ) internal pure returns (uint target, uint resources, bytes calldata data) {
802
- uint cur = exec.decoders.select(lane);
636
+ function unpackCall(Execution memory exec) internal pure returns (uint target, uint resources, bytes calldata data) {
637
+ uint cur = exec.decoders;
803
638
  uint abs = cur.absolute();
804
639
  uint end;
805
640
  (target, resources, data, end) = Blocks.unpackCall(abs);
806
641
  exec.decoders = cur.seekAbs(end);
807
642
  }
808
643
 
809
- /// @notice Decode and consume one ANNOTATION block from `lane`.
644
+ /// @notice Decode and consume one ANNOTATION block from the active lane.
810
645
  /// @param exec Execution whose decoder is advanced.
811
- /// @param lane Decoder lane to consume.
812
646
  /// @return entity Decoded entity identifier.
813
647
  /// @return data Decoded annotation block stream.
814
- function unpackAnnotation(
815
- Execution memory exec,
816
- uint8 lane
817
- ) internal pure returns (uint entity, bytes calldata data) {
818
- uint cur = exec.decoders.select(lane);
648
+ function unpackAnnotation(Execution memory exec) internal pure returns (uint entity, bytes calldata data) {
649
+ uint cur = exec.decoders;
819
650
  uint end;
820
651
  (entity, data, end) = Blocks.unpackAnnotation(cur.absolute());
821
652
  exec.decoders = cur.seekAbs(end);
822
653
  }
823
654
 
824
- /// @notice Decode and consume one CONTEXT block from `lane`.
655
+ /// @notice Decode and consume one CONTEXT block from the active lane.
825
656
  /// @param exec Execution whose decoder is advanced.
826
- /// @param lane Decoder lane to consume.
827
657
  /// @return account Decoded account identifier.
828
658
  /// @return state Decoded nested state.
829
659
  /// @return input Decoded nested input.
830
- function unpackContext(
831
- Execution memory exec,
832
- uint8 lane
833
- ) internal pure returns (bytes32 account, bytes calldata state, bytes calldata input) {
834
- uint cur = exec.decoders.select(lane);
660
+ function unpackContext(Execution memory exec) internal pure returns (bytes32 account, bytes calldata state, bytes calldata input) {
661
+ uint cur = exec.decoders;
835
662
  uint abs = cur.absolute();
836
663
  uint end;
837
664
  (account, state, input, end) = Blocks.unpackContext(abs);
838
665
  exec.decoders = cur.seekAbs(end);
839
666
  }
840
667
 
841
- /// @notice Decode and consume one RELAY block from `lane`.
668
+ /// @notice Decode and consume one RELAY block from the active lane.
842
669
  /// @param exec Execution whose decoder is advanced.
843
- /// @param lane Decoder lane to consume.
844
670
  /// @return portal Decoded destination portal.
845
671
  /// @return resources Decoded packed resources.
846
672
  /// @return input Decoded nested input.
847
- function unpackRelay(
848
- Execution memory exec,
849
- uint8 lane
850
- ) internal pure returns (uint portal, uint resources, bytes calldata input) {
851
- uint cur = exec.decoders.select(lane);
673
+ function unpackRelay(Execution memory exec) internal pure returns (uint portal, uint resources, bytes calldata input) {
674
+ uint cur = exec.decoders;
852
675
  uint end;
853
676
  (portal, resources, input, end) = Blocks.unpackRelay(cur.absolute());
854
677
  exec.decoders = cur.seekAbs(end);
855
678
  }
856
679
 
857
- /// @notice Decode and consume one DISPATCH block from `lane`.
680
+ /// @notice Decode and consume one DISPATCH block from the active lane.
858
681
  /// @param exec Execution whose decoder is advanced.
859
- /// @param lane Decoder lane to consume.
860
682
  /// @return portal Decoded destination portal.
861
683
  /// @return resources Decoded packed resources.
862
684
  /// @return payload Decoded dispatch payload.
863
- function unpackDispatch(
864
- Execution memory exec,
865
- uint8 lane
866
- ) internal pure returns (uint portal, uint resources, bytes calldata payload) {
867
- uint cur = exec.decoders.select(lane);
685
+ function unpackDispatch(Execution memory exec) internal pure returns (uint portal, uint resources, bytes calldata payload) {
686
+ uint cur = exec.decoders;
868
687
  uint abs = cur.absolute();
869
688
  uint end;
870
689
  (portal, resources, payload, end) = Blocks.unpackDispatch(abs);
871
690
  exec.decoders = cur.seekAbs(end);
872
691
  }
873
692
 
874
- /// @notice Decode and consume one LABEL block from `lane`.
693
+ /// @notice Decode and consume one LABEL block from the active lane.
875
694
  /// @param exec Execution whose decoder is advanced.
876
- /// @param lane Decoder lane to consume.
877
695
  /// @return namespace Decoded label namespace.
878
696
  /// @return name Decoded label text.
879
- function unpackLabel(
880
- Execution memory exec,
881
- uint8 lane
882
- ) internal pure returns (bytes32 namespace, string memory name) {
883
- uint cur = exec.decoders.select(lane);
697
+ function unpackLabel(Execution memory exec) internal pure returns (bytes32 namespace, string memory name) {
698
+ uint cur = exec.decoders;
884
699
  uint abs = cur.absolute();
885
700
  uint end;
886
701
  (namespace, name, end) = Blocks.unpackLabel(abs);
887
702
  exec.decoders = cur.seekAbs(end);
888
703
  }
889
704
 
890
- /// @notice Decode and consume one SCHEMA block from `lane`.
705
+ /// @notice Decode and consume one SCHEMA block from the active lane.
891
706
  /// @param exec Execution whose decoder is advanced.
892
- /// @param lane Decoder lane to consume.
893
707
  /// @return spec Decoded block specification.
894
708
  /// @return body Decoded schema body.
895
709
  /// @return name Decoded schema name.
896
- function unpackSchema(
897
- Execution memory exec,
898
- uint8 lane
899
- ) internal pure returns (uint spec, string memory body, bytes32 name) {
900
- uint cur = exec.decoders.select(lane);
710
+ function unpackSchema(Execution memory exec) internal pure returns (uint spec, string memory body, bytes32 name) {
711
+ uint cur = exec.decoders;
901
712
  uint abs = cur.absolute();
902
713
  uint end;
903
714
  (spec, body, name, end) = Blocks.unpackSchema(abs);
904
715
  exec.decoders = cur.seekAbs(end);
905
716
  }
906
717
 
907
- /// @notice Decode and consume one RECOVER block from `lane`.
718
+ /// @notice Decode and consume one RECOVER block from the active lane.
908
719
  /// @param exec Execution whose decoder is advanced.
909
- /// @param lane Decoder lane to consume.
910
720
  /// @return handler Decoded recovery handler.
911
721
  /// @return resources Decoded packed resources.
912
722
  /// @return key Decoded recovery key.
913
723
  /// @return witness Decoded recovery witness.
914
- function unpackRecover(
915
- Execution memory exec,
916
- uint8 lane
917
- ) internal pure returns (uint handler, uint resources, bytes32 key, bytes calldata witness) {
918
- uint cur = exec.decoders.select(lane);
724
+ function unpackRecover(Execution memory exec) internal pure returns (uint handler, uint resources, bytes32 key, bytes calldata witness) {
725
+ uint cur = exec.decoders;
919
726
  uint abs = cur.absolute();
920
727
  uint end;
921
728
  (handler, resources, key, witness, end) = Blocks.unpackRecover(abs);
@@ -932,8 +739,7 @@ library Executions {
932
739
  /// @param touch Number of bytes that must be addressable by the write.
933
740
  /// @return i Relative output offset reserved for the write.
934
741
  function reserve(Execution memory exec, uint amount, uint touch) internal pure returns (uint i) {
935
- uint writers = exec.writers.select(Lanes.Output);
936
- (exec.writers, exec.output, i) = Buffers.reserve(writers, exec.output, amount, touch);
742
+ (exec.writer, exec.output, i) = Buffers.reserve(exec.writer, exec.output, amount, touch);
937
743
  }
938
744
 
939
745
  /// @dev Reserve an exact number of output bytes.
@@ -941,7 +747,7 @@ library Executions {
941
747
  /// @param size Number of bytes to reserve and touch.
942
748
  /// @return i Relative output offset reserved for the write.
943
749
  function reserve(Execution memory exec, uint size) private pure returns (uint i) {
944
- return reserve(exec, size, size);
750
+ (exec.writer, exec.output, i) = Buffers.reserve(exec.writer, exec.output, size, size);
945
751
  }
946
752
 
947
753
  /// @notice Append an empty block to execution output.
@@ -1224,12 +1030,12 @@ library Executions {
1224
1030
  /// @notice Append a STEP block to execution output.
1225
1031
  /// @param exec Execution receiving the block.
1226
1032
  /// @param cmd Command identifier to encode.
1227
- /// @param resources Packed resources to encode.
1033
+ /// @param value Native value to encode.
1228
1034
  /// @param input Command input to encode.
1229
- function outputStep(Execution memory exec, uint cmd, uint resources, bytes memory input) internal pure {
1230
- uint size = Sizes.B64 + Sizes.Header + input.length;
1035
+ function outputStep(Execution memory exec, uint cmd, uint128 value, bytes memory input) internal pure {
1036
+ uint size = Sizes.Step + input.length;
1231
1037
  uint i = reserve(exec, size);
1232
- Blocks.writeStep(exec.output, i, cmd, resources, input);
1038
+ Blocks.writeStep(exec.output, i, cmd, value, input);
1233
1039
  }
1234
1040
 
1235
1041
  /// @notice Append a CALL block to execution output.
@@ -1361,10 +1167,10 @@ library Executions {
1361
1167
  }
1362
1168
 
1363
1169
  /// @notice Append a STEP block to execution output by copying its nested input from calldata.
1364
- function outputCopyStep(Execution memory exec, uint cmd, uint resources, bytes calldata input) internal pure {
1365
- uint size = Sizes.B64 + Sizes.Header + input.length;
1170
+ function outputCopyStep(Execution memory exec, uint cmd, uint128 value, bytes calldata input) internal pure {
1171
+ uint size = Sizes.Step + input.length;
1366
1172
  uint i = reserve(exec, size);
1367
- Blocks.copyStep(exec.output, i, cmd, resources, input);
1173
+ Blocks.copyStep(exec.output, i, cmd, value, input);
1368
1174
  }
1369
1175
 
1370
1176
  /// @notice Append a CALL block to execution output by copying its nested payload from calldata.
@@ -1414,7 +1220,7 @@ library Executions {
1414
1220
  }
1415
1221
 
1416
1222
  // -------------------------------------------------------------------------
1417
- // Value and transaction writing
1223
+ // Value
1418
1224
  // -------------------------------------------------------------------------
1419
1225
 
1420
1226
  /// @notice Remove and return the remaining execution value budget.
@@ -1452,63 +1258,6 @@ library Executions {
1452
1258
  return uint128(useValue(exec, uint128(resources)));
1453
1259
  }
1454
1260
 
1455
- /// @notice Append a deferred transaction to the transaction writer lane.
1456
- /// @param exec Execution receiving the transaction.
1457
- /// @param from Debit account identifier.
1458
- /// @param to Credit account identifier.
1459
- /// @param asset Asset identifier.
1460
- /// @param amount Transaction amount.
1461
- function queueTransaction(
1462
- Execution memory exec,
1463
- bytes32 from,
1464
- bytes32 to,
1465
- bytes32 asset,
1466
- uint amount
1467
- ) internal pure {
1468
- uint i;
1469
- uint size = Sizes.Transaction;
1470
- uint writers = exec.writers.select(Lanes.Transactions);
1471
- (exec.writers, exec.transactions, i) = Buffers.reserve(writers, exec.transactions, size, size);
1472
- Blocks.writeTransaction(exec.transactions, i, from, to, asset, amount);
1473
- }
1474
-
1475
- /// @notice Queue a transaction that debits `account`.
1476
- /// @param exec Execution receiving the transaction.
1477
- /// @param account Account to debit.
1478
- /// @param asset Asset to debit.
1479
- /// @param amount Amount to debit.
1480
- function queueDebit(Execution memory exec, bytes32 account, bytes32 asset, uint amount) internal pure {
1481
- queueTransaction(exec, account, bytes32(0), asset, amount);
1482
- }
1483
-
1484
- /// @notice Queue a transaction that credits `account`.
1485
- /// @param exec Execution receiving the transaction.
1486
- /// @param account Account to credit.
1487
- /// @param asset Asset to credit.
1488
- /// @param amount Amount to credit.
1489
- function queueCredit(Execution memory exec, bytes32 account, bytes32 asset, uint amount) internal pure {
1490
- queueTransaction(exec, bytes32(0), account, asset, amount);
1491
- }
1492
-
1493
- /// @notice Drain the remaining value budget and queue it as an account refund.
1494
- /// @dev Creates a one-transaction writer lane when the descriptor declared none.
1495
- /// @param exec Execution whose remaining budget is refunded.
1496
- /// @param account Account receiving the refund.
1497
- /// @param asset Asset identifier used for the refund transaction.
1498
- /// @return amount Value removed from the execution budget and queued for refund.
1499
- function refundValue(Execution memory exec, bytes32 account, bytes32 asset) internal pure returns (uint amount) {
1500
- amount = exec.budget;
1501
- if (amount == 0) return 0;
1502
-
1503
- exec.budget = 0;
1504
- if (!exec.writers.contains(Lanes.Transactions)) {
1505
- uint refunds = Buffers.cursor(Sizes.Transaction, 1, false, Lanes.Transactions);
1506
- exec.writers = Cursors.pair(exec.writers, refunds);
1507
- }
1508
-
1509
- queueCredit(exec, account, asset, amount);
1510
- }
1511
-
1512
1261
  // -------------------------------------------------------------------------
1513
1262
  // Finalization
1514
1263
  // -------------------------------------------------------------------------
@@ -1517,19 +1266,32 @@ library Executions {
1517
1266
  /// @param exec Execution whose output is finalized.
1518
1267
  /// @return out Trimmed output bytes.
1519
1268
  function finish(Execution memory exec) internal pure returns (bytes memory out) {
1269
+ if (exec.decoders.any()) revert UnconsumedData();
1520
1270
  if (exec.output.length == 0) return new bytes(0);
1521
1271
 
1522
- uint writers = exec.writers.select(Lanes.Output);
1523
- out = Buffers.finish(writers, exec.output);
1272
+ out = Buffers.finish(exec.writer, exec.output);
1524
1273
  }
1525
1274
 
1526
- /// @notice Finalize and return queued execution transactions.
1527
- /// @param exec Execution whose transactions are finalized.
1528
- /// @return out Trimmed transaction bytes.
1529
- function finishTransactions(Execution memory exec) internal pure returns (bytes memory out) {
1530
- if (exec.transactions.length == 0) return new bytes(0);
1275
+ /// @notice Close an execution and return its output and remaining budget.
1276
+ /// @param exec Execution whose lanes, writer, and budget are finalized.
1277
+ /// @return output Final encoded output block stream.
1278
+ /// @return credit Remaining native value to credit to the caller's budget.
1279
+ function close(Execution memory exec) internal pure returns (bytes memory output, uint credit) {
1280
+ return close(exec, 0);
1281
+ }
1531
1282
 
1532
- uint writers = exec.writers.select(Lanes.Transactions);
1533
- out = Buffers.finish(writers, exec.transactions);
1283
+ /// @notice Close an execution and combine its remaining budget with additional command credit.
1284
+ /// @param exec Execution whose lanes, writer, and budget are finalized.
1285
+ /// @param extraCredit Additional trusted credit produced by the command.
1286
+ /// @return output Final encoded output block stream.
1287
+ /// @return credit Remaining execution budget plus `extraCredit`.
1288
+ function close(
1289
+ Execution memory exec,
1290
+ uint extraCredit
1291
+ ) internal pure returns (bytes memory output, uint credit) {
1292
+ output = finish(exec);
1293
+ credit = exec.budget + extraCredit;
1294
+ exec.budget = 0;
1534
1295
  }
1296
+
1535
1297
  }