@rootzero/contracts 1.14.0 → 1.16.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 +100 -0
  2. package/Codec.sol +1 -1
  3. package/Commands.sol +1 -1
  4. package/Core.sol +8 -5
  5. package/Endpoints.sol +6 -6
  6. package/Events.sol +1 -3
  7. package/README.md +118 -35
  8. package/annotations/Action.sol +17 -0
  9. package/annotations/Label.sol +23 -0
  10. package/annotations/Schema.sol +53 -0
  11. package/codec/Blocks.sol +127 -32
  12. package/codec/Buffers.sol +3 -3
  13. package/codec/Decoders.sol +46 -13
  14. package/codec/Descriptors.sol +0 -1
  15. package/codec/Keys.sol +8 -4
  16. package/codec/Readers.sol +13 -0
  17. package/codec/Schema.sol +12 -3
  18. package/codec/Specs.sol +28 -4
  19. package/codec/Writers.sol +21 -6
  20. package/commands/Base.sol +39 -44
  21. package/commands/Burn.sol +8 -4
  22. package/commands/Credit.sol +35 -3
  23. package/commands/Debit.sol +46 -13
  24. package/commands/Deposit.sol +14 -8
  25. package/commands/Payout.sol +6 -2
  26. package/commands/Provision.sol +4 -4
  27. package/commands/Recover.sol +15 -8
  28. package/commands/Relay.sol +37 -12
  29. package/commands/Settle.sol +77 -0
  30. package/commands/Withdraw.sol +8 -4
  31. package/commands/admin/AllowAssets.sol +2 -2
  32. package/commands/admin/Allowance.sol +2 -2
  33. package/commands/admin/Annotate.sol +36 -0
  34. package/commands/admin/Appoint.sol +6 -5
  35. package/commands/admin/Authorize.sol +2 -2
  36. package/commands/admin/Base.sol +8 -1
  37. package/commands/admin/DenyAssets.sol +2 -2
  38. package/commands/admin/Dismiss.sol +6 -5
  39. package/commands/admin/Execute.sol +5 -4
  40. package/commands/admin/Unauthorize.sol +2 -2
  41. package/core/Access.sol +91 -49
  42. package/core/Calls.sol +27 -22
  43. package/core/Endpoint.sol +36 -46
  44. package/core/Host.sol +63 -21
  45. package/core/Pipeline.sol +6 -6
  46. package/core/Settlement.sol +37 -8
  47. package/core/Types.sol +13 -1
  48. package/docs/Schema.md +68 -7
  49. package/events/Annotation.sol +24 -0
  50. package/events/Guardian.sol +2 -2
  51. package/events/Introduction.sol +3 -2
  52. package/execution/Budget.sol +12 -4
  53. package/execution/Execution.sol +113 -18
  54. package/guards/Base.sol +4 -4
  55. package/package.json +1 -1
  56. package/ports/Base.sol +19 -7
  57. package/ports/Dispatch.sol +6 -6
  58. package/ports/{Settle.sol → Post.sol} +13 -9
  59. package/queries/Base.sol +18 -3
  60. package/utils/Accounts.sol +0 -23
  61. package/utils/Actions.sol +1 -0
  62. package/utils/Cursors.sol +79 -34
  63. package/utils/Layout.sol +0 -2
  64. package/commands/admin/Label.sol +0 -36
  65. package/commands/admin/Schemas.sol +0 -36
  66. package/events/Labeled.sol +0 -21
  67. package/events/Position.sol +0 -22
  68. package/events/Schema.sol +0 -23
package/utils/Cursors.sol CHANGED
@@ -12,47 +12,57 @@ struct Cur {
12
12
  }
13
13
 
14
14
  /// @title Cursors
15
- /// @notice Packed cursor state and navigation for grouped byte regions.
15
+ /// @notice Packed cursor state and navigation for byte regions.
16
16
  /// @dev Each 128-bit cursor uses the following layout:
17
17
  /// bits 0-31 i
18
18
  /// bits 32-63 offset
19
19
  /// bits 64-95 len
