@rootzero/contracts 0.9.1 → 0.9.3
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 +16 -16
- package/Cursors.sol +1 -1
- package/Events.sol +3 -3
- package/Utils.sol +1 -1
- package/blocks/Cursors.sol +51 -9
- package/blocks/Keys.sol +1 -1
- package/blocks/Schema.sol +98 -4
- package/blocks/Writers.sol +21 -125
- package/commands/Base.sol +0 -19
- package/commands/Burn.sol +2 -2
- package/commands/Credit.sol +3 -2
- package/commands/Debit.sol +3 -3
- package/commands/Deposit.sol +6 -6
- package/commands/Pipe.sol +17 -12
- package/commands/Provision.sol +8 -8
- package/commands/Transfer.sol +2 -2
- package/commands/Withdraw.sol +3 -2
- package/commands/{control → admin}/AllowAssets.sol +5 -5
- package/commands/{control → admin}/Allowance.sol +9 -9
- package/commands/{control → admin}/Authorize.sol +5 -5
- package/commands/{control → admin}/DenyAssets.sol +5 -5
- package/commands/{control → admin}/Destroy.sol +4 -4
- package/commands/{control → admin}/Execute.sol +5 -5
- package/commands/{control → admin}/Init.sol +4 -4
- package/commands/{control → admin}/Unauthorize.sol +5 -5
- package/core/Access.sol +2 -2
- package/core/Calls.sol +16 -2
- package/core/Context.sol +10 -11
- package/core/Host.sol +4 -4
- package/core/Types.sol +1 -1
- package/events/{Control.sol → Admin.sol} +9 -5
- package/events/Command.sol +7 -2
- package/events/Listing.sol +3 -4
- package/events/Peer.sol +26 -0
- package/events/{RootZero.sol → Piped.sol} +3 -3
- package/events/Query.sol +5 -2
- package/package.json +1 -1
- package/peer/AllowAssets.sol +38 -0
- package/peer/Allowance.sol +35 -0
- package/peer/BalancePull.sol +43 -0
- package/peer/Base.sol +40 -0
- package/peer/DenyAssets.sol +38 -0
- package/peer/Settle.sol +32 -0
- package/queries/Assets.sol +4 -5
- package/queries/Balances.sol +4 -5
- package/queries/Positions.sol +4 -5
- package/utils/Accounts.sol +8 -0
- package/utils/Ids.sol +35 -30
- package/utils/Layout.sol +3 -3
- package/utils/Utils.sol +2 -2
- package/events/Remote.sol +0 -24
- package/remote/AllowAssets.sol +0 -39
- package/remote/Allowance.sol +0 -36
- package/remote/AssetPull.sol +0 -44
- package/remote/Base.sol +0 -40
- package/remote/DenyAssets.sol +0 -39
- package/remote/Settle.sol +0 -33
package/commands/Base.sol
CHANGED
|
@@ -18,25 +18,6 @@ struct CommandContext {
|
|
|
18
18
|
bytes request;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
/// @notice ABI-encode a command call from a command ID and execution context.
|
|
22
|
-
/// @dev Derives the function selector from `cid` via `Ids.commandSelector(cid)`.
|
|
23
|
-
/// Reverts if `cid` is not a valid command ID.
|
|
24
|
-
/// @param cid Command node ID embedding the target selector.
|
|
25
|
-
/// @param account Caller account identifier for the command context.
|
|
26
|
-
/// @param state Current state block stream passed to the command.
|
|
27
|
-
/// @param request Input block stream for the command invocation.
|
|
28
|
-
/// @return ABI-encoded calldata for the command entry point.
|
|
29
|
-
function encodeCommandCall(
|
|
30
|
-
uint cid,
|
|
31
|
-
bytes32 account,
|
|
32
|
-
bytes memory state,
|
|
33
|
-
bytes calldata request
|
|
34
|
-
) pure returns (bytes memory) {
|
|
35
|
-
bytes4 selector = Ids.commandSelector(cid);
|
|
36
|
-
CommandContext memory ctx = CommandContext(account, state, request);
|
|
37
|
-
return abi.encodeWithSelector(selector, ctx);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
21
|
/// @title CommandBase
|
|
41
22
|
/// @notice Abstract base for all rootzero command contracts.
|
|
42
23
|
/// Provides access control modifiers, event emission, and the `commandId`
|
package/commands/Burn.sol
CHANGED
|
@@ -25,11 +25,11 @@ abstract contract Burn is CommandBase, BurnHook {
|
|
|
25
25
|
uint internal immutable burnId = commandId(NAME);
|
|
26
26
|
|
|
27
27
|
constructor() {
|
|
28
|
-
emit Command(host, burnId, NAME, "", Keys.Balance, Keys.Empty, false);
|
|
28
|
+
emit Command(host, burnId, NAME, "0:1:0", "", Keys.Balance, Keys.Empty, false);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
function burn(CommandContext calldata c) external onlyCommand(c.account) returns (bytes memory) {
|
|
32
|
-
(Cur memory state,
|
|
32
|
+
(Cur memory state, ) = cursor(c.state, 1);
|
|
33
33
|
|
|
34
34
|
while (state.i < state.bound) {
|
|
35
35
|
(bytes32 asset, bytes32 meta, uint amount) = state.unpackBalance();
|
package/commands/Credit.sol
CHANGED
|
@@ -22,17 +22,18 @@ abstract contract CreditAccountHook {
|
|
|
22
22
|
/// An optional ACCOUNT block in the request overrides the default `c.account` destination.
|
|
23
23
|
abstract contract CreditAccount is CommandBase, CreditAccountHook {
|
|
24
24
|
string private constant NAME = "creditAccount";
|
|
25
|
+
string private constant REQUEST = string.concat(Schemas.Empty, ";", Schemas.Account, "?");
|
|
25
26
|
|
|
26
27
|
uint internal immutable creditAccountId = commandId(NAME);
|
|
27
28
|
|
|
28
29
|
constructor() {
|
|
29
|
-
emit Command(host, creditAccountId, NAME,
|
|
30
|
+
emit Command(host, creditAccountId, NAME, "0:1:0", REQUEST, Keys.Balance, Keys.Empty, false);
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
function creditAccount(
|
|
33
34
|
CommandContext calldata c
|
|
34
35
|
) external onlyCommand(c.account) returns (bytes memory) {
|
|
35
|
-
(Cur memory state,
|
|
36
|
+
(Cur memory state, ) = cursor(c.state, 1);
|
|
36
37
|
bytes32 to = Cursors.resolveAccount(c.request, c.account);
|
|
37
38
|
|
|
38
39
|
while (state.i < state.bound) {
|
package/commands/Debit.sol
CHANGED
|
@@ -27,15 +27,15 @@ abstract contract DebitAccount is CommandBase, DebitAccountHook {
|
|
|
27
27
|
uint internal immutable debitAccountId = commandId(NAME);
|
|
28
28
|
|
|
29
29
|
constructor() {
|
|
30
|
-
emit Command(host, debitAccountId, NAME, Schemas.Amount, Keys.Empty, Keys.Balance, false);
|
|
30
|
+
emit Command(host, debitAccountId, NAME, "1:0:1", Schemas.Amount, Keys.Empty, Keys.Balance, false);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/// @notice Override to customize request parsing or batching for debits.
|
|
34
34
|
/// The default implementation iterates AMOUNT blocks, calls
|
|
35
35
|
/// `debitAccount`, and emits matching BALANCE blocks.
|
|
36
36
|
function debitAccount(bytes32 account, bytes calldata request) internal virtual returns (bytes memory) {
|
|
37
|
-
(Cur memory input, uint
|
|
38
|
-
Writer memory writer = Writers.allocBalances(
|
|
37
|
+
(Cur memory input, uint groups) = cursor(request, 1);
|
|
38
|
+
Writer memory writer = Writers.allocBalances(groups);
|
|
39
39
|
|
|
40
40
|
while (input.i < input.bound) {
|
|
41
41
|
(bytes32 asset, bytes32 meta, uint amount) = input.unpackAmount();
|
package/commands/Deposit.sol
CHANGED
|
@@ -41,14 +41,14 @@ abstract contract Deposit is CommandBase, DepositHook {
|
|
|
41
41
|
uint internal immutable depositId = commandId(NAME);
|
|
42
42
|
|
|
43
43
|
constructor() {
|
|
44
|
-
emit Command(host, depositId, NAME, Schemas.Amount, Keys.Empty, Keys.Balance, false);
|
|
44
|
+
emit Command(host, depositId, NAME, "1:0:1", Schemas.Amount, Keys.Empty, Keys.Balance, false);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
function deposit(
|
|
48
48
|
CommandContext calldata c
|
|
49
49
|
) external onlyCommand(c.account) returns (bytes memory) {
|
|
50
|
-
(Cur memory request, uint
|
|
51
|
-
Writer memory writer = Writers.allocBalances(
|
|
50
|
+
(Cur memory request, uint groups) = cursor(c.request, 1);
|
|
51
|
+
Writer memory writer = Writers.allocBalances(groups);
|
|
52
52
|
|
|
53
53
|
while (request.i < request.bound) {
|
|
54
54
|
(bytes32 asset, bytes32 meta, uint amount) = request.unpackAmount();
|
|
@@ -69,14 +69,14 @@ abstract contract DepositPayable is CommandPayable, DepositPayableHook {
|
|
|
69
69
|
uint internal immutable depositPayableId = commandId(NAME);
|
|
70
70
|
|
|
71
71
|
constructor() {
|
|
72
|
-
emit Command(host, depositPayableId, NAME, Schemas.Amount, Keys.Empty, Keys.Balance, true);
|
|
72
|
+
emit Command(host, depositPayableId, NAME, "1:0:1", Schemas.Amount, Keys.Empty, Keys.Balance, true);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
function depositPayable(
|
|
76
76
|
CommandContext calldata c
|
|
77
77
|
) external payable onlyCommand(c.account) returns (bytes memory) {
|
|
78
|
-
(Cur memory request, uint
|
|
79
|
-
Writer memory writer = Writers.allocBalances(
|
|
78
|
+
(Cur memory request, uint groups) = cursor(c.request, 1);
|
|
79
|
+
Writer memory writer = Writers.allocBalances(groups);
|
|
80
80
|
Budget memory budget = Values.fromMsg();
|
|
81
81
|
|
|
82
82
|
while (request.i < request.bound) {
|
package/commands/Pipe.sol
CHANGED
|
@@ -9,8 +9,17 @@ import {Budget, Values} from "../utils/Value.sol";
|
|
|
9
9
|
using Cursors for Cur;
|
|
10
10
|
|
|
11
11
|
abstract contract PipePayableHook {
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
/// @notice Override to dispatch one piped command step.
|
|
13
|
+
/// Called once per STEP block. The returned bytes become the state passed to
|
|
14
|
+
/// the next step.
|
|
15
|
+
/// @param id Command node ID to invoke or handle.
|
|
16
|
+
/// @param account Account identifier for the piped command context.
|
|
17
|
+
/// @param state Current threaded state block stream.
|
|
18
|
+
/// @param request Step request block stream.
|
|
19
|
+
/// @param value Native value assigned to this step.
|
|
20
|
+
/// @return Updated state block stream for the next step.
|
|
21
|
+
function dispatchCommand(
|
|
22
|
+
uint id,
|
|
14
23
|
bytes32 account,
|
|
15
24
|
bytes memory state,
|
|
16
25
|
bytes calldata request,
|
|
@@ -20,7 +29,7 @@ abstract contract PipePayableHook {
|
|
|
20
29
|
|
|
21
30
|
/// @title PipePayable
|
|
22
31
|
/// @notice Command that sequences multiple sub-command STEP invocations in a single transaction.
|
|
23
|
-
/// Each STEP block carries a
|
|
32
|
+
/// Each STEP block carries a command node, native value to forward, and an embedded request.
|
|
24
33
|
/// State threads through the steps: each step's output becomes the next step's state.
|
|
25
34
|
/// Admin accounts are not permitted to use `pipePayable`.
|
|
26
35
|
abstract contract PipePayable is CommandPayable, PipePayableHook {
|
|
@@ -29,7 +38,7 @@ abstract contract PipePayable is CommandPayable, PipePayableHook {
|
|
|
29
38
|
uint internal immutable pipePayableId = commandId(NAME);
|
|
30
39
|
|
|
31
40
|
constructor() {
|
|
32
|
-
emit Command(host, pipePayableId, NAME, Schemas.Step, Keys.Empty, Keys.Empty, true);
|
|
41
|
+
emit Command(host, pipePayableId, NAME, "1:0:0", Schemas.Step, Keys.Empty, Keys.Empty, true);
|
|
33
42
|
}
|
|
34
43
|
|
|
35
44
|
function pipe(
|
|
@@ -38,12 +47,12 @@ abstract contract PipePayable is CommandPayable, PipePayableHook {
|
|
|
38
47
|
bytes calldata steps,
|
|
39
48
|
Budget memory budget
|
|
40
49
|
) internal returns (bytes memory) {
|
|
41
|
-
(Cur memory input,
|
|
50
|
+
(Cur memory input, ) = cursor(steps, 1);
|
|
42
51
|
|
|
43
52
|
while (input.i < input.bound) {
|
|
44
53
|
(uint target, uint value, bytes calldata request) = input.unpackStep();
|
|
45
54
|
uint spend = Values.use(budget, value);
|
|
46
|
-
state =
|
|
55
|
+
state = dispatchCommand(target, account, state, request, spend);
|
|
47
56
|
}
|
|
48
57
|
|
|
49
58
|
settleValue(account, budget);
|
|
@@ -52,11 +61,7 @@ abstract contract PipePayable is CommandPayable, PipePayableHook {
|
|
|
52
61
|
}
|
|
53
62
|
|
|
54
63
|
/// @notice Execute the pipePayable command.
|
|
55
|
-
function pipePayable(
|
|
56
|
-
|
|
57
|
-
) external payable onlyCommand(c.account) returns (bytes memory) {
|
|
58
|
-
if (Accounts.isAdmin(c.account)) revert Accounts.InvalidAccount();
|
|
59
|
-
Budget memory budget = Values.fromMsg();
|
|
60
|
-
return pipe(c.account, c.state, c.request, budget);
|
|
64
|
+
function pipePayable(CommandContext calldata c) external payable onlyCommand(c.account) returns (bytes memory) {
|
|
65
|
+
return pipe(Accounts.ensureNotAdmin(c.account), c.state, c.request, Values.fromMsg());
|
|
61
66
|
}
|
|
62
67
|
}
|
package/commands/Provision.sol
CHANGED
|
@@ -29,7 +29,7 @@ abstract contract ProvisionPayableHook {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/// @title Provision
|
|
32
|
-
/// @notice Command that provisions assets to
|
|
32
|
+
/// @notice Command that provisions assets to peer hosts from ALLOCATION request blocks.
|
|
33
33
|
/// Each request block supplies the target host plus an asset amount; the output is a CUSTODY state stream.
|
|
34
34
|
abstract contract Provision is CommandBase, ProvisionHook {
|
|
35
35
|
string private constant NAME = "provision";
|
|
@@ -37,12 +37,12 @@ abstract contract Provision is CommandBase, ProvisionHook {
|
|
|
37
37
|
uint internal immutable provisionId = commandId(NAME);
|
|
38
38
|
|
|
39
39
|
constructor() {
|
|
40
|
-
emit Command(host, provisionId, NAME, Schemas.Allocation, Keys.Empty, Keys.Custody, false);
|
|
40
|
+
emit Command(host, provisionId, NAME, "1:0:1", Schemas.Allocation, Keys.Empty, Keys.Custody, false);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
function provision(CommandContext calldata c) external onlyCommand(c.account) returns (bytes memory) {
|
|
44
|
-
(Cur memory request, uint
|
|
45
|
-
Writer memory writer = Writers.allocCustodies(
|
|
44
|
+
(Cur memory request, uint groups) = cursor(c.request, 1);
|
|
45
|
+
Writer memory writer = Writers.allocCustodies(groups);
|
|
46
46
|
|
|
47
47
|
while (request.i < request.bound) {
|
|
48
48
|
HostAmount memory allocation = request.unpackAllocationValue();
|
|
@@ -55,7 +55,7 @@ abstract contract Provision is CommandBase, ProvisionHook {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
/// @title ProvisionPayable
|
|
58
|
-
/// @notice Command that provisions assets to
|
|
58
|
+
/// @notice Command that provisions assets to peer hosts from ALLOCATION request blocks.
|
|
59
59
|
/// Each request block supplies the target host plus an asset amount; the output is a CUSTODY state stream.
|
|
60
60
|
/// The hook receives a mutable native-value budget drawn from `msg.value`.
|
|
61
61
|
abstract contract ProvisionPayable is CommandPayable, ProvisionPayableHook {
|
|
@@ -64,14 +64,14 @@ abstract contract ProvisionPayable is CommandPayable, ProvisionPayableHook {
|
|
|
64
64
|
uint internal immutable provisionPayableId = commandId(NAME);
|
|
65
65
|
|
|
66
66
|
constructor() {
|
|
67
|
-
emit Command(host, provisionPayableId, NAME, Schemas.Allocation, Keys.Empty, Keys.Custody, true);
|
|
67
|
+
emit Command(host, provisionPayableId, NAME, "1:0:1", Schemas.Allocation, Keys.Empty, Keys.Custody, true);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
function provisionPayable(
|
|
71
71
|
CommandContext calldata c
|
|
72
72
|
) external payable onlyCommand(c.account) returns (bytes memory) {
|
|
73
|
-
(Cur memory request, uint
|
|
74
|
-
Writer memory writer = Writers.allocCustodies(
|
|
73
|
+
(Cur memory request, uint groups) = cursor(c.request, 1);
|
|
74
|
+
Writer memory writer = Writers.allocCustodies(groups);
|
|
75
75
|
Budget memory budget = Values.fromMsg();
|
|
76
76
|
|
|
77
77
|
while (request.i < request.bound) {
|
package/commands/Transfer.sol
CHANGED
|
@@ -23,7 +23,7 @@ abstract contract Transfer is CommandBase, TransferHook {
|
|
|
23
23
|
uint internal immutable transferId = commandId(NAME);
|
|
24
24
|
|
|
25
25
|
constructor() {
|
|
26
|
-
emit Command(host, transferId, NAME, Schemas.Payout, Keys.Empty, Keys.Empty, false);
|
|
26
|
+
emit Command(host, transferId, NAME, "1:0:0", Schemas.Payout, Keys.Empty, Keys.Empty, false);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/// @notice Override to customize request parsing or batching for transfers.
|
|
@@ -32,7 +32,7 @@ abstract contract Transfer is CommandBase, TransferHook {
|
|
|
32
32
|
/// @param request Full request bytes.
|
|
33
33
|
/// @return Empty bytes (transfers produce no state output).
|
|
34
34
|
function transfer(bytes32 from, bytes calldata request) internal virtual returns (bytes memory) {
|
|
35
|
-
(Cur memory input,
|
|
35
|
+
(Cur memory input, ) = cursor(request, 1);
|
|
36
36
|
Tx memory value;
|
|
37
37
|
value.from = from;
|
|
38
38
|
|
package/commands/Withdraw.sol
CHANGED
|
@@ -21,17 +21,18 @@ abstract contract WithdrawHook {
|
|
|
21
21
|
/// For internal balance credits, use `creditAccount` instead.
|
|
22
22
|
abstract contract Withdraw is CommandBase, WithdrawHook {
|
|
23
23
|
string private constant NAME = "withdraw";
|
|
24
|
+
string private constant REQUEST = string.concat(Schemas.Empty, ";", Schemas.Account, "?");
|
|
24
25
|
|
|
25
26
|
uint internal immutable withdrawId = commandId(NAME);
|
|
26
27
|
|
|
27
28
|
constructor() {
|
|
28
|
-
emit Command(host, withdrawId, NAME,
|
|
29
|
+
emit Command(host, withdrawId, NAME, "0:1:0", REQUEST, Keys.Balance, Keys.Empty, false);
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
function withdraw(
|
|
32
33
|
CommandContext calldata c
|
|
33
34
|
) external onlyCommand(c.account) returns (bytes memory) {
|
|
34
|
-
(Cur memory state,
|
|
35
|
+
(Cur memory state, ) = cursor(c.state, 1);
|
|
35
36
|
bytes32 to = Cursors.resolveAccount(c.request, c.account);
|
|
36
37
|
|
|
37
38
|
while (state.i < state.bound) {
|
|
@@ -3,7 +3,7 @@ pragma solidity ^0.8.33;
|
|
|
3
3
|
|
|
4
4
|
import { CommandBase, CommandContext, Keys } from "../Base.sol";
|
|
5
5
|
import { Cursors, Cur, Schemas } from "../../Cursors.sol";
|
|
6
|
-
import {
|
|
6
|
+
import { AdminEvent } from "../../events/Admin.sol";
|
|
7
7
|
using Cursors for Cur;
|
|
8
8
|
|
|
9
9
|
abstract contract AllowAssetsHook {
|
|
@@ -13,21 +13,21 @@ abstract contract AllowAssetsHook {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
/// @title AllowAssets
|
|
16
|
-
/// @notice
|
|
16
|
+
/// @notice Admin command that permits a list of (asset, meta) pairs via a virtual hook.
|
|
17
17
|
/// Each ASSET block in the request calls `allowAsset`. Only callable by the admin account.
|
|
18
|
-
abstract contract AllowAssets is CommandBase,
|
|
18
|
+
abstract contract AllowAssets is CommandBase, AdminEvent, AllowAssetsHook {
|
|
19
19
|
string private constant NAME = "allowAssets";
|
|
20
20
|
|
|
21
21
|
uint internal immutable allowAssetsId = commandId(NAME);
|
|
22
22
|
|
|
23
23
|
constructor() {
|
|
24
|
-
emit
|
|
24
|
+
emit Admin(host, allowAssetsId, NAME, "1:0:0", Schemas.Asset, Keys.Empty, Keys.Empty, false);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
function allowAssets(
|
|
28
28
|
CommandContext calldata c
|
|
29
29
|
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
30
|
-
(Cur memory request,
|
|
30
|
+
(Cur memory request, ) = cursor(c.request, 1);
|
|
31
31
|
|
|
32
32
|
while (request.i < request.bound) {
|
|
33
33
|
(bytes32 asset, bytes32 meta) = request.unpackAsset();
|
|
@@ -3,7 +3,7 @@ pragma solidity ^0.8.33;
|
|
|
3
3
|
|
|
4
4
|
import {CommandBase, CommandContext, Keys} from "../Base.sol";
|
|
5
5
|
import {Cursors, Cur, Schemas} from "../../Cursors.sol";
|
|
6
|
-
import {
|
|
6
|
+
import {AdminEvent} from "../../events/Admin.sol";
|
|
7
7
|
using Cursors for Cur;
|
|
8
8
|
|
|
9
9
|
abstract contract AllowanceHook {
|
|
@@ -11,30 +11,30 @@ abstract contract AllowanceHook {
|
|
|
11
11
|
/// Called once per ALLOWANCE block in the request. Implementations decide
|
|
12
12
|
/// how the allowance is represented, e.g. ERC-20 approval, an internal cap,
|
|
13
13
|
/// or another host-specific authorization record.
|
|
14
|
-
/// @param
|
|
14
|
+
/// @param peer Host node receiving the allowed cap.
|
|
15
15
|
/// @param asset Asset identifier.
|
|
16
16
|
/// @param meta Asset metadata slot.
|
|
17
17
|
/// @param amount Allowed cap amount.
|
|
18
|
-
function allowance(uint
|
|
18
|
+
function allowance(uint peer, bytes32 asset, bytes32 meta, uint amount) internal virtual;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/// @title Allowance
|
|
22
|
-
/// @notice
|
|
22
|
+
/// @notice Admin command that applies cross-host allowance entries via a virtual hook.
|
|
23
23
|
/// Each ALLOWANCE block grants or updates a host-scoped asset cap. Only callable by the admin account.
|
|
24
|
-
abstract contract Allowance is CommandBase,
|
|
24
|
+
abstract contract Allowance is CommandBase, AdminEvent, AllowanceHook {
|
|
25
25
|
string private constant NAME = "allowance";
|
|
26
26
|
uint internal immutable allowanceId = commandId(NAME);
|
|
27
27
|
|
|
28
28
|
constructor() {
|
|
29
|
-
emit
|
|
29
|
+
emit Admin(host, allowanceId, NAME, "1:0:0", Schemas.Allowance, Keys.Empty, Keys.Empty, false);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
function allowance(CommandContext calldata c) external onlyAdmin(c.account) returns (bytes memory) {
|
|
33
|
-
(Cur memory request,
|
|
33
|
+
(Cur memory request, ) = cursor(c.request, 1);
|
|
34
34
|
|
|
35
35
|
while (request.i < request.bound) {
|
|
36
|
-
(uint
|
|
37
|
-
allowance(
|
|
36
|
+
(uint peer, bytes32 asset, bytes32 meta, uint amount) = request.unpackAllowance();
|
|
37
|
+
allowance(peer, asset, meta, amount);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
request.complete();
|
|
@@ -3,26 +3,26 @@ pragma solidity ^0.8.33;
|
|
|
3
3
|
|
|
4
4
|
import { CommandBase, CommandContext, Keys } from "../Base.sol";
|
|
5
5
|
import { Cursors, Cur, Schemas } from "../../Cursors.sol";
|
|
6
|
-
import {
|
|
6
|
+
import { AdminEvent } from "../../events/Admin.sol";
|
|
7
7
|
using Cursors for Cur;
|
|
8
8
|
|
|
9
9
|
/// @title Authorize
|
|
10
|
-
/// @notice
|
|
10
|
+
/// @notice Admin command that grants authorization to a list of node IDs.
|
|
11
11
|
/// Each NODE block in the request is authorized on the host.
|
|
12
12
|
/// Only callable by the admin account.
|
|
13
|
-
abstract contract Authorize is CommandBase,
|
|
13
|
+
abstract contract Authorize is CommandBase, AdminEvent {
|
|
14
14
|
string private constant NAME = "authorize";
|
|
15
15
|
|
|
16
16
|
uint internal immutable authorizeId = commandId(NAME);
|
|
17
17
|
|
|
18
18
|
constructor() {
|
|
19
|
-
emit
|
|
19
|
+
emit Admin(host, authorizeId, NAME, "1:0:0", Schemas.Node, Keys.Empty, Keys.Empty, false);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
function authorize(
|
|
23
23
|
CommandContext calldata c
|
|
24
24
|
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
25
|
-
(Cur memory request,
|
|
25
|
+
(Cur memory request, ) = cursor(c.request, 1);
|
|
26
26
|
|
|
27
27
|
while (request.i < request.bound) {
|
|
28
28
|
uint node = request.unpackNode();
|
|
@@ -3,7 +3,7 @@ pragma solidity ^0.8.33;
|
|
|
3
3
|
|
|
4
4
|
import { CommandBase, CommandContext, Keys } from "../Base.sol";
|
|
5
5
|
import { Cursors, Cur, Schemas } from "../../Cursors.sol";
|
|
6
|
-
import {
|
|
6
|
+
import { AdminEvent } from "../../events/Admin.sol";
|
|
7
7
|
using Cursors for Cur;
|
|
8
8
|
|
|
9
9
|
abstract contract DenyAssetsHook {
|
|
@@ -13,21 +13,21 @@ abstract contract DenyAssetsHook {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
/// @title DenyAssets
|
|
16
|
-
/// @notice
|
|
16
|
+
/// @notice Admin command that blocks a list of (asset, meta) pairs via a virtual hook.
|
|
17
17
|
/// Each ASSET block in the request calls `denyAsset`. Only callable by the admin account.
|
|
18
|
-
abstract contract DenyAssets is CommandBase,
|
|
18
|
+
abstract contract DenyAssets is CommandBase, AdminEvent, DenyAssetsHook {
|
|
19
19
|
string private constant NAME = "denyAssets";
|
|
20
20
|
|
|
21
21
|
uint internal immutable denyAssetsId = commandId(NAME);
|
|
22
22
|
|
|
23
23
|
constructor() {
|
|
24
|
-
emit
|
|
24
|
+
emit Admin(host, denyAssetsId, NAME, "1:0:0", Schemas.Asset, Keys.Empty, Keys.Empty, false);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
function denyAssets(
|
|
28
28
|
CommandContext calldata c
|
|
29
29
|
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
30
|
-
(Cur memory request,
|
|
30
|
+
(Cur memory request, ) = cursor(c.request, 1);
|
|
31
31
|
|
|
32
32
|
while (request.i < request.bound) {
|
|
33
33
|
(bytes32 asset, bytes32 meta) = request.unpackAsset();
|
|
@@ -3,7 +3,7 @@ pragma solidity ^0.8.33;
|
|
|
3
3
|
|
|
4
4
|
import { CommandBase, CommandContext, Keys } from "../Base.sol";
|
|
5
5
|
import { Cursors, Cur } from "../../Cursors.sol";
|
|
6
|
-
import {
|
|
6
|
+
import { AdminEvent } from "../../events/Admin.sol";
|
|
7
7
|
|
|
8
8
|
using Cursors for Cur;
|
|
9
9
|
|
|
@@ -14,15 +14,15 @@ abstract contract DestroyHook {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/// @title Destroy
|
|
17
|
-
/// @notice
|
|
17
|
+
/// @notice Admin command that runs host teardown logic via a virtual hook.
|
|
18
18
|
/// The full request is passed to `destroy` as a cursor. Only callable by the admin account.
|
|
19
|
-
abstract contract Destroy is CommandBase,
|
|
19
|
+
abstract contract Destroy is CommandBase, AdminEvent, DestroyHook {
|
|
20
20
|
string private constant NAME = "destroy";
|
|
21
21
|
|
|
22
22
|
uint internal immutable destroyId = commandId(NAME);
|
|
23
23
|
|
|
24
24
|
constructor(string memory input) {
|
|
25
|
-
emit
|
|
25
|
+
emit Admin(host, destroyId, NAME, "1:0:0", input, Keys.Empty, Keys.Empty, false);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
function destroy(
|
|
@@ -3,27 +3,27 @@ pragma solidity ^0.8.33;
|
|
|
3
3
|
|
|
4
4
|
import {CommandContext, CommandPayable, Keys} from "../Base.sol";
|
|
5
5
|
import {Cursors, Cur, Schemas} from "../../Cursors.sol";
|
|
6
|
-
import {
|
|
6
|
+
import {AdminEvent} from "../../events/Admin.sol";
|
|
7
7
|
import {Budget, Values} from "../../utils/Value.sol";
|
|
8
8
|
import {Ids} from "../../utils/Ids.sol";
|
|
9
9
|
|
|
10
10
|
using Cursors for Cur;
|
|
11
11
|
|
|
12
12
|
/// @title ExecutePayable
|
|
13
|
-
/// @notice
|
|
13
|
+
/// @notice Admin command that forwards raw calldata to one or more target nodes.
|
|
14
14
|
/// Each CALL block specifies a target node ID, native value, and raw calldata payload.
|
|
15
15
|
/// Only callable by the admin account.
|
|
16
|
-
abstract contract ExecutePayable is CommandPayable,
|
|
16
|
+
abstract contract ExecutePayable is CommandPayable, AdminEvent {
|
|
17
17
|
string private constant NAME = "executePayable";
|
|
18
18
|
|
|
19
19
|
uint internal immutable executePayableId = commandId(NAME);
|
|
20
20
|
|
|
21
21
|
constructor() {
|
|
22
|
-
emit
|
|
22
|
+
emit Admin(host, executePayableId, NAME, "1:0:0", Schemas.Call, Keys.Empty, Keys.Empty, true);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
function executePayable(CommandContext calldata c) external payable onlyAdmin(c.account) returns (bytes memory) {
|
|
26
|
-
(Cur memory request,
|
|
26
|
+
(Cur memory request, ) = cursor(c.request, 1);
|
|
27
27
|
Budget memory budget = Values.fromMsg();
|
|
28
28
|
|
|
29
29
|
while (request.i < request.bound) {
|
|
@@ -3,7 +3,7 @@ pragma solidity ^0.8.33;
|
|
|
3
3
|
|
|
4
4
|
import { CommandBase, CommandContext, Keys } from "../Base.sol";
|
|
5
5
|
import { Cursors, Cur } from "../../Cursors.sol";
|
|
6
|
-
import {
|
|
6
|
+
import { AdminEvent } from "../../events/Admin.sol";
|
|
7
7
|
|
|
8
8
|
using Cursors for Cur;
|
|
9
9
|
|
|
@@ -14,15 +14,15 @@ abstract contract InitHook {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/// @title Init
|
|
17
|
-
/// @notice
|
|
17
|
+
/// @notice Admin command that runs host initialization logic via a virtual hook.
|
|
18
18
|
/// The full request is passed to `init` as a cursor. Only callable by the admin account.
|
|
19
|
-
abstract contract Init is CommandBase,
|
|
19
|
+
abstract contract Init is CommandBase, AdminEvent, InitHook {
|
|
20
20
|
string private constant NAME = "init";
|
|
21
21
|
|
|
22
22
|
uint internal immutable initId = commandId(NAME);
|
|
23
23
|
|
|
24
24
|
constructor(string memory input) {
|
|
25
|
-
emit
|
|
25
|
+
emit Admin(host, initId, NAME, "1:0:0", input, Keys.Empty, Keys.Empty, false);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
function init(
|
|
@@ -3,26 +3,26 @@ pragma solidity ^0.8.33;
|
|
|
3
3
|
|
|
4
4
|
import { CommandBase, CommandContext, Keys } from "../Base.sol";
|
|
5
5
|
import { Cursors, Cur, Schemas } from "../../Cursors.sol";
|
|
6
|
-
import {
|
|
6
|
+
import { AdminEvent } from "../../events/Admin.sol";
|
|
7
7
|
using Cursors for Cur;
|
|
8
8
|
|
|
9
9
|
/// @title Unauthorize
|
|
10
|
-
/// @notice
|
|
10
|
+
/// @notice Admin command that revokes authorization from a list of node IDs.
|
|
11
11
|
/// Each NODE block in the request is deauthorized on the host.
|
|
12
12
|
/// Only callable by the admin account.
|
|
13
|
-
abstract contract Unauthorize is CommandBase,
|
|
13
|
+
abstract contract Unauthorize is CommandBase, AdminEvent {
|
|
14
14
|
string private constant NAME = "unauthorize";
|
|
15
15
|
|
|
16
16
|
uint internal immutable unauthorizeId = commandId(NAME);
|
|
17
17
|
|
|
18
18
|
constructor() {
|
|
19
|
-
emit
|
|
19
|
+
emit Admin(host, unauthorizeId, NAME, "1:0:0", Schemas.Node, Keys.Empty, Keys.Empty, false);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
function unauthorize(
|
|
23
23
|
CommandContext calldata c
|
|
24
24
|
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
25
|
-
(Cur memory request,
|
|
25
|
+
(Cur memory request, ) = cursor(c.request, 1);
|
|
26
26
|
|
|
27
27
|
while (request.i < request.bound) {
|
|
28
28
|
uint node = request.unpackNode();
|
package/core/Access.sol
CHANGED
|
@@ -12,7 +12,7 @@ import {addrOr} from "../utils/Utils.sol";
|
|
|
12
12
|
/// Tracks an immutable trusted commander, the host's own node ID, and a
|
|
13
13
|
/// mapping of externally trusted node IDs. Inbound trust is host-based:
|
|
14
14
|
/// trusted hosts, the commander, and this contract itself may interact
|
|
15
|
-
/// with the host through the guarded command and
|
|
15
|
+
/// with the host through the guarded command and peer entrypoints.
|
|
16
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.
|
|
@@ -69,7 +69,7 @@ abstract contract AccessControl is RootZeroContext, AccessEvent {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
/// @notice Assert that `caller` is trusted and return it.
|
|
72
|
-
/// Used by command and
|
|
72
|
+
/// Used by command and peer modifiers to gate execution to authorized senders.
|
|
73
73
|
/// @param caller Address to validate.
|
|
74
74
|
/// @return The same `caller` value if trusted.
|
|
75
75
|
function enforceCaller(address caller) internal view returns (address) {
|
package/core/Calls.sol
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
4
|
import {AccessControl} from "./Access.sol";
|
|
5
|
+
import {CommandContext} from "../commands/Base.sol";
|
|
5
6
|
import {Ids} from "../utils/Ids.sol";
|
|
6
7
|
|
|
7
8
|
/// @dev Emitted when a trusted inter-node call fails.
|
|
@@ -53,7 +54,8 @@ abstract contract NodeCalls is AccessControl {
|
|
|
53
54
|
/// @param data Encoded calldata to send.
|
|
54
55
|
/// @return out Return data from the successful call.
|
|
55
56
|
function callTo(uint node, uint value, bytes memory data) internal returns (bytes memory out) {
|
|
56
|
-
|
|
57
|
+
ensureTrusted(node);
|
|
58
|
+
address addr = Ids.nodeAddr(node);
|
|
57
59
|
return callAddr(addr, value, data);
|
|
58
60
|
}
|
|
59
61
|
|
|
@@ -64,7 +66,19 @@ abstract contract NodeCalls is AccessControl {
|
|
|
64
66
|
/// @param data Encoded calldata to send.
|
|
65
67
|
/// @return out Return data from the successful query.
|
|
66
68
|
function queryTo(uint node, bytes memory data) internal view returns (bytes memory out) {
|
|
67
|
-
|
|
69
|
+
ensureTrusted(node);
|
|
70
|
+
address addr = Ids.nodeAddr(node);
|
|
68
71
|
return queryAddr(addr, data);
|
|
69
72
|
}
|
|
73
|
+
|
|
74
|
+
/// @notice Encode and call a trusted command node.
|
|
75
|
+
/// @param ctx Command execution context.
|
|
76
|
+
/// @param cid Command node ID embedding the target selector.
|
|
77
|
+
/// @param value Native value to forward in wei.
|
|
78
|
+
/// @return Decoded command output block stream.
|
|
79
|
+
function callCommand(CommandContext memory ctx, uint cid, uint value) internal returns (bytes memory) {
|
|
80
|
+
bytes4 selector = Ids.commandSelector(cid);
|
|
81
|
+
bytes memory data = abi.encodeWithSelector(selector, ctx);
|
|
82
|
+
return abi.decode(callTo(cid, value, data), (bytes));
|
|
83
|
+
}
|
|
70
84
|
}
|