@rootzero/contracts 0.9.9 → 1.0.1

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 (48) hide show
  1. package/Endpoints.sol +2 -0
  2. package/Events.sol +1 -0
  3. package/README.md +19 -18
  4. package/blocks/Cursors.sol +104 -52
  5. package/blocks/Keys.sol +6 -0
  6. package/blocks/Schema.sol +4 -2
  7. package/blocks/Writers.sol +4 -4
  8. package/commands/Burn.sol +4 -1
  9. package/commands/Credit.sol +4 -1
  10. package/commands/Debit.sol +4 -1
  11. package/commands/Deposit.sol +8 -2
  12. package/commands/Payout.sol +7 -3
  13. package/commands/Provision.sol +8 -2
  14. package/commands/Relay.sol +57 -0
  15. package/commands/Withdraw.sol +4 -1
  16. package/commands/admin/AllowAssets.sol +6 -1
  17. package/commands/admin/Allowance.sol +4 -1
  18. package/commands/admin/Appoint.sol +4 -1
  19. package/commands/admin/Authorize.sol +4 -1
  20. package/commands/admin/DenyAssets.sol +6 -1
  21. package/commands/admin/Destroy.sol +4 -2
  22. package/commands/admin/Dismiss.sol +4 -1
  23. package/commands/admin/Execute.sol +5 -2
  24. package/commands/admin/Init.sol +4 -2
  25. package/commands/admin/Unauthorize.sol +4 -1
  26. package/core/Host.sol +10 -1
  27. package/core/Pipeline.sol +2 -1
  28. package/core/Runtime.sol +3 -3
  29. package/events/Admin.sol +5 -5
  30. package/events/Chain.sol +20 -0
  31. package/events/Command.sol +5 -5
  32. package/guards/Revoke.sol +1 -1
  33. package/package.json +1 -1
  34. package/peer/AllowAssets.sol +3 -1
  35. package/peer/Allowance.sol +3 -1
  36. package/peer/BalancePull.sol +3 -1
  37. package/peer/DenyAssets.sol +3 -1
  38. package/peer/Dispatch.sol +50 -0
  39. package/peer/Pipe.sol +5 -3
  40. package/peer/Settle.sol +3 -1
  41. package/queries/Assets.sol +1 -1
  42. package/queries/Balances.sol +1 -1
  43. package/queries/Positions.sol +1 -1
  44. package/utils/Accounts.sol +1 -34
  45. package/utils/Assets.sol +21 -21
  46. package/utils/Ids.sol +12 -2
  47. package/utils/Layout.sol +21 -17
  48. package/utils/Utils.sol +2 -2
@@ -19,10 +19,13 @@ abstract contract Authorize is CommandBase, AdminEvent {
19
19
  emit Admin(host, authorizeId, NAME, "1:0:0", Schemas.Node, Keys.Empty, Keys.Empty, false, false);
20
20
  }
21
21
 
