@rootzero/contracts 1.17.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/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
  // -------------------------------------------------------------------------
@@ -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.context(account, bytes(state), bytes(payload));
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.context(account, bytes(state), bytes(payload));
69
+ bytes memory context = Blocks.contextCopy(account, state, payload);
70
70
 
71
71
  relayTo(portal, resources, context, exec);
72
72
 
@@ -0,0 +1,83 @@
1
+ // SPDX-License-Identifier: GPL-3.0-only
2
+ pragma solidity ^0.8.33;
3
+
4
+ import {Execution, Executions, CommandBase, Lanes, Specs} from "./Base.sol";
5
+ import {RepayHook} from "../core/Settlement.sol";
6
+ import {Action} from "../annotations/Action.sol";
7
+ import {Actions} from "../utils/Actions.sol";
8
+
9
+ using Executions for Execution;
10
+
11
+ /// @notice Hook implemented by hosts that repay position liabilities using native value.
12
+ abstract contract RepayPayableHook {
13
+ /// @notice Override to repay one liability for `account` with a shared value budget.
14
+ /// @param account Account whose liability is being repaid.
15
+ /// @param liability Identifier for the liability side.
16
+ /// @param debt Quantity on the liability side.
17
+ /// @param funds Mutable execution used only for its remaining native-value budget.
18
+ function repay(bytes32 account, bytes32 liability, uint debt, Execution memory funds) internal virtual;
19
+ }
20
+
21
+ /// @title Repay
22
+ /// @notice Command that repays POSITION liabilities and returns their assets as BALANCE state.
23
+ abstract contract Repay is CommandBase, RepayHook, Action {
24
+ uint private immutable descriptor;
25
+
26
+ constructor() {
27
+ uint id;
28
+ (id, descriptor) = command("repay", Specs.Position, Specs.Empty, Specs.Balance, 0, false, false);
29
+ action(id, Actions.Settle);
30
+ }
31
+
32
+ /// @notice Repay each POSITION liability and return its asset as BALANCE state.
33
+ /// @param state POSITION block stream.
34
+ /// @return BALANCE output state containing each released asset side.
35
+ /// @return Empty transaction stream.
36
+ function repay(
37
+ bytes32 account,
38
+ bytes calldata state,
39
+ bytes calldata input
40
+ ) external onlyCommand returns (bytes memory, bytes memory) {
41
+ Execution memory exec = openCommand(state, input, descriptor, 0);
42
+
43
+ while (exec.more()) {
44
+ (bytes32 asset, uint amount, bytes32 liability, uint debt) = exec.unpackPosition(Lanes.State);
45
+ repay(account, liability, debt);
46
+ exec.outputBalance(asset, amount);
47
+ }
48
+
49
+ return close(exec, account);
50
+ }
51
+ }
52
+
53
+ /// @title RepayPayable
54
+ /// @notice Funded command that repays POSITION liabilities and returns their assets as BALANCE state.
55
+ abstract contract RepayPayable is CommandBase, RepayPayableHook, Action {
56
+ uint private immutable descriptor;
57
+
58
+ constructor() {
59
+ uint id;
60
+ (id, descriptor) = command("repayPayable", Specs.Position, Specs.Empty, Specs.Balance, 0, true, false);
61
+ action(id, Actions.Settle);
62
+ }
63
+
64
+ /// @notice Repay each POSITION liability and return its asset as BALANCE state.
65
+ /// @param state POSITION block stream.
66
+ /// @return BALANCE output state containing each released asset side.
67
+ /// @return Remaining native value as a refund transaction stream.
68
+ function repayPayable(
69
+ bytes32 account,
70
+ bytes calldata state,
71
+ bytes calldata input
72
+ ) external payable onlyCommand returns (bytes memory, bytes memory) {
73
+ Execution memory exec = openCommand(state, input, descriptor, 0);
74
+
75
+ while (exec.more()) {
76
+ (bytes32 asset, uint amount, bytes32 liability, uint debt) = exec.unpackPosition(Lanes.State);
77
+ repay(account, liability, debt, exec);
78
+ exec.outputBalance(asset, amount);
79
+ }
80
+
81
+ return close(exec, account);
82
+ }
83
+ }
@@ -28,22 +28,23 @@ abstract contract PostHook {
28
28
  function post(bytes32 from, bytes32 to, bytes32 asset, uint amount) internal virtual;
29
29
  }
30
30
 
31
+ /// @title RepayHook
32
+ /// @notice Hook for repaying one account liability.
33
+ abstract contract RepayHook {
34
+ /// @notice Override to repay `debt` denominated in `liability` for `account`.
35
+ function repay(bytes32 account, bytes32 liability, uint debt) internal virtual;
36
+ }
37
+
31
38
  /// @title SettleHook
32
39
  /// @notice Hook for settling one asset-liability position.
33
40
  abstract contract SettleHook {
34
41
  /// @notice Override to settle one position for `account`.
35
- function settle(
36
- bytes32 account,
37
- bytes32 asset,
38
- uint amount,
39
- bytes32 liability,
40
- uint debt
41
- ) internal virtual;
42
+ function settle(bytes32 account, bytes32 asset, uint amount, bytes32 liability, uint debt) internal virtual;
42
43
  }
43
44
 
44
45
  /// @title Settlement
45
46
  /// @notice Default account-hook implementation for transaction posting and position settlement.
