@rootzero/contracts 0.9.7 → 0.9.9
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/Core.sol +3 -3
- package/Endpoints.sol +1 -1
- package/Events.sol +4 -3
- package/Utils.sol +2 -1
- package/blocks/Cursors.sol +117 -155
- package/blocks/Keys.sol +4 -6
- package/blocks/Schema.sol +14 -8
- package/commands/Burn.sol +4 -4
- package/commands/Credit.sol +6 -9
- package/commands/Debit.sol +4 -4
- package/commands/Deposit.sol +8 -8
- package/commands/Payout.sol +45 -0
- package/commands/Provision.sol +8 -8
- package/commands/Withdraw.sol +7 -9
- package/commands/admin/AllowAssets.sol +4 -4
- package/commands/admin/Allowance.sol +4 -4
- package/commands/admin/Appoint.sol +4 -4
- package/commands/admin/Authorize.sol +4 -4
- package/commands/admin/DenyAssets.sol +4 -4
- package/commands/admin/Destroy.sol +2 -2
- package/commands/admin/Dismiss.sol +4 -4
- package/commands/admin/Execute.sol +4 -4
- package/commands/admin/Init.sol +2 -2
- package/commands/admin/Unauthorize.sol +4 -4
- package/core/Access.sol +2 -2
- package/core/Host.sol +4 -2
- package/core/Pipeline.sol +3 -3
- package/core/Runtime.sol +14 -0
- package/core/Types.sol +1 -1
- package/docs/Schema.md +0 -1
- package/events/Admin.sol +10 -7
- package/events/Command.sol +10 -7
- package/events/Locked.sol +21 -0
- package/events/Peer.sol +5 -5
- package/events/Position.sol +4 -2
- package/events/Query.sol +2 -4
- package/events/Received.sol +4 -3
- package/events/Spent.sol +4 -3
- package/events/Transfer.sol +22 -0
- package/events/Unlocked.sol +21 -0
- package/guards/Revoke.sol +3 -3
- package/package.json +1 -1
- package/peer/AllowAssets.sol +3 -3
- package/peer/Allowance.sol +3 -3
- package/peer/BalancePull.sol +3 -3
- package/peer/DenyAssets.sol +3 -3
- package/peer/Pipe.sol +3 -3
- package/peer/Settle.sol +11 -8
- package/queries/Assets.sol +3 -3
- package/queries/Balances.sol +3 -3
- package/queries/Base.sol +2 -2
- package/queries/Positions.sol +3 -3
- package/utils/Accounts.sol +8 -0
- package/utils/Actions.sol +18 -0
- package/commands/Transfer.sol +0 -54
- package/core/Context.sol +0 -47
- package/events/Collateral.sol +0 -24
- package/events/Contexts.sol +0 -12
- package/events/Debt.sol +0 -25
package/commands/Deposit.sol
CHANGED
|
@@ -42,22 +42,22 @@ abstract contract Deposit is CommandBase, DepositHook {
|
|
|
42
42
|
uint internal immutable depositId = commandId(NAME);
|
|
43
43
|
|
|
44
44
|
constructor() {
|
|
45
|
-
emit Command(host, depositId, NAME, "1:0:1", Schemas.Amount, Keys.Empty, Keys.Balance, false);
|
|
45
|
+
emit Command(host, depositId, NAME, "1:0:1", Schemas.Amount, Keys.Empty, Keys.Balance, false, false);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
function deposit(
|
|
49
49
|
CommandContext calldata c
|
|
50
50
|
) external onlyCommand returns (bytes memory) {
|
|
51
|
-
(Cur memory request, uint groups) =
|
|
51
|
+
(Cur memory request, uint groups) = Cursors.first(c.request, 1);
|
|
52
52
|
Writer memory writer = Writers.allocBalances(groups);
|
|
53
53
|
|
|
54
|
-
while (request.i < request.
|
|
54
|
+
while (request.i < request.len) {
|
|
55
55
|
(bytes32 asset, bytes32 meta, uint amount) = request.unpackAmount();
|
|
56
56
|
deposit(c.account, asset, meta, amount);
|
|
57
57
|
writer.appendBalance(asset, meta, amount);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
request.
|
|
60
|
+
request.complete();
|
|
61
61
|
return writer.finish();
|
|
62
62
|
}
|
|
63
63
|
}
|
|
@@ -71,24 +71,24 @@ abstract contract DepositPayable is CommandBase, Payable, DepositPayableHook {
|
|
|
71
71
|
uint internal immutable depositPayableId = commandId(NAME);
|
|
72
72
|
|
|
73
73
|
constructor() {
|
|
74
|
-
emit Command(host, depositPayableId, NAME, "1:0:1", Schemas.Amount, Keys.Empty, Keys.Balance, true);
|
|
74
|
+
emit Command(host, depositPayableId, NAME, "1:0:1", Schemas.Amount, Keys.Empty, Keys.Balance, false, true);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
function depositPayable(
|
|
78
78
|
CommandContext calldata c
|
|
79
79
|
) external payable onlyCommand returns (bytes memory) {
|
|
80
|
-
(Cur memory request, uint groups) =
|
|
80
|
+
(Cur memory request, uint groups) = Cursors.first(c.request, 1);
|
|
81
81
|
Writer memory writer = Writers.allocBalances(groups);
|
|
82
82
|
Budget memory budget = valueBudget();
|
|
83
83
|
|
|
84
|
-
while (request.i < request.
|
|
84
|
+
while (request.i < request.len) {
|
|
85
85
|
(bytes32 asset, bytes32 meta, uint amount) = request.unpackAmount();
|
|
86
86
|
deposit(c.account, asset, meta, amount, budget);
|
|
87
87
|
writer.appendBalance(asset, meta, amount);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
settleValue(c.account, budget);
|
|
91
|
-
request.
|
|
91
|
+
request.complete();
|
|
92
92
|
return writer.finish();
|
|
93
93
|
}
|
|
94
94
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
pragma solidity ^0.8.33;
|
|
3
|
+
|
|
4
|
+
import {CommandContext, CommandBase, Keys} from "./Base.sol";
|
|
5
|
+
import {Cursors, Cur, Schemas} from "../Cursors.sol";
|
|
6
|
+
|
|
7
|
+
using Cursors for Cur;
|
|
8
|
+
|
|
9
|
+
abstract contract PayoutHook {
|
|
10
|
+
/// @notice Override to pay `amount` from `account` to `to`.
|
|
11
|
+
/// Called once per paired BALANCE state block and ACCOUNT request block.
|
|
12
|
+
/// @param account Source account identifier.
|
|
13
|
+
/// @param to Destination account identifier.
|
|
14
|
+
/// @param asset Asset identifier.
|
|
15
|
+
/// @param meta Asset metadata slot.
|
|
16
|
+
/// @param amount Amount to pay out.
|
|
17
|
+
function payout(bytes32 account, bytes32 to, bytes32 asset, bytes32 meta, uint amount) internal virtual;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/// @title Payout
|
|
21
|
+
/// @notice Command that sinks BALANCE state blocks to matching ACCOUNT request blocks.
|
|
22
|
+
/// Each BALANCE block is paired with one ACCOUNT block at the same position.
|
|
23
|
+
abstract contract Payout is CommandBase, PayoutHook {
|
|
24
|
+
string private constant NAME = "payout";
|
|
25
|
+
|
|
26
|
+
uint internal immutable payoutId = commandId(NAME);
|
|
27
|
+
|
|
28
|
+
constructor() {
|
|
29
|
+
emit Command(host, payoutId, NAME, "1:1:0", Schemas.Account, Keys.Balance, Keys.Empty, false, false);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function payout(CommandContext calldata c) external onlyCommand returns (bytes memory) {
|
|
33
|
+
(Cur memory state, uint groups) = Cursors.first(c.state, 1);
|
|
34
|
+
Cur memory request = Cursors.first(c.request, 1, groups);
|
|
35
|
+
|
|
36
|
+
while (state.i < state.len) {
|
|
37
|
+
(bytes32 asset, bytes32 meta, uint amount) = state.unpackBalance();
|
|
38
|
+
bytes32 to = request.unpackAccount();
|
|
39
|
+
payout(c.account, to, asset, meta, amount);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
state.complete();
|
|
43
|
+
return "";
|
|
44
|
+
}
|
|
45
|
+
}
|
package/commands/Provision.sol
CHANGED
|
@@ -38,20 +38,20 @@ abstract contract Provision is CommandBase, ProvisionHook {
|
|
|
38
38
|
uint internal immutable provisionId = commandId(NAME);
|
|
39
39
|
|
|
40
40
|
constructor() {
|
|
41
|
-
emit Command(host, provisionId, NAME, "1:0:1", Schemas.Allocation, Keys.Empty, Keys.Custody, false);
|
|
41
|
+
emit Command(host, provisionId, NAME, "1:0:1", Schemas.Allocation, Keys.Empty, Keys.Custody, false, false);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
function provision(CommandContext calldata c) external onlyCommand returns (bytes memory) {
|
|
45
|
-
(Cur memory request, uint groups) =
|
|
45
|
+
(Cur memory request, uint groups) = Cursors.first(c.request, 1);
|
|
46
46
|
Writer memory writer = Writers.allocCustodies(groups);
|
|
47
47
|
|
|
48
|
-
while (request.i < request.
|
|
48
|
+
while (request.i < request.len) {
|
|
49
49
|
HostAmount memory allocation = request.unpackAllocationValue();
|
|
50
50
|
provision(c.account, allocation);
|
|
51
51
|
writer.appendCustody(allocation);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
request.
|
|
54
|
+
request.complete();
|
|
55
55
|
return writer.finish();
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -66,24 +66,24 @@ abstract contract ProvisionPayable is CommandBase, Payable, ProvisionPayableHook
|
|
|
66
66
|
uint internal immutable provisionPayableId = commandId(NAME);
|
|
67
67
|
|
|
68
68
|
constructor() {
|
|
69
|
-
emit Command(host, provisionPayableId, NAME, "1:0:1", Schemas.Allocation, Keys.Empty, Keys.Custody, true);
|
|
69
|
+
emit Command(host, provisionPayableId, NAME, "1:0:1", Schemas.Allocation, Keys.Empty, Keys.Custody, false, true);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
function provisionPayable(
|
|
73
73
|
CommandContext calldata c
|
|
74
74
|
) external payable onlyCommand returns (bytes memory) {
|
|
75
|
-
(Cur memory request, uint groups) =
|
|
75
|
+
(Cur memory request, uint groups) = Cursors.first(c.request, 1);
|
|
76
76
|
Writer memory writer = Writers.allocCustodies(groups);
|
|
77
77
|
Budget memory budget = valueBudget();
|
|
78
78
|
|
|
79
|
-
while (request.i < request.
|
|
79
|
+
while (request.i < request.len) {
|
|
80
80
|
HostAmount memory allocation = request.unpackAllocationValue();
|
|
81
81
|
provision(c.account, allocation, budget);
|
|
82
82
|
writer.appendCustody(allocation);
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
settleValue(c.account, budget);
|
|
86
|
-
request.
|
|
86
|
+
request.complete();
|
|
87
87
|
return writer.finish();
|
|
88
88
|
}
|
|
89
89
|
}
|
package/commands/Withdraw.sol
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
4
|
import { CommandContext, CommandBase, Keys } from "./Base.sol";
|
|
5
|
-
import { Cursors, Cur
|
|
5
|
+
import { Cursors, Cur } from "../Cursors.sol";
|
|
6
6
|
using Cursors for Cur;
|
|
7
7
|
|
|
8
8
|
abstract contract WithdrawHook {
|
|
9
9
|
/// @notice Override to send funds to `account`.
|
|
10
10
|
/// Called once per BALANCE block in state.
|
|
11
|
-
/// @param account Destination account identifier
|
|
11
|
+
/// @param account Destination account identifier.
|
|
12
12
|
/// @param asset Asset identifier.
|
|
13
13
|
/// @param meta Asset metadata slot.
|
|
14
14
|
/// @param amount Amount to deliver.
|
|
@@ -21,26 +21,24 @@ 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.Unit, ", maybe ", Schemas.Account);
|
|
25
24
|
|
|
26
25
|
uint internal immutable withdrawId = commandId(NAME);
|
|
27
26
|
|
|
28
27
|
constructor() {
|
|
29
|
-
emit Command(host, withdrawId, NAME, "0:1:0",
|
|
28
|
+
emit Command(host, withdrawId, NAME, "0:1:0", "", Keys.Balance, Keys.Empty, false, false);
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
function withdraw(
|
|
33
32
|
CommandContext calldata c
|
|
34
33
|
) external onlyCommand returns (bytes memory) {
|
|
35
|
-
(Cur memory state, ) =
|
|
36
|
-
bytes32 to = Cursors.resolveAccount(c.request, c.account);
|
|
34
|
+
(Cur memory state, ) = Cursors.first(c.state, 1);
|
|
37
35
|
|
|
38
|
-
while (state.i < state.
|
|
36
|
+
while (state.i < state.len) {
|
|
39
37
|
(bytes32 asset, bytes32 meta, uint amount) = state.unpackBalance();
|
|
40
|
-
withdraw(
|
|
38
|
+
withdraw(c.account, asset, meta, amount);
|
|
41
39
|
}
|
|
42
40
|
|
|
43
|
-
state.
|
|
41
|
+
state.complete();
|
|
44
42
|
return "";
|
|
45
43
|
}
|
|
46
44
|
}
|
|
@@ -21,20 +21,20 @@ abstract contract AllowAssets is CommandBase, AdminEvent, AllowAssetsHook {
|
|
|
21
21
|
uint internal immutable allowAssetsId = commandId(NAME);
|
|
22
22
|
|
|
23
23
|
constructor() {
|
|
24
|
-
emit Admin(host, allowAssetsId, NAME, "1:0:0", Schemas.Asset, Keys.Empty, Keys.Empty, false);
|
|
24
|
+
emit Admin(host, allowAssetsId, NAME, "1:0:0", Schemas.Asset, Keys.Empty, Keys.Empty, false, 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, ) = Cursors.first(c.request, 1);
|
|
31
31
|
|
|
32
|
-
while (request.i < request.
|
|
32
|
+
while (request.i < request.len) {
|
|
33
33
|
(bytes32 asset, bytes32 meta) = request.unpackAsset();
|
|
34
34
|
allowAsset(asset, meta);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
request.
|
|
37
|
+
request.complete();
|
|
38
38
|
return "";
|
|
39
39
|
}
|
|
40
40
|
}
|
|
@@ -26,18 +26,18 @@ abstract contract Allowance is CommandBase, AdminEvent, AllowanceHook {
|
|
|
26
26
|
uint internal immutable allowanceId = commandId(NAME);
|
|
27
27
|
|
|
28
28
|
constructor() {
|
|
29
|
-
emit Admin(host, allowanceId, NAME, "1:0:0", Schemas.Allowance, Keys.Empty, Keys.Empty, false);
|
|
29
|
+
emit Admin(host, allowanceId, NAME, "1:0:0", Schemas.Allowance, Keys.Empty, Keys.Empty, false, 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, ) = Cursors.first(c.request, 1);
|
|
34
34
|
|
|
35
|
-
while (request.i < request.
|
|
35
|
+
while (request.i < request.len) {
|
|
36
36
|
(uint peer, bytes32 asset, bytes32 meta, uint amount) = request.unpackAllowance();
|
|
37
37
|
allowance(peer, asset, meta, amount);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
request.
|
|
40
|
+
request.complete();
|
|
41
41
|
return "";
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -16,20 +16,20 @@ abstract contract Appoint is CommandBase, AdminEvent {
|
|
|
16
16
|
uint internal immutable appointId = commandId(NAME);
|
|
17
17
|
|
|
18
18
|
constructor() {
|
|
19
|
-
emit Admin(host, appointId, NAME, "1:0:0", Schemas.Account, Keys.Empty, Keys.Empty, false);
|
|
19
|
+
emit Admin(host, appointId, NAME, "1:0:0", Schemas.Account, Keys.Empty, Keys.Empty, false, false);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
function appoint(
|
|
23
23
|
CommandContext calldata c
|
|
24
24
|
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
25
|
-
(Cur memory request, ) =
|
|
25
|
+
(Cur memory request, ) = Cursors.first(c.request, 1);
|
|
26
26
|
|
|
27
|
-
while (request.i < request.
|
|
27
|
+
while (request.i < request.len) {
|
|
28
28
|
bytes32 account = request.unpackAccount();
|
|
29
29
|
setGuardian(account, true);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
request.
|
|
32
|
+
request.complete();
|
|
33
33
|
return "";
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -16,20 +16,20 @@ abstract contract Authorize is CommandBase, AdminEvent {
|
|
|
16
16
|
uint internal immutable authorizeId = commandId(NAME);
|
|
17
17
|
|
|
18
18
|
constructor() {
|
|
19
|
-
emit Admin(host, authorizeId, NAME, "1:0:0", Schemas.Node, Keys.Empty, Keys.Empty, false);
|
|
19
|
+
emit Admin(host, authorizeId, NAME, "1:0:0", Schemas.Node, Keys.Empty, Keys.Empty, false, 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, ) = Cursors.first(c.request, 1);
|
|
26
26
|
|
|
27
|
-
while (request.i < request.
|
|
27
|
+
while (request.i < request.len) {
|
|
28
28
|
uint node = request.unpackNode();
|
|
29
29
|
setNode(node, true);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
request.
|
|
32
|
+
request.complete();
|
|
33
33
|
return "";
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -21,20 +21,20 @@ abstract contract DenyAssets is CommandBase, AdminEvent, DenyAssetsHook {
|
|
|
21
21
|
uint internal immutable denyAssetsId = commandId(NAME);
|
|
22
22
|
|
|
23
23
|
constructor() {
|
|
24
|
-
emit Admin(host, denyAssetsId, NAME, "1:0:0", Schemas.Asset, Keys.Empty, Keys.Empty, false);
|
|
24
|
+
emit Admin(host, denyAssetsId, NAME, "1:0:0", Schemas.Asset, Keys.Empty, Keys.Empty, false, 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, ) = Cursors.first(c.request, 1);
|
|
31
31
|
|
|
32
|
-
while (request.i < request.
|
|
32
|
+
while (request.i < request.len) {
|
|
33
33
|
(bytes32 asset, bytes32 meta) = request.unpackAsset();
|
|
34
34
|
denyAsset(asset, meta);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
request.
|
|
37
|
+
request.complete();
|
|
38
38
|
return "";
|
|
39
39
|
}
|
|
40
40
|
}
|
|
@@ -22,13 +22,13 @@ abstract contract Destroy is CommandBase, AdminEvent, DestroyHook {
|
|
|
22
22
|
uint internal immutable destroyId = commandId(NAME);
|
|
23
23
|
|
|
24
24
|
constructor(string memory input) {
|
|
25
|
-
emit Admin(host, destroyId, NAME, "1:0:0", input, Keys.Empty, Keys.Empty, false);
|
|
25
|
+
emit Admin(host, destroyId, NAME, "1:0:0", input, Keys.Empty, Keys.Empty, false, false);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
function destroy(
|
|
29
29
|
CommandContext calldata c
|
|
30
30
|
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
31
|
-
Cur memory input =
|
|
31
|
+
Cur memory input = Cursors.open(c.request);
|
|
32
32
|
destroy(input);
|
|
33
33
|
return "";
|
|
34
34
|
}
|
|
@@ -16,20 +16,20 @@ abstract contract Dismiss is CommandBase, AdminEvent {
|
|
|
16
16
|
uint internal immutable dismissId = commandId(NAME);
|
|
17
17
|
|
|
18
18
|
constructor() {
|
|
19
|
-
emit Admin(host, dismissId, NAME, "1:0:0", Schemas.Account, Keys.Empty, Keys.Empty, false);
|
|
19
|
+
emit Admin(host, dismissId, NAME, "1:0:0", Schemas.Account, Keys.Empty, Keys.Empty, false, false);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
function dismiss(
|
|
23
23
|
CommandContext calldata c
|
|
24
24
|
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
25
|
-
(Cur memory request, ) =
|
|
25
|
+
(Cur memory request, ) = Cursors.first(c.request, 1);
|
|
26
26
|
|
|
27
|
-
while (request.i < request.
|
|
27
|
+
while (request.i < request.len) {
|
|
28
28
|
bytes32 account = request.unpackAccount();
|
|
29
29
|
setGuardian(account, false);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
request.
|
|
32
|
+
request.complete();
|
|
33
33
|
return "";
|
|
34
34
|
}
|
|
35
35
|
}
|
|
@@ -20,20 +20,20 @@ abstract contract ExecutePayable is CommandBase, Payable, AdminEvent {
|
|
|
20
20
|
uint internal immutable executePayableId = commandId(NAME);
|
|
21
21
|
|
|
22
22
|
constructor() {
|
|
23
|
-
emit Admin(host, executePayableId, NAME, "1:0:0", Schemas.Call, Keys.Empty, Keys.Empty, true);
|
|
23
|
+
emit Admin(host, executePayableId, NAME, "1:0:0", Schemas.Call, Keys.Empty, Keys.Empty, false, true);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
function executePayable(CommandContext calldata c) external payable onlyAdmin(c.account) returns (bytes memory) {
|
|
27
|
-
(Cur memory request, ) =
|
|
27
|
+
(Cur memory request, ) = Cursors.first(c.request, 1);
|
|
28
28
|
Budget memory budget = valueBudget();
|
|
29
29
|
|
|
30
|
-
while (request.i < request.
|
|
30
|
+
while (request.i < request.len) {
|
|
31
31
|
(uint target, uint value, bytes calldata data) = request.unpackCall();
|
|
32
32
|
address addr = Ids.nodeAddr(target);
|
|
33
33
|
callAddr(addr, useValue(budget, value), data);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
request.
|
|
36
|
+
request.complete();
|
|
37
37
|
settleValue(c.account, budget);
|
|
38
38
|
return "";
|
|
39
39
|
}
|
package/commands/admin/Init.sol
CHANGED
|
@@ -22,13 +22,13 @@ abstract contract Init is CommandBase, AdminEvent, InitHook {
|
|
|
22
22
|
uint internal immutable initId = commandId(NAME);
|
|
23
23
|
|
|
24
24
|
constructor(string memory input) {
|
|
25
|
-
emit Admin(host, initId, NAME, "1:0:0", input, Keys.Empty, Keys.Empty, false);
|
|
25
|
+
emit Admin(host, initId, NAME, "1:0:0", input, Keys.Empty, Keys.Empty, false, false);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
function init(
|
|
29
29
|
CommandContext calldata c
|
|
30
30
|
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
31
|
-
Cur memory input =
|
|
31
|
+
Cur memory input = Cursors.open(c.request);
|
|
32
32
|
init(input);
|
|
33
33
|
return "";
|
|
34
34
|
}
|
|
@@ -16,20 +16,20 @@ abstract contract Unauthorize is CommandBase, AdminEvent {
|
|
|
16
16
|
uint internal immutable unauthorizeId = commandId(NAME);
|
|
17
17
|
|
|
18
18
|
constructor() {
|
|
19
|
-
emit Admin(host, unauthorizeId, NAME, "1:0:0", Schemas.Node, Keys.Empty, Keys.Empty, false);
|
|
19
|
+
emit Admin(host, unauthorizeId, NAME, "1:0:0", Schemas.Node, Keys.Empty, Keys.Empty, false, 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, ) = Cursors.first(c.request, 1);
|
|
26
26
|
|
|
27
|
-
while (request.i < request.
|
|
27
|
+
while (request.i < request.len) {
|
|
28
28
|
uint node = request.unpackNode();
|
|
29
29
|
setNode(node, false);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
request.
|
|
32
|
+
request.complete();
|
|
33
33
|
return "";
|
|
34
34
|
}
|
|
35
35
|
}
|
package/core/Access.sol
CHANGED
|
@@ -3,7 +3,7 @@ pragma solidity ^0.8.33;
|
|
|
3
3
|
|
|
4
4
|
import {NodeEvent} from "../events/Node.sol";
|
|
5
5
|
import {GuardianEvent} from "../events/Guardian.sol";
|
|
6
|
-
import {
|
|
6
|
+
import {Runtime} from "./Runtime.sol";
|
|
7
7
|
import {Accounts} from "../utils/Accounts.sol";
|
|
8
8
|
import {Ids} from "../utils/Ids.sol";
|
|
9
9
|
import {addrOr} from "../utils/Utils.sol";
|
|
@@ -14,7 +14,7 @@ import {addrOr} from "../utils/Utils.sol";
|
|
|
14
14
|
/// mapping of externally trusted node IDs. Inbound trust is host-based:
|
|
15
15
|
/// trusted hosts, the commander, and this contract itself may interact
|
|
16
16
|
/// with the host through the guarded command and peer entrypoints.
|
|
17
|
-
abstract contract AccessControl is
|
|
17
|
+
abstract contract AccessControl is Runtime, NodeEvent, GuardianEvent {
|
|
18
18
|
/// @dev Trusted commander address. All calls from this address are implicitly trusted.
|
|
19
19
|
/// Defaults to `address(this)` when no external commander is provided.
|
|
20
20
|
address internal immutable commander;
|
package/core/Host.sol
CHANGED
|
@@ -7,6 +7,7 @@ import {Authorize} from "../commands/admin/Authorize.sol";
|
|
|
7
7
|
import {Dismiss} from "../commands/admin/Dismiss.sol";
|
|
8
8
|
import {Unauthorize} from "../commands/admin/Unauthorize.sol";
|
|
9
9
|
import {ExecutePayable} from "../commands/admin/Execute.sol";
|
|
10
|
+
import {Revoke} from "../guards/Revoke.sol";
|
|
10
11
|
import {IntroductionEvent} from "../events/Introduction.sol";
|
|
11
12
|
import {Ids} from "../utils/Ids.sol";
|
|
12
13
|
|
|
@@ -23,10 +24,11 @@ interface IHostIntroduction {
|
|
|
23
24
|
|
|
24
25
|
/// @title Host
|
|
25
26
|
/// @notice Abstract base contract for rootzero host implementations.
|
|
26
|
-
/// Inherits admin command support (authorize, unauthorize, executePayable)
|
|
27
|
+
/// Inherits admin command support (authorize, unauthorize, executePayable),
|
|
28
|
+
/// guardian management, the default guardian revoke action, and
|
|
27
29
|
/// optionally introduces itself to a commander host at deployment.
|
|
28
30
|
/// Accepts native ETH payments via the `receive` function.
|
|
29
|
-
abstract contract Host is Authorize, Unauthorize, Appoint, Dismiss, ExecutePayable, IntroductionEvent, IHostIntroduction {
|
|
31
|
+
abstract contract Host is Authorize, Unauthorize, Revoke, Appoint, Dismiss, ExecutePayable, IntroductionEvent, IHostIntroduction {
|
|
30
32
|
/// @param cmdr Commander address; passed to `AccessControl`.
|
|
31
33
|
/// If `cmdr` is a deployed contract, the host calls `introduce`
|
|
32
34
|
/// on it during construction.
|
package/core/Pipeline.sol
CHANGED
|
@@ -41,15 +41,15 @@ abstract contract Pipeline is Payable {
|
|
|
41
41
|
bytes calldata steps,
|
|
42
42
|
Budget memory budget
|
|
43
43
|
) internal {
|
|
44
|
-
(Cur memory input, ) = Cursors.
|
|
44
|
+
(Cur memory input, ) = Cursors.first(steps, 1);
|
|
45
45
|
|
|
46
|
-
while (input.i < input.
|
|
46
|
+
while (input.i < input.len) {
|
|
47
47
|
(uint target, uint value, bytes calldata request) = input.unpackStep();
|
|
48
48
|
state = dispatch(target, account, state, request, useValue(budget, value));
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
if (state.length != 0) revert UnexpectedState();
|
|
52
52
|
settleValue(account, budget);
|
|
53
|
-
input.
|
|
53
|
+
input.complete();
|
|
54
54
|
}
|
|
55
55
|
}
|
package/core/Runtime.sol
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
pragma solidity ^0.8.33;
|
|
3
|
+
|
|
4
|
+
import {Assets} from "../utils/Assets.sol";
|
|
5
|
+
import {Ids} from "../utils/Ids.sol";
|
|
6
|
+
|
|
7
|
+
/// @title Runtime
|
|
8
|
+
/// @notice Shared runtime for host identity and native value identity.
|
|
9
|
+
abstract contract Runtime {
|
|
10
|
+
/// @dev This contract's host node ID, set to `Ids.toHost(address(this))` at construction.
|
|
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();
|
|
14
|
+
}
|
package/core/Types.sol
CHANGED
|
@@ -21,7 +21,7 @@ struct AccountAsset {
|
|
|
21
21
|
bytes32 meta;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
/// @notice Account-scoped amount shape
|
|
24
|
+
/// @notice Account-scoped amount shape for requests, responses, and reporting.
|
|
25
25
|
struct AccountAmount {
|
|
26
26
|
/// @dev Account identifier.
|
|
27
27
|
bytes32 account;
|
package/docs/Schema.md
CHANGED
|
@@ -185,7 +185,6 @@ Common protocol schemas live in `contracts/blocks/Schema.sol`:
|
|
|
185
185
|
#amount { bytes32 asset, bytes32 meta, uint amount }
|
|
186
186
|
#balance { bytes32 asset, bytes32 meta, uint amount }
|
|
187
187
|
#custody { uint host, bytes32 asset, bytes32 meta, uint amount }
|
|
188
|
-
#payout { bytes32 account, bytes32 asset, bytes32 meta, uint amount }
|
|
189
188
|
#call { uint target, uint value, #bytes as payload }
|
|
190
189
|
#step { uint target, uint value, #bytes as request }
|
|
191
190
|
#context { bytes32 account, #bytes as state, #bytes as request }
|
package/events/Admin.sol
CHANGED
|
@@ -6,18 +6,20 @@ 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
|
|
9
|
+
"event Admin(uint indexed host, uint id, string name, bytes32 shape, string request, bytes4 state, bytes4 output, bool checked, 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
|
-
/// @param shape Per-operation
|
|
15
|
-
///
|
|
16
|
-
///
|
|
17
|
-
///
|
|
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,
|
|
16
|
+
/// a constraint run follows the input run, or starts the request when `request`
|
|
17
|
+
/// is empty. State globals may follow the state run and are excluded.
|
|
18
|
+
/// @param request Schema DSL string describing the input request run, or empty if none.
|
|
18
19
|
/// @param state Block key expected for input state, or `Keys.Empty`.
|
|
19
20
|
/// @param output Block key produced for output state, or `Keys.Empty`.
|
|
20
|
-
/// @param
|
|
21
|
+
/// @param checked Whether a constraint block run is expected to exist in the request.
|
|
22
|
+
/// @param funded Whether the command entrypoint accepts nonzero `msg.value`.
|
|
21
23
|
event Admin(
|
|
22
24
|
uint indexed host,
|
|
23
25
|
uint id,
|
|
@@ -26,7 +28,8 @@ abstract contract AdminEvent is EventEmitter {
|
|
|
26
28
|
string request,
|
|
27
29
|
bytes4 state,
|
|
28
30
|
bytes4 output,
|
|
29
|
-
bool
|
|
31
|
+
bool checked,
|
|
32
|
+
bool funded
|
|
30
33
|
);
|
|
31
34
|
|
|
32
35
|
constructor() {
|
package/events/Command.sol
CHANGED
|
@@ -6,18 +6,20 @@ 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
|
|
9
|
+
"event Command(uint indexed host, uint id, string name, bytes32 shape, string request, bytes4 state, bytes4 output, bool checked, 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
|
-
/// @param shape Per-operation
|
|
15
|
-
///
|
|
16
|
-
///
|
|
17
|
-
///
|
|
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,
|
|
16
|
+
/// a constraint run follows the input run, or starts the request when `request`
|
|
17
|
+
/// is empty. State globals may follow the state run and are excluded.
|
|
18
|
+
/// @param request Schema string describing the input request run, or empty if none.
|
|
18
19
|
/// @param state Block key expected for input state, or `Keys.Empty`.
|
|
19
20
|
/// @param output Block key produced for output state, or `Keys.Empty`.
|
|
20
|
-
/// @param
|
|
21
|
+
/// @param checked Whether a constraint block run is expected to exist in the request.
|
|
22
|
+
/// @param funded Whether the command entrypoint accepts nonzero `msg.value`.
|
|
21
23
|
event Command(
|
|
22
24
|
uint indexed host,
|
|
23
25
|
uint id,
|
|
@@ -26,7 +28,8 @@ abstract contract CommandEvent is EventEmitter {
|
|
|
26
28
|
string request,
|
|
27
29
|
bytes4 state,
|
|
28
30
|
bytes4 output,
|
|
29
|
-
bool
|
|
31
|
+
bool checked,
|
|
32
|
+
bool funded
|
|
30
33
|
);
|
|
31
34
|
|
|
32
35
|
constructor() {
|
|
@@ -0,0 +1,21 @@
|
|
|
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 an account locks an asset in a protocol operation.
|
|
7
|
+
abstract contract LockedEvent is EventEmitter {
|
|
8
|
+
string private constant ABI = "event Locked(bytes32 indexed account, bytes32 asset, bytes32 meta, uint amount, uint32 action, uint context)";
|
|
9
|
+
|
|
10
|
+
/// @param account Account identifier that locked the asset.
|
|
11
|
+
/// @param asset Asset identifier.
|
|
12
|
+
/// @param meta Asset metadata slot.
|
|
13
|
+
/// @param amount Amount locked.
|
|
14
|
+
/// @param action Primary operation hint from `Actions`.
|
|
15
|
+
/// @param context Reserved context value for future use.
|
|
16
|
+
event Locked(bytes32 indexed account, bytes32 asset, bytes32 meta, uint amount, uint32 action, uint context);
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
emit EventAbi(ABI);
|
|
20
|
+
}
|
|
21
|
+
}
|