20
- /// bits 96-111 groups
20
+ /// bits 96-111 count (opaque consumer metadata)
21
21
  /// bits 112-119 flags (consumer-defined)
22
22
  /// bits 120-127 tag
23
- /// A packed word may contain a lower cursor in bits 0-127 and a higher cursor
24
- /// in bits 128-255. Operations target the lower cursor; `select` swaps a
25
- /// requested tagged cursor into that position.
23
+ ///
24
+ /// A cursor is one 128-bit value with this layout. A pair is a 256-bit value
25
+ /// containing a lower cursor in bits 0-127 and an optional higher cursor in
26
+ /// bits 128-255. The lower cursor is the active cursor: navigation and
27
+ /// inspection operations target it, and `select` swaps a requested tagged
28
+ /// cursor into that position while preserving the pair.
29
+ ///
30
+ /// A mark is a standalone cursor value used as an immutable positional
31
+ /// reference. It retains the cursor's offset, length, count, flags, and tag,
32
+ /// but may carry a different `i`. A mark has no intrinsic boundary or movement
33
+ /// semantics; callers may later use its position for comparison, validation,
34
+ /// seeking, or another operation. Because it has the ordinary single-cursor
35
+ /// layout, existing positional decoding and absolute-position rules also apply
36
+ /// to marks. A zero mark identifies the empty cursor at position zero; `before`
37
+ /// therefore treats it as already reached.
38
+ ///
26
39
  /// The zero word represents an absent cursor.
