@rootzero/contracts 1.13.0 → 1.14.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 +45 -3
- package/Codec.sol +21 -0
- package/Commands.sol +14 -0
- package/Core.sol +2 -3
- package/Endpoints.sol +1 -5
- package/README.md +34 -30
- package/Utils.sol +2 -4
- package/codec/Blocks.sol +1606 -0
- package/codec/Buffers.sol +165 -0
- package/codec/Decoders.sol +558 -0
- package/codec/Descriptors.sol +124 -0
- package/{blocks → codec}/Keys.sol +4 -16
- package/codec/Readers.sol +114 -0
- package/{blocks → codec}/Schema.sol +38 -80
- package/codec/Specs.sol +218 -0
- package/codec/Writers.sol +487 -0
- package/commands/Allocate.sol +21 -20
- package/commands/Base.sol +71 -37
- package/commands/Burn.sol +18 -13
- package/commands/Credit.sol +21 -20
- package/commands/Debit.sol +25 -28
- package/commands/Deposit.sol +34 -35
- package/commands/Payout.sol +21 -15
- package/commands/Provision.sol +37 -38
- package/commands/Recover.sol +20 -19
- package/commands/Relay.sol +24 -22
- package/commands/Withdraw.sol +15 -18
- package/commands/admin/AllowAssets.sol +19 -16
- package/commands/admin/Allowance.sol +18 -13
- package/commands/admin/Appoint.sol +17 -15
- package/commands/admin/Authorize.sol +23 -14
- package/commands/admin/Base.sol +1 -1
- package/commands/admin/DenyAssets.sol +19 -16
- package/commands/admin/Dismiss.sol +17 -15
- package/commands/admin/Execute.sol +20 -19
- package/commands/admin/Label.sol +17 -13
- package/commands/admin/Schemas.sol +18 -14
- package/commands/admin/Unauthorize.sol +23 -14
- package/core/Calls.sol +3 -11
- package/core/Endpoint.sol +42 -127
- package/core/Pipeline.sol +16 -15
- package/core/Types.sol +1 -1
- package/docs/Schema.md +35 -29
- package/events/Endpoint.sol +2 -2
- package/events/Schema.sol +5 -5
- package/execution/Budget.sol +40 -0
- package/execution/Execution.sol +1083 -0
- package/guards/Base.sol +8 -9
- package/guards/Revoke.sol +11 -9
- package/package.json +1 -1
- package/ports/AllowAssets.sol +12 -15
- package/ports/Allowance.sol +11 -9
- package/ports/Base.sol +18 -11
- package/ports/Credit.sol +11 -9
- package/ports/Debit.sol +11 -9
- package/ports/DenyAssets.sol +10 -13
- package/ports/Dispatch.sol +13 -15
- package/ports/Pipe.sol +14 -12
- package/ports/Redeem.sol +12 -9
- package/ports/Settle.sol +11 -9
- package/queries/Assets.sol +15 -15
- package/queries/Balances.sol +17 -17
- package/queries/Base.sol +11 -12
- package/utils/Actions.sol +1 -0
- package/utils/Cursors.sol +308 -0
- package/utils/Lanes.sol +14 -0
- package/utils/Selectors.sol +2 -2
- package/utils/Utils.sol +46 -0
- package/Cursors.sol +0 -16
- package/blocks/Cursors.sol +0 -1529
- package/blocks/Writers.sol +0 -1036
- package/core/Payable.sol +0 -53
- package/utils/Value.sol +0 -43
package/commands/Base.sol
CHANGED
|
@@ -2,26 +2,24 @@
|
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
4
|
import {NodeCalls} from "../core/Calls.sol";
|
|
5
|
-
import {EndpointBase
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import {EndpointBase} from "../core/Endpoint.sol";
|
|
6
|
+
import {Blocks} from "../codec/Blocks.sol";
|
|
7
|
+
import {Specs} from "../codec/Specs.sol";
|
|
8
|
+
import {HostAmount} from "../core/Types.sol";
|
|
9
|
+
import {Execution, Executions, Lanes} from "../execution/Execution.sol";
|
|
10
|
+
import {ReceivedEvent} from "../events/Received.sol";
|
|
11
|
+
import {Actions} from "../utils/Actions.sol";
|
|
12
|
+
import {Descriptors} from "../codec/Descriptors.sol";
|
|
8
13
|
import {Nodes} from "../utils/Nodes.sol";
|
|
9
14
|
import {Selectors} from "../utils/Selectors.sol";
|
|
15
|
+
import {Cursors} from "../utils/Cursors.sol";
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
struct CommandContext {
|
|
13
|
-
/// @dev Caller's account identifier.
|
|
14
|
-
bytes32 account;
|
|
15
|
-
/// @dev Current state block stream (previous command output or initial state).
|
|
16
|
-
bytes state;
|
|
17
|
-
/// @dev Input block stream for this invocation.
|
|
18
|
-
bytes input;
|
|
19
|
-
}
|
|
17
|
+
using Executions for Execution;
|
|
20
18
|
|
|
21
19
|
/// @title CommandBase
|
|
22
20
|
/// @notice Abstract base for all rootzero command contracts.
|
|
23
21
|
/// Provides access control modifiers and command endpoint metadata helpers.
|
|
24
|
-
abstract contract CommandBase is NodeCalls, EndpointBase {
|
|
22
|
+
abstract contract CommandBase is NodeCalls, EndpointBase, ReceivedEvent {
|
|
25
23
|
/// @dev Thrown when `onlyActive` finds that `deadline` has already passed.
|
|
26
24
|
error Expired();
|
|
27
25
|
|
|
@@ -45,42 +43,78 @@ abstract contract CommandBase is NodeCalls, EndpointBase {
|
|
|
45
43
|
_;
|
|
46
44
|
}
|
|
47
45
|
|
|
46
|
+
/// @notice Close a command execution and refund unspent value to `account`.
|
|
47
|
+
/// @param exec Command execution to close.
|
|
48
|
+
/// @param account Account that should receive any unspent value.
|
|
49
|
+
/// @return output Final encoded output block stream.
|
|
50
|
+
/// @return transactions Final encoded transaction block stream.
|
|
51
|
+
function close(
|
|
52
|
+
Execution memory exec,
|
|
53
|
+
bytes32 account
|
|
54
|
+
) internal returns (bytes memory output, bytes memory transactions) {
|
|
55
|
+
if (exec.budget == 0 && Cursors.initial(exec.writers)) return ("", "");
|
|
56
|
+
|
|
57
|
+
output = close(exec);
|
|
58
|
+
uint amount = exec.refundValue(account, nativeAsset);
|
|
59
|
+
if (amount != 0) {
|
|
60
|
+
emit Received(account, nativeAsset, amount, Actions.Refund, 0);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
transactions = exec.finishTransactions();
|
|
64
|
+
}
|
|
65
|
+
|
|
48
66
|
/// @notice Publish command metadata and a default label.
|
|
49
|
-
/// @param name
|
|
50
|
-
///
|
|
51
|
-
/// @param
|
|
52
|
-
/// @param
|
|
53
|
-
/// @param
|
|
67
|
+
/// @param name Command entrypoint name and default label. It must exactly
|
|
68
|
+
/// match the Solidity command function name used by the canonical ABI.
|
|
69
|
+
/// @param state State block specification.
|
|
70
|
+
/// @param input Input block specification.
|
|
71
|
+
/// @param output Output block specification.
|
|
72
|
+
/// @param transactions Number of transaction blocks produced per batch, or zero for none.
|
|
54
73
|
/// @param funded Whether the command accepts nonzero native value.
|
|
55
74
|
/// @param admin Whether the command is restricted to the admin account.
|
|
56
75
|
/// @return id Command node ID.
|
|
57
76
|
/// @return descriptor Packed endpoint lane metadata and flags.
|
|
58
77
|
function command(
|
|
59
78
|
string memory name,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
79
|
+
uint state,
|
|
80
|
+
uint input,
|
|
81
|
+
uint output,
|
|
82
|
+
uint8 transactions,
|
|
64
83
|
bool funded,
|
|
65
84
|
bool admin
|
|
66
|
-
) internal returns (uint id,
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
85
|
+
) internal returns (uint id, uint descriptor) {
|
|
86
|
+
id = Nodes.toCommand(Selectors.command(name), address(this));
|
|
87
|
+
uint8 flags;
|
|
88
|
+
if (funded) flags |= Descriptors.Funded;
|
|
89
|
+
if (admin) flags |= Descriptors.Admin;
|
|
90
|
+
descriptor = endpoint(id, name, state, input, output, transactions, flags);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/// @notice Open a command state stream and return the expected output block count.
|
|
94
|
+
/// @param source State block stream to open.
|
|
95
|
+
/// @param descriptor Packed command endpoint descriptor.
|
|
96
|
+
/// @param batches Required batch count, or zero to accept the state count.
|
|
97
|
+
/// @return exec Execution with its output buffer metadata initialized for the state batch count.
|
|
98
|
+
function openState(
|
|
99
|
+
bytes calldata source,
|
|
100
|
+
uint descriptor,
|
|
101
|
+
uint batches
|
|
102
|
+
) internal view returns (Execution memory exec) {
|
|
103
|
+
return Executions.openState(source, descriptor, batches);
|
|
70
104
|
}
|
|
71
105
|
|
|
72
|
-
/// @notice Open
|
|
73
|
-
/// @param
|
|
106
|
+
/// @notice Open a command execution with batches derived from its input and state lanes.
|
|
107
|
+
/// @param state Current command state block stream.
|
|
108
|
+
/// @param input Command input block stream.
|
|
74
109
|
/// @param descriptor Packed command endpoint descriptor.
|
|
75
|
-
/// @
|
|
76
|
-
/// @return
|
|
77
|
-
/// @return outputs Number of output blocks implied by the matched group count.
|
|
110
|
+
/// @param batches Required batch count, or zero to reconcile the lane counts.
|
|
111
|
+
/// @return exec Execution with its output buffer metadata initialized for the reconciled batch count.
|
|
78
112
|
function openCommand(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
uint
|
|
83
|
-
|
|
84
|
-
(state, ,
|
|
113
|
+
bytes calldata state,
|
|
114
|
+
bytes calldata input,
|
|
115
|
+
uint descriptor,
|
|
116
|
+
uint batches
|
|
117
|
+
) internal view returns (Execution memory exec) {
|
|
118
|
+
return Executions.open(state, input, descriptor, batches);
|
|
85
119
|
}
|
|
86
120
|
}
|
package/commands/Burn.sol
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import { CommandBase,
|
|
5
|
-
|
|
6
|
-
using Cursors for Cur;
|
|
4
|
+
import { Execution, Executions, CommandBase, Lanes, Specs } from "./Base.sol";
|
|
5
|
+
using Executions for Execution;
|
|
7
6
|
|
|
7
|
+
/// @notice Hook implemented by hosts that burn account assets.
|
|
8
8
|
abstract contract BurnHook {
|
|
9
9
|
/// @notice Override to burn or consume the provided balance amount.
|
|
10
10
|
/// Called once per BALANCE block in state.
|
|
@@ -19,24 +19,29 @@ 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
|
+
uint private immutable descriptor;
|
|
23
23
|
|
|
24
24
|
constructor() {
|
|
25
|
-
(, descriptor) = command("burn",
|
|
25
|
+
(, descriptor) = command("burn", Specs.Balance, Specs.Empty, Specs.Empty, 0, false, false);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/// @notice Burn each BALANCE block from the command state.
|
|
29
|
-
/// @param
|
|
29
|
+
/// @param state BALANCE block stream.
|
|
30
30
|
/// @return Empty output state.
|
|
31
31
|
/// @return Empty transaction stream.
|
|
32
|
-
function burn(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
function burn(
|
|
33
|
+
bytes32 account,
|
|
34
|
+
bytes calldata state,
|
|
35
|
+
bytes calldata
|
|
36
|
+
) external onlyCommand returns (bytes memory, bytes memory) {
|
|
37
|
+
Execution memory exec = openState(state, descriptor, 0);
|
|
38
|
+
|
|
39
|
+
while (exec.more()) {
|
|
40
|
+
(bytes32 asset, uint amount) = exec.unpackBalance(Lanes.State);
|
|
41
|
+
burn(account, asset, amount);
|
|
38
42
|
}
|
|
39
|
-
|
|
43
|
+
|
|
44
|
+
return close(exec, account);
|
|
40
45
|
}
|
|
41
46
|
}
|
|
42
47
|
|
package/commands/Credit.sol
CHANGED
|
@@ -1,42 +1,43 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import { CommandBase,
|
|
5
|
-
import {
|
|
6
|
-
import { CreditAccountHook } from "../core/Settlement.sol";
|
|
4
|
+
import {Execution, Executions, CommandBase, Lanes, Specs} from "./Base.sol";
|
|
5
|
+
import {CreditAccountHook} from "../core/Settlement.sol";
|
|
7
6
|
|
|
8
|
-
using
|
|
7
|
+
using Executions for Execution;
|
|
9
8
|
|
|
10
9
|
/// @title CreditAccount
|
|
11
10
|
/// @notice Command that delivers BALANCE state blocks to an account via a virtual hook.
|
|
12
11
|
/// Use for internally recording credits that have already been settled externally.
|
|
13
12
|
abstract contract CreditAccount is CommandBase, CreditAccountHook {
|
|
14
|
-
|
|
15
|
-
uint
|
|
13
|
+
uint private immutable descriptor;
|
|
14
|
+
uint private immutable id;
|
|
16
15
|
|
|
17
16
|
constructor() {
|
|
18
|
-
(
|
|
17
|
+
(id, descriptor) = command("creditAccount", Specs.Balance, Specs.Empty, Specs.Empty, 0, false, false);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/// @notice Return the registered CREDIT_ACCOUNT command ID.
|
|
21
|
+
function creditAccountId() internal view returns (uint) {
|
|
22
|
+
return id;
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
/// @notice Credit each BALANCE block from the command state to the command account.
|
|
22
|
-
/// @param
|
|
26
|
+
/// @param state BALANCE block stream.
|
|
23
27
|
/// @return Empty output state.
|
|
24
28
|
/// @return Empty transaction stream.
|
|
25
29
|
function creditAccount(
|
|
26
|
-
|
|
30
|
+
bytes32 account,
|
|
31
|
+
bytes calldata state,
|
|
32
|
+
bytes calldata
|
|
27
33
|
) external onlyCommand returns (bytes memory, bytes memory) {
|
|
28
|
-
|
|
34
|
+
Execution memory exec = openState(state, descriptor, 0);
|
|
29
35
|
|
|
30
|
-
while (
|
|
31
|
-
(bytes32 asset, uint amount) =
|
|
32
|
-
creditAccount(
|
|
36
|
+
while (exec.more()) {
|
|
37
|
+
(bytes32 asset, uint amount) = exec.unpackBalance(Lanes.State);
|
|
38
|
+
creditAccount(account, asset, amount);
|
|
33
39
|
}
|
|
34
|
-
|
|
40
|
+
|
|
41
|
+
return close(exec, account);
|
|
35
42
|
}
|
|
36
43
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
package/commands/Debit.sol
CHANGED
|
@@ -1,55 +1,52 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { DebitAccountHook } from "../core/Settlement.sol";
|
|
4
|
+
import {Execution, Executions, CommandBase, Lanes, Specs} from "./Base.sol";
|
|
5
|
+
import {DebitAccountHook} from "../core/Settlement.sol";
|
|
7
6
|
|
|
8
|
-
using
|
|
9
|
-
using Writers for Writer;
|
|
7
|
+
using Executions for Execution;
|
|
10
8
|
|
|
11
9
|
/// @title DebitAccount
|
|
12
10
|
/// @notice Command that deducts AMOUNT blocks from an account and emits matching BALANCE state.
|
|
13
11
|
/// Use for internally recording debits. The virtual `debitAccount` hook is called once per
|
|
14
|
-
/// AMOUNT block; the default batch implementation handles the full
|
|
12
|
+
/// AMOUNT block; the default batch implementation handles the full input loop.
|
|
15
13
|
abstract contract DebitAccount is CommandBase, DebitAccountHook {
|
|
16
|
-
|
|
17
|
-
uint
|
|
14
|
+
uint private immutable descriptor;
|
|
15
|
+
uint private immutable id;
|
|
18
16
|
|
|
19
17
|
constructor() {
|
|
20
|
-
(
|
|
18
|
+
(id, descriptor) = command("debitAccount", Specs.Empty, Specs.Amount, Specs.Balance, 0, false, false);
|
|
21
19
|
}
|
|
22
20
|
|
|
23
|
-
/// @notice
|
|
21
|
+
/// @notice Return the registered DEBIT_ACCOUNT command ID.
|
|
22
|
+
function debitAccountId() internal view returns (uint) {
|
|
23
|
+
return id;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/// @notice Override to customize input parsing or batching for debits.
|
|
24
27
|
/// The default implementation iterates AMOUNT blocks, calls
|
|
25
28
|
/// `debitAccount`, and emits matching BALANCE blocks.
|
|
26
|
-
function debitAccount(bytes32 account, bytes calldata
|
|
27
|
-
|
|
28
|
-
Writer memory output = Writers.allocBalances(outputs);
|
|
29
|
+
function debitAccount(bytes32 account, bytes calldata input) internal virtual returns (bytes memory, bytes memory) {
|
|
30
|
+
Execution memory exec = openInput(input, descriptor, 0);
|
|
29
31
|
|
|
30
|
-
while (
|
|
31
|
-
(bytes32 asset, uint amount) =
|
|
32
|
+
while (exec.more()) {
|
|
33
|
+
(bytes32 asset, uint amount) = exec.unpackAmount(Lanes.Input);
|
|
32
34
|
debitAccount(account, asset, amount);
|
|
33
|
-
|
|
35
|
+
exec.outputBalance(asset, amount);
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
return
|
|
38
|
+
return close(exec, account);
|
|
37
39
|
}
|
|
38
40
|
|
|
39
|
-
/// @notice Debit AMOUNT
|
|
40
|
-
/// @param
|
|
41
|
+
/// @notice Debit AMOUNT input blocks from the command account and output matching BALANCE blocks.
|
|
42
|
+
/// @param input AMOUNT block stream.
|
|
41
43
|
/// @return BALANCE block stream matching the debited amounts.
|
|
42
44
|
/// @return Empty transaction stream.
|
|
43
45
|
function debitAccount(
|
|
44
|
-
|
|
46
|
+
bytes32 account,
|
|
47
|
+
bytes calldata,
|
|
48
|
+
bytes calldata input
|
|
45
49
|
) external onlyCommand returns (bytes memory, bytes memory) {
|
|
46
|
-
return
|
|
50
|
+
return debitAccount(account, input);
|
|
47
51
|
}
|
|
48
52
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
package/commands/Deposit.sol
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import { Payable } from "../core/Payable.sol";
|
|
6
|
-
import { Cursors, Cur, Writer, Writers } from "../Cursors.sol";
|
|
7
|
-
import { Budget } from "../utils/Value.sol";
|
|
4
|
+
import { Execution, Executions, CommandBase, Lanes, Specs } from "./Base.sol";
|
|
8
5
|
|
|
9
|
-
using
|
|
10
|
-
using Writers for Writer;
|
|
6
|
+
using Executions for Execution;
|
|
11
7
|
|
|
8
|
+
/// @notice Hook implemented by hosts that accept account deposits.
|
|
12
9
|
abstract contract DepositHook {
|
|
13
10
|
/// @notice Override to receive externally sourced funds for `account`.
|
|
14
11
|
/// Called once per AMOUNT block. A matching BALANCE block is appended to the
|
|
@@ -19,6 +16,7 @@ abstract contract DepositHook {
|
|
|
19
16
|
function deposit(bytes32 account, bytes32 asset, uint amount) internal virtual;
|
|
20
17
|
}
|
|
21
18
|
|
|
19
|
+
/// @notice Hook implemented by hosts that accept value-funded deposits.
|
|
22
20
|
abstract contract DepositPayableHook {
|
|
23
21
|
/// @notice Override to receive externally sourced funds for `account`.
|
|
24
22
|
/// Called once per AMOUNT block. A matching BALANCE block is appended to the
|
|
@@ -26,8 +24,8 @@ abstract contract DepositPayableHook {
|
|
|
26
24
|
/// @param account Destination account identifier.
|
|
27
25
|
/// @param asset Asset identifier.
|
|
28
26
|
/// @param amount Amount received.
|
|
29
|
-
/// @param
|
|
30
|
-
function deposit(bytes32 account, bytes32 asset, uint amount,
|
|
27
|
+
/// @param funds Mutable execution used only for its remaining native-value budget.
|
|
28
|
+
function deposit(bytes32 account, bytes32 asset, uint amount, Execution memory funds) internal virtual;
|
|
31
29
|
}
|
|
32
30
|
|
|
33
31
|
/// @title Deposit
|
|
@@ -35,60 +33,61 @@ abstract contract DepositPayableHook {
|
|
|
35
33
|
/// Use `deposit` for assets arriving from outside the protocol (e.g. ERC-20 transfers, ETH).
|
|
36
34
|
/// For internal balance deductions, use `debitAccount` instead.
|
|
37
35
|
abstract contract Deposit is CommandBase, DepositHook {
|
|
38
|
-
|
|
36
|
+
uint private immutable descriptor;
|
|
39
37
|
|
|
40
38
|
constructor() {
|
|
41
|
-
(, descriptor) = command("deposit",
|
|
39
|
+
(, descriptor) = command("deposit", Specs.Empty, Specs.Amount, Specs.Balance, 0, false, false);
|
|
42
40
|
}
|
|
43
41
|
|
|
44
|
-
/// @notice Deposit AMOUNT
|
|
45
|
-
/// @param
|
|
42
|
+
/// @notice Deposit AMOUNT input blocks into the command account and output matching BALANCE blocks.
|
|
43
|
+
/// @param input AMOUNT block stream.
|
|
46
44
|
/// @return BALANCE block stream matching the deposited amounts.
|
|
47
45
|
/// @return Empty transaction stream.
|
|
48
46
|
function deposit(
|
|
49
|
-
|
|
47
|
+
bytes32 account,
|
|
48
|
+
bytes calldata,
|
|
49
|
+
bytes calldata input
|
|
50
50
|
) external onlyCommand returns (bytes memory, bytes memory) {
|
|
51
|
-
|
|
52
|
-
Writer memory output = Writers.allocBalances(outputs);
|
|
51
|
+
Execution memory exec = openInput(input, descriptor, 0);
|
|
53
52
|
|
|
54
|
-
while (
|
|
55
|
-
(bytes32 asset, uint amount) =
|
|
56
|
-
deposit(
|
|
57
|
-
|
|
53
|
+
while (exec.more()) {
|
|
54
|
+
(bytes32 asset, uint amount) = exec.unpackAmount(Lanes.Input);
|
|
55
|
+
deposit(account, asset, amount);
|
|
56
|
+
exec.outputBalance(asset, amount);
|
|
58
57
|
}
|
|
59
58
|
|
|
60
|
-
return (
|
|
59
|
+
return close(exec, account);
|
|
61
60
|
}
|
|
62
61
|
}
|
|
63
62
|
|
|
64
63
|
/// @title DepositPayable
|
|
65
64
|
/// @notice Command that receives externally sourced assets and records them as BALANCE state.
|
|
66
65
|
/// Use `depositPayable` when the hook needs tracked access to `msg.value` via a mutable budget.
|
|
67
|
-
abstract contract DepositPayable is CommandBase,
|
|
68
|
-
|
|
66
|
+
abstract contract DepositPayable is CommandBase, DepositPayableHook {
|
|
67
|
+
uint private immutable descriptor;
|
|
69
68
|
|
|
70
69
|
constructor() {
|
|
71
|
-
(, descriptor) = command("depositPayable",
|
|
70
|
+
(, descriptor) = command("depositPayable", Specs.Empty, Specs.Amount, Specs.Balance, 0, true, false);
|
|
72
71
|
}
|
|
73
72
|
|
|
74
|
-
/// @notice Deposit AMOUNT
|
|
75
|
-
/// @param
|
|
73
|
+
/// @notice Deposit AMOUNT input blocks with access to a mutable native-value budget.
|
|
74
|
+
/// @param input AMOUNT block stream.
|
|
76
75
|
/// @return BALANCE block stream matching the deposited amounts.
|
|
77
76
|
/// @return Remaining native value as a refund transaction stream.
|
|
78
77
|
function depositPayable(
|
|
79
|
-
|
|
78
|
+
bytes32 account,
|
|
79
|
+
bytes calldata,
|
|
80
|
+
bytes calldata input
|
|
80
81
|
) external payable onlyCommand returns (bytes memory, bytes memory) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
(
|
|
87
|
-
deposit(c.account, asset, amount, budget);
|
|
88
|
-
output.appendBalance(asset, amount);
|
|
82
|
+
Execution memory exec = openInput(input, descriptor, 0);
|
|
83
|
+
|
|
84
|
+
while (exec.more()) {
|
|
85
|
+
(bytes32 asset, uint amount) = exec.unpackAmount(Lanes.Input);
|
|
86
|
+
deposit(account, asset, amount, exec);
|
|
87
|
+
exec.outputBalance(asset, amount);
|
|
89
88
|
}
|
|
90
89
|
|
|
91
|
-
return (
|
|
90
|
+
return close(exec, account);
|
|
92
91
|
}
|
|
93
92
|
}
|
|
94
93
|
|
package/commands/Payout.sol
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import {Cursors, Cur} from "../Cursors.sol";
|
|
4
|
+
import {Execution, Executions, CommandBase, Lanes, Specs} from "./Base.sol";
|
|
6
5
|
|
|
7
|
-
using
|
|
6
|
+
using Executions for Execution;
|
|
8
7
|
|
|
8
|
+
/// @notice Hook implemented by hosts that pay balances to accounts.
|
|
9
9
|
abstract contract PayoutHook {
|
|
10
10
|
/// @notice Override to pay `amount` from `account` to `to`.
|
|
11
|
-
/// Called once per paired BALANCE state block and ACCOUNT
|
|
11
|
+
/// Called once per paired BALANCE state block and ACCOUNT input block.
|
|
12
12
|
/// @param account Source account identifier.
|
|
13
13
|
/// @param to Destination account identifier.
|
|
14
14
|
/// @param asset Asset identifier.
|
|
@@ -17,26 +17,32 @@ abstract contract PayoutHook {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/// @title Payout
|
|
20
|
-
/// @notice Command that sinks BALANCE state blocks to matching ACCOUNT
|
|
20
|
+
/// @notice Command that sinks BALANCE state blocks to matching ACCOUNT input 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
|
+
uint private immutable descriptor;
|
|
24
24
|
|
|
25
25
|
constructor() {
|
|
26
|
-
(, descriptor) = command("payout",
|
|
26
|
+
(, descriptor) = command("payout", Specs.Balance, Specs.Account, Specs.Empty, 0, false, false);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
/// @notice Pay out BALANCE state blocks to matching ACCOUNT
|
|
30
|
-
/// @param
|
|
29
|
+
/// @notice Pay out BALANCE state blocks to matching ACCOUNT input blocks.
|
|
30
|
+
/// @param state BALANCE block stream.
|
|
31
|
+
/// @param input Matching ACCOUNT block stream.
|
|
31
32
|
/// @return Empty output state.
|
|
32
33
|
/// @return Empty transaction stream.
|
|
33
|
-
function payout(
|
|
34
|
-
|
|
34
|
+
function payout(
|
|
35
|
+
bytes32 account,
|
|
36
|
+
bytes calldata state,
|
|
37
|
+
bytes calldata input
|
|
38
|
+
) external onlyCommand returns (bytes memory, bytes memory) {
|
|
39
|
+
Execution memory exec = openCommand(state, input, descriptor, 0);
|
|
35
40
|
|
|
36
|
-
while (
|
|
37
|
-
(bytes32 asset, uint amount) =
|
|
38
|
-
payout(
|
|
41
|
+
while (exec.more()) {
|
|
42
|
+
(bytes32 asset, uint amount) = exec.unpackBalance(Lanes.State);
|
|
43
|
+
payout(account, exec.unpackAccount(Lanes.Input), asset, amount);
|
|
39
44
|
}
|
|
40
|
-
|
|
45
|
+
|
|
46
|
+
return close(exec, account);
|
|
41
47
|
}
|
|
42
48
|
}
|