@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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import { CommandBase, CommandContext,
|
|
4
|
+
import { CommandBase, CommandContext, Keys } from "../Base.sol";
|
|
5
5
|
import { Cursors, Cur, Schemas } from "../../Cursors.sol";
|
|
6
6
|
using Cursors for Cur;
|
|
7
7
|
|
|
@@ -20,12 +20,12 @@ abstract contract DenyAssets is CommandBase, DenyAssetsHook {
|
|
|
20
20
|
uint internal immutable denyAssetsId = commandId(NAME);
|
|
21
21
|
|
|
22
22
|
constructor() {
|
|
23
|
-
emit Command(host, NAME, Schemas.Asset,
|
|
23
|
+
emit Command(host, denyAssetsId, NAME, Schemas.Asset, Keys.Empty, Keys.Empty, false);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
function denyAssets(
|
|
27
27
|
CommandContext calldata c
|
|
28
|
-
) external onlyAdmin(c.account)
|
|
28
|
+
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
29
29
|
(Cur memory request, , ) = cursor(c.request, 1);
|
|
30
30
|
|
|
31
31
|
while (request.i < request.bound) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import { CommandBase, CommandContext,
|
|
4
|
+
import { CommandBase, CommandContext, Keys } from "../Base.sol";
|
|
5
5
|
import { Cursors, Cur } from "../../Cursors.sol";
|
|
6
6
|
|
|
7
7
|
string constant NAME = "destroy";
|
|
@@ -21,12 +21,12 @@ abstract contract Destroy is CommandBase, DestroyHook {
|
|
|
21
21
|
uint internal immutable destroyId = commandId(NAME);
|
|
22
22
|
|
|
23
23
|
constructor(string memory input) {
|
|
24
|
-
emit Command(host, NAME, input,
|
|
24
|
+
emit Command(host, destroyId, NAME, input, Keys.Empty, Keys.Empty, false);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
function destroy(
|
|
28
28
|
CommandContext calldata c
|
|
29
|
-
) external onlyAdmin(c.account)
|
|
29
|
+
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
30
30
|
Cur memory input = cursor(c.request);
|
|
31
31
|
destroy(input);
|
|
32
32
|
return "";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
pragma solidity ^0.8.33;
|
|
3
|
+
|
|
4
|
+
import {CommandContext, CommandPayable, Keys} from "../Base.sol";
|
|
5
|
+
import {Cursors, Cur, Schemas} from "../../Cursors.sol";
|
|
6
|
+
import {Budget, Values} from "../../utils/Value.sol";
|
|
7
|
+
import {Ids} from "../../utils/Ids.sol";
|
|
8
|
+
|
|
9
|
+
using Cursors for Cur;
|
|
10
|
+
|
|
11
|
+
string constant NAME = "executePayable";
|
|
12
|
+
|
|
13
|
+
/// @title ExecutePayable
|
|
14
|
+
/// @notice Admin command that forwards raw calldata to one or more target nodes.
|
|
15
|
+
/// Each CALL block specifies a target node ID, native value, and raw calldata payload.
|
|
16
|
+
/// Only callable by the admin account.
|
|
17
|
+
abstract contract ExecutePayable is CommandPayable {
|
|
18
|
+
uint internal immutable executePayableId = commandId(NAME);
|
|
19
|
+
|
|
20
|
+
constructor() {
|
|
21
|
+
emit Command(host, executePayableId, NAME, Schemas.Call, Keys.Empty, Keys.Empty, true);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function executePayable(CommandContext calldata c) external payable onlyAdmin(c.account) returns (bytes memory) {
|
|
25
|
+
(Cur memory request, , ) = cursor(c.request, 1);
|
|
26
|
+
Budget memory budget = Values.fromMsg();
|
|
27
|
+
|
|
28
|
+
while (request.i < request.bound) {
|
|
29
|
+
(uint target, uint value, bytes calldata data) = request.unpackCall();
|
|
30
|
+
address addr = Ids.nodeAddr(target);
|
|
31
|
+
callAddr(addr, Values.use(budget, value), data);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
request.complete();
|
|
35
|
+
settleValue(c.account, budget);
|
|
36
|
+
return "";
|
|
37
|
+
}
|
|
38
|
+
}
|
package/commands/admin/Init.sol
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import { CommandBase, CommandContext,
|
|
4
|
+
import { CommandBase, CommandContext, Keys } from "../Base.sol";
|
|
5
5
|
import { Cursors, Cur } from "../../Cursors.sol";
|
|
6
6
|
|
|
7
7
|
string constant NAME = "init";
|
|
@@ -21,12 +21,12 @@ abstract contract Init is CommandBase, InitHook {
|
|
|
21
21
|
uint internal immutable initId = commandId(NAME);
|
|
22
22
|
|
|
23
23
|
constructor(string memory input) {
|
|
24
|
-
emit Command(host, NAME, input,
|
|
24
|
+
emit Command(host, initId, NAME, input, Keys.Empty, Keys.Empty, false);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
function init(
|
|
28
28
|
CommandContext calldata c
|
|
29
|
-
) external onlyAdmin(c.account)
|
|
29
|
+
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
30
30
|
Cur memory input = cursor(c.request);
|
|
31
31
|
init(input);
|
|
32
32
|
return "";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import { CommandContext, CommandPayable,
|
|
4
|
+
import { CommandContext, CommandPayable, Keys } from "../Base.sol";
|
|
5
5
|
import { Cursors, Cur, Schemas } from "../../Cursors.sol";
|
|
6
6
|
import { Budget, Values } from "../../utils/Value.sol";
|
|
7
7
|
using Cursors for Cur;
|
|
@@ -10,23 +10,23 @@ string constant NAME = "relocatePayable";
|
|
|
10
10
|
|
|
11
11
|
/// @title RelocatePayable
|
|
12
12
|
/// @notice Admin command that forwards native value (ETH) to one or more destination hosts.
|
|
13
|
-
/// Each
|
|
13
|
+
/// Each RELOCATION block in the request specifies a target host node ID and an amount to forward.
|
|
14
14
|
/// Only callable by the admin account.
|
|
15
15
|
abstract contract RelocatePayable is CommandPayable {
|
|
16
16
|
uint internal immutable relocatePayableId = commandId(NAME);
|
|
17
17
|
|
|
18
18
|
constructor() {
|
|
19
|
-
emit Command(host, NAME, Schemas.
|
|
19
|
+
emit Command(host, relocatePayableId, NAME, Schemas.Relocation, Keys.Empty, Keys.Empty, true);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
function relocatePayable(
|
|
23
23
|
CommandContext calldata c
|
|
24
|
-
) external payable onlyAdmin(c.account)
|
|
24
|
+
) external payable onlyAdmin(c.account) returns (bytes memory) {
|
|
25
25
|
(Cur memory request, , ) = cursor(c.request, 1);
|
|
26
26
|
Budget memory budget = Values.fromMsg();
|
|
27
27
|
|
|
28
28
|
while (request.i < request.bound) {
|
|
29
|
-
(uint peer, uint amount) = request.
|
|
29
|
+
(uint peer, uint amount) = request.unpackRelocation();
|
|
30
30
|
callTo(peer, Values.use(budget, amount), "");
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import { CommandBase, CommandContext,
|
|
4
|
+
import { CommandBase, CommandContext, Keys } from "../Base.sol";
|
|
5
5
|
import { Cursors, Cur, Schemas } from "../../Cursors.sol";
|
|
6
6
|
using Cursors for Cur;
|
|
7
7
|
|
|
@@ -15,17 +15,17 @@ abstract contract Unauthorize is CommandBase {
|
|
|
15
15
|
uint internal immutable unauthorizeId = commandId(NAME);
|
|
16
16
|
|
|
17
17
|
constructor() {
|
|
18
|
-
emit Command(host, NAME, Schemas.Node,
|
|
18
|
+
emit Command(host, unauthorizeId, NAME, Schemas.Node, Keys.Empty, Keys.Empty, false);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
function unauthorize(
|
|
22
22
|
CommandContext calldata c
|
|
23
|
-
) external onlyAdmin(c.account)
|
|
23
|
+
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
24
24
|
(Cur memory request, , ) = cursor(c.request, 1);
|
|
25
25
|
|
|
26
26
|
while (request.i < request.bound) {
|
|
27
27
|
uint node = request.unpackNode();
|
|
28
|
-
|
|
28
|
+
unauthorize(node);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
request.complete();
|
package/core/Access.sol
CHANGED
|
@@ -1,46 +1,53 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
4
|
+
import {AccessEvent} from "../events/Access.sol";
|
|
5
|
+
import {RootZeroContext} from "./Context.sol";
|
|
6
|
+
import {Accounts} from "../utils/Accounts.sol";
|
|
7
|
+
import {Ids} from "../utils/Ids.sol";
|
|
8
|
+
import {addrOr} from "../utils/Utils.sol";
|
|
9
9
|
|
|
10
10
|
/// @title AccessControl
|
|
11
11
|
/// @notice Host access control layer.
|
|
12
12
|
/// Tracks an immutable trusted commander, the host's own node ID, and a
|
|
13
|
-
/// mapping of externally
|
|
14
|
-
///
|
|
13
|
+
/// mapping of externally trusted node IDs. Inbound trust is host-based:
|
|
14
|
+
/// trusted hosts, the commander, and this contract itself may interact
|
|
15
15
|
/// with the host through the guarded command and peer entrypoints.
|
|
16
|
-
abstract contract AccessControl is
|
|
16
|
+
abstract contract AccessControl is RootZeroContext, AccessEvent {
|
|
17
17
|
/// @dev Trusted commander address. All calls from this address are implicitly trusted.
|
|
18
18
|
/// Defaults to `address(this)` when no external commander is provided.
|
|
19
19
|
address internal immutable commander;
|
|
20
20
|
/// @dev Admin account ID derived from the commander address at construction time.
|
|
21
21
|
bytes32 internal immutable adminAccount;
|
|
22
22
|
|
|
23
|
-
/// @dev Mapping from node ID to
|
|
24
|
-
|
|
25
|
-
mapping(uint => bool) internal authorized;
|
|
23
|
+
/// @dev Mapping from node ID to trust status.
|
|
24
|
+
mapping(uint node => bool) internal trusted;
|
|
26
25
|
|
|
27
|
-
/// @dev Thrown when `ensureTrusted` is called with a node that is not authorized.
|
|
28
|
-
error UnauthorizedNode(uint node);
|
|
29
26
|
/// @dev Thrown when `enforceCaller` is called by an address that is not trusted.
|
|
30
27
|
error UnauthorizedCaller(address addr);
|
|
31
28
|
|
|
29
|
+
/// @dev Thrown when a required trusted node is missing from the trusted set.
|
|
30
|
+
error UnauthorizedNode(uint node);
|
|
31
|
+
|
|
32
32
|
constructor(address cmdr) {
|
|
33
33
|
commander = addrOr(cmdr, address(this));
|
|
34
34
|
adminAccount = Accounts.toAdmin(commander);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
/// @notice Grant
|
|
38
|
-
///
|
|
39
|
-
/// @param node Node ID to authorize
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
/// @notice Grant authorization for a node.
|
|
38
|
+
/// Accepts any node ID that should be trusted by this contract.
|
|
39
|
+
/// @param node Node ID to authorize.
|
|
40
|
+
function authorize(uint node) internal {
|
|
41
|
+
trusted[node] = true;
|
|
42
|
+
emit Access(host, node, true);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/// @notice Revoke authorization for a node.
|
|
46
|
+
/// Accepts any node ID that should no longer be trusted by this contract.
|
|
47
|
+
/// @param node Node ID to unauthorize.
|
|
48
|
+
function unauthorize(uint node) internal {
|
|
49
|
+
trusted[node] = false;
|
|
50
|
+
emit Access(host, node, false);
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
/// @notice Return true if `caller` is an implicitly trusted address.
|
|
@@ -48,7 +55,17 @@ abstract contract AccessControl is HostBound, AccessEvent {
|
|
|
48
55
|
/// whose host ID has been explicitly authorized.
|
|
49
56
|
/// @param caller Address to check.
|
|
50
57
|
function isTrusted(address caller) internal view returns (bool) {
|
|
51
|
-
return caller == commander || caller == address(this) ||
|
|
58
|
+
return caller == commander || caller == address(this) || trusted[Ids.toHost(caller)];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/// @notice Assert that `node` is in the trusted set and return it.
|
|
62
|
+
/// @param node Node ID to validate.
|
|
63
|
+
/// @return The same `node` value if trusted.
|
|
64
|
+
function ensureTrusted(uint node) internal view returns (uint) {
|
|
65
|
+
if (node == 0 || !trusted[node]) {
|
|
66
|
+
revert UnauthorizedNode(node);
|
|
67
|
+
}
|
|
68
|
+
return node;
|
|
52
69
|
}
|
|
53
70
|
|
|
54
71
|
/// @notice Assert that `caller` is trusted and return it.
|
|
@@ -61,17 +78,4 @@ abstract contract AccessControl is HostBound, AccessEvent {
|
|
|
61
78
|
}
|
|
62
79
|
return caller;
|
|
63
80
|
}
|
|
64
|
-
|
|
65
|
-
/// @notice Assert that `node` is in the authorized set and return it.
|
|
66
|
-
/// Used for outbound trust checks before calling another node.
|
|
67
|
-
/// Accepts any authorized node ID (host or command).
|
|
68
|
-
/// Inbound caller authentication is host-only via `enforceCaller(msg.sender)`.
|
|
69
|
-
/// @param node Node ID to validate.
|
|
70
|
-
/// @return The same `node` value if authorized.
|
|
71
|
-
function ensureTrusted(uint node) internal view returns (uint) {
|
|
72
|
-
if (node == 0 || !authorized[node]) {
|
|
73
|
-
revert UnauthorizedNode(node);
|
|
74
|
-
}
|
|
75
|
-
return node;
|
|
76
|
-
}
|
|
77
81
|
}
|
package/core/Balances.sol
CHANGED
|
@@ -7,34 +7,33 @@ import {BalanceEvent} from "../events/Balance.sol";
|
|
|
7
7
|
error InsufficientFunds();
|
|
8
8
|
|
|
9
9
|
/// @title Balances
|
|
10
|
-
/// @notice On-chain ledger for per-account, per-
|
|
11
|
-
///
|
|
12
|
-
/// value returned by `Assets.key(asset, meta)`.
|
|
10
|
+
/// @notice On-chain ledger for per-account, per-slot balances.
|
|
11
|
+
/// Higher-level modules decide how slots are derived and validated.
|
|
13
12
|
abstract contract Balances is BalanceEvent {
|
|
14
|
-
/// @dev account ->
|
|
15
|
-
mapping(bytes32 account => mapping(bytes32
|
|
13
|
+
/// @dev account -> slot -> balance.
|
|
14
|
+
mapping(bytes32 account => mapping(bytes32 slot => uint amount)) internal balances;
|
|
15
|
+
|
|
16
|
+
/// @notice Add `amount` to an account balance and return the new balance.
|
|
17
|
+
/// @param account Account identifier.
|
|
18
|
+
/// @param slot Storage slot for the position being credited.
|
|
19
|
+
/// @param amount Amount to credit.
|
|
20
|
+
/// @return balance New balance after the credit.
|
|
21
|
+
function creditTo(bytes32 account, bytes32 slot, uint amount) internal returns (uint balance) {
|
|
22
|
+
balance = balances[account][slot] += amount;
|
|
23
|
+
}
|
|
16
24
|
|
|
17
25
|
/// @notice Deduct `amount` from an account balance and return the new balance.
|
|
18
26
|
/// Reverts with `InsufficientFunds` if the current balance is less than `amount`.
|
|
19
27
|
/// @param account Account identifier.
|
|
20
|
-
/// @param
|
|
28
|
+
/// @param slot Storage slot for the position being debited.
|
|
21
29
|
/// @param amount Amount to deduct.
|
|
22
30
|
/// @return balance New balance after the debit.
|
|
23
|
-
function debitFrom(bytes32 account, bytes32
|
|
24
|
-
balance = balances[account][
|
|
31
|
+
function debitFrom(bytes32 account, bytes32 slot, uint amount) internal returns (uint balance) {
|
|
32
|
+
balance = balances[account][slot];
|
|
25
33
|
if (balance < amount) revert InsufficientFunds();
|
|
26
34
|
unchecked {
|
|
27
35
|
balance -= amount;
|
|
28
36
|
}
|
|
29
|
-
balances[account][
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/// @notice Add `amount` to an account balance and return the new balance.
|
|
33
|
-
/// @param account Account identifier.
|
|
34
|
-
/// @param assetKey Storage key for the (asset, meta) pair.
|
|
35
|
-
/// @param amount Amount to credit.
|
|
36
|
-
/// @return balance New balance after the credit.
|
|
37
|
-
function creditTo(bytes32 account, bytes32 assetKey, uint amount) internal returns (uint balance) {
|
|
38
|
-
balance = balances[account][assetKey] += amount;
|
|
37
|
+
balances[account][slot] = balance;
|
|
39
38
|
}
|
|
40
39
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { Ids } from "../utils/Ids.sol";
|
|
4
|
+
import {AccessControl} from "./Access.sol";
|
|
5
|
+
import {Ids} from "../utils/Ids.sol";
|
|
7
6
|
|
|
8
7
|
/// @dev Emitted when a trusted inter-node call fails.
|
|
9
8
|
/// @param addr Contract address that was called.
|
|
@@ -11,11 +10,9 @@ import { Ids } from "../utils/Ids.sol";
|
|
|
11
10
|
/// @param err Revert data returned by the failed call.
|
|
12
11
|
error FailedCall(address addr, bytes4 selector, bytes err);
|
|
13
12
|
|
|
14
|
-
/// @title
|
|
15
|
-
/// @notice Shared
|
|
16
|
-
|
|
17
|
-
/// and trusted inter-node calls. Inherits access control from `AccessControl`.
|
|
18
|
-
abstract contract OperationBase is CursorBase, AccessControl {
|
|
13
|
+
/// @title NodeCalls
|
|
14
|
+
/// @notice Shared trusted inter-node call helpers for contracts that can talk to other nodes.
|
|
15
|
+
abstract contract NodeCalls is AccessControl {
|
|
19
16
|
/// @notice Return the host node ID corresponding to the current caller.
|
|
20
17
|
/// @dev Encodes `msg.sender` as a host ID using the local-chain host layout.
|
|
21
18
|
/// @return Host node ID for `msg.sender`.
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {Cur, Cursors} from "../Cursors.sol";
|
|
5
|
+
import {Assets} from "../utils/Assets.sol";
|
|
6
|
+
import {Ids} from "../utils/Ids.sol";
|
|
5
7
|
|
|
6
8
|
using Cursors for Cur;
|
|
7
9
|
|
|
8
|
-
/// @title
|
|
9
|
-
/// @notice Shared
|
|
10
|
-
abstract contract
|
|
10
|
+
/// @title RootZeroContext
|
|
11
|
+
/// @notice Shared rootzero contract context for host identity, native value identity, and block-stream cursors.
|
|
12
|
+
abstract contract RootZeroContext {
|
|
13
|
+
/// @dev This contract's host node ID, set to `Ids.toHost(address(this))` at construction.
|
|
14
|
+
uint public immutable host = Ids.toHost(address(this));
|
|
15
|
+
/// @dev Asset ID for the native chain value (ETH), bound to the current chain at deployment.
|
|
16
|
+
bytes32 internal immutable valueAsset = Assets.toValue();
|
|
17
|
+
|
|
11
18
|
/// @notice Open a cursor over a calldata block stream.
|
|
12
19
|
/// @param source Calldata slice to parse.
|
|
13
20
|
/// @return cur Cursor positioned at the beginning of `source`.
|
|
@@ -39,5 +46,4 @@ abstract contract CursorBase {
|
|
|
39
46
|
(, , uint quotient) = cur.primeRun(group);
|
|
40
47
|
if (quotient != expectedQuotient) revert Cursors.BadRatio();
|
|
41
48
|
}
|
|
42
|
-
|
|
43
49
|
}
|
package/core/Host.sol
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
4
|
+
import {AccessControl} from "./Access.sol";
|
|
5
|
+
import {Authorize} from "../commands/admin/Authorize.sol";
|
|
6
|
+
import {Unauthorize} from "../commands/admin/Unauthorize.sol";
|
|
7
|
+
import {ExecutePayable} from "../commands/admin/Execute.sol";
|
|
8
|
+
import {RelocatePayable} from "../commands/admin/Relocate.sol";
|
|
9
|
+
import {HostAnnouncedEvent} from "../events/Host.sol";
|
|
10
|
+
import {IHostDiscovery} from "../interfaces/IHostDiscovery.sol";
|
|
11
|
+
import {Ids} from "../utils/Ids.sol";
|
|
11
12
|
|
|
12
13
|
/// @notice Mixin that allows a contract to act as a host discovery registry.
|
|
13
14
|
/// Hosts call `announceHost` on a discovery contract to register themselves.
|
|
@@ -25,10 +26,10 @@ abstract contract HostDiscovery is HostAnnouncedEvent, IHostDiscovery {
|
|
|
25
26
|
|
|
26
27
|
/// @title Host
|
|
27
28
|
/// @notice Abstract base contract for rootzero host implementations.
|
|
28
|
-
/// Inherits admin command support (authorize, unauthorize, relocatePayable) and
|
|
29
|
+
/// Inherits admin command support (authorize, unauthorize, executePayable, relocatePayable) and
|
|
29
30
|
/// optionally announces itself to a discovery contract at deployment.
|
|
30
31
|
/// Accepts native ETH payments via the `receive` function.
|
|
31
|
-
abstract contract Host is Authorize, Unauthorize, RelocatePayable {
|
|
32
|
+
abstract contract Host is Authorize, Unauthorize, ExecutePayable, RelocatePayable {
|
|
32
33
|
/// @param cmdr Commander address; passed to `AccessControl`.
|
|
33
34
|
/// If `cmdr` is a deployed contract, the host calls `announceHost`
|
|
34
35
|
/// on it during construction to register with the discovery registry.
|
package/core/Types.sol
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
pragma solidity ^0.8.33;
|
|
3
|
+
|
|
4
|
+
/// @notice Asset and amount pair used across ledger, command, and block flows.
|
|
5
|
+
struct AssetAmount {
|
|
6
|
+
/// @dev Asset identifier.
|
|
7
|
+
bytes32 asset;
|
|
8
|
+
/// @dev Asset metadata slot.
|
|
9
|
+
bytes32 meta;
|
|
10
|
+
/// @dev Token amount in the asset's native units.
|
|
11
|
+
uint amount;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/// @notice Account-scoped asset shape.
|
|
15
|
+
struct AccountAsset {
|
|
16
|
+
/// @dev Account identifier.
|
|
17
|
+
bytes32 account;
|
|
18
|
+
/// @dev Asset identifier.
|
|
19
|
+
bytes32 asset;
|
|
20
|
+
/// @dev Asset metadata slot.
|
|
21
|
+
bytes32 meta;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/// @notice Account-scoped amount shape used by payout blocks and query responses.
|
|
25
|
+
struct AccountAmount {
|
|
26
|
+
/// @dev Account identifier.
|
|
27
|
+
bytes32 account;
|
|
28
|
+
/// @dev Asset identifier.
|
|
29
|
+
bytes32 asset;
|
|
30
|
+
/// @dev Asset metadata slot.
|
|
31
|
+
bytes32 meta;
|
|
32
|
+
/// @dev Token amount in the asset's native units.
|
|
33
|
+
uint amount;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/// @notice Host-scoped asset and amount shape.
|
|
37
|
+
struct HostAmount {
|
|
38
|
+
/// @dev Host node identifier.
|
|
39
|
+
uint host;
|
|
40
|
+
/// @dev Asset identifier.
|
|
41
|
+
bytes32 asset;
|
|
42
|
+
/// @dev Asset metadata slot.
|
|
43
|
+
bytes32 meta;
|
|
44
|
+
/// @dev Token amount in the asset's native units.
|
|
45
|
+
uint amount;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/// @notice Host-scoped account asset shape.
|
|
49
|
+
struct HostAccountAsset {
|
|
50
|
+
/// @dev Host node identifier.
|
|
51
|
+
uint host;
|
|
52
|
+
/// @dev Account identifier.
|
|
53
|
+
bytes32 account;
|
|
54
|
+
/// @dev Asset identifier.
|
|
55
|
+
bytes32 asset;
|
|
56
|
+
/// @dev Asset metadata slot.
|
|
57
|
+
bytes32 meta;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/// @notice Host-scoped account amount shape.
|
|
61
|
+
struct HostAccountAmount {
|
|
62
|
+
/// @dev Host node identifier.
|
|
63
|
+
uint host;
|
|
64
|
+
/// @dev Account identifier.
|
|
65
|
+
bytes32 account;
|
|
66
|
+
/// @dev Asset identifier.
|
|
67
|
+
bytes32 asset;
|
|
68
|
+
/// @dev Asset metadata slot.
|
|
69
|
+
bytes32 meta;
|
|
70
|
+
/// @dev Token amount in the asset's native units.
|
|
71
|
+
uint amount;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/// @notice Transfer payload used by transaction blocks and peer settlement.
|
|
75
|
+
struct Tx {
|
|
76
|
+
/// @dev Sender account identifier.
|
|
77
|
+
bytes32 from;
|
|
78
|
+
/// @dev Destination account identifier.
|
|
79
|
+
bytes32 to;
|
|
80
|
+
/// @dev Asset identifier.
|
|
81
|
+
bytes32 asset;
|
|
82
|
+
/// @dev Asset metadata slot.
|
|
83
|
+
bytes32 meta;
|
|
84
|
+
/// @dev Transfer amount in the asset's native units.
|
|
85
|
+
uint amount;
|
|
86
|
+
}
|