22
+ /// @notice Authorize each NODE block in the admin request.
23
+ /// @param c Admin command context; `c.request` must contain NODE blocks.
24
+ /// @return Empty output state.
22
25
  function authorize(
23
26
  CommandContext calldata c
24
27
  ) external onlyAdmin(c.account) returns (bytes memory) {
25
- (Cur memory request, ) = Cursors.first(c.request, 1);
28
+ (Cur memory request, , ) = Cursors.init(c.request, 0, 1);
26
29
 
27
30
  while (request.i < request.len) {
28
31
  uint node = request.unpackNode();
@@ -9,6 +9,8 @@ using Cursors for Cur;
9
9
  abstract contract DenyAssetsHook {
10
10
  /// @dev Override to deny a single asset/meta pair.
11
11
  /// Called once per ASSET block in the request.
12
+ /// @param asset Asset identifier.
13
+ /// @param meta Asset metadata slot.
12
14
  function denyAsset(bytes32 asset, bytes32 meta) internal virtual;
13
15
  }
14
16
 
@@ -24,10 +26,13 @@ abstract contract DenyAssets is CommandBase, AdminEvent, DenyAssetsHook {
24
26
  emit Admin(host, denyAssetsId, NAME, "1:0:0", Schemas.Asset, Keys.Empty, Keys.Empty, false, false);
25
27
  }
26
28
 
29
+ /// @notice Deny each ASSET block in the admin request.
30
+ /// @param c Admin command context; `c.request` must contain ASSET blocks.
31
+ /// @return Empty output state.
27
32
  function denyAssets(
28
33
  CommandContext calldata c
29
34
  ) external onlyAdmin(c.account) returns (bytes memory) {
30
- (Cur memory request, ) = Cursors.first(c.request, 1);
35
+ (Cur memory request, , ) = Cursors.init(c.request, 0, 1);
31
36
 
32
37
  while (request.i < request.len) {
33
38
  (bytes32 asset, bytes32 meta) = request.unpackAsset();
@@ -25,11 +25,13 @@ abstract contract Destroy is CommandBase, AdminEvent, DestroyHook {
25
25
  emit Admin(host, destroyId, NAME, "1:0:0", input, Keys.Empty, Keys.Empty, false, false);
26
26
  }
27
27
 
28
+ /// @notice Run host teardown logic over the full admin request.
29
+ /// @param c Admin command context; `c.request` is passed through as a cursor.
30
+ /// @return Empty output state.
28
31
  function destroy(
29
32
  CommandContext calldata c
30
33
  ) external onlyAdmin(c.account) returns (bytes memory) {
31
- Cur memory input = Cursors.open(c.request);
32
- destroy(input);
34
+ destroy(Cursors.open(c.request));
33
35
  return "";
34
36
  }
35
37
  }
@@ -19,10 +19,13 @@ abstract contract Dismiss is CommandBase, AdminEvent {
19
19
  emit Admin(host, dismissId, NAME, "1:0:0", Schemas.Account, Keys.Empty, Keys.Empty, false, false);
20
20
  }
21
21
 
22
+ /// @notice Dismiss each ACCOUNT block in the admin request from guardian status.
23
+ /// @param c Admin command context; `c.request` must contain ACCOUNT blocks.
24
+ /// @return Empty output state.
22
25
  function dismiss(
23
26
  CommandContext calldata c
24
27
  ) external onlyAdmin(c.account) returns (bytes memory) {
25
- (Cur memory request, ) = Cursors.first(c.request, 1);
28
+ (Cur memory request, , ) = Cursors.init(c.request, 0, 1);
26
29
 
27
30
  while (request.i < request.len) {
28
31
  bytes32 account = request.unpackAccount();
@@ -14,6 +14,7 @@ using Cursors for Cur;
14
14
  /// @notice Admin command that forwards raw calldata to one or more target nodes.
15
15
  /// Each CALL block specifies a target node ID, native value, and raw calldata payload.
16
16
  /// Only callable by the admin account.
17
+ /// Unspent top-level `msg.value` remains on this host.
17
18
  abstract contract ExecutePayable is CommandBase, Payable, AdminEvent {
18
19
  string private constant NAME = "executePayable";
19
20
 
@@ -23,8 +24,11 @@ abstract contract ExecutePayable is CommandBase, Payable, AdminEvent {
23
24
  emit Admin(host, executePayableId, NAME, "1:0:0", Schemas.Call, Keys.Empty, Keys.Empty, false, true);
24
25
  }
25
26
 
27
+ /// @notice Execute each CALL block in the admin request.
28
+ /// @param c Admin command context; `c.request` must contain CALL blocks.
29
+ /// @return Empty output state.
26
30
  function executePayable(CommandContext calldata c) external payable onlyAdmin(c.account) returns (bytes memory) {
27
- (Cur memory request, ) = Cursors.first(c.request, 1);
31
+ (Cur memory request, , ) = Cursors.init(c.request, 0, 1);
28
32
  Budget memory budget = valueBudget();
29
33
 
30
34
  while (request.i < request.len) {
@@ -34,7 +38,6 @@ abstract contract ExecutePayable is CommandBase, Payable, AdminEvent {
34
38
  }
35
39
 
36
40
  request.complete();
37
- settleValue(c.account, budget);
38
41
  return "";
39
42
  }
40
43
  }
@@ -25,11 +25,13 @@ abstract contract Init is CommandBase, AdminEvent, InitHook {
25
25
  emit Admin(host, initId, NAME, "1:0:0", input, Keys.Empty, Keys.Empty, false, false);
26
26
  }
27
27
 
28
+ /// @notice Run host initialization logic over the full admin request.
29
+ /// @param c Admin command context; `c.request` is passed through as a cursor.
30
+ /// @return Empty output state.
28
31
  function init(
29
32
  CommandContext calldata c
30
33
  ) external onlyAdmin(c.account) returns (bytes memory) {
31
- Cur memory input = Cursors.open(c.request);
32
- init(input);
34
+ init(Cursors.open(c.request));
33
35
  return "";
34
36
  }
35
37
  }
@@ -19,10 +19,13 @@ abstract contract Unauthorize is CommandBase, AdminEvent {
19
19
  emit Admin(host, unauthorizeId, NAME, "1:0:0", Schemas.Node, Keys.Empty, Keys.Empty, false, false);
20
20
  }
21
21
 
22
+ /// @notice Unauthorize each NODE block in the admin request.
23
+ /// @param c Admin command context; `c.request` must contain NODE blocks.
24
+ /// @return Empty output state.
22
25
  function unauthorize(
23
26
  CommandContext calldata c
24
27
  ) external onlyAdmin(c.account) returns (bytes memory) {
25
- (Cur memory request, ) = Cursors.first(c.request, 1);
28
+ (Cur memory request, , ) = Cursors.init(c.request, 0, 1);
26
29
 
27
30
  while (request.i < request.len) {
28
31
  uint node = request.unpackNode();
package/core/Host.sol CHANGED
@@ -28,7 +28,16 @@ interface IHostIntroduction {
28
28
  /// guardian management, the default guardian revoke action, and
29
29
  /// optionally introduces itself to a commander host at deployment.
30
30
  /// Accepts native ETH payments via the `receive` function.
31
- abstract contract Host is Authorize, Unauthorize, Revoke, Appoint, Dismiss, ExecutePayable, IntroductionEvent, IHostIntroduction {
31
+ abstract contract Host is
32
+ Authorize,
33
+ Unauthorize,
34
+ Revoke,
35
+ Appoint,
36
+ Dismiss,
37
+ ExecutePayable,
38
+ IntroductionEvent,
39
+ IHostIntroduction
40
+ {
32
41
  /// @param cmdr Commander address; passed to `AccessControl`.
33
42
  /// If `cmdr` is a deployed contract, the host calls `introduce`
34
43
  /// on it during construction.
package/core/Pipeline.sol CHANGED
@@ -10,6 +10,7 @@ using Cursors for Cur;
10
10
  /// @title Pipeline
11
11
  /// @notice Core pipeline functionality shared by higher-level surfaces.
12
12
  abstract contract Pipeline is Payable {
13
+ /// @dev Thrown when the pipeline finishes with non-empty threaded state.
13
14
  error UnexpectedState();
14
15
 
15
16
  /// @notice Override to dispatch one piped step.
@@ -41,7 +42,7 @@ abstract contract Pipeline is Payable {
41
42
  bytes calldata steps,
42
43
  Budget memory budget
43
44
  ) internal {
44
- (Cur memory input, ) = Cursors.first(steps, 1);
45
+ (Cur memory input, , ) = Cursors.init(steps, 0, 1);
45
46
 
46
47
  while (input.i < input.len) {
47
48
  (uint target, uint value, bytes calldata request) = input.unpackStep();
package/core/Runtime.sol CHANGED
@@ -5,10 +5,10 @@ import {Assets} from "../utils/Assets.sol";
5
5
  import {Ids} from "../utils/Ids.sol";
6
6
 
7
7
  /// @title Runtime
8
- /// @notice Shared runtime for host identity and native value identity.
8
+ /// @notice Shared runtime for host identity and native asset identity.
9
9
  abstract contract Runtime {
10
10
  /// @dev This contract's host node ID, set to `Ids.toHost(address(this))` at construction.
11
11
  uint public immutable host = Ids.toHost(address(this));
12
- /// @dev Asset ID for the native chain value (ETH), bound to the current chain at deployment.
13
- bytes32 internal immutable valueAsset = Assets.toValue();
12
+ /// @dev Asset ID for the native chain coin/token, bound to the current chain at deployment.
13
+ bytes32 internal immutable nativeAsset = Assets.toNative();
14
14
  }
package/events/Admin.sol CHANGED
@@ -6,19 +6,19 @@ import { EventEmitter } from "./Emitter.sol";
6
6
  /// @notice Emitted once per admin command during host deployment to publish its request schema and state keys.
7
7
  abstract contract AdminEvent is EventEmitter {
8
8
  string private constant ABI =
9
- "event Admin(uint indexed host, uint id, string name, bytes32 shape, string request, bytes4 state, bytes4 output, bool checked, bool funded)";
9
+ "event Admin(uint indexed host, uint id, string name, bytes32 shape, string request, bytes4 state, bytes4 output, bool postcheck, bool funded)";
10
10
 
11
11
  /// @param host Host node ID that owns this admin command.
12
12
  /// @param id Command node ID.
13
13
  /// @param name Human-readable command name.
14
14
  /// @param shape Per-operation block counts encoded as `request:state:output`.
15
- /// The request count covers only the input request run. If `checked` is true,
15
+ /// The request count covers only the input request run. If `postcheck` is true,
16
16
  /// a constraint run follows the input run, or starts the request when `request`
17
17
  /// is empty. State globals may follow the state run and are excluded.
18
18
  /// @param request Schema DSL string describing the input request run, or empty if none.
19
- /// @param state Block key expected for input state, or `Keys.Empty`.
19
+ /// @param state Block key expected for input state, `Keys.Empty`, or `Keys.Any`.
20
20
  /// @param output Block key produced for output state, or `Keys.Empty`.
21
- /// @param checked Whether a constraint block run is expected to exist in the request.
21
+ /// @param postcheck Whether command output is validated after execution.
22
22
  /// @param funded Whether the command entrypoint accepts nonzero `msg.value`.
23
23
  event Admin(
24
24
  uint indexed host,
@@ -28,7 +28,7 @@ abstract contract AdminEvent is EventEmitter {
28
28
  string request,
29
29
  bytes4 state,
30
30
  bytes4 output,
31
- bool checked,
31
+ bool postcheck,
32
32
  bool funded
33
33
  );
34
34
 
@@ -0,0 +1,20 @@
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 a chain/domain node is announced.
7
+ abstract contract ChainEvent is EventEmitter {
8
+ string private constant ABI = "event Chain(uint indexed chain, bytes32 native, uint commander, bytes32 admin, string name)";
9
+
10
+ /// @param chain Chain node ID.
11
+ /// @param native Native asset ID for the chain.
12
+ /// @param commander Commander host node ID for the chain.
13
+ /// @param admin Admin account for the commander host on the chain.
14
+ /// @param name Chain or domain name.
15
+ event Chain(uint indexed chain, bytes32 native, uint commander, bytes32 admin, string name);
16
+
17
+ constructor() {
18
+ emit EventAbi(ABI);
19
+ }
20
+ }
@@ -6,19 +6,19 @@ import { EventEmitter } from "./Emitter.sol";
6
6
  /// @notice Emitted once per command during host deployment to publish its request schema and state keys.
7
7
  abstract contract CommandEvent is EventEmitter {
8
8
  string private constant ABI =
9
- "event Command(uint indexed host, uint id, string name, bytes32 shape, string request, bytes4 state, bytes4 output, bool checked, bool funded)";
9
+ "event Command(uint indexed host, uint id, string name, bytes32 shape, string request, bytes4 state, bytes4 output, bool postcheck, bool funded)";
10
10
 
11
11
  /// @param host Host node ID that owns this command.
12
12
  /// @param id Command node ID.
13
13
  /// @param name Human-readable command name.
14
14
  /// @param shape Per-operation block counts encoded as `request:state:output`.
15
- /// The request count covers only the input request run. If `checked` is true,
15
+ /// The request count covers only the input request run. If `postcheck` is true,
16
16
  /// a constraint run follows the input run, or starts the request when `request`
17
17
  /// is empty. State globals may follow the state run and are excluded.
18
18
  /// @param request Schema string describing the input request run, or empty if none.
19
- /// @param state Block key expected for input state, or `Keys.Empty`.
19
+ /// @param state Block key expected for input state, `Keys.Empty`, or `Keys.Any`.
20
20
  /// @param output Block key produced for output state, or `Keys.Empty`.
21
- /// @param checked Whether a constraint block run is expected to exist in the request.
21
+ /// @param postcheck Whether command output is validated after execution.
22
22
  /// @param funded Whether the command entrypoint accepts nonzero `msg.value`.
23
23
  event Command(
24
24
  uint indexed host,
@@ -28,7 +28,7 @@ abstract contract CommandEvent is EventEmitter {
28
28
  string request,
29
29
  bytes4 state,
30
30
  bytes4 output,
31
- bool checked,
31
+ bool postcheck,
32
32
  bool funded
33
33
  );
34
34
 
package/guards/Revoke.sol CHANGED
@@ -19,7 +19,7 @@ abstract contract Revoke is GuardBase {
19
19
  }
20
20
 
21
21
  function revoke(bytes calldata request) external onlyGuardian {
22
- (Cur memory input, ) = Cursors.first(request, 1);
22
+ (Cur memory input, , ) = Cursors.init(request, 0, 1);
23
23
 
24
24
  while (input.i < input.len) {
25
25
  uint node = input.unpackNode();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rootzero/contracts",
3
- "version": "0.9.9",
3
+ "version": "1.0.1",
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",
@@ -19,8 +19,10 @@ abstract contract PeerAllowAssets is PeerBase, AllowAssetsHook {
19
19
  }
20
20
 
21
21
  /// @notice Execute the allow-assets peer call.
22
+ /// @param request ASSET block stream supplied by the trusted peer.
23
+ /// @return Empty response bytes.
22
24
  function peerAllowAssets(bytes calldata request) external onlyPeer returns (bytes memory) {
23
- (Cur memory assets, ) = Cursors.first(request, 1);
25
+ (Cur memory assets, , ) = Cursors.init(request, 0, 1);
24
26
 
25
27
  while (assets.i < assets.len) {
26
28
  (bytes32 asset, bytes32 meta) = assets.unpackAsset();
@@ -20,8 +20,10 @@ abstract contract PeerAllowance is PeerBase, AllowanceHook {
20
20
  }
21
21
 
22
22
  /// @notice Execute the allowance peer call.
23
+ /// @param request AMOUNT block stream requested by the trusted peer.
24
+ /// @return Empty response bytes.
23
25
  function peerAllowance(bytes calldata request) external onlyPeer returns (bytes memory) {
24
- (Cur memory amounts, ) = Cursors.first(request, 1);
26
+ (Cur memory amounts, , ) = Cursors.init(request, 0, 1);
25
27
  uint peer = caller();
26
28
 
27
29
  while (amounts.i < amounts.len) {
@@ -28,8 +28,10 @@ abstract contract PeerBalancePull is PeerBase, BalancePullHook {
28
28
  }
29
29
 
30
30
  /// @notice Execute the balance-pull peer call.
31
+ /// @param request BALANCE block stream requested by the trusted peer.
32
+ /// @return Empty response bytes.
31
33
  function peerBalancePull(bytes calldata request) external onlyPeer returns (bytes memory) {
32
- (Cur memory input, ) = Cursors.first(request, 1);
34
+ (Cur memory input, , ) = Cursors.init(request, 0, 1);
33
35
  uint peer = caller();
34
36
 
35
37
  while (input.i < input.len) {
@@ -19,8 +19,10 @@ abstract contract PeerDenyAssets is PeerBase, DenyAssetsHook {
19
19
  }
20
20
 
21
21
  /// @notice Execute the deny-assets peer call.
22
+ /// @param request ASSET block stream supplied by the trusted peer.
23
+ /// @return Empty response bytes.
22
24
  function peerDenyAssets(bytes calldata request) external onlyPeer returns (bytes memory) {
23
- (Cur memory assets, ) = Cursors.first(request, 1);
25
+ (Cur memory assets, , ) = Cursors.init(request, 0, 1);
24
26
 
25
27
  while (assets.i < assets.len) {
26
28
  (bytes32 asset, bytes32 meta) = assets.unpackAsset();
@@ -0,0 +1,50 @@
1
+ // SPDX-License-Identifier: GPL-3.0-only
2
+ pragma solidity ^0.8.33;
3
+
4
+ import { PeerBase } from "./Base.sol";
5
+ import { Payable } from "../core/Payable.sol";
6
+ import { Cursors, Cur, Schemas } from "../Cursors.sol";
7
+ import { Budget } from "../utils/Value.sol";
8
+
9
+ using Cursors for Cur;
10
+
11
+ abstract contract PeerDispatchPayableHook {
12
+ /// @notice Override to dispatch an already encoded payload to `chain`.
13
+ /// @param chain Destination chain node ID.
14
+ /// @param resources Chain-adapter-specific destination resources. EVM adapters
15
+ /// may interpret this as packed execution gas and destination value.
16
+ /// @param payload Encoded payload ready for the transport layer.
17
+ /// @param budget Source-chain native-value budget available for transport
18
+ /// fees and destination resource funding.
19
+ function dispatch(uint chain, uint resources, bytes calldata payload, Budget memory budget) internal virtual;
20
+ }
21
+
22
+ /// @title PeerDispatchPayable
23
+ /// @notice Peer endpoint that forwards DISPATCH blocks to a host-defined dispatch hook.
24
+ abstract contract PeerDispatchPayable is PeerBase, Payable, PeerDispatchPayableHook {
25
+ string private constant NAME = "peerDispatchPayable";
26
+ uint internal immutable peerDispatchPayableId = peerId(NAME);
27
+
28
+ constructor() {
29
+ emit Peer(host, peerDispatchPayableId, NAME, "1:0", Schemas.Dispatch, "", true);
30
+ }
31
+
32
+ /// @notice Forward peer-supplied dispatches to the host-defined dispatch hook.
33
+ /// @dev Dispatch hooks receive the shared top-level source-chain value
34
+ /// budget. Any `msg.value` not spent by the hook remains on this host.
35
+ /// @param request DISPATCH block stream supplied by the trusted peer.
36
+ /// @return output Empty response bytes.
37
+ function peerDispatchPayable(bytes calldata request) external payable onlyPeer returns (bytes memory output) {
38
+ (Cur memory input, , ) = Cursors.init(request, 0, 1);
39
+ Budget memory budget = valueBudget();
40
+
41
+ while (input.i < input.len) {
42
+ (uint chain, uint resources, bytes calldata payload) = input.unpackDispatch();
43
+ dispatch(chain, resources, payload, budget);
44
+ }
45
+
46
+ input.complete();
47
+ return "";
48
+ }
49
+
50
+ }
package/peer/Pipe.sol CHANGED
@@ -9,9 +9,9 @@ import {Budget} from "../utils/Value.sol";
9
9
  using Cursors for Cur;
10
10
 
11
11
  /// @title PeerPipePayable
12
- /// @notice Peer that consumes PIPE blocks and executes each context request as a STEP stream.
12
+ /// @notice Peer that consumes PIPE blocks and executes each context step stream.
13
13
  /// Each PIPE block carries a value budget plus a CONTEXT block; the nested
14
- /// context request is passed to the shared pipeline as the step stream.
14
+ /// context steps are passed to the shared pipeline as the step stream.
15
15
  abstract contract PeerPipePayable is PeerBase, Pipeline {
16
16
  string private constant NAME = "peerPipePayable";
17
17
  uint internal immutable peerPipePayableId = peerId(NAME);
@@ -23,8 +23,10 @@ abstract contract PeerPipePayable is PeerBase, Pipeline {
23
23
  /// @notice Execute peer-supplied pipes through the shared payable pipe.
24
24
  /// @dev Each pipe receives its own explicit value sub-budget. Any top-level
25
25
  /// `msg.value` not assigned to a pipe remains on this host.
26
+ /// @param request PIPE block stream supplied by the trusted peer.
27
+ /// @return Empty response bytes.
26
28
  function peerPipePayable(bytes calldata request) external payable onlyPeer returns (bytes memory) {
27
- (Cur memory input, ) = Cursors.first(request, 1);
29
+ (Cur memory input, , ) = Cursors.init(request, 0, 1);
28
30
  Budget memory budget = valueBudget();
29
31
 
30
32
  while (input.i < input.len) {
package/peer/Settle.sol CHANGED
@@ -20,8 +20,10 @@ abstract contract PeerSettle is PeerBase, DebitAccountHook, CreditAccountHook {
20
20
  }
21
21
 
22
22
  /// @notice Execute the peer-settle call.
23
+ /// @param request TRANSACTION block stream supplied by the trusted peer.
24
+ /// @return Empty response bytes.
23
25
  function peerSettle(bytes calldata request) external onlyPeer returns (bytes memory) {
24
- (Cur memory state, ) = Cursors.first(request, 1);
26
+ (Cur memory state, , ) = Cursors.init(request, 0, 1);
25
27
 
26
28
  while (state.i < state.len) {
27
29
  (bytes32 from, bytes32 to, bytes32 asset, bytes32 meta, uint amount) = state.unpackTransaction();
@@ -33,7 +33,7 @@ abstract contract AssetStatus is QueryBase, AssetStatusHook {
33
33
  /// @param request Block-stream request consisting of `#asset { bytes32 asset, bytes32 meta }` blocks.
34
34
  /// @return Block-stream response containing one `#status { uint code }` per asset block.
35
35
  function assetStatus(bytes calldata request) external view returns (bytes memory) {
36
- (Cur memory query, uint groups) = Cursors.first(request, 1);
36
+ (Cur memory query, uint groups, ) = Cursors.init(request, 0, 1);
37
37
  Writer memory response = Writers.allocStatuses(groups);
38
38
 
39
39
  while (query.i < query.len) {
@@ -33,7 +33,7 @@ abstract contract GetBalances is QueryBase, GetBalancesHook {
33
33
  /// @param request Block-stream request consisting of `accountAsset(account, asset, meta)*`.
34
34
  /// @return Block-stream response containing one `accountAmount(account, asset, meta, amount)` block per request block.
35
35
  function getBalances(bytes calldata request) external view returns (bytes memory) {
36
- (Cur memory query, uint groups) = Cursors.first(request, 1);
36
+ (Cur memory query, uint groups, ) = Cursors.init(request, 0, 1);
37
37
  Writer memory response = Writers.allocAccountAmounts(groups);
38
38
 
39
39
  while (query.i < query.len) {
@@ -42,7 +42,7 @@ abstract contract GetPosition is QueryBase, GetPositionHook {
42
42
  /// @param request Block-stream request consisting of `accountAsset(account, asset, meta)*`.
43
43
  /// @return Block-stream response containing one output-schema block per position block.
44
44
  function getPosition(bytes calldata request) external view returns (bytes memory) {
45
- (Cur memory query, uint groups) = Cursors.first(request, 1);
45
+ (Cur memory query, uint groups, ) = Cursors.init(request, 0, 1);
46
46
  Writer memory response = Writers.allocAny(groups);
47
47
 
48
48
  while (query.i < query.len) {
@@ -23,8 +23,6 @@ library Accounts {
23
23
  uint32 constant Guardian = (uint32(Layout.Evm32) << 16) | (uint32(Layout.Account) << 8) | uint32(Layout.Guardian);
24
24
  /// @dev Full 4-byte type prefix for user accounts (chain-agnostic EVM address).
25
25
  uint32 constant User = (uint32(Layout.Evm32) << 16) | (uint32(Layout.Account) << 8) | uint32(Layout.User);
26
- /// @dev Full 4-byte type prefix for keccak accounts (opaque 28-byte hash).
27
- uint32 constant Keccak = (uint32(Layout.Opaque32) << 16) | (uint32(Layout.Account) << 8) | uint32(Layout.Keccak);
28
26
 
29
27
  /// @notice Extract the 4-byte type prefix from an account ID.
30
28
  /// @param account Account identifier.
@@ -53,14 +51,10 @@ library Accounts {
53
51
  return prefix(account) == User;
54
52
  }
55
53
 
56
- function isKeccak(bytes32 account) internal pure returns (bool) {
57
- return prefix(account) == Keccak;
58
- }
59
-
60
54
  /// @notice Assert that `input` is an account and return it unchanged.
61
55
  /// @param input Account identifier to validate.
62
56
  /// @return account The same `input` if it is an account.
63
- function any(bytes32 input) internal pure returns (bytes32 account) {
57
+ function ensure(bytes32 input) internal pure returns (bytes32 account) {
64
58
  if (!isAccount(input)) revert InvalidAccount();
65
59
  return input;
66
60
  }
@@ -89,14 +83,6 @@ library Accounts {
89
83
  return input;
90
84
  }
91
85
 
92
- /// @notice Assert that `input` is a keccak account and return it unchanged.
93
- /// @param input Account identifier to validate.
94
- /// @return account The same `input` if it is a keccak account.
95
- function keccak(bytes32 input) internal pure returns (bytes32 account) {
96
- if (!isKeccak(input)) revert InvalidAccount();
97
- return input;
98
- }
99
-
100
86
  /// @notice Encode an EVM address as a chain-local admin account ID.
101
87
  /// @param addr EVM address to embed.
102
88
  /// @return Admin account ID bound to the current chain.
@@ -118,25 +104,6 @@ library Accounts {
118
104
  return bytes32(toUnspecifiedBase(User) | (uint(uint160(addr)) << 32));
119
105
  }
120
106
 
121
- function toKeccak(bytes32 head, bytes32 meta) internal pure returns (bytes32) {
122
- return bytes32(toUnspecifiedBase(Keccak) | uint224(uint256(keccak256(bytes.concat(head, meta)))));
123
- }
124
-
125
- function matchesKeccak(bytes32 account, bytes32 head, bytes32 meta) internal pure returns (bool) {
126
- return account == toKeccak(head, meta);
127
- }
128
-
129
- /// @notice Assert that `account` uses the Account layout tag and return it unchanged.
130
- /// Ignores width, chain binding, and subtype details.
131
- /// @param account Account ID to validate.
132
- /// @return The same `account` value if valid.
133
- function ensure(bytes32 account) internal pure returns (bytes32) {
134
- if (uint8(uint(account) >> 232) != Layout.Account) {
135
- revert InvalidAccount();
136
- }
137
- return account;
138
- }
139
-
140
107
  /// @notice Assert that `account` belongs to the EVM account family and return it unchanged.
141
108
  /// @param account Account ID to validate.
142
109
  /// @return The same `account` value if valid.
package/utils/Assets.sol CHANGED
@@ -8,10 +8,10 @@ import {matchesBase, toLocalBase} from "./Utils.sol";
8
8
  /// @notice Encoding and decoding helpers for 256-bit asset identifiers.
9
9
  ///
10
10
  /// Asset IDs embed a 4-byte type tag in bits [255:224]:
11
- /// - `Value` native chain value (ETH); no address payload
12
- /// - `Erc20` ERC-20 token; contract address in bits [191:32]
13
- /// - `Erc721` ERC-721 collection; collection address in bits [191:32]
14
- /// - `Erc1155` ERC-1155 collection; collection address in bits [191:32]
11
+ /// - `Native` - native chain coin/token; no address payload
12
+ /// - `Erc20` - ERC-20 token; contract address in bits [191:32]
13
+ /// - `Erc721` - ERC-721 collection; collection address in bits [191:32]
14
+ /// - `Erc1155` - ERC-1155 collection; collection address in bits [191:32]
15
15
  ///
16
16
  /// All asset IDs are chain-local (include `block.chainid` in bits [223:192]).
17
17
  library Assets {
@@ -20,8 +20,8 @@ library Assets {
20
20
  /// @dev Thrown when an asset is not authorized for the requested operation.
21
21
  error UnauthorizedAsset();
22
22
 
23
- /// @dev Full 4-byte type prefix for the native value asset.
24
- uint32 constant Value = (uint32(Layout.Evm32) << 16) | (uint32(Layout.Asset) << 8) | uint32(Layout.Value);
23
+ /// @dev Full 4-byte type prefix for the native chain coin/token asset.
24
+ uint32 constant Native = (uint32(Layout.Evm32) << 16) | (uint32(Layout.Asset) << 8) | uint32(Layout.Native);
25
25
  /// @dev Full 4-byte type prefix for ERC-20 assets.
26
26
  uint32 constant Erc20 = (uint32(Layout.Evm32) << 16) | (uint32(Layout.Asset) << 8) | uint32(Layout.Erc20);
27
27
  /// @dev Full 4-byte type prefix for ERC-721 assets.
@@ -34,19 +34,19 @@ library Assets {
34
34
  return uint8(uint(asset) >> 232) == Layout.Asset;
35
35
  }
36
36
 
37
- /// @notice Return true if `asset` uses the 32-byte asset layout with no metadata identity (top byte is `0x20`).
37
+ /// @notice Return true if `asset` uses a 32-byte asset layout with no metadata identity.
38
38
  function is32(bytes32 asset) internal pure returns (bool) {
39
- return isAsset(asset) && bytes1(asset) == 0x20;
39
+ return isAsset(asset) && uint8(uint(asset) >> 240) == Layout.Width32;
40
40
  }
41
41
 
42
- /// @notice Return true if `asset` uses the 64-byte asset layout with metadata-backed identity (top byte is `0x40`).
42
+ /// @notice Return true if `asset` uses a 64-byte asset layout with metadata-backed identity.
43
43
  function is64(bytes32 asset) internal pure returns (bool) {
44
- return isAsset(asset) && bytes1(asset) == 0x40;
44
+ return isAsset(asset) && uint8(uint(asset) >> 240) == Layout.Width64;
45
45
  }
46
46
 
47
- /// @notice Return true if `asset` is the local native value asset.
48
- function isValue(bytes32 asset) internal view returns (bool) {
49
- return asset == toValue();
47
+ /// @notice Return true if `asset` is the local native chain coin/token asset.
48
+ function isNative(bytes32 asset) internal view returns (bool) {
49
+ return asset == toNative();
50
50
  }
51
51
 
52
52
  /// @notice Return true if `asset` is a local ERC-20 asset.
@@ -64,11 +64,11 @@ library Assets {
64
64
  return matchesBase(asset, toLocalBase(Erc1155));
65
65
  }
66
66
 
67
- /// @notice Assert that `input` is the local native value asset and return it unchanged.
67
+ /// @notice Assert that `input` is the local native chain coin/token asset and return it unchanged.
68
68
  /// @param input Asset identifier to validate.
69
- /// @return asset The same `input` if it is the local native value asset.
70
- function value(bytes32 input) internal view returns (bytes32 asset) {
71
- if (!isValue(input)) revert InvalidAsset();
69
+ /// @return asset The same `input` if it is the local native asset.
70
+ function native(bytes32 input) internal view returns (bytes32 asset) {
71
+ if (!isNative(input)) revert InvalidAsset();
72
72
  return input;
73
73
  }
74
74
 
@@ -96,10 +96,10 @@ library Assets {
96
96
  return input;
97
97
  }
98
98
 
99
- /// @notice Create a chain-local native value asset ID.
99
+ /// @notice Create a chain-local native coin/token asset ID.
100
100
  /// @return Asset ID for the native token on the current chain.
101
- function toValue() internal view returns (bytes32) {
102
- return bytes32(toLocalBase(Value));
101
+ function toNative() internal view returns (bytes32) {
102
+ return bytes32(toLocalBase(Native));
103
103
  }
104
104
 
105
105
  /// @notice Create a chain-local ERC-20 asset ID for `addr`.
@@ -178,7 +178,7 @@ library Assets {
178
178
  }
179
179
 
180
180
  /// @notice Derive a storage slot for an (asset, meta) pair.
181
- /// For 32-byte EVM assets (no meta), the slot is the asset ID itself.
181
+ /// For 32-byte assets (no meta), the slot is the asset ID itself.
182
182
  /// For assets with metadata (e.g. ERC-721 or ERC-1155 token IDs), the slot is
183
183
  /// `keccak256(asset ++ meta)`.
184
184
  /// Reverts only if `asset` is zero.