46
- abstract contract Settlement is PostHook, SettleHook, DebitAccountHook, CreditAccountHook {
47
+ abstract contract Settlement is PostHook, SettleHook, RepayHook, DebitAccountHook, CreditAccountHook {
47
48
  /// @notice Post one transaction by debiting its source and crediting its destination.
48
49
  /// Returns without calling either hook when `amount` is zero and skips either
49
50
  /// operation when the corresponding account is zero.
@@ -53,6 +54,12 @@ abstract contract Settlement is PostHook, SettleHook, DebitAccountHook, CreditAc
53
54
  if (to != 0) creditAccount(to, asset, amount);
54
55
  }
55
56
 
57
+ /// @notice Repay one liability by debiting it from the account.
58
+ /// Skips the debit when `debt` is zero.
59
+ function repay(bytes32 account, bytes32 liability, uint debt) internal virtual override {
60
+ if (debt != 0) debitAccount(account, liability, debt);
61
+ }
62
+
56
63
  /// @notice Settle one position by crediting its asset and debiting its liability.
57
64
  /// Skips either operation when its corresponding amount is zero.
58
65
  function settle(
@@ -62,7 +69,7 @@ abstract contract Settlement is PostHook, SettleHook, DebitAccountHook, CreditAc
62
69
  bytes32 liability,
63
70
  uint debt
64
71
  ) internal virtual override {
72
+ repay(account, liability, debt);
65
73
  if (amount != 0) creditAccount(account, asset, amount);
66
- if (debt != 0) debitAccount(account, liability, debt);
67
74
  }
68
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.
@@ -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/guards/Revoke.sol CHANGED
@@ -2,6 +2,7 @@
2
2
  pragma solidity ^0.8.33;
3
3
 
4
4
  import {AllowanceHook} from "../commands/admin/Allowance.sol";
5
+ import {DenyAssetsHook} from "../commands/admin/DenyAssets.sol";
5
6
  import {GuardBase} from "./Base.sol";
6
7
  import {Specs} from "../Codec.sol";
7
8
  import {Execution, Executions, Lanes} from "../execution/Execution.sol";
@@ -49,3 +50,24 @@ abstract contract RevokeAllowance is GuardBase, AllowanceHook {
49
50
  }
50
51
  }
51
52
  }
53
+
54
+ /// @title RevokeAsset
55
+ /// @notice Guardian action that denies assets through the host's existing asset hook.
56
+ /// @dev Opt-in guard. Hosts expose it by inheriting this contract and implementing DenyAssetsHook.
57
+ abstract contract RevokeAsset is GuardBase, DenyAssetsHook {
58
+ uint private immutable descriptor;
59
+
60
+ constructor() {
61
+ (, descriptor) = guard("revokeAsset", Specs.Asset);
62
+ }
63
+
64
+ /// @notice Deny every ASSET block in `input` as the active guardian.
65
+ function revokeAsset(bytes calldata input) external onlyGuardian {
66
+ Execution memory exec = openInput(input, descriptor, 0);
67
+
68
+ while (exec.more()) {
69
+ bytes32 asset = exec.unpackAsset(Lanes.Input);
70
+ denyAsset(asset);
71
+ }
72
+ }
73
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rootzero/contracts",
3
- "version": "1.17.0",
3
+ "version": "1.19.0",
4
4
  "description": "Solidity contracts and protocol building blocks for rootzero hosts and commands.",
5
5
  "private": false,
6
6
  "license": "GPL-3.0-only",
@@ -8,10 +8,10 @@ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
8
8
 
9
9
  using Executions for Execution;
10
10
 
11
- /// @title PortAllowAssets
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 PortAllowAssets is PortBase, AllowAssetsHook {
14
+ abstract contract AllowAssetsPort is PortBase, AllowAssetsHook {
15
15
  uint private immutable descriptor;
16
16
 
17
17
  constructor() {
@@ -8,11 +8,11 @@ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
8
8
 
9
9
  using Executions for Execution;
10
10
 
11
- /// @title PortAllowance
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 PortAllowance is PortBase, AllowanceHook {
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 PortCreditAccount
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 PortCreditAccount is PortBase, CreditAccountHook {
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 PortDebitAccount
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 PortDebitAccount is PortBase, DebitAccountHook {
14
+ abstract contract DebitAccountPort is PortBase, DebitAccountHook {
15
15
  uint private immutable descriptor;
16
16
 
17
17
  constructor() {
@@ -8,10 +8,10 @@ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
8
8
 
9
9
  using Executions for Execution;
10
10
 
11
- /// @title PortDenyAssets
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 PortDenyAssets is PortBase, DenyAssetsHook {
14
+ abstract contract DenyAssetsPort is PortBase, DenyAssetsHook {
15
15
  uint private immutable descriptor;
16
16
 
17
17
  constructor() {
@@ -8,9 +8,9 @@ import {Execution, Executions, Lanes} from "../execution/Execution.sol";
8
8
 
9
9
  using Executions for Execution;
10
10
 
11
- /// @title PortDispatchPayable
11
+ /// @title DispatchPayablePort
12
12
  /// @notice Port endpoint that forwards DISPATCH blocks to a host-defined relay hook.
13
- abstract contract PortDispatchPayable is PortBase, RelayPayableHook {
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, bytes(payload), exec);
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 PortPipePayable
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 PortPipePayable is PortBase, Pipeline {
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 PortPost
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 PortPost is PortBase, PostHook, Action {
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 PortRedeemBalance
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 PortRedeemBalance is PortBase, RedeemBalanceHook {
23
+ abstract contract RedeemBalancePort is PortBase, RedeemBalanceHook {
24
24
  uint private immutable descriptor;
25
25
 
26
26
  constructor() {