@rootzero/contracts 1.10.0 → 1.11.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/CHANGELOG.md +20 -1
- package/Core.sol +1 -0
- package/Endpoints.sol +1 -3
- package/Events.sol +2 -5
- package/README.md +35 -33
- package/Utils.sol +2 -1
- package/blocks/Cursors.sol +26 -75
- package/blocks/Keys.sol +14 -4
- package/blocks/Schema.sol +49 -44
- package/commands/Base.sol +43 -13
- package/commands/Burn.sol +3 -6
- package/commands/Credit.sol +9 -6
- package/commands/Debit.sol +15 -11
- package/commands/Deposit.sol +19 -23
- package/commands/Payout.sol +6 -10
- package/commands/Provision.sol +19 -23
- package/commands/Recover.sol +7 -9
- package/commands/Relay.sol +10 -11
- package/commands/Withdraw.sol +3 -6
- package/commands/admin/AllowAssets.sol +7 -10
- package/commands/admin/Allowance.sol +7 -10
- package/commands/admin/Appoint.sol +7 -10
- package/commands/admin/Authorize.sol +7 -10
- package/commands/admin/Base.sol +1 -2
- package/commands/admin/DenyAssets.sol +7 -10
- package/commands/admin/Dismiss.sol +7 -10
- package/commands/admin/Execute.sol +7 -10
- package/commands/admin/Label.sol +8 -11
- package/commands/admin/Unauthorize.sol +7 -10
- package/core/Endpoint.sol +153 -0
- package/docs/Schema.md +114 -82
- package/events/Endpoint.sol +19 -0
- package/events/Schema.sol +23 -0
- package/guards/Base.sol +17 -8
- package/guards/Revoke.sol +4 -6
- package/package.json +1 -1
- package/ports/AllowAssets.sol +6 -9
- package/ports/Allowance.sol +6 -9
- package/ports/Base.sol +21 -8
- package/ports/Credit.sol +6 -9
- package/ports/Debit.sol +6 -9
- package/ports/DenyAssets.sol +6 -9
- package/ports/Dispatch.sol +6 -9
- package/ports/Pipe.sol +4 -7
- package/ports/Redeem.sol +4 -7
- package/ports/Settle.sol +6 -9
- package/queries/Assets.sol +9 -12
- package/queries/Balances.sol +7 -9
- package/queries/Base.sol +19 -11
- package/utils/Selectors.sol +49 -0
- package/commands/admin/Destroy.sol +0 -43
- package/commands/admin/Init.sol +0 -43
- package/events/Admin.sol +0 -32
- package/events/Command.sol +0 -32
- package/events/Guard.sol +0 -18
- package/events/Port.sol +0 -22
- package/events/Query.sol +0 -20
- package/queries/Positions.sol +0 -54
package/commands/Base.sol
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
4
|
import {NodeCalls} from "../core/Calls.sol";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import {EndpointBase, Lane} from "../core/Endpoint.sol";
|
|
6
|
+
import {Cur} from "../Cursors.sol";
|
|
7
7
|
import {Keys} from "../blocks/Keys.sol";
|
|
8
8
|
import {Nodes} from "../utils/Nodes.sol";
|
|
9
|
+
import {Selectors} from "../utils/Selectors.sol";
|
|
9
10
|
|
|
10
11
|
/// @notice Execution context passed to every command invocation.
|
|
11
12
|
struct CommandContext {
|
|
@@ -14,14 +15,13 @@ struct CommandContext {
|
|
|
14
15
|
/// @dev Current state block stream (previous command output or initial state).
|
|
15
16
|
bytes state;
|
|
16
17
|
/// @dev Input block stream for this invocation.
|
|
17
|
-
bytes
|
|
18
|
+
bytes input;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
/// @title CommandBase
|
|
21
22
|
/// @notice Abstract base for all rootzero command contracts.
|
|
22
|
-
/// Provides access control modifiers
|
|
23
|
-
|
|
24
|
-
abstract contract CommandBase is NodeCalls, CommandEvent, LabeledEvent {
|
|
23
|
+
/// Provides access control modifiers and command endpoint metadata helpers.
|
|
24
|
+
abstract contract CommandBase is NodeCalls, EndpointBase {
|
|
25
25
|
/// @dev Thrown when `onlyActive` finds that `deadline` has already passed.
|
|
26
26
|
error Expired();
|
|
27
27
|
|
|
@@ -45,12 +45,42 @@ abstract contract CommandBase is NodeCalls, CommandEvent, LabeledEvent {
|
|
|
45
45
|
_;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
/// @notice
|
|
49
|
-
///
|
|
50
|
-
///
|
|
51
|
-
/// @param
|
|
52
|
-
/// @
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
/// @notice Publish command metadata and a default label.
|
|
49
|
+
/// @param name Default human-readable command label and selector name.
|
|
50
|
+
/// @param state Packed state lane plus optional group byte.
|
|
51
|
+
/// @param input Packed input lane plus optional group byte.
|
|
52
|
+
/// @param output Packed output lane plus optional group byte.
|
|
53
|
+
/// @param selector Command ABI selector, or zero to derive it from `name`.
|
|
54
|
+
/// @param funded Whether the command accepts nonzero native value.
|
|
55
|
+
/// @param admin Whether the command is restricted to the admin account.
|
|
56
|
+
/// @return id Command node ID.
|
|
57
|
+
/// @return descriptor Packed endpoint lane metadata and flags.
|
|
58
|
+
function command(
|
|
59
|
+
string memory name,
|
|
60
|
+
bytes9 state,
|
|
61
|
+
bytes9 input,
|
|
62
|
+
bytes9 output,
|
|
63
|
+
bytes4 selector,
|
|
64
|
+
bool funded,
|
|
65
|
+
bool admin
|
|
66
|
+
) internal returns (uint id, bytes32 descriptor) {
|
|
67
|
+
selector = selector == bytes4(0) ? Selectors.command(name) : selector;
|
|
68
|
+
id = Nodes.toCommand(selector, address(this));
|
|
69
|
+
descriptor = endpoint(id, name, state, input, output, funded, admin);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/// @notice Open input/state cursors and return the expected output block count.
|
|
73
|
+
/// @param c Command invocation context.
|
|
74
|
+
/// @param descriptor Packed command endpoint descriptor.
|
|
75
|
+
/// @return input Cursor scoped to the command input lane.
|
|
76
|
+
/// @return state Cursor scoped to the command state lane.
|
|
77
|
+
/// @return outputs Number of output blocks implied by the matched group count.
|
|
78
|
+
function openCommand(
|
|
79
|
+
CommandContext calldata c,
|
|
80
|
+
bytes32 descriptor
|
|
81
|
+
) internal pure returns (Cur memory input, Cur memory state, uint outputs) {
|
|
82
|
+
uint groups;
|
|
83
|
+
(input, groups, ) = openLane(c.input, descriptor, Lane.Input, 0);
|
|
84
|
+
(state, , outputs) = openLane(c.state, descriptor, Lane.State, groups);
|
|
55
85
|
}
|
|
56
86
|
}
|
package/commands/Burn.sol
CHANGED
|
@@ -19,25 +19,22 @@ abstract contract BurnHook {
|
|
|
19
19
|
/// @notice Command that irreversibly destroys each BALANCE state block via a virtual hook.
|
|
20
20
|
/// Produces no output state.
|
|
21
21
|
abstract contract Burn is CommandBase, BurnHook {
|
|
22
|
-
|
|
22
|
+
bytes32 private immutable descriptor;
|
|
23
23
|
|
|
24
24
|
constructor() {
|
|
25
|
-
|
|
26
|
-
emit Labeled(burnId, bytes32(0), "burn");
|
|
25
|
+
(, descriptor) = command("burn", Keys.Balance, Keys.Empty, Keys.Empty, 0, false, false);
|
|
27
26
|
}
|
|
28
27
|
|
|
29
28
|
/// @notice Burn each BALANCE block from the command state.
|
|
30
29
|
/// @param c Command context; `c.state` must contain BALANCE blocks.
|
|
31
30
|
/// @return Empty output state.
|
|
32
31
|
function burn(CommandContext calldata c) external onlyCommand returns (bytes memory) {
|
|
33
|
-
(Cur memory state, ) =
|
|
32
|
+
(Cur memory state, ) = openState(c.state, descriptor);
|
|
34
33
|
|
|
35
34
|
while (state.i < state.len) {
|
|
36
35
|
(bytes32 asset, uint amount) = state.unpackBalance();
|
|
37
36
|
burn(c.account, asset, amount);
|
|
38
37
|
}
|
|
39
|
-
|
|
40
|
-
state.complete();
|
|
41
38
|
return "";
|
|
42
39
|
}
|
|
43
40
|
}
|
package/commands/Credit.sol
CHANGED
|
@@ -19,11 +19,16 @@ abstract contract CreditAccountHook {
|
|
|
19
19
|
/// @notice Command that delivers BALANCE state blocks to an account via a virtual hook.
|
|
20
20
|
/// Use for internally recording credits that have already been settled externally.
|
|
21
21
|
abstract contract CreditAccount is CommandBase, CreditAccountHook {
|
|
22
|
-
|
|
22
|
+
bytes32 private immutable descriptor;
|
|
23
|
+
uint private immutable id;
|
|
23
24
|
|
|
24
25
|
constructor() {
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
(id, descriptor) = command("creditAccount", Keys.Balance, Keys.Empty, Keys.Empty, 0, false, false);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/// @notice Return true if `candidate` is this command's credit account ID.
|
|
30
|
+
function isCreditAccount(uint candidate) internal view returns (bool) {
|
|
31
|
+
return candidate == id;
|
|
27
32
|
}
|
|
28
33
|
|
|
29
34
|
/// @notice Credit each BALANCE block from the command state to the command account.
|
|
@@ -32,14 +37,12 @@ abstract contract CreditAccount is CommandBase, CreditAccountHook {
|
|
|
32
37
|
function creditAccount(
|
|
33
38
|
CommandContext calldata c
|
|
34
39
|
) external onlyCommand returns (bytes memory) {
|
|
35
|
-
(Cur memory state, ) =
|
|
40
|
+
(Cur memory state, ) = openState(c.state, descriptor);
|
|
36
41
|
|
|
37
42
|
while (state.i < state.len) {
|
|
38
43
|
(bytes32 asset, uint amount) = state.unpackBalance();
|
|
39
44
|
creditAccount(c.account, asset, amount);
|
|
40
45
|
}
|
|
41
|
-
|
|
42
|
-
state.complete();
|
|
43
46
|
return "";
|
|
44
47
|
}
|
|
45
48
|
}
|
package/commands/Debit.sol
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
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, Writer, Writers } from "../Cursors.sol";
|
|
6
6
|
|
|
7
7
|
using Cursors for Cur;
|
|
8
8
|
using Writers for Writer;
|
|
@@ -21,37 +21,41 @@ abstract contract DebitAccountHook {
|
|
|
21
21
|
/// Use for internally recording debits. The virtual `debitAccount` hook is called once per
|
|
22
22
|
/// AMOUNT block; the default batch implementation handles the full request loop.
|
|
23
23
|
abstract contract DebitAccount is CommandBase, DebitAccountHook {
|
|
24
|
-
|
|
24
|
+
bytes32 private immutable descriptor;
|
|
25
|
+
uint private immutable id;
|
|
25
26
|
|
|
26
27
|
constructor() {
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
(id, descriptor) = command("debitAccount", Keys.Empty, Keys.Amount, Keys.Balance, 0, false, false);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/// @notice Return true if `candidate` is this command's debit account ID.
|
|
32
|
+
function isDebitAccount(uint candidate) internal view returns (bool) {
|
|
33
|
+
return candidate == id;
|
|
29
34
|
}
|
|
30
35
|
|
|
31
36
|
/// @notice Override to customize request parsing or batching for debits.
|
|
32
37
|
/// The default implementation iterates AMOUNT blocks, calls
|
|
33
38
|
/// `debitAccount`, and emits matching BALANCE blocks.
|
|
34
39
|
function debitAccount(bytes32 account, bytes calldata request) internal virtual returns (bytes memory) {
|
|
35
|
-
(Cur memory input, uint
|
|
36
|
-
Writer memory
|
|
40
|
+
(Cur memory input, uint outputs) = openInput(request, descriptor);
|
|
41
|
+
Writer memory output = Writers.allocBalances(outputs);
|
|
37
42
|
|
|
38
43
|
while (input.i < input.len) {
|
|
39
44
|
(bytes32 asset, uint amount) = input.unpackAmount();
|
|
40
45
|
debitAccount(account, asset, amount);
|
|
41
|
-
|
|
46
|
+
output.appendBalance(asset, amount);
|
|
42
47
|
}
|
|
43
48
|
|
|
44
|
-
|
|
45
|
-
return writer.finish();
|
|
49
|
+
return output.finish();
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
/// @notice Debit AMOUNT request blocks from the command account and output matching BALANCE blocks.
|
|
49
|
-
/// @param c Command context; `c.
|
|
53
|
+
/// @param c Command context; `c.input` must contain AMOUNT blocks.
|
|
50
54
|
/// @return BALANCE block stream matching the debited amounts.
|
|
51
55
|
function debitAccount(
|
|
52
56
|
CommandContext calldata c
|
|
53
57
|
) external onlyCommand returns (bytes memory) {
|
|
54
|
-
return debitAccount(c.account, c.
|
|
58
|
+
return debitAccount(c.account, c.input);
|
|
55
59
|
}
|
|
56
60
|
}
|
|
57
61
|
|
package/commands/Deposit.sol
CHANGED
|
@@ -3,7 +3,7 @@ pragma solidity ^0.8.33;
|
|
|
3
3
|
|
|
4
4
|
import { CommandContext, CommandBase, Keys } from "./Base.sol";
|
|
5
5
|
import { Payable } from "../core/Payable.sol";
|
|
6
|
-
import { Cursors, Cur,
|
|
6
|
+
import { Cursors, Cur, Writer, Writers } from "../Cursors.sol";
|
|
7
7
|
import { Budget } from "../utils/Value.sol";
|
|
8
8
|
|
|
9
9
|
using Cursors for Cur;
|
|
@@ -35,30 +35,28 @@ abstract contract DepositPayableHook {
|
|
|
35
35
|
/// Use `deposit` for assets arriving from outside the protocol (e.g. ERC-20 transfers, ETH).
|
|
36
36
|
/// For internal balance deductions, use `debitAccount` instead.
|
|
37
37
|
abstract contract Deposit is CommandBase, DepositHook {
|
|
38
|
-
|
|
38
|
+
bytes32 private immutable descriptor;
|
|
39
39
|
|
|
40
40
|
constructor() {
|
|
41
|
-
|
|
42
|
-
emit Labeled(depositId, bytes32(0), "deposit");
|
|
41
|
+
(, descriptor) = command("deposit", Keys.Empty, Keys.Amount, Keys.Balance, 0, false, false);
|
|
43
42
|
}
|
|
44
43
|
|
|
45
44
|
/// @notice Deposit AMOUNT request blocks into the command account and output matching BALANCE blocks.
|
|
46
|
-
/// @param c Command context; `c.
|
|
45
|
+
/// @param c Command context; `c.input` must contain AMOUNT blocks.
|
|
47
46
|
/// @return BALANCE block stream matching the deposited amounts.
|
|
48
47
|
function deposit(
|
|
49
48
|
CommandContext calldata c
|
|
50
49
|
) external onlyCommand returns (bytes memory) {
|
|
51
|
-
(Cur memory
|
|
52
|
-
Writer memory
|
|
50
|
+
(Cur memory input, uint outputs) = openInput(c.input, descriptor);
|
|
51
|
+
Writer memory output = Writers.allocBalances(outputs);
|
|
53
52
|
|
|
54
|
-
while (
|
|
55
|
-
(bytes32 asset, uint amount) =
|
|
53
|
+
while (input.i < input.len) {
|
|
54
|
+
(bytes32 asset, uint amount) = input.unpackAmount();
|
|
56
55
|
deposit(c.account, asset, amount);
|
|
57
|
-
|
|
56
|
+
output.appendBalance(asset, amount);
|
|
58
57
|
}
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
return writer.finish();
|
|
59
|
+
return output.finish();
|
|
62
60
|
}
|
|
63
61
|
}
|
|
64
62
|
|
|
@@ -66,32 +64,30 @@ abstract contract Deposit is CommandBase, DepositHook {
|
|
|
66
64
|
/// @notice Command that receives externally sourced assets and records them as BALANCE state.
|
|
67
65
|
/// Use `depositPayable` when the hook needs tracked access to `msg.value` via a mutable budget.
|
|
68
66
|
abstract contract DepositPayable is CommandBase, Payable, DepositPayableHook {
|
|
69
|
-
|
|
67
|
+
bytes32 private immutable descriptor;
|
|
70
68
|
|
|
71
69
|
constructor() {
|
|
72
|
-
|
|
73
|
-
emit Labeled(depositPayableId, bytes32(0), "depositPayable");
|
|
70
|
+
(, descriptor) = command("depositPayable", Keys.Empty, Keys.Amount, Keys.Balance, 0, true, false);
|
|
74
71
|
}
|
|
75
72
|
|
|
76
73
|
/// @notice Deposit AMOUNT request blocks with access to a mutable native-value budget.
|
|
77
|
-
/// @param c Command context; `c.
|
|
74
|
+
/// @param c Command context; `c.input` must contain AMOUNT blocks.
|
|
78
75
|
/// @return BALANCE block stream matching the deposited amounts.
|
|
79
76
|
function depositPayable(
|
|
80
77
|
CommandContext calldata c
|
|
81
78
|
) external payable onlyCommand returns (bytes memory) {
|
|
82
|
-
(Cur memory
|
|
83
|
-
Writer memory
|
|
79
|
+
(Cur memory input, uint outputs) = openInput(c.input, descriptor);
|
|
80
|
+
Writer memory output = Writers.allocBalances(outputs);
|
|
84
81
|
Budget memory budget = openValue();
|
|
85
82
|
|
|
86
|
-
while (
|
|
87
|
-
(bytes32 asset, uint amount) =
|
|
83
|
+
while (input.i < input.len) {
|
|
84
|
+
(bytes32 asset, uint amount) = input.unpackAmount();
|
|
88
85
|
deposit(c.account, asset, amount, budget);
|
|
89
|
-
|
|
86
|
+
output.appendBalance(asset, amount);
|
|
90
87
|
}
|
|
91
88
|
|
|
92
89
|
closeValue(c.account, budget);
|
|
93
|
-
|
|
94
|
-
return writer.finish();
|
|
90
|
+
return output.finish();
|
|
95
91
|
}
|
|
96
92
|
}
|
|
97
93
|
|
package/commands/Payout.sol
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
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
|
|
|
7
7
|
using Cursors for Cur;
|
|
8
8
|
|
|
@@ -20,26 +20,22 @@ abstract contract PayoutHook {
|
|
|
20
20
|
/// @notice Command that sinks BALANCE state blocks to matching ACCOUNT request blocks.
|
|
21
21
|
/// Each BALANCE block is paired with one ACCOUNT block at the same position.
|
|
22
22
|
abstract contract Payout is CommandBase, PayoutHook {
|
|
23
|
-
|
|
23
|
+
bytes32 private immutable descriptor;
|
|
24
24
|
|
|
25
25
|
constructor() {
|
|
26
|
-
|
|
27
|
-
emit Labeled(payoutId, bytes32(0), "payout");
|
|
26
|
+
(, descriptor) = command("payout", Keys.Balance, Keys.Account, Keys.Empty, 0, false, false);
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
/// @notice Pay out BALANCE state blocks to matching ACCOUNT request blocks.
|
|
31
|
-
/// @param c Command context; `c.state` must contain BALANCE blocks and `c.
|
|
30
|
+
/// @param c Command context; `c.state` must contain BALANCE blocks and `c.input` matching ACCOUNT blocks.
|
|
32
31
|
/// @return Empty output state.
|
|
33
32
|
function payout(CommandContext calldata c) external onlyCommand returns (bytes memory) {
|
|
34
|
-
(Cur memory state,
|
|
35
|
-
Cur memory request = Cursors.init(c.request, 1, groups);
|
|
33
|
+
(Cur memory input, Cur memory state, ) = openCommand(c, descriptor);
|
|
36
34
|
|
|
37
35
|
while (state.i < state.len) {
|
|
38
36
|
(bytes32 asset, uint amount) = state.unpackBalance();
|
|
39
|
-
payout(c.account,
|
|
37
|
+
payout(c.account, input.unpackAccount(), asset, amount);
|
|
40
38
|
}
|
|
41
|
-
|
|
42
|
-
state.complete();
|
|
43
39
|
return "";
|
|
44
40
|
}
|
|
45
41
|
}
|
package/commands/Provision.sol
CHANGED
|
@@ -3,7 +3,7 @@ pragma solidity ^0.8.33;
|
|
|
3
3
|
|
|
4
4
|
import {CommandContext, CommandBase, Keys} from "./Base.sol";
|
|
5
5
|
import {Payable} from "../core/Payable.sol";
|
|
6
|
-
import {HostAmount, Cursors, Cur,
|
|
6
|
+
import {HostAmount, Cursors, Cur, Writer, Writers} from "../Cursors.sol";
|
|
7
7
|
import {Budget} from "../utils/Value.sol";
|
|
8
8
|
using Cursors for Cur;
|
|
9
9
|
using Writers for Writer;
|
|
@@ -33,28 +33,26 @@ abstract contract ProvisionPayableHook {
|
|
|
33
33
|
/// @notice Command that provisions assets to peer hosts from ALLOCATION request blocks.
|
|
34
34
|
/// Each request block supplies the target host plus an asset amount; the output is a CUSTODY state stream.
|
|
35
35
|
abstract contract Provision is CommandBase, ProvisionHook {
|
|
36
|
-
|
|
36
|
+
bytes32 private immutable descriptor;
|
|
37
37
|
|
|
38
38
|
constructor() {
|
|
39
|
-
|
|
40
|
-
emit Labeled(provisionId, bytes32(0), "provision");
|
|
39
|
+
(, descriptor) = command("provision", Keys.Empty, Keys.Allocation, Keys.Custody, 0, false, false);
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
/// @notice Provision ALLOCATION request blocks and output matching CUSTODY state blocks.
|
|
44
|
-
/// @param c Command context; `c.
|
|
43
|
+
/// @param c Command context; `c.input` must contain ALLOCATION blocks.
|
|
45
44
|
/// @return CUSTODY block stream matching the provisioned allocations.
|
|
46
45
|
function provision(CommandContext calldata c) external onlyCommand returns (bytes memory) {
|
|
47
|
-
(Cur memory
|
|
48
|
-
Writer memory
|
|
46
|
+
(Cur memory input, uint outputs) = openInput(c.input, descriptor);
|
|
47
|
+
Writer memory output = Writers.allocCustodies(outputs);
|
|
49
48
|
|
|
50
|
-
while (
|
|
51
|
-
HostAmount memory allocation =
|
|
49
|
+
while (input.i < input.len) {
|
|
50
|
+
HostAmount memory allocation = input.unpackAllocationValue();
|
|
52
51
|
provision(c.account, allocation);
|
|
53
|
-
|
|
52
|
+
output.appendCustody(allocation);
|
|
54
53
|
}
|
|
55
54
|
|
|
56
|
-
|
|
57
|
-
return writer.finish();
|
|
55
|
+
return output.finish();
|
|
58
56
|
}
|
|
59
57
|
}
|
|
60
58
|
|
|
@@ -63,32 +61,30 @@ abstract contract Provision is CommandBase, ProvisionHook {
|
|
|
63
61
|
/// Each request block supplies the target host plus an asset amount; the output is a CUSTODY state stream.
|
|
64
62
|
/// The hook receives a mutable native-value budget drawn from `msg.value`.
|
|
65
63
|
abstract contract ProvisionPayable is CommandBase, Payable, ProvisionPayableHook {
|
|
66
|
-
|
|
64
|
+
bytes32 private immutable descriptor;
|
|
67
65
|
|
|
68
66
|
constructor() {
|
|
69
|
-
|
|
70
|
-
emit Labeled(provisionPayableId, bytes32(0), "provisionPayable");
|
|
67
|
+
(, descriptor) = command("provisionPayable", Keys.Empty, Keys.Allocation, Keys.Custody, 0, true, false);
|
|
71
68
|
}
|
|
72
69
|
|
|
73
70
|
/// @notice Provision ALLOCATION request blocks with access to a mutable native-value budget.
|
|
74
|
-
/// @param c Command context; `c.
|
|
71
|
+
/// @param c Command context; `c.input` must contain ALLOCATION blocks.
|
|
75
72
|
/// @return CUSTODY block stream matching the provisioned allocations.
|
|
76
73
|
function provisionPayable(
|
|
77
74
|
CommandContext calldata c
|
|
78
75
|
) external payable onlyCommand returns (bytes memory) {
|
|
79
|
-
(Cur memory
|
|
80
|
-
Writer memory
|
|
76
|
+
(Cur memory input, uint outputs) = openInput(c.input, descriptor);
|
|
77
|
+
Writer memory output = Writers.allocCustodies(outputs);
|
|
81
78
|
Budget memory budget = openValue();
|
|
82
79
|
|
|
83
|
-
while (
|
|
84
|
-
HostAmount memory allocation =
|
|
80
|
+
while (input.i < input.len) {
|
|
81
|
+
HostAmount memory allocation = input.unpackAllocationValue();
|
|
85
82
|
provision(c.account, allocation, budget);
|
|
86
|
-
|
|
83
|
+
output.appendCustody(allocation);
|
|
87
84
|
}
|
|
88
85
|
|
|
89
86
|
closeValue(c.account, budget);
|
|
90
|
-
|
|
91
|
-
return writer.finish();
|
|
87
|
+
return output.finish();
|
|
92
88
|
}
|
|
93
89
|
}
|
|
94
90
|
|
package/commands/Recover.sol
CHANGED
|
@@ -3,7 +3,7 @@ pragma solidity ^0.8.33;
|
|
|
3
3
|
|
|
4
4
|
import {CommandBase, CommandContext, Keys} from "./Base.sol";
|
|
5
5
|
import {Payable} from "../core/Payable.sol";
|
|
6
|
-
import {Cursors, Cur
|
|
6
|
+
import {Cursors, Cur} from "../Cursors.sol";
|
|
7
7
|
import {Budget} from "../utils/Value.sol";
|
|
8
8
|
|
|
9
9
|
using Cursors for Cur;
|
|
@@ -23,27 +23,25 @@ abstract contract RecoverHook {
|
|
|
23
23
|
/// value settlement, but the recovered subject is defined by each witness.
|
|
24
24
|
/// Produces no output state.
|
|
25
25
|
abstract contract RecoverPayable is CommandBase, Payable, RecoverHook {
|
|
26
|
-
|
|
26
|
+
bytes32 private immutable descriptor;
|
|
27
27
|
|
|
28
28
|
constructor() {
|
|
29
|
-
|
|
30
|
-
emit Labeled(recoverPayableId, bytes32(0), "recoverPayable");
|
|
29
|
+
(, descriptor) = command("recoverPayable", Keys.Empty, Keys.Recover, Keys.Empty, 0, true, false);
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
/// @notice Recover each recover block in the command request.
|
|
34
|
-
/// @param c Command context; `c.
|
|
33
|
+
/// @param c Command context; `c.input` must contain Recover blocks.
|
|
35
34
|
/// @return Empty output state.
|
|
36
35
|
function recoverPayable(CommandContext calldata c) external payable onlyCommand returns (bytes memory) {
|
|
37
|
-
(Cur memory
|
|
36
|
+
(Cur memory input, ) = openInput(c.input, descriptor);
|
|
38
37
|
Budget memory budget = openValue();
|
|
39
38
|
|
|
40
|
-
while (
|
|
41
|
-
(uint handler, uint resources, bytes32 key, bytes calldata witness) =
|
|
39
|
+
while (input.i < input.len) {
|
|
40
|
+
(uint handler, uint resources, bytes32 key, bytes calldata witness) = input.unpackRecover();
|
|
42
41
|
recover(handler, key, witness, useValue(budget, resources));
|
|
43
42
|
}
|
|
44
43
|
|
|
45
44
|
closeValue(c.account, budget);
|
|
46
|
-
request.complete();
|
|
47
45
|
return "";
|
|
48
46
|
}
|
|
49
47
|
}
|
package/commands/Relay.sol
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
4
|
import {CommandBase, CommandContext, Keys} from "./Base.sol";
|
|
5
|
+
import {Lane} from "../core/Endpoint.sol";
|
|
5
6
|
import {Payable} from "../core/Payable.sol";
|
|
6
|
-
import {Cursors, Cur
|
|
7
|
+
import {Cursors, Cur} from "../Cursors.sol";
|
|
7
8
|
import {Budget} from "../utils/Value.sol";
|
|
8
9
|
|
|
9
10
|
using Cursors for Cur;
|
|
@@ -25,25 +26,23 @@ abstract contract RoutePayableHook {
|
|
|
25
26
|
/// the same state from being duplicated across multiple relays.
|
|
26
27
|
/// Produces no output state.
|
|
27
28
|
abstract contract RelayPayable is CommandBase, Payable, RoutePayableHook {
|
|
28
|
-
|
|
29
|
+
bytes32 private immutable descriptor;
|
|
29
30
|
|
|
30
31
|
constructor() {
|
|
31
|
-
|
|
32
|
-
emit Labeled(relayPayableId, bytes32(0), "relayPayable");
|
|
32
|
+
(, descriptor) = command("relayPayable", Keys.Any, Keys.Relay, Keys.Empty, 0, true, false);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/// @notice Relay one RELAY request block with the command account and current state.
|
|
36
|
-
/// @param c Command context; `c.
|
|
37
|
-
/// @return
|
|
38
|
-
function relayPayable(CommandContext calldata c) external payable onlyCommand returns (bytes memory
|
|
39
|
-
Cur memory
|
|
40
|
-
|
|
36
|
+
/// @param c Command context; `c.input` must contain exactly one RELAY block.
|
|
37
|
+
/// @return Empty output state.
|
|
38
|
+
function relayPayable(CommandContext calldata c) external payable onlyCommand returns (bytes memory) {
|
|
39
|
+
(Cur memory input, , ) = openLane(c.input, descriptor, Lane.Input, 1);
|
|
40
|
+
(uint portal, uint resources, bytes memory context) = input.relayToContext(c.account, c.state);
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
Budget memory budget = openValue();
|
|
43
43
|
route(portal, resources, context, budget);
|
|
44
44
|
|
|
45
45
|
closeValue(c.account, budget);
|
|
46
|
-
request.complete();
|
|
47
46
|
return "";
|
|
48
47
|
}
|
|
49
48
|
}
|
package/commands/Withdraw.sol
CHANGED
|
@@ -19,11 +19,10 @@ abstract contract WithdrawHook {
|
|
|
19
19
|
/// Use `withdraw` for assets being sent outside the protocol (e.g. ERC-20 transfers, ETH sends).
|
|
20
20
|
/// For internal balance credits, use `creditAccount` instead.
|
|
21
21
|
abstract contract Withdraw is CommandBase, WithdrawHook {
|
|
22
|
-
|
|
22
|
+
bytes32 private immutable descriptor;
|
|
23
23
|
|
|
24
24
|
constructor() {
|
|
25
|
-
|
|
26
|
-
emit Labeled(withdrawId, bytes32(0), "withdraw");
|
|
25
|
+
(, descriptor) = command("withdraw", Keys.Balance, Keys.Empty, Keys.Empty, 0, false, false);
|
|
27
26
|
}
|
|
28
27
|
|
|
29
28
|
/// @notice Withdraw each BALANCE block from the command state to the command account.
|
|
@@ -32,14 +31,12 @@ abstract contract Withdraw is CommandBase, WithdrawHook {
|
|
|
32
31
|
function withdraw(
|
|
33
32
|
CommandContext calldata c
|
|
34
33
|
) external onlyCommand returns (bytes memory) {
|
|
35
|
-
(Cur memory state, ) =
|
|
34
|
+
(Cur memory state, ) = openState(c.state, descriptor);
|
|
36
35
|
|
|
37
36
|
while (state.i < state.len) {
|
|
38
37
|
(bytes32 asset, uint amount) = state.unpackBalance();
|
|
39
38
|
withdraw(c.account, asset, amount);
|
|
40
39
|
}
|
|
41
|
-
|
|
42
|
-
state.complete();
|
|
43
40
|
return "";
|
|
44
41
|
}
|
|
45
42
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
4
|
import { AdminBase, CommandContext, 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 AllowAssetsHook {
|
|
@@ -16,27 +16,24 @@ abstract contract AllowAssetsHook {
|
|
|
16
16
|
/// @notice Admin command that permits a list of assets via a virtual hook.
|
|
17
17
|
/// Each ASSET block in the request calls `allowAsset`. Only callable by the admin account.
|
|
18
18
|
abstract contract AllowAssets is AdminBase, AllowAssetsHook {
|
|
19
|
-
|
|
19
|
+
bytes32 private immutable descriptor;
|
|
20
20
|
|
|
21
21
|
constructor() {
|
|
22
|
-
|
|
23
|
-
emit Labeled(allowAssetsId, bytes32(0), "allowAssets");
|
|
22
|
+
(, descriptor) = command("allowAssets", Keys.Empty, Keys.Asset, Keys.Empty, 0, false, true);
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
/// @notice Allow each ASSET block in the admin request.
|
|
27
|
-
/// @param c Admin command context; `c.
|
|
26
|
+
/// @param c Admin command context; `c.input` must contain ASSET blocks.
|
|
28
27
|
/// @return Empty output state.
|
|
29
28
|
function allowAssets(
|
|
30
29
|
CommandContext calldata c
|
|
31
30
|
) external onlyAdmin(c.account) returns (bytes memory) {
|
|
32
|
-
(Cur memory
|
|
31
|
+
(Cur memory input, ) = openInput(c.input, descriptor);
|
|
33
32
|
|
|
34
|
-
while (
|
|
35
|
-
bytes32 asset =
|
|
33
|
+
while (input.i < input.len) {
|
|
34
|
+
bytes32 asset = input.unpackAsset();
|
|
36
35
|
allowAsset(asset);
|
|
37
36
|
}
|
|
38
|
-
|
|
39
|
-
request.complete();
|
|
40
37
|
return "";
|
|
41
38
|
}
|
|
42
39
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
4
|
import {AdminBase, CommandContext, 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 AllowanceHook {
|
|
@@ -20,25 +20,22 @@ abstract contract AllowanceHook {
|
|
|
20
20
|
/// @notice Admin command that applies cross-host allowance entries via a virtual hook.
|
|
21
21
|
/// Each ALLOWANCE block grants or updates a host-scoped asset cap. Only callable by the admin account.
|
|
22
22
|
abstract contract Allowance is AdminBase, AllowanceHook {
|
|
23
|
-
|
|
23
|
+
bytes32 private immutable descriptor;
|
|
24
24
|
|
|
25
25
|
constructor() {
|
|
26
|
-
|
|
27
|
-
emit Labeled(allowanceId, bytes32(0), "allowance");
|
|
26
|
+
(, descriptor) = command("allowance", Keys.Empty, Keys.Allowance, Keys.Empty, 0, false, true);
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
/// @notice Apply each ALLOWANCE block in the admin request.
|
|
31
|
-
/// @param c Admin command context; `c.
|
|
30
|
+
/// @param c Admin command context; `c.input` must contain ALLOWANCE blocks.
|
|
32
31
|
/// @return Empty output state.
|
|
33
32
|
function allowance(CommandContext calldata c) external onlyAdmin(c.account) returns (bytes memory) {
|
|
34
|
-
(Cur memory
|
|
33
|
+
(Cur memory input, ) = openInput(c.input, descriptor);
|
|
35
34
|
|
|
36
|
-
while (
|
|
37
|
-
(uint peer, bytes32 asset, uint amount) =
|
|
35
|
+
while (input.i < input.len) {
|
|
36
|
+
(uint peer, bytes32 asset, uint amount) = input.unpackAllowance();
|
|
38
37
|
allowance(peer, asset, amount);
|
|
39
38
|
}
|
|
40
|
-
|
|
41
|
-
request.complete();
|
|
42
39
|
return "";
|
|
43
40
|
}
|
|
44
41
|
}
|