@rootzero/contracts 0.8.0 → 0.9.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/Commands.sol +5 -10
- package/Core.sol +3 -4
- package/Cursors.sol +4 -6
- package/Events.sol +1 -1
- package/Queries.sol +1 -1
- package/README.md +18 -19
- package/Utils.sol +3 -3
- package/blocks/Cursors.sol +1437 -0
- package/blocks/Keys.sol +59 -34
- package/blocks/Schema.sol +109 -126
- package/blocks/Writers.sol +476 -301
- package/commands/Base.sol +32 -22
- package/commands/Burn.sol +3 -3
- package/commands/Credit.sol +6 -7
- package/commands/Debit.sol +3 -3
- package/commands/Deposit.sol +7 -7
- package/commands/Pipe.sol +3 -3
- package/commands/Provision.sol +19 -49
- package/commands/Transfer.sol +9 -19
- package/commands/Withdraw.sol +5 -6
- package/commands/admin/AllowAssets.sol +3 -3
- package/commands/admin/Allowance.sol +43 -0
- package/commands/admin/Authorize.sol +4 -4
- package/commands/admin/DenyAssets.sol +3 -3
- package/commands/admin/Destroy.sol +3 -3
- package/commands/admin/Execute.sol +38 -0
- package/commands/admin/Init.sol +3 -3
- package/commands/admin/Relocate.sol +5 -5
- package/commands/admin/Unauthorize.sol +4 -4
- package/core/Access.sol +38 -34
- package/core/Balances.sol +17 -18
- package/core/{Operation.sol → Calls.sol} +5 -8
- package/core/{CursorBase.sol → Context.sol} +11 -5
- package/core/Host.sol +10 -9
- package/core/Types.sol +86 -0
- package/docs/GETTING_STARTED.md +37 -29
- package/events/Asset.sol +1 -1
- package/events/Command.sol +10 -10
- package/events/Deposit.sol +3 -4
- package/events/Listing.sol +1 -1
- package/events/Peer.sol +3 -3
- package/events/Position.sol +21 -0
- package/events/Query.sol +3 -3
- package/events/Withdraw.sol +2 -3
- package/package.json +1 -1
- package/peer/AllowAssets.sol +1 -1
- package/peer/Allowance.sol +36 -0
- package/peer/AssetPull.sol +1 -1
- package/peer/Base.sol +8 -4
- package/peer/DenyAssets.sol +1 -1
- package/peer/Settle.sol +3 -4
- package/queries/Assets.sol +8 -8
- package/queries/Balances.sol +11 -11
- package/queries/Base.sol +2 -3
- package/queries/Positions.sol +25 -19
- package/utils/Accounts.sol +14 -13
- package/utils/Assets.sol +77 -57
- package/utils/Ids.sol +4 -4
- package/utils/Layout.sol +1 -1
- package/utils/Utils.sol +10 -0
- package/blocks/cursors/Core.sol +0 -1121
- package/blocks/cursors/Erc1155.sol +0 -149
- package/blocks/cursors/Erc20.sol +0 -130
- package/blocks/cursors/Erc721.sol +0 -66
- package/commands/Create.sol +0 -44
- package/commands/Remove.sol +0 -44
- package/commands/Settle.sol +0 -38
- package/commands/Stake.sol +0 -49
- package/commands/Supply.sol +0 -43
- package/commands/admin/Allocate.sol +0 -43
- package/core/HostBound.sol +0 -14
- package/events/Erc721.sol +0 -20
- package/peer/Pull.sol +0 -41
- package/peer/Push.sol +0 -47
- package/utils/State.sol +0 -22
package/queries/Positions.sol
CHANGED
|
@@ -1,49 +1,55 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {Cur, Cursors, Writer, Writers
|
|
5
|
-
import {
|
|
4
|
+
import {Cur, Cursors, Writer, Writers} from "../Cursors.sol";
|
|
5
|
+
import {Forms} from "../blocks/Schema.sol";
|
|
6
6
|
import {QueryBase} from "./Base.sol";
|
|
7
7
|
|
|
8
8
|
using Cursors for Cur;
|
|
9
9
|
|
|
10
|
-
string constant NAME = "
|
|
10
|
+
string constant NAME = "getPosition";
|
|
11
11
|
|
|
12
|
-
abstract contract
|
|
13
|
-
/// @notice Resolve the position payload for one requested
|
|
12
|
+
abstract contract GetPositionHook {
|
|
13
|
+
/// @notice Resolve the position payload for one requested position.
|
|
14
14
|
/// Concrete implementations must append exactly one `RESPONSE` block whose payload
|
|
15
15
|
/// length matches `positionResponseSize`.
|
|
16
|
+
/// @param account Requested account identifier.
|
|
16
17
|
/// @param asset Requested asset identifier.
|
|
17
18
|
/// @param meta Requested asset metadata slot.
|
|
18
19
|
/// @param response Destination writer for the response stream.
|
|
19
|
-
function
|
|
20
|
+
function appendPosition(
|
|
21
|
+
bytes32 account,
|
|
22
|
+
bytes32 asset,
|
|
23
|
+
bytes32 meta,
|
|
24
|
+
Writer memory response
|
|
25
|
+
) internal view virtual;
|
|
20
26
|
}
|
|
21
27
|
|
|
22
|
-
/// @title
|
|
23
|
-
/// @notice Rootzero query that resolves one dynamic position response for each requested
|
|
24
|
-
/// The request is a run of `
|
|
25
|
-
/// The response returns one dynamic `RESPONSE` block per
|
|
26
|
-
abstract contract
|
|
27
|
-
uint public immutable
|
|
28
|
+
/// @title GetPosition
|
|
29
|
+
/// @notice Rootzero query that resolves one dynamic position response for each requested position.
|
|
30
|
+
/// The request is a run of `ACCOUNT_ASSET` form blocks.
|
|
31
|
+
/// The response returns one dynamic `RESPONSE` block per position entry, preserving request order.
|
|
32
|
+
abstract contract GetPosition is QueryBase, GetPositionHook {
|
|
33
|
+
uint public immutable getPositionId = queryId(NAME);
|
|
28
34
|
uint internal immutable positionResponseSize;
|
|
29
35
|
|
|
30
36
|
constructor(string memory output, uint responseSize) {
|
|
31
37
|
positionResponseSize = responseSize;
|
|
32
|
-
emit Query(host, NAME,
|
|
38
|
+
emit Query(host, getPositionId, NAME, Forms.AccountAsset, output);
|
|
33
39
|
}
|
|
34
40
|
|
|
35
|
-
/// @notice Resolve positions for a run of requested `(asset, meta)` tuples.
|
|
41
|
+
/// @notice Resolve positions for a run of requested `(account, asset, meta)` tuples.
|
|
36
42
|
/// @dev Allocates from the configured fixed response payload length so each hook call
|
|
37
43
|
/// can append one `RESPONSE` block directly into the output stream.
|
|
38
|
-
/// @param request Block-stream request consisting of `
|
|
39
|
-
/// @return Block-stream response containing one `response(bytes data)` block per
|
|
40
|
-
function
|
|
44
|
+
/// @param request Block-stream request consisting of `accountAsset(account, asset, meta)*`.
|
|
45
|
+
/// @return Block-stream response containing one `response(bytes data)` block per position block.
|
|
46
|
+
function getPosition(bytes calldata request) external view returns (bytes memory) {
|
|
41
47
|
(Cur memory query, uint count, ) = cursor(request, 1);
|
|
42
48
|
Writer memory response = Writers.allocBytes(count, positionResponseSize);
|
|
43
49
|
|
|
44
50
|
while (query.i < query.bound) {
|
|
45
|
-
(bytes32 asset, bytes32 meta) = query.
|
|
46
|
-
|
|
51
|
+
(bytes32 account, bytes32 asset, bytes32 meta) = query.unpackAccountAsset();
|
|
52
|
+
appendPosition(account, asset, meta, response);
|
|
47
53
|
}
|
|
48
54
|
|
|
49
55
|
return query.complete(response);
|
package/utils/Accounts.sol
CHANGED
|
@@ -10,7 +10,6 @@ import {isFamily, toLocalBase, toUnspecifiedBase} from "./Utils.sol";
|
|
|
10
10
|
/// Account IDs embed a 4-byte type tag in bits [255:224]:
|
|
11
11
|
/// - `Admin` — chain-local EVM address in bits [191:32]
|
|
12
12
|
/// - `User` — chain-agnostic EVM address in bits [191:32]
|
|
13
|
-
/// - `Keccak` — 28-byte keccak hash of an arbitrary key
|
|
14
13
|
library Accounts {
|
|
15
14
|
/// @dev Thrown when an account ID does not belong to the EVM family.
|
|
16
15
|
error InvalidAccount();
|
|
@@ -31,12 +30,21 @@ library Accounts {
|
|
|
31
30
|
return uint32(uint(account) >> 224);
|
|
32
31
|
}
|
|
33
32
|
|
|
33
|
+
/// @notice Return true if `account` uses the Account category tag in the type field.
|
|
34
|
+
function isAccount(bytes32 account) internal pure returns (bool) {
|
|
35
|
+
return uint8(uint(account) >> 232) == Layout.Account;
|
|
36
|
+
}
|
|
37
|
+
|
|
34
38
|
/// @notice Return true if `account` is an admin account.
|
|
35
39
|
function isAdmin(bytes32 account) internal pure returns (bool) {
|
|
36
40
|
return prefix(account) == Admin;
|
|
37
41
|
}
|
|
38
42
|
|
|
39
|
-
/// @notice Return true if `account` is a
|
|
43
|
+
/// @notice Return true if `account` is a user account.
|
|
44
|
+
function isUser(bytes32 account) internal pure returns (bool) {
|
|
45
|
+
return prefix(account) == User;
|
|
46
|
+
}
|
|
47
|
+
|
|
40
48
|
function isKeccak(bytes32 account) internal pure returns (bool) {
|
|
41
49
|
return prefix(account) == Keccak;
|
|
42
50
|
}
|
|
@@ -55,19 +63,12 @@ library Accounts {
|
|
|
55
63
|
return bytes32(toUnspecifiedBase(User) | (uint(uint160(addr)) << 32));
|
|
56
64
|
}
|
|
57
65
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
/// @param raw Arbitrary key bytes to hash.
|
|
61
|
-
/// @return Keccak account ID.
|
|
62
|
-
function toKeccak(bytes calldata raw) internal pure returns (bytes32) {
|
|
63
|
-
return bytes32(toUnspecifiedBase(Keccak) | uint224(uint256(keccak256(raw))));
|
|
66
|
+
function toKeccak(bytes32 head, bytes32 meta) internal pure returns (bytes32) {
|
|
67
|
+
return bytes32(toUnspecifiedBase(Keccak) | uint224(uint256(keccak256(bytes.concat(head, meta)))));
|
|
64
68
|
}
|
|
65
69
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
/// @param raw Raw key bytes to hash and compare against.
|
|
69
|
-
function matchesKeccak(bytes32 account, bytes calldata raw) internal pure returns (bool) {
|
|
70
|
-
return account == toKeccak(raw);
|
|
70
|
+
function matchesKeccak(bytes32 account, bytes32 head, bytes32 meta) internal pure returns (bool) {
|
|
71
|
+
return account == toKeccak(head, meta);
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
/// @notice Assert that `account` uses the Account layout tag and return it unchanged.
|
package/utils/Assets.sol
CHANGED
|
@@ -27,14 +27,71 @@ library Assets {
|
|
|
27
27
|
/// @dev Full 4-byte type prefix for ERC-1155 assets.
|
|
28
28
|
uint32 constant Erc1155 = (uint32(Layout.Evm64) << 16) | (uint32(Layout.Asset) << 8) | uint32(Layout.Erc1155);
|
|
29
29
|
|
|
30
|
+
/// @notice Return true if `asset` uses the Asset category tag in the type field.
|
|
31
|
+
function isAsset(bytes32 asset) internal pure returns (bool) {
|
|
32
|
+
return uint8(uint(asset) >> 232) == Layout.Asset;
|
|
33
|
+
}
|
|
34
|
+
|
|
30
35
|
/// @notice Return true if `asset` uses the 32-byte asset layout with no metadata identity (top byte is `0x20`).
|
|
31
36
|
function is32(bytes32 asset) internal pure returns (bool) {
|
|
32
|
-
return bytes1(asset) == 0x20;
|
|
37
|
+
return isAsset(asset) && bytes1(asset) == 0x20;
|
|
33
38
|
}
|
|
34
39
|
|
|
35
40
|
/// @notice Return true if `asset` uses the 64-byte asset layout with metadata-backed identity (top byte is `0x40`).
|
|
36
41
|
function is64(bytes32 asset) internal pure returns (bool) {
|
|
37
|
-
return bytes1(asset) == 0x40;
|
|
42
|
+
return isAsset(asset) && bytes1(asset) == 0x40;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/// @notice Return true if `asset` is the local native value asset.
|
|
46
|
+
function isValue(bytes32 asset) internal view returns (bool) {
|
|
47
|
+
return asset == toValue();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/// @notice Return true if `asset` is a local ERC-20 asset.
|
|
51
|
+
function isErc20(bytes32 asset) internal view returns (bool) {
|
|
52
|
+
return matchesBase(asset, toLocalBase(Erc20));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/// @notice Return true if `asset` is a local ERC-721 asset.
|
|
56
|
+
function isErc721(bytes32 asset) internal view returns (bool) {
|
|
57
|
+
return matchesBase(asset, toLocalBase(Erc721));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/// @notice Return true if `asset` is a local ERC-1155 asset.
|
|
61
|
+
function isErc1155(bytes32 asset) internal view returns (bool) {
|
|
62
|
+
return matchesBase(asset, toLocalBase(Erc1155));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/// @notice Assert that `input` is the local native value asset and return it unchanged.
|
|
66
|
+
/// @param input Asset identifier to validate.
|
|
67
|
+
/// @return asset The same `input` if it is the local native value asset.
|
|
68
|
+
function value(bytes32 input) internal view returns (bytes32 asset) {
|
|
69
|
+
if (!isValue(input)) revert InvalidAsset();
|
|
70
|
+
return input;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/// @notice Assert that `input` is a local ERC-20 asset and return it unchanged.
|
|
74
|
+
/// @param input Asset identifier to validate.
|
|
75
|
+
/// @return asset The same `input` if it is a local ERC-20 asset.
|
|
76
|
+
function erc20(bytes32 input) internal view returns (bytes32 asset) {
|
|
77
|
+
if (!isErc20(input)) revert InvalidAsset();
|
|
78
|
+
return input;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/// @notice Assert that `input` is a local ERC-721 asset and return it unchanged.
|
|
82
|
+
/// @param input Asset identifier to validate.
|
|
83
|
+
/// @return asset The same `input` if it is a local ERC-721 asset.
|
|
84
|
+
function erc721(bytes32 input) internal view returns (bytes32 asset) {
|
|
85
|
+
if (!isErc721(input)) revert InvalidAsset();
|
|
86
|
+
return input;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/// @notice Assert that `input` is a local ERC-1155 asset and return it unchanged.
|
|
90
|
+
/// @param input Asset identifier to validate.
|
|
91
|
+
/// @return asset The same `input` if it is a local ERC-1155 asset.
|
|
92
|
+
function erc1155(bytes32 input) internal view returns (bytes32 asset) {
|
|
93
|
+
if (!isErc1155(input)) revert InvalidAsset();
|
|
94
|
+
return input;
|
|
38
95
|
}
|
|
39
96
|
|
|
40
97
|
/// @notice Create a chain-local native value asset ID.
|
|
@@ -64,52 +121,12 @@ library Assets {
|
|
|
64
121
|
return bytes32(toLocalBase(Erc1155) | (uint(uint160(collection)) << 32));
|
|
65
122
|
}
|
|
66
123
|
|
|
67
|
-
/// @notice Derive a storage key for an (asset, meta) pair.
|
|
68
|
-
/// For 32-byte EVM assets (no meta), the key is the asset ID itself.
|
|
69
|
-
/// For assets with metadata (e.g. ERC-721 or ERC-1155 token IDs), the key is
|
|
70
|
-
/// `keccak256(asset ++ meta)`.
|
|
71
|
-
/// Reverts only if `asset` is zero.
|
|
72
|
-
/// For 32-byte assets, `meta` is ignored and does not affect the derived key.
|
|
73
|
-
/// @param asset Asset identifier.
|
|
74
|
-
/// @param meta Asset metadata slot (e.g. token ID context).
|
|
75
|
-
/// @return Storage key for the (asset, meta) combination.
|
|
76
|
-
function key(bytes32 asset, bytes32 meta) internal pure returns (bytes32) {
|
|
77
|
-
if (asset == 0) revert InvalidAsset();
|
|
78
|
-
return bytes1(asset) == 0x20 ? asset : keccak256(bytes.concat(asset, meta));
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/// @notice Return true when two local ERC-20 assets are already in canonical token-address order.
|
|
82
|
-
/// Useful for pair-style integrations that require a stable token ordering
|
|
83
|
-
/// regardless of the caller's input order.
|
|
84
|
-
/// Reverts if either asset is not a local ERC-20 asset.
|
|
85
|
-
/// @param a First ERC-20 asset identifier.
|
|
86
|
-
/// @param b Second ERC-20 asset identifier.
|
|
87
|
-
/// @return ordered Whether `a`'s token address is lower than `b`'s token address.
|
|
88
|
-
function isSortedErc20(bytes32 a, bytes32 b) internal view returns (bool ordered) {
|
|
89
|
-
return erc20Addr(a) < erc20Addr(b);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/// @notice Extract the token addresses for two local ERC-20 assets and report whether they are already ordered.
|
|
93
|
-
/// The returned addresses preserve the original input order.
|
|
94
|
-
/// Reverts if either asset is not a local ERC-20 asset.
|
|
95
|
-
/// @param a First ERC-20 asset identifier.
|
|
96
|
-
/// @param b Second ERC-20 asset identifier.
|
|
97
|
-
/// @return addrA Token address extracted from `a`.
|
|
98
|
-
/// @return addrB Token address extracted from `b`.
|
|
99
|
-
/// @return ordered Whether `addrA` is lower than `addrB`.
|
|
100
|
-
function erc20Addrs(bytes32 a, bytes32 b) internal view returns (address addrA, address addrB, bool ordered) {
|
|
101
|
-
addrA = erc20Addr(a);
|
|
102
|
-
addrB = erc20Addr(b);
|
|
103
|
-
ordered = addrA < addrB;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
124
|
/// @notice Extract the ERC-20 contract address from an asset ID.
|
|
107
125
|
/// Reverts if `asset` is not a local ERC-20 asset.
|
|
108
126
|
/// @param asset ERC-20 asset identifier.
|
|
109
127
|
/// @return Token contract address embedded in bits [191:32].
|
|
110
128
|
function erc20Addr(bytes32 asset) internal view returns (address) {
|
|
111
|
-
|
|
112
|
-
return address(uint160(uint(asset) >> 32));
|
|
129
|
+
return address(uint160(uint(erc20(asset)) >> 32));
|
|
113
130
|
}
|
|
114
131
|
|
|
115
132
|
/// @notice Assert that `asset` is a local ERC-20 for `token` and return it unchanged.
|
|
@@ -127,8 +144,7 @@ library Assets {
|
|
|
127
144
|
/// @param asset ERC-721 asset identifier.
|
|
128
145
|
/// @return Collection contract address embedded in bits [191:32].
|
|
129
146
|
function erc721Collection(bytes32 asset) internal view returns (address) {
|
|
130
|
-
|
|
131
|
-
return address(uint160(uint(asset) >> 32));
|
|
147
|
+
return address(uint160(uint(erc721(asset)) >> 32));
|
|
132
148
|
}
|
|
133
149
|
|
|
134
150
|
/// @notice Assert that `asset` is a local ERC-721 for `collection` and return it unchanged.
|
|
@@ -146,8 +162,7 @@ library Assets {
|
|
|
146
162
|
/// @param asset ERC-1155 asset identifier.
|
|
147
163
|
/// @return Collection contract address embedded in bits [191:32].
|
|
148
164
|
function erc1155Collection(bytes32 asset) internal view returns (address) {
|
|
149
|
-
|
|
150
|
-
return address(uint160(uint(asset) >> 32));
|
|
165
|
+
return address(uint160(uint(erc1155(asset)) >> 32));
|
|
151
166
|
}
|
|
152
167
|
|
|
153
168
|
/// @notice Assert that `asset` is a local ERC-1155 for `collection` and return it unchanged.
|
|
@@ -159,6 +174,21 @@ library Assets {
|
|
|
159
174
|
if (erc1155Collection(asset) != collection) revert InvalidAsset();
|
|
160
175
|
return asset;
|
|
161
176
|
}
|
|
177
|
+
|
|
178
|
+
/// @notice Derive a storage slot for an (asset, meta) pair.
|
|
179
|
+
/// For 32-byte EVM assets (no meta), the slot is the asset ID itself.
|
|
180
|
+
/// For assets with metadata (e.g. ERC-721 or ERC-1155 token IDs), the slot is
|
|
181
|
+
/// `keccak256(asset ++ meta)`.
|
|
182
|
+
/// Reverts only if `asset` is zero.
|
|
183
|
+
/// For 32-byte assets, `meta` is ignored and does not affect the derived slot.
|
|
184
|
+
/// @param asset Asset identifier.
|
|
185
|
+
/// @param meta Asset metadata slot (e.g. token ID context).
|
|
186
|
+
/// @return Storage slot for the (asset, meta) combination.
|
|
187
|
+
function slot(bytes32 asset, bytes32 meta) internal pure returns (bytes32) {
|
|
188
|
+
if (is32(asset)) return asset;
|
|
189
|
+
if (meta == 0 || !is64(asset)) revert InvalidAsset();
|
|
190
|
+
return keccak256(bytes.concat(asset, meta));
|
|
191
|
+
}
|
|
162
192
|
}
|
|
163
193
|
|
|
164
194
|
/// @title Amounts
|
|
@@ -191,16 +221,6 @@ library Amounts {
|
|
|
191
221
|
return amount;
|
|
192
222
|
}
|
|
193
223
|
|
|
194
|
-
/// @notice Assert non-zero amount and derive the storage key for the (asset, meta) pair.
|
|
195
|
-
/// @param asset Asset identifier.
|
|
196
|
-
/// @param meta Asset metadata slot.
|
|
197
|
-
/// @param amount Amount to validate (must be non-zero).
|
|
198
|
-
/// @return key_ Storage key from `Assets.key(asset, meta)`.
|
|
199
|
-
function ensureKey(bytes32 asset, bytes32 meta, uint amount) internal pure returns (bytes32 key_) {
|
|
200
|
-
ensure(amount);
|
|
201
|
-
return Assets.key(asset, meta);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
224
|
/// @notice Clamp `available` to `[min, max]`.
|
|
205
225
|
/// Uses all of `available` if it does not exceed `max`; reverts if the result
|
|
206
226
|
/// would fall below `min`.
|
package/utils/Ids.sol
CHANGED
|
@@ -81,8 +81,8 @@ library Ids {
|
|
|
81
81
|
|
|
82
82
|
/// @notice Assert that `id` is a query ID and return it unchanged.
|
|
83
83
|
/// @param id Node ID to validate.
|
|
84
|
-
/// @return
|
|
85
|
-
function query(uint id) internal pure returns (uint
|
|
84
|
+
/// @return queryId The same `id` value if it is a query.
|
|
85
|
+
function query(uint id) internal pure returns (uint queryId) {
|
|
86
86
|
if (!isQuery(id)) revert InvalidId();
|
|
87
87
|
return id;
|
|
88
88
|
}
|
|
@@ -163,8 +163,8 @@ library Ids {
|
|
|
163
163
|
/// @title Selectors
|
|
164
164
|
/// @notice ABI-selector derivation helpers for command, peer, and query dispatch.
|
|
165
165
|
library Selectors {
|
|
166
|
-
/// @dev ABI argument encoding for command entry points: `((
|
|
167
|
-
string constant CommandArgs = "((
|
|
166
|
+
/// @dev ABI argument encoding for command entry points: `((bytes32,bytes,bytes))`.
|
|
167
|
+
string constant CommandArgs = "((bytes32,bytes,bytes))";
|
|
168
168
|
/// @dev ABI argument encoding for peer entry points: `(bytes)`.
|
|
169
169
|
string constant PeerArgs = "(bytes)";
|
|
170
170
|
/// @dev ABI argument encoding for query entry points: `(bytes)`.
|
package/utils/Layout.sol
CHANGED
|
@@ -39,7 +39,7 @@ library Layout {
|
|
|
39
39
|
uint8 constant Admin = 0x01;
|
|
40
40
|
/// @dev User account — chain-agnostic, backed by an EVM address.
|
|
41
41
|
uint8 constant User = 0x02;
|
|
42
|
-
/// @dev Keccak account — opaque 28-byte
|
|
42
|
+
/// @dev Keccak account — opaque 28-byte keccak commitment.
|
|
43
43
|
uint8 constant Keccak = 0x03;
|
|
44
44
|
|
|
45
45
|
// -------------------------------------------------------------------------
|
package/utils/Utils.sol
CHANGED
|
@@ -92,6 +92,16 @@ function addrOr(address addr, address or) pure returns (address) {
|
|
|
92
92
|
return addr == address(0) ? or : addr;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
/// @notice Convert a signed integer to its 32-byte two's-complement representation.
|
|
96
|
+
function intToBytes32(int value) pure returns (bytes32) {
|
|
97
|
+
return bytes32(uint(value));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/// @notice Convert a 32-byte two's-complement representation to a signed integer.
|
|
101
|
+
function bytes32ToInt(bytes32 value) pure returns (int) {
|
|
102
|
+
return int(uint(value));
|
|
103
|
+
}
|
|
104
|
+
|
|
95
105
|
/// @notice Convert a null-terminated `bytes32` value to a Solidity string.
|
|
96
106
|
/// Stops at the first zero byte and returns only the meaningful prefix.
|
|
97
107
|
function bytes32ToString(bytes32 value) pure returns (string memory result) {
|