27
40
  library Cursors {
28
41
  /// @dev A cursor position exceeds its logical length.
29
42
  error OutOfBounds();
30
43
 
31
- /// @dev Two optional group counts are both set but do not match.
32
- error BadRatio();
33
-
34
44
  /// @dev A cursor is not positioned at the expected offset.
35
45
  error UnexpectedPosition();
36
46
 
37
47
  /// @dev Paired cursors must have different identity tags.
38
48
  error DuplicateTag(uint8 tag);
39
49
 
40
- /// @dev Neither packed cursor has the requested tag.
41
- error MissingTag(uint8 tag);
50
+ /// @dev Neither packed cursor matches the requested identity.
51
+ error MissingCursor();
42
52
 
43
53
  // Creation and sources
44
54
 
45
55
  /// @notice Create a cursor positioned at its beginning.
46
56
  /// @param offset Absolute source or buffer offset.
47
57
  /// @param len Logical byte length.
48
- /// @param groups Logical group count.
58
+ /// @param items Opaque item count associated with the region.
49
59
  /// @param flags Consumer-defined flags.
50
60
  /// @param tag Cursor identity tag.
51
61
  /// @return cur Packed cursor.
52
- function create(uint offset, uint len, uint groups, uint8 flags, uint8 tag) internal pure returns (uint cur) {
62
+ function create(uint offset, uint len, uint items, uint8 flags, uint8 tag) internal pure returns (uint cur) {
53
63
  cur |= max32(offset) << 32;
54
64
  cur |= max32(len) << 64;
55
- cur |= max16(groups) << 96;
65
+ cur |= max16(items) << 96;
56
66
  cur |= uint(flags) << 112;
57
67
  cur |= uint(tag) << 120;
58
68
  }
@@ -97,6 +107,14 @@ library Cursors {
97
107
  len = uint32(cur >> 64);
98
108
  }
99
109
 
110
+ /// @notice Return the active cursor without its position.
111
+ /// @dev Ignores the upper cursor when `cur` is a pair.
112
+ /// @param cur Packed cursor or cursor pair.
113
+ /// @return The lower cursor's offset, length, count, flags, and tag.
114
+ function frame(uint cur) internal pure returns (uint) {
115
+ return clear32(uint128(cur), 0);
116
+ }
117
+
100
118
  /// @notice Return the absolute position of the lower cursor as `offset + i`.
101
119
  /// @dev Performs no bounds check.
102
120
  /// @param cur Packed cursor or cursor pair.
@@ -107,15 +125,20 @@ library Cursors {
107
125
 
108
126
  /// @notice Decode the consumer metadata and identity tag from the lower cursor.
109
127
  /// @param cur Packed cursor or cursor pair.
110
- /// @return groups Logical group count.
128
+ /// @return items Opaque item count.
111
129
  /// @return flags Consumer-defined flags.
112
130
  /// @return tag Cursor identity tag.
113
- function meta(uint cur) internal pure returns (uint groups, uint8 flags, uint8 tag) {
114
- groups = uint16(cur >> 96);
131
+ function meta(uint cur) internal pure returns (uint items, uint8 flags, uint8 tag) {
132
+ items = uint16(cur >> 96);
115
133
  flags = uint8(cur >> 112);
116
134
  tag = uint8(cur >> 120);
117
135
  }
118
136
 
137
+ /// @notice Return the opaque item count attached to the active cursor.
138
+ function count(uint cur) internal pure returns (uint) {
139
+ return uint16(cur >> 96);
140
+ }
141
+
119
142
  /// @notice Return whether both packed cursors remain at their initial positions.
120
143
  /// @param cur Packed cursor or cursor pair.
121
144
  /// @return Whether both lane positions are zero.
@@ -144,6 +167,13 @@ library Cursors {
144
167
  if (uint32(cur) != i) revert UnexpectedPosition();
145
168
  }
146
169
 
170
+ /// @notice Require the lower cursor to be positioned at absolute position `abs`.
171
+ /// @param cur Packed cursor or cursor pair.
172
+ /// @param abs Expected absolute position.
173
+ function expectAbs(uint cur, uint abs) internal pure {
174
+ if (absolute(cur) != abs) revert UnexpectedPosition();
175
+ }
176
+
147
177
  /// @notice Return whether the lower cursor contains `flag`.
148
178
  /// @param cur Packed cursor or cursor pair.
149
179
  /// @param flag Consumer-defined flag bit or bit set.
@@ -205,7 +235,7 @@ library Cursors {
205
235
  }
206
236
 
207
237
  /// @notice Create a child cursor over `[start, end)` within the lower cursor.
208
- /// @dev The child starts at position zero, has no groups, and uses the
238
+ /// @dev The child starts at position zero, has no recorded count, and uses the
209
239
  /// supplied tag. Any higher cursor is omitted.
210
240
  /// @param cur Parent cursor or cursor pair.
211
241
  /// @param start Child start relative to the parent base.
@@ -220,22 +250,6 @@ library Cursors {
220
250
 
221
251
  // Pairing and selection
222
252
 
223
- /// @notice Reconcile both packed cursor lanes with an expected group count.
224
- /// @dev Zero lanes and lanes with zero groups do not constrain the result.
225
- /// @param cur Packed cursor or cursor pair.
226
- /// @param expected Expected group count; zero accepts the encoded count.
227
- /// @return groups Reconciled effective group count.
228
- function reconcile(uint cur, uint expected) internal pure returns (uint groups) {
229
- uint low = uint16(cur >> 96);
230
- uint high = uint16(cur >> 224);
231
- if (low != 0 && high != 0 && low != high) revert BadRatio();
232
-
233
- groups = low != 0 ? low : high;
234
- if (groups != 0 && expected != 0 && groups != expected) revert BadRatio();
235
- if (groups == 0) groups = expected;
236
- max16(groups);
237
- }
238
-
239
253
  /// @notice Combine two cursors into one packed word.
240
254
  /// @dev Zero represents absence and acts as the identity value.
241
255
  /// @param low Cursor placed in the lower lane.
@@ -279,7 +293,38 @@ library Cursors {
279
293
  if (uint8(cur >> 120) == expected) return cur;
280
294
 
281
295
  updated = swap(cur);
282
- if (uint8(updated >> 120) != expected) revert MissingTag(expected);
296
+ if (uint8(updated >> 120) != expected) revert MissingCursor();
297
+ }
298
+
299
+ // Marks
300
+
301
+ /// @notice Select the live cursor whose frame matches the active cursor in `mark`.
302
+ /// @dev Only the lower 128 bits of `mark` are considered. The returned value
303
+ /// preserves the cursor pair and places the matching cursor in the lower half.
304
+ /// A zero frame may select an empty cursor lane.
305
+ /// @param cur Packed cursor or cursor pair to search.
306
+ /// @param mark Cursor-shaped positional reference to match.
307
+ /// @return located Cursor pair with the matching cursor active.
308
+ function locate(uint cur, uint mark) internal pure returns (uint located) {
309
+ uint expected = frame(mark);
310
+ if (frame(cur) == expected) return cur;
311
+
312
+ located = swap(cur);
313
+ if (frame(located) != expected) revert MissingCursor();
314
+ }
315
+
316
+ /// @notice Return whether a matched cursor is positioned before `mark`.
317
+ /// @dev Returns false at the mark and reverts after it. Only the active lower
318
+ /// cursor in `mark` participates in the comparison. A zero mark represents
319
+ /// the already-reached position of an empty cursor.
320
+ /// @param cur Packed cursor or cursor pair containing the marked cursor.
321
+ /// @param mark Cursor-shaped positional reference.
322
+ /// @return Whether the live cursor position precedes the marked position.
323
+ function before(uint cur, uint mark) internal pure returns (bool) {
324
+ uint i = uint32(locate(cur, mark));
325
+ uint target = uint32(mark);
326
+ if (i > target) revert OutOfBounds();
327
+ return i < target;
283
328
  }
284
329
 
285
330
  // Consumption
package/utils/Layout.sol CHANGED
@@ -40,8 +40,6 @@ library Layout {
40
40
 
41
41
  /// @dev Admin account — chain-local, backed by an EVM address.
42
42
  uint8 constant Admin = 0x01;
43
- /// @dev Guardian account — chain-local, backed by an EVM address.
44
- uint8 constant Guardian = 0x02;
45
43
  /// @dev User account — chain-agnostic, backed by an EVM address.
46
44
  uint8 constant User = 0x03;
47
45
  // -------------------------------------------------------------------------
@@ -1,36 +0,0 @@
1
- // SPDX-License-Identifier: GPL-3.0-only
2
- pragma solidity ^0.8.33;
3
-
4
- import {AdminBase, Execution, Executions, Lanes, Specs} from "./Base.sol";
5
- using Executions for Execution;
6
-
7
- /// @title Label
8
- /// @notice Admin command that publishes namespaced labels for node IDs.
9
- /// Each LABEL block in the input emits one `Labeled` event. Only callable by
10
- /// the admin account.
11
- abstract contract Label is AdminBase {
12
- uint private immutable descriptor;
13
-
14
- constructor() {
15
- (, descriptor) = command("label", Specs.Empty, Specs.Label, Specs.Empty, 0, false, true);
16
- }
17
-
18
- /// @notice Publish each LABEL block in the admin input.
19
- /// @param input LABEL block stream.
20
- /// @return Empty output state.
21
- /// @return Empty transaction stream.
22
- function label(
23
- bytes32 account,
24
- bytes calldata,
25
- bytes calldata input
26
- ) external onlyAdmin(account) returns (bytes memory, bytes memory) {
27
- Execution memory exec = openInput(input, descriptor, 0);
28
-
29
- while (exec.more()) {
30
- (uint node, bytes32 namespace, string memory name) = exec.unpackLabel(Lanes.Input);
31
- emit Labeled(node, namespace, name);
32
- }
33
-
34
- return close(exec, account);
35
- }
36
- }
@@ -1,36 +0,0 @@
1
- // SPDX-License-Identifier: GPL-3.0-only
2
- pragma solidity ^0.8.33;
3
-
4
- import {AdminBase, Execution, Executions, Lanes, Specs} from "./Base.sol";
5
- using Executions for Execution;
6
-
7
- /// @title PublishSchema
8
- /// @notice Admin command that publishes block schemas for keys.
9
- /// Each SCHEMA block in the input emits one `Schema` event. Only callable by
10
- /// the admin account.
11
- abstract contract PublishSchema is AdminBase {
12
- uint private immutable descriptor;
13
-
14
- constructor() {
15
- (, descriptor) = command("publishSchema", Specs.Empty, Specs.Schema, Specs.Empty, 0, false, true);
16
- }
17
-
18
- /// @notice Publish each SCHEMA block in the admin input.
19
- /// @param input SCHEMA block stream.
20
- /// @return Empty output state.
21
- /// @return Empty transaction stream.
22
- function publishSchema(
23
- bytes32 account,
24
- bytes calldata,
25
- bytes calldata input
26
- ) external onlyAdmin(account) returns (bytes memory, bytes memory) {
27
- Execution memory exec = openInput(input, descriptor, 0);
28
-
29
- while (exec.more()) {
30
- (uint spec, string memory body, bytes32 name) = exec.unpackSchema(Lanes.Input);
31
- emit Schema(host, spec, body, name);
32
- }
33
-
34
- return close(exec, account);
35
- }
36
- }
@@ -1,21 +0,0 @@
1
- // SPDX-License-Identifier: GPL-3.0-only
2
- pragma solidity ^0.8.33;
3
-
4
- import {EventEmitter} from "./Emitter.sol";
5
-
6
- /// @notice Emitted to attach a human-readable namespaced label to an entity.
7
- /// @dev Labels are claims by the emitting contract. Any contract may emit a
8
- /// label for any entity, so off-chain indexers must decide which emitters are
9
- /// trusted for each labeled entity or namespace.
10
- abstract contract LabeledEvent is EventEmitter {
11
- string private constant ABI = "event Labeled(uint indexed entity, bytes32 namespace, string name)";
12
-
13
- /// @param entity Entity being labeled.
14
- /// @param namespace Label namespace.
15
- /// @param name Human-readable name within the namespace.
16
- event Labeled(uint indexed entity, bytes32 namespace, string name);
17
-
18
- constructor() {
19
- emit EventAbi(ABI);
20
- }
21
- }
@@ -1,22 +0,0 @@
1
- // SPDX-License-Identifier: GPL-3.0-only
2
- pragma solidity ^0.8.33;
3
-
4
- import {EventEmitter} from "./Emitter.sol";
5
-
6
- /// @notice Emitted when the reported value of an asset-backed position changes or is observed.
7
- /// A value of 0 should be interpreted as a closed position.
8
- abstract contract PositionEvent is EventEmitter {
9
- string private constant ABI = "event Position(bytes32 indexed account, bytes32 asset, uint value, uint32 action, uint context, uint queryId)";
10
-
11
- /// @param account Account identifier that owns or is associated with the position.
12
- /// @param asset Asset identifier for the asset class.
13
- /// @param value Context-specific position value; 0 indicates a closed position.
14
- /// @param action Primary operation hint from `Actions`.
15
- /// @param context Reserved context value for future use.
16
- /// @param queryId Query ID associated with the position lookup or reporting context.
17
- event Position(bytes32 indexed account, bytes32 asset, uint value, uint32 action, uint context, uint queryId);
18
-
19
- constructor() {
20
- emit EventAbi(ABI);
21
- }
22
- }
package/events/Schema.sol DELETED
@@ -1,23 +0,0 @@
1
- // SPDX-License-Identifier: GPL-3.0-only
2
- pragma solidity ^0.8.33;
3
-
4
- import {EventEmitter} from "./Emitter.sol";
5
-
6
- /// @title SchemaEvent
7
- /// @notice Emitted during host deployment to publish a block spec and payload schema.
8
- /// Block keys are opaque `bytes4` tags. Standard protocol blocks use
9
- /// keccak-derived keys by convention, but custom block keys only need to be
10
- /// unique within the publishing host/schema context.
11
- abstract contract SchemaEvent is EventEmitter {
12
- string private constant ABI = "event Schema(uint indexed host, uint spec, string body, bytes32 name)";
13
-
14
- /// @param host Host node ID that publishes this block schema.
15
- /// @param spec Block specification being defined by `host`.
16
- /// @param body Schema DSL string describing the block payload body.
17
- /// @param name Optional block alias used by endpoint descriptors and nested schemas.
18
- event Schema(uint indexed host, uint spec, string body, bytes32 name);
19
-
20
- constructor() {
21
- emit EventAbi(ABI);
22
- }
23
- }