@rootzero/contracts 1.18.0 → 1.19.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/CHANGELOG.md +57 -0
- package/Endpoints.sol +39 -44
- package/annotations/Label.sol +1 -5
- package/codec/Blocks.sol +359 -74
- package/codec/Buffers.sol +14 -0
- package/codec/Decoders.sol +59 -0
- package/codec/Writers.sol +102 -0
- package/commands/Relay.sol +2 -2
- package/core/Settlement.sol +1 -1
- package/docs/Schema.md +5 -0
- package/execution/Execution.sol +150 -0
- package/package.json +1 -1
- package/ports/AllowAssets.sol +2 -2
- package/ports/Allowance.sol +2 -2
- package/ports/Credit.sol +2 -2
- package/ports/Debit.sol +2 -2
- package/ports/DenyAssets.sol +2 -2
- package/ports/Dispatch.sol +3 -3
- package/ports/Pipe.sol +2 -2
- package/ports/Post.sol +2 -2
- package/ports/Redeem.sol +2 -2
- package/utils/Cursors.sol +10 -3
package/codec/Writers.sol
CHANGED
|
@@ -22,6 +22,7 @@ struct Writer {
|
|
|
22
22
|
/// then lazily allocates and writes binary-encoded blocks sequentially.
|
|
23
23
|
/// Physical allocation is rounded up to whole 32-byte words for scratch space,
|
|
24
24
|
/// while the writer cursor length tracks logical capacity. Call `finish` to trim the buffer.
|
|
25
|
+
/// `append*` helpers consume memory inputs; `copy*` helpers consume calldata inputs.
|
|
25
26
|
library Writers {
|
|
26
27
|
// -------------------------------------------------------------------------
|
|
27
28
|
// Initialization helpers
|
|
@@ -497,6 +498,107 @@ library Writers {
|
|
|
497
498
|
Blocks.writeSchema(writer.dst, i, spec, body, name);
|
|
498
499
|
}
|
|
499
500
|
|
|
501
|
+
// -------------------------------------------------------------------------
|
|
502
|
+
// Calldata copy helpers
|
|
503
|
+
// -------------------------------------------------------------------------
|
|
504
|
+
|
|
505
|
+
/// @notice Append arbitrary calldata bytes to the writer.
|
|
506
|
+
/// @param writer Destination writer; `i` is advanced by `data.length`.
|
|
507
|
+
/// @param data Calldata bytes to append.
|
|
508
|
+
function copy(Writer memory writer, bytes calldata data) internal pure {
|
|
509
|
+
uint i = reserve(writer, data.length, data.length);
|
|
510
|
+
Buffers.copy(writer.dst, i, data);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/// @notice Append a custom block by copying its payload from calldata.
|
|
514
|
+
function copyBlock(Writer memory writer, uint spec, bytes calldata data) internal pure {
|
|
515
|
+
Specs.validate(spec, data.length);
|
|
516
|
+
uint size = Sizes.Header + data.length;
|
|
517
|
+
uint i = reserve(writer, size);
|
|
518
|
+
Blocks.copy(writer.dst, i, Specs.key(spec), data);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/// @notice Append a LIST block by copying its payload from calldata.
|
|
522
|
+
function copyList(Writer memory writer, bytes calldata value) internal pure {
|
|
523
|
+
uint size = Sizes.Header + value.length;
|
|
524
|
+
uint i = reserve(writer, size);
|
|
525
|
+
Blocks.copyList(writer.dst, i, value);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/// @notice Append an EVM block by copying its payload from calldata.
|
|
529
|
+
function copyEvm(Writer memory writer, bytes calldata value) internal pure {
|
|
530
|
+
uint size = Sizes.Header + value.length;
|
|
531
|
+
uint i = reserve(writer, size);
|
|
532
|
+
Blocks.copyEvm(writer.dst, i, value);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
/// @notice Append a BYTES block by copying its payload from calldata.
|
|
536
|
+
function copyBytes(Writer memory writer, bytes calldata value) internal pure {
|
|
537
|
+
uint size = Sizes.Header + value.length;
|
|
538
|
+
uint i = reserve(writer, size);
|
|
539
|
+
Blocks.copyBytes(writer.dst, i, value);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/// @notice Append a STRING block by copying its payload from calldata.
|
|
543
|
+
function copyString(Writer memory writer, string calldata value) internal pure {
|
|
544
|
+
uint size = Sizes.Header + bytes(value).length;
|
|
545
|
+
uint i = reserve(writer, size);
|
|
546
|
+
Blocks.copyString(writer.dst, i, value);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/// @notice Append a STEP block by copying its nested input from calldata.
|
|
550
|
+
function copyStep(Writer memory writer, uint cmd, uint resources, bytes calldata input) internal pure {
|
|
551
|
+
uint size = Sizes.B64 + Sizes.Header + input.length;
|
|
552
|
+
uint i = reserve(writer, size);
|
|
553
|
+
Blocks.copyStep(writer.dst, i, cmd, resources, input);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
/// @notice Append a CALL block by copying its nested payload from calldata.
|
|
557
|
+
function copyCall(Writer memory writer, uint target, uint resources, bytes calldata payload) internal pure {
|
|
558
|
+
uint size = Sizes.B64 + Sizes.Header + payload.length;
|
|
559
|
+
uint i = reserve(writer, size);
|
|
560
|
+
Blocks.copyCall(writer.dst, i, target, resources, payload);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/// @notice Append a RELAY block by copying its nested input from calldata.
|
|
564
|
+
function copyRelay(Writer memory writer, uint portal, uint resources, bytes calldata input) internal pure {
|
|
565
|
+
uint size = Sizes.B64 + Sizes.Header + input.length;
|
|
566
|
+
uint i = reserve(writer, size);
|
|
567
|
+
Blocks.copyRelay(writer.dst, i, portal, resources, input);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/// @notice Append a DISPATCH block by copying its nested payload from calldata.
|
|
571
|
+
function copyDispatch(Writer memory writer, uint portal, uint resources, bytes calldata payload) internal pure {
|
|
572
|
+
uint size = Sizes.B64 + Sizes.Header + payload.length;
|
|
573
|
+
uint i = reserve(writer, size);
|
|
574
|
+
Blocks.copyDispatch(writer.dst, i, portal, resources, payload);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/// @notice Append a CONTEXT block by copying its nested streams from calldata.
|
|
578
|
+
function copyContext(
|
|
579
|
+
Writer memory writer,
|
|
580
|
+
bytes32 account,
|
|
581
|
+
bytes calldata state,
|
|
582
|
+
bytes calldata input
|
|
583
|
+
) internal pure {
|
|
584
|
+
uint size = Sizes.B32 + 2 * Sizes.Header + state.length + input.length;
|
|
585
|
+
uint i = reserve(writer, size);
|
|
586
|
+
Blocks.copyContext(writer.dst, i, account, state, input);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/// @notice Append a RECOVER block by copying its nested witness from calldata.
|
|
590
|
+
function copyRecover(
|
|
591
|
+
Writer memory writer,
|
|
592
|
+
uint handler,
|
|
593
|
+
uint resources,
|
|
594
|
+
bytes32 recoverykey,
|
|
595
|
+
bytes calldata witness
|
|
596
|
+
) internal pure {
|
|
597
|
+
uint size = Sizes.B96 + Sizes.Header + witness.length;
|
|
598
|
+
uint i = reserve(writer, size);
|
|
599
|
+
Blocks.copyRecover(writer.dst, i, handler, resources, recoverykey, witness);
|
|
600
|
+
}
|
|
601
|
+
|
|
500
602
|
// -------------------------------------------------------------------------
|
|
501
603
|
// Finalisation
|
|
502
604
|
// -------------------------------------------------------------------------
|
package/commands/Relay.sol
CHANGED
|
@@ -34,7 +34,7 @@ abstract contract RelayPayable is CommandBase, RelayPayableHook {
|
|
|
34
34
|
) external payable onlyCommand returns (bytes memory, bytes memory) {
|
|
35
35
|
Execution memory exec = openCommand(state, input, descriptor, 1);
|
|
36
36
|
(uint portal, uint resources, bytes calldata payload) = exec.unpackRelay(Lanes.Input);
|
|
37
|
-
bytes memory context = Blocks.
|
|
37
|
+
bytes memory context = Blocks.contextCopy(account, state, payload);
|
|
38
38
|
|
|
39
39
|
relayTo(portal, resources, context, exec);
|
|
40
40
|
|
|
@@ -66,7 +66,7 @@ abstract contract RelayBalancePayable is CommandBase, RelayPayableHook {
|
|
|
66
66
|
) external payable onlyCommand returns (bytes memory, bytes memory) {
|
|
67
67
|
Execution memory exec = openCommand(state, input, descriptor, 1);
|
|
68
68
|
(uint portal, uint resources, bytes calldata payload) = exec.unpackRelay(Lanes.Input);
|
|
69
|
-
bytes memory context = Blocks.
|
|
69
|
+
bytes memory context = Blocks.contextCopy(account, state, payload);
|
|
70
70
|
|
|
71
71
|
relayTo(portal, resources, context, exec);
|
|
72
72
|
|
package/core/Settlement.sol
CHANGED
|
@@ -69,7 +69,7 @@ abstract contract Settlement is PostHook, SettleHook, RepayHook, DebitAccountHoo
|
|
|
69
69
|
bytes32 liability,
|
|
70
70
|
uint debt
|
|
71
71
|
) internal virtual override {
|
|
72
|
+
repay(account, liability, debt);
|
|
72
73
|
if (amount != 0) creditAccount(account, asset, amount);
|
|
73
|
-
if (debt != 0) debitAccount(account, liability, debt);
|
|
74
74
|
}
|
|
75
75
|
}
|
package/docs/Schema.md
CHANGED
|
@@ -301,6 +301,11 @@ bytes1 through bytes32
|
|
|
301
301
|
`uint` means `uint256`; `int` means `int256`. Other integer widths, unsized
|
|
302
302
|
`bytes`, `string`, and array syntax are not part of the core schema DSL.
|
|
303
303
|
|
|
304
|
+
Restricting fixed bytes to the power-of-two widths `bytes1`, `bytes2`,
|
|
305
|
+
`bytes4`, `bytes8`, `bytes16`, and `bytes32` is under consideration, but has
|
|
306
|
+
not been decided. Until that decision is made, the schema DSL continues to
|
|
307
|
+
allow every `bytesN` width from 1 through 32.
|
|
308
|
+
|
|
304
309
|
Integers are encoded big-endian. Signed integers use two's-complement encoding
|
|
305
310
|
for their declared width. `bool` is one byte: `0x00` for false and `0x01` for
|
|
306
311
|
true. `bytesN` values are encoded as exactly `N` bytes with no padding.
|
package/execution/Execution.sol
CHANGED
|
@@ -24,6 +24,8 @@ struct Execution {
|
|
|
24
24
|
|
|
25
25
|
/// @title Executions
|
|
26
26
|
/// @notice Opening, decoding, output, transaction, and value helpers for executions.
|
|
27
|
+
/// @dev `output*` helpers consume memory inputs; `outputCopy*` helpers copy
|
|
28
|
+
/// calldata inputs directly to the output lane.
|
|
27
29
|
library Executions {
|
|
28
30
|
using Cursors for uint;
|
|
29
31
|
|
|
@@ -197,6 +199,21 @@ library Executions {
|
|
|
197
199
|
exec.decoders = cur.seekAbs(end);
|
|
198
200
|
}
|
|
199
201
|
|
|
202
|
+
/// @notice Validate and enter the payload of the next block in an execution decoder lane.
|
|
203
|
+
/// @dev The selected lane remains in its existing frame so callers can decode
|
|
204
|
+
/// child blocks in place. Callers should prove complete payload consumption
|
|
205
|
+
/// with `exec.expectAbs(end)` after decoding the children from the same lane.
|
|
206
|
+
/// @param exec Execution whose selected decoder cursor advances over the block header.
|
|
207
|
+
/// @param lane Execution decoder lane to select.
|
|
208
|
+
/// @param spec Expected parent block specification.
|
|
209
|
+
/// @return abs Absolute position of the first payload byte.
|
|
210
|
+
/// @return end Absolute position immediately after the payload.
|
|
211
|
+
function enter(Execution memory exec, uint8 lane, uint spec) internal pure returns (uint abs, uint end) {
|
|
212
|
+
uint cur = exec.decoders.select(lane);
|
|
213
|
+
(abs, end) = Blocks.expect(cur.absolute(), spec);
|
|
214
|
+
exec.decoders = cur.seekAbs(abs);
|
|
215
|
+
}
|
|
216
|
+
|
|
200
217
|
/// @notice Require the active execution decoder to be at absolute position `abs`.
|
|
201
218
|
/// @dev The most recent lane-aware decoder operation determines the active lane.
|
|
202
219
|
/// @param exec Execution whose active decoder position is validated.
|
|
@@ -218,6 +235,46 @@ library Executions {
|
|
|
218
235
|
// Fixed-width block decoding
|
|
219
236
|
// -------------------------------------------------------------------------
|
|
220
237
|
|
|
238
|
+
/// @dev Return the next raw calldata word from `lane` and advance by `size` bytes.
|
|
239
|
+
function next(Execution memory exec, uint8 lane, uint size) private pure returns (bytes32 value) {
|
|
240
|
+
uint abs;
|
|
241
|
+
(exec.decoders, abs) = exec.decoders.consume(lane, size);
|
|
242
|
+
value = Blocks.read32(abs);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/// @notice Return the next raw byte from a decoder lane and advance it by one byte.
|
|
246
|
+
function next1(Execution memory exec, uint8 lane) internal pure returns (bytes1 value) {
|
|
247
|
+
value = bytes1(next(exec, lane, 1));
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/// @notice Return the next two raw bytes from a decoder lane and advance it by two bytes.
|
|
251
|
+
function next2(Execution memory exec, uint8 lane) internal pure returns (bytes2 value) {
|
|
252
|
+
value = bytes2(next(exec, lane, 2));
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/// @notice Return the next four raw bytes from a decoder lane and advance it by four bytes.
|
|
256
|
+
function next4(Execution memory exec, uint8 lane) internal pure returns (bytes4 value) {
|
|
257
|
+
value = bytes4(next(exec, lane, 4));
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/// @notice Return the next eight raw bytes from a decoder lane and advance it by eight bytes.
|
|
261
|
+
function next8(Execution memory exec, uint8 lane) internal pure returns (bytes8 value) {
|
|
262
|
+
value = bytes8(next(exec, lane, 8));
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/// @notice Return the next sixteen raw bytes from a decoder lane and advance it by sixteen bytes.
|
|
266
|
+
function next16(Execution memory exec, uint8 lane) internal pure returns (bytes16 value) {
|
|
267
|
+
value = bytes16(next(exec, lane, 16));
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/// @notice Return the next raw calldata word from a decoder lane and advance it.
|
|
271
|
+
/// @param exec Execution whose selected decoder cursor advances by one word.
|
|
272
|
+
/// @param lane Execution decoder lane to select.
|
|
273
|
+
/// @return value Raw word at the selected lane's previous position.
|
|
274
|
+
function next32(Execution memory exec, uint8 lane) internal pure returns (bytes32 value) {
|
|
275
|
+
value = next(exec, lane, Sizes.Word);
|
|
276
|
+
}
|
|
277
|
+
|
|
221
278
|
/// @notice Decode one fixed 32-byte payload from `lane`.
|
|
222
279
|
/// @param exec Execution whose decoder is advanced.
|
|
223
280
|
/// @param lane Decoder lane to consume.
|
|
@@ -1097,6 +1154,99 @@ library Executions {
|
|
|
1097
1154
|
Blocks.writeSchema(exec.output, i, spec, body, name);
|
|
1098
1155
|
}
|
|
1099
1156
|
|
|
1157
|
+
// -------------------------------------------------------------------------
|
|
1158
|
+
// Calldata output copy helpers
|
|
1159
|
+
// -------------------------------------------------------------------------
|
|
1160
|
+
|
|
1161
|
+
/// @notice Append a custom block to execution output by copying its payload from calldata.
|
|
1162
|
+
function outputCopyBlock(Execution memory exec, uint spec, bytes calldata data) internal pure {
|
|
1163
|
+
Specs.validate(spec, data.length);
|
|
1164
|
+
uint size = Sizes.Header + data.length;
|
|
1165
|
+
uint i = reserve(exec, size);
|
|
1166
|
+
Blocks.copy(exec.output, i, Specs.key(spec), data);
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
/// @notice Append a LIST block to execution output by copying its payload from calldata.
|
|
1170
|
+
function outputCopyList(Execution memory exec, bytes calldata value) internal pure {
|
|
1171
|
+
uint size = Sizes.Header + value.length;
|
|
1172
|
+
uint i = reserve(exec, size);
|
|
1173
|
+
Blocks.copyList(exec.output, i, value);
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
/// @notice Append an EVM block to execution output by copying its payload from calldata.
|
|
1177
|
+
function outputCopyEvm(Execution memory exec, bytes calldata value) internal pure {
|
|
1178
|
+
uint size = Sizes.Header + value.length;
|
|
1179
|
+
uint i = reserve(exec, size);
|
|
1180
|
+
Blocks.copyEvm(exec.output, i, value);
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
/// @notice Append a BYTES block to execution output by copying its payload from calldata.
|
|
1184
|
+
function outputCopyBytes(Execution memory exec, bytes calldata value) internal pure {
|
|
1185
|
+
uint size = Sizes.Header + value.length;
|
|
1186
|
+
uint i = reserve(exec, size);
|
|
1187
|
+
Blocks.copyBytes(exec.output, i, value);
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
/// @notice Append a STRING block to execution output by copying its payload from calldata.
|
|
1191
|
+
function outputCopyString(Execution memory exec, string calldata value) internal pure {
|
|
1192
|
+
uint size = Sizes.Header + bytes(value).length;
|
|
1193
|
+
uint i = reserve(exec, size);
|
|
1194
|
+
Blocks.copyString(exec.output, i, value);
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
/// @notice Append a STEP block to execution output by copying its nested input from calldata.
|
|
1198
|
+
function outputCopyStep(Execution memory exec, uint cmd, uint resources, bytes calldata input) internal pure {
|
|
1199
|
+
uint size = Sizes.B64 + Sizes.Header + input.length;
|
|
1200
|
+
uint i = reserve(exec, size);
|
|
1201
|
+
Blocks.copyStep(exec.output, i, cmd, resources, input);
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
/// @notice Append a CALL block to execution output by copying its nested payload from calldata.
|
|
1205
|
+
function outputCopyCall(Execution memory exec, uint target, uint resources, bytes calldata payload) internal pure {
|
|
1206
|
+
uint size = Sizes.B64 + Sizes.Header + payload.length;
|
|
1207
|
+
uint i = reserve(exec, size);
|
|
1208
|
+
Blocks.copyCall(exec.output, i, target, resources, payload);
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
/// @notice Append a RELAY block to execution output by copying its nested input from calldata.
|
|
1212
|
+
function outputCopyRelay(Execution memory exec, uint portal, uint resources, bytes calldata input) internal pure {
|
|
1213
|
+
uint size = Sizes.B64 + Sizes.Header + input.length;
|
|
1214
|
+
uint i = reserve(exec, size);
|
|
1215
|
+
Blocks.copyRelay(exec.output, i, portal, resources, input);
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
/// @notice Append a DISPATCH block to execution output by copying its nested payload from calldata.
|
|
1219
|
+
function outputCopyDispatch(Execution memory exec, uint portal, uint resources, bytes calldata payload) internal pure {
|
|
1220
|
+
uint size = Sizes.B64 + Sizes.Header + payload.length;
|
|
1221
|
+
uint i = reserve(exec, size);
|
|
1222
|
+
Blocks.copyDispatch(exec.output, i, portal, resources, payload);
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
/// @notice Append a CONTEXT block to execution output by copying its nested streams from calldata.
|
|
1226
|
+
function outputCopyContext(
|
|
1227
|
+
Execution memory exec,
|
|
1228
|
+
bytes32 account,
|
|
1229
|
+
bytes calldata state,
|
|
1230
|
+
bytes calldata input
|
|
1231
|
+
) internal pure {
|
|
1232
|
+
uint size = Sizes.B32 + 2 * Sizes.Header + state.length + input.length;
|
|
1233
|
+
uint i = reserve(exec, size);
|
|
1234
|
+
Blocks.copyContext(exec.output, i, account, state, input);
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
/// @notice Append a RECOVER block to execution output by copying its nested witness from calldata.
|
|
1238
|
+
function outputCopyRecover(
|
|
1239
|
+
Execution memory exec,
|
|
1240
|
+
uint handler,
|
|
1241
|
+
uint resources,
|
|
1242
|
+
bytes32 recoverykey,
|
|
1243
|
+
bytes calldata witness
|
|
1244
|
+
) internal pure {
|
|
1245
|
+
uint size = Sizes.B96 + Sizes.Header + witness.length;
|
|
1246
|
+
uint i = reserve(exec, size);
|
|
1247
|
+
Blocks.copyRecover(exec.output, i, handler, resources, recoverykey, witness);
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1100
1250
|
// -------------------------------------------------------------------------
|
|
1101
1251
|
// Value and transaction writing
|
|
1102
1252
|
// -------------------------------------------------------------------------
|
package/package.json
CHANGED
package/ports/AllowAssets.sol
CHANGED
|
@@ -8,10 +8,10 @@ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
|
|
|
8
8
|
|
|
9
9
|
using Executions for Execution;
|
|
10
10
|
|
|
11
|
-
/// @title
|
|
11
|
+
/// @title AllowAssetsPort
|
|
12
12
|
/// @notice Port that permits a list of assets on behalf of a peer host.
|
|
13
13
|
/// Each ASSET block in the input calls `allowAsset`. Restricted to trusted peers.
|
|
14
|
-
abstract contract
|
|
14
|
+
abstract contract AllowAssetsPort is PortBase, AllowAssetsHook {
|
|
15
15
|
uint private immutable descriptor;
|
|
16
16
|
|
|
17
17
|
constructor() {
|
package/ports/Allowance.sol
CHANGED
|
@@ -8,11 +8,11 @@ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
|
|
|
8
8
|
|
|
9
9
|
using Executions for Execution;
|
|
10
10
|
|
|
11
|
-
/// @title
|
|
11
|
+
/// @title AllowancePort
|
|
12
12
|
/// @notice Port that lets a trusted peer host input or refresh its own allowance.
|
|
13
13
|
/// Each AMOUNT block in the input is scoped to the peer host and passed to the
|
|
14
14
|
/// shared allowance hook as a host-scoped allowance. Restricted to trusted peers.
|
|
15
|
-
abstract contract
|
|
15
|
+
abstract contract AllowancePort is PortBase, AllowanceHook {
|
|
16
16
|
uint private immutable descriptor;
|
|
17
17
|
|
|
18
18
|
constructor() {
|
package/ports/Credit.sol
CHANGED
|
@@ -8,10 +8,10 @@ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
|
|
|
8
8
|
|
|
9
9
|
using Executions for Execution;
|
|
10
10
|
|
|
11
|
-
/// @title
|
|
11
|
+
/// @title CreditAccountPort
|
|
12
12
|
/// @notice Port that lets a trusted peer credit supplied accounts directly.
|
|
13
13
|
/// Each ACCOUNT_AMOUNT block calls `creditAccount` for its account.
|
|
14
|
-
abstract contract
|
|
14
|
+
abstract contract CreditAccountPort is PortBase, CreditAccountHook {
|
|
15
15
|
uint private immutable descriptor;
|
|
16
16
|
|
|
17
17
|
constructor() {
|
package/ports/Debit.sol
CHANGED
|
@@ -8,10 +8,10 @@ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
|
|
|
8
8
|
|
|
9
9
|
using Executions for Execution;
|
|
10
10
|
|
|
11
|
-
/// @title
|
|
11
|
+
/// @title DebitAccountPort
|
|
12
12
|
/// @notice Port that lets a trusted peer debit supplied accounts directly.
|
|
13
13
|
/// Each ACCOUNT_AMOUNT block calls `debitAccount` for its account.
|
|
14
|
-
abstract contract
|
|
14
|
+
abstract contract DebitAccountPort is PortBase, DebitAccountHook {
|
|
15
15
|
uint private immutable descriptor;
|
|
16
16
|
|
|
17
17
|
constructor() {
|
package/ports/DenyAssets.sol
CHANGED
|
@@ -8,10 +8,10 @@ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
|
|
|
8
8
|
|
|
9
9
|
using Executions for Execution;
|
|
10
10
|
|
|
11
|
-
/// @title
|
|
11
|
+
/// @title DenyAssetsPort
|
|
12
12
|
/// @notice Port that blocks a list of assets on behalf of a peer host.
|
|
13
13
|
/// Each ASSET block in the input calls `denyAsset`. Restricted to trusted peers.
|
|
14
|
-
abstract contract
|
|
14
|
+
abstract contract DenyAssetsPort is PortBase, DenyAssetsHook {
|
|
15
15
|
uint private immutable descriptor;
|
|
16
16
|
|
|
17
17
|
constructor() {
|
package/ports/Dispatch.sol
CHANGED
|
@@ -8,9 +8,9 @@ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
|
|
|
8
8
|
|
|
9
9
|
using Executions for Execution;
|
|
10
10
|
|
|
11
|
-
/// @title
|
|
11
|
+
/// @title DispatchPayablePort
|
|
12
12
|
/// @notice Port endpoint that forwards DISPATCH blocks to a host-defined relay hook.
|
|
13
|
-
abstract contract
|
|
13
|
+
abstract contract DispatchPayablePort is PortBase, RelayPayableHook {
|
|
14
14
|
uint private immutable descriptor;
|
|
15
15
|
|
|
16
16
|
constructor() {
|
|
@@ -27,7 +27,7 @@ abstract contract PortDispatchPayable is PortBase, RelayPayableHook {
|
|
|
27
27
|
|
|
28
28
|
while (exec.more()) {
|
|
29
29
|
(uint portal, uint resources, bytes calldata payload) = exec.unpackDispatch(Lanes.Input);
|
|
30
|
-
relayTo(portal, resources,
|
|
30
|
+
relayTo(portal, resources, payload, exec);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
return "";
|
package/ports/Pipe.sol
CHANGED
|
@@ -9,10 +9,10 @@ import {Budget} from "../execution/Budget.sol";
|
|
|
9
9
|
|
|
10
10
|
using Executions for Execution;
|
|
11
11
|
|
|
12
|
-
/// @title
|
|
12
|
+
/// @title PipePayablePort
|
|
13
13
|
/// @notice Port that consumes CONTEXT blocks and executes each input as a step stream.
|
|
14
14
|
/// Each context's input bytes are passed to the shared pipeline.
|
|
15
|
-
abstract contract
|
|
15
|
+
abstract contract PipePayablePort is PortBase, Pipeline {
|
|
16
16
|
uint private immutable descriptor;
|
|
17
17
|
|
|
18
18
|
constructor() {
|
package/ports/Post.sol
CHANGED
|
@@ -10,10 +10,10 @@ import {Actions} from "../utils/Actions.sol";
|
|
|
10
10
|
|
|
11
11
|
using Executions for Execution;
|
|
12
12
|
|
|
13
|
-
/// @title
|
|
13
|
+
/// @title PostPort
|
|
14
14
|
/// @notice Port that posts peer-supplied TRANSACTION blocks through debit and credit hooks.
|
|
15
15
|
/// Each TRANSACTION block calls `debitAccount` for `from` and `creditAccount` for `to`.
|
|
16
|
-
abstract contract
|
|
16
|
+
abstract contract PostPort is PortBase, PostHook, Action {
|
|
17
17
|
uint private immutable descriptor;
|
|
18
18
|
|
|
19
19
|
constructor() {
|
package/ports/Redeem.sol
CHANGED
|
@@ -16,11 +16,11 @@ abstract contract RedeemBalanceHook {
|
|
|
16
16
|
function redeemBalance(uint peer, bytes32 asset, uint amount) internal virtual;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
/// @title
|
|
19
|
+
/// @title RedeemBalancePort
|
|
20
20
|
/// @notice Port that redeems balance state from a peer host into local assets.
|
|
21
21
|
/// Each BALANCE block in the input calls `redeemBalance(peer, asset, amount)`.
|
|
22
22
|
/// Restricted to trusted peers.
|
|
23
|
-
abstract contract
|
|
23
|
+
abstract contract RedeemBalancePort is PortBase, RedeemBalanceHook {
|
|
24
24
|
uint private immutable descriptor;
|
|
25
25
|
|
|
26
26
|
constructor() {
|
package/utils/Cursors.sol
CHANGED
|
@@ -36,6 +36,11 @@ struct Cur {
|
|
|
36
36
|
/// to marks. A zero mark identifies the empty cursor at position zero; `before`
|
|
37
37
|
/// therefore treats it as already reached.
|
|
38
38
|
///
|
|
39
|
+
/// Cursor navigation assumes packed cursor inputs satisfy `i <= len`.
|
|
40
|
+
/// Constructors and composition helpers establish this invariant, and navigation
|
|
41
|
+
/// helpers preserve it. Manually constructing or modifying packed cursor words
|
|
42
|
+
/// may cause arithmetic panics instead of cursor-specific errors.
|
|
43
|
+
///
|
|
39
44
|
/// The zero word represents an absent cursor.
|
|
40
45
|
library Cursors {
|
|
41
46
|
/// @dev A cursor position exceeds its logical length.
|
|
@@ -214,11 +219,12 @@ library Cursors {
|
|
|
214
219
|
}
|
|
215
220
|
|
|
216
221
|
/// @notice Advance the current position of the lower cursor.
|
|
222
|
+
/// @dev Assumes `cur` satisfies the cursor invariant `i <= len`.
|
|
217
223
|
/// @param cur Packed cursor or cursor pair.
|
|
218
224
|
/// @param amount Number of bytes to advance.
|
|
219
225
|
/// @return updated Cursor advanced by `amount`.
|
|
220
226
|
function advance(uint cur, uint amount) internal pure returns (uint updated) {
|
|
221
|
-
uint i = uint32(
|
|
227
|
+
uint i = uint32(cur);
|
|
222
228
|
uint len = uint32(cur >> 64);
|
|
223
229
|
if (amount > len - i) revert OutOfBounds();
|
|
224
230
|
updated = cur + amount;
|
|
@@ -236,14 +242,15 @@ library Cursors {
|
|
|
236
242
|
|
|
237
243
|
/// @notice Create a child cursor over `[start, end)` within the lower cursor.
|
|
238
244
|
/// @dev The child starts at position zero, has no recorded count, and uses the
|
|
239
|
-
/// supplied tag. Any higher cursor is omitted.
|
|
245
|
+
/// supplied tag. Any higher cursor is omitted. Assumes `cur` satisfies the
|
|
246
|
+
/// cursor invariant `i <= len`.
|
|
240
247
|
/// @param cur Parent cursor or cursor pair.
|
|
241
248
|
/// @param start Child start relative to the parent base.
|
|
242
249
|
/// @param end Child exclusive end relative to the parent base.
|
|
243
250
|
/// @param tag Child identity tag.
|
|
244
251
|
/// @return child Packed child cursor.
|
|
245
252
|
function slice(uint cur, uint start, uint end, uint8 tag) internal pure returns (uint child) {
|
|
246
|
-
(, uint offset, uint len) = decode(
|
|
253
|
+
(, uint offset, uint len) = decode(cur);
|
|
247
254
|
if (start > end || end > len) revert OutOfBounds();
|
|
248
255
|
child = create(offset + start, end - start, 0, 0, tag);
|
|
249
256
|
}
|