@rootzero/contracts 1.28.0 → 1.29.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 +13 -0
- package/Endpoints.sol +5 -5
- package/README.md +15 -8
- package/commands/Bootstrap.sol +3 -1
- package/commands/Cashout.sol +6 -5
- package/commands/Credit.sol +6 -5
- package/commands/Debit.sol +7 -6
- package/commands/Repay.sol +6 -5
- package/commands/Settle.sol +6 -5
- package/core/Pipeline.sol +10 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,19 @@ sections are immutable and must continue to describe the tagged release.
|
|
|
8
8
|
|
|
9
9
|
## Unreleased
|
|
10
10
|
|
|
11
|
+
## 1.29.0
|
|
12
|
+
|
|
13
|
+
### Breaking Changes
|
|
14
|
+
|
|
15
|
+
- `ExecuteHook.execute` and the optimized local command helpers now return a
|
|
16
|
+
leading `bool handled`. A local command returned as unhandled is invoked
|
|
17
|
+
through its trusted normal external command entrypoint; handled commands keep
|
|
18
|
+
the optimized internal path and are authorized by the hook implementation.
|
|
19
|
+
- Renamed `CashoutInternal`, `DebitAccountInternal`, `CreditAccountInternal`,
|
|
20
|
+
`SettleInternal`, and `RepayInternal` to `ExecuteCashout`,
|
|
21
|
+
`ExecuteDebitAccount`, `ExecuteCreditAccount`, `ExecuteSettle`, and
|
|
22
|
+
`ExecuteRepay`.
|
|
23
|
+
|
|
11
24
|
## 1.28.0
|
|
12
25
|
|
|
13
26
|
### Breaking Changes
|
package/Endpoints.sol
CHANGED
|
@@ -14,23 +14,23 @@ import {CommandBase} from "./commands/Base.sol";
|
|
|
14
14
|
import {Allocate, AllocateHook} from "./commands/Allocate.sol";
|
|
15
15
|
import {Burn, BurnHook} from "./commands/Burn.sol";
|
|
16
16
|
import {Bootstrap} from "./commands/Bootstrap.sol";
|
|
17
|
-
import {Cashout, CashoutHook,
|
|
18
|
-
import {CreditAccount,
|
|
19
|
-
import {DebitAccount,
|
|
17
|
+
import {Cashout, CashoutHook, ExecuteCashout} from "./commands/Cashout.sol";
|
|
18
|
+
import {CreditAccount, ExecuteCreditAccount} from "./commands/Credit.sol";
|
|
19
|
+
import {DebitAccount, ExecuteDebitAccount} from "./commands/Debit.sol";
|
|
20
20
|
import {Deposit, DepositHook, DepositPayable, DepositPayableHook} from "./commands/Deposit.sol";
|
|
21
21
|
import {Payout, PayoutHook} from "./commands/Payout.sol";
|
|
22
22
|
import {Provision, ProvisionHook, ProvisionPayable, ProvisionPayableHook} from "./commands/Provision.sol";
|
|
23
23
|
import {RecoverPayable, RecoverPayableHook} from "./commands/Recover.sol";
|
|
24
24
|
import {
|
|
25
25
|
Repay,
|
|
26
|
-
|
|
26
|
+
ExecuteRepay,
|
|
27
27
|
RepayPayable,
|
|
28
28
|
RepayPayableHook,
|
|
29
29
|
RepayPosition,
|
|
30
30
|
RepayPositionPayable
|
|
31
31
|
} from "./commands/Repay.sol";
|
|
32
32
|
import {RelayPayable, RelayBalancePayable, RelayPayableHook} from "./commands/Relay.sol";
|
|
33
|
-
import {Settle, SettlePayable, SettlePayableHook,
|
|
33
|
+
import {Settle, SettlePayable, SettlePayableHook, ExecuteSettle} from "./commands/Settle.sol";
|
|
34
34
|
import {Withdraw, WithdrawHook} from "./commands/Withdraw.sol";
|
|
35
35
|
|
|
36
36
|
// Admin commands
|
package/README.md
CHANGED
|
@@ -388,13 +388,17 @@ while (cur.more()) {
|
|
|
388
388
|
(bytes4 selector, address target) = unpackCommand(cmd);
|
|
389
389
|
if (budget < value) revert InsufficientValue();
|
|
390
390
|
unchecked { budget -= value; }
|
|
391
|
+
bool handled;
|
|
392
|
+
bytes memory output;
|
|
391
393
|
uint credit;
|
|
392
394
|
if (target == address(this)) {
|
|
393
|
-
(
|
|
394
|
-
}
|
|
395
|
+
(handled, output, credit) = execute(cmd, account, state, input, value);
|
|
396
|
+
}
|
|
397
|
+
if (!handled) {
|
|
395
398
|
ensureTrusted(cmd);
|
|
396
|
-
(
|
|
399
|
+
(output, credit) = rawCommandCall(selector, target, value, account, state, input);
|
|
397
400
|
}
|
|
401
|
+
state = output;
|
|
398
402
|
budget += credit;
|
|
399
403
|
}
|
|
400
404
|
if (state.length != 0) revert UnexpectedState();
|
|
@@ -414,15 +418,18 @@ parameters. A `resources` word is never itself native value; EVM adapters use
|
|
|
414
418
|
`useResourceValue` to extract its low 128-bit value lane before spending it.
|
|
415
419
|
|
|
416
420
|
Hosts that implement a pipeline locally can inherit `Bootstrap`,
|
|
417
|
-
`
|
|
418
|
-
`
|
|
419
|
-
`
|
|
421
|
+
`ExecuteCashout`, `ExecuteDebitAccount`, `ExecuteCreditAccount`,
|
|
422
|
+
`ExecuteSettle`, and
|
|
423
|
+
`ExecuteRepay` to register canonical command metadata while executing
|
|
420
424
|
their local command IDs through `executeBootstrap`, `executeCashout`,
|
|
421
425
|
`executeDebitAccount`, `executeCreditAccount`, `executeSettle`, and
|
|
422
426
|
`executeRepay`. The bootstrap, cashout, and debit adapters decode fixed-stride
|
|
423
427
|
calldata input directly; the other three
|
|
424
|
-
decode memory-backed pipeline state. All
|
|
425
|
-
|
|
428
|
+
decode memory-backed pipeline state. All return `handled = true` and avoid an
|
|
429
|
+
external self-call. The host's `execute` hook must authorize a command before
|
|
430
|
+
returning true. Returning `handled = false` delegates a local command to its
|
|
431
|
+
trusted normal external entrypoint. Pass the step value into each adapter.
|
|
432
|
+
Bootstrap is pipeline-local rather than an
|
|
426
433
|
externally callable command and may consume value for native-asset balance;
|
|
427
434
|
the other five reject nonzero value because those commands are non-funded.
|
|
428
435
|
|
package/commands/Bootstrap.sol
CHANGED
|
@@ -52,6 +52,7 @@ abstract contract Bootstrap is CommandBase, DebitAccountHook {
|
|
|
52
52
|
/// @param state Empty pipeline state required by the command schema.
|
|
53
53
|
/// @param input BOOTSTRAP block stream.
|
|
54
54
|
/// @param value Native value available to fund native-asset balances.
|
|
55
|
+
/// @return handled Always true because this helper executed the command.
|
|
55
56
|
/// @return output One BALANCE block per BOOTSTRAP input.
|
|
56
57
|
/// @return credit Sourced budget contributions plus unused assigned value.
|
|
57
58
|
function executeBootstrap(
|
|
@@ -59,7 +60,7 @@ abstract contract Bootstrap is CommandBase, DebitAccountHook {
|
|
|
59
60
|
bytes memory state,
|
|
60
61
|
bytes calldata input,
|
|
61
62
|
uint value
|
|
62
|
-
) internal returns (bytes memory output, uint credit) {
|
|
63
|
+
) internal returns (bool handled, bytes memory output, uint credit) {
|
|
63
64
|
if (state.length != 0) revert UnexpectedState();
|
|
64
65
|
if (input.length % Sizes.Bootstrap != 0) revert Blocks.InvalidBlock();
|
|
65
66
|
|
|
@@ -77,5 +78,6 @@ abstract contract Bootstrap is CommandBase, DebitAccountHook {
|
|
|
77
78
|
i += Sizes.Balance;
|
|
78
79
|
}
|
|
79
80
|
}
|
|
81
|
+
handled = true;
|
|
80
82
|
}
|
|
81
83
|
}
|
package/commands/Cashout.sol
CHANGED
|
@@ -54,14 +54,15 @@ abstract contract Cashout is CommandBase, CashoutHook, Action {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
/// @title
|
|
58
|
-
/// @notice Extends cashout with optimized local pipeline
|
|
59
|
-
abstract contract
|
|
57
|
+
/// @title ExecuteCashout
|
|
58
|
+
/// @notice Extends cashout with optimized local pipeline execution.
|
|
59
|
+
abstract contract ExecuteCashout is Cashout {
|
|
60
60
|
/// @notice Execute cashout directly against a calldata CASHOUT stream.
|
|
61
61
|
/// @param account Account whose native asset is withdrawn.
|
|
62
62
|
/// @param state Empty pipeline state required by the command schema.
|
|
63
63
|
/// @param input CASHOUT block stream.
|
|
64
64
|
/// @param value Native value assigned to this command; must be zero.
|
|
65
|
+
/// @return handled Always true because this helper executed the command.
|
|
65
66
|
/// @return output Empty output state.
|
|
66
67
|
/// @return credit Zero native budget credit.
|
|
67
68
|
function executeCashout(
|
|
@@ -69,7 +70,7 @@ abstract contract CashoutInternal is Cashout {
|
|
|
69
70
|
bytes memory state,
|
|
70
71
|
bytes calldata input,
|
|
71
72
|
uint value
|
|
72
|
-
) internal returns (bytes memory, uint) {
|
|
73
|
+
) internal returns (bool handled, bytes memory output, uint credit) {
|
|
73
74
|
if (value != 0) revert ValueNotAllowed();
|
|
74
75
|
if (state.length != 0) revert UnexpectedState();
|
|
75
76
|
if (input.length % Sizes.Cashout != 0) revert Blocks.InvalidBlock();
|
|
@@ -81,6 +82,6 @@ abstract contract CashoutInternal is Cashout {
|
|
|
81
82
|
abs += Sizes.Cashout;
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
|
-
return ("", 0);
|
|
85
|
+
return (true, "", 0);
|
|
85
86
|
}
|
|
86
87
|
}
|
package/commands/Credit.sol
CHANGED
|
@@ -43,16 +43,17 @@ abstract contract CreditAccount is CommandBase, CreditAccountHook {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
/// @title
|
|
47
|
-
/// @notice Extends the advertised credit-account command with memory-state pipeline
|
|
46
|
+
/// @title ExecuteCreditAccount
|
|
47
|
+
/// @notice Extends the advertised credit-account command with memory-state pipeline execution.
|
|
48
48
|
/// @dev This adapter is not a separate command. It uses the command ID and account hook
|
|
49
49
|
/// inherited from `CreditAccount` while accepting the state location used by `Pipeline`.
|
|
50
|
-
abstract contract
|
|
50
|
+
abstract contract ExecuteCreditAccount is CreditAccount {
|
|
51
51
|
/// @notice Execute the inherited credit-account command from an internal pipeline.
|
|
52
52
|
/// @param account Account credited by each balance.
|
|
53
53
|
/// @param state BALANCE block stream held in pipeline memory.
|
|
54
54
|
/// @param input Empty input required by the command schema.
|
|
55
55
|
/// @param value Native value assigned to the command; must be zero.
|
|
56
|
+
/// @return handled Always true because this helper executed the command.
|
|
56
57
|
/// @return output Empty output state.
|
|
57
58
|
/// @return credit Zero native budget credit.
|
|
58
59
|
function executeCreditAccount(
|
|
@@ -60,7 +61,7 @@ abstract contract CreditAccountInternal is CreditAccount {
|
|
|
60
61
|
bytes memory state,
|
|
61
62
|
bytes calldata input,
|
|
62
63
|
uint value
|
|
63
|
-
) internal returns (bytes memory, uint) {
|
|
64
|
+
) internal returns (bool handled, bytes memory output, uint credit) {
|
|
64
65
|
if (value != 0) revert ValueNotAllowed();
|
|
65
66
|
if (input.length != 0) revert UnexpectedInput();
|
|
66
67
|
if (state.length == 0) revert Blocks.EmptyRun();
|
|
@@ -74,6 +75,6 @@ abstract contract CreditAccountInternal is CreditAccount {
|
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
77
|
|
|
77
|
-
return ("", 0);
|
|
78
|
+
return (true, "", 0);
|
|
78
79
|
}
|
|
79
80
|
}
|
package/commands/Debit.sol
CHANGED
|
@@ -46,16 +46,17 @@ abstract contract DebitAccount is CommandBase, DebitAccountHook {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
/// @title
|
|
50
|
-
/// @notice Extends the advertised debit-account command with optimized pipeline
|
|
49
|
+
/// @title ExecuteDebitAccount
|
|
50
|
+
/// @notice Extends the advertised debit-account command with optimized pipeline execution.
|
|
51
51
|
/// @dev This adapter is not a separate command. It uses the command ID and account hook
|
|
52
52
|
/// inherited from `DebitAccount` while decoding its fixed-stride input directly from calldata.
|
|
53
|
-
abstract contract
|
|
53
|
+
abstract contract ExecuteDebitAccount is DebitAccount {
|
|
54
54
|
/// @notice Execute the inherited debit-account command from an internal pipeline.
|
|
55
55
|
/// @param account Account whose funds are debited.
|
|
56
56
|
/// @param state Empty pipeline state required by the command schema.
|
|
57
57
|
/// @param input AMOUNT block stream.
|
|
58
58
|
/// @param value Native value assigned to the command; must be zero.
|
|
59
|
+
/// @return handled Always true because this helper executed the command.
|
|
59
60
|
/// @return output BALANCE block stream matching the debited amounts.
|
|
60
61
|
/// @return credit Zero native budget credit.
|
|
61
62
|
function executeDebitAccount(
|
|
@@ -63,14 +64,14 @@ abstract contract DebitAccountInternal is DebitAccount {
|
|
|
63
64
|
bytes memory state,
|
|
64
65
|
bytes calldata input,
|
|
65
66
|
uint value
|
|
66
|
-
) internal returns (bytes memory, uint) {
|
|
67
|
+
) internal returns (bool handled, bytes memory output, uint credit) {
|
|
67
68
|
if (value != 0) revert ValueNotAllowed();
|
|
68
69
|
if (state.length != 0) revert UnexpectedState();
|
|
69
70
|
if (input.length == 0) revert Blocks.EmptyRun();
|
|
70
71
|
if (input.length % Sizes.Amount != 0) revert Blocks.InvalidBlock();
|
|
71
72
|
|
|
72
73
|
(uint abs, uint end) = Cursors.bounds(input);
|
|
73
|
-
|
|
74
|
+
output = new bytes(input.length);
|
|
74
75
|
uint i;
|
|
75
76
|
|
|
76
77
|
while (abs < end) {
|
|
@@ -83,6 +84,6 @@ abstract contract DebitAccountInternal is DebitAccount {
|
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
return (output, 0);
|
|
87
|
+
return (true, output, 0);
|
|
87
88
|
}
|
|
88
89
|
}
|
package/commands/Repay.sol
CHANGED
|
@@ -146,16 +146,17 @@ abstract contract RepayPositionPayable is CommandBase, RepayPayableHook, Action
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
/// @title
|
|
150
|
-
/// @notice Extends the advertised repay command with memory-state pipeline
|
|
149
|
+
/// @title ExecuteRepay
|
|
150
|
+
/// @notice Extends the advertised repay command with memory-state pipeline execution.
|
|
151
151
|
/// @dev This adapter is not a separate command. It uses the command ID and repayment hook
|
|
152
152
|
/// inherited from `Repay` while accepting the state location used by `Pipeline`.
|
|
153
|
-
abstract contract
|
|
153
|
+
abstract contract ExecuteRepay is Repay {
|
|
154
154
|
/// @notice Execute the inherited repay command from an internal pipeline.
|
|
155
155
|
/// @param account Account whose liabilities are repaid.
|
|
156
156
|
/// @param state DEBT block stream held in pipeline memory.
|
|
157
157
|
/// @param input Empty input required by the command schema.
|
|
158
158
|
/// @param value Native value assigned to the command; must be zero.
|
|
159
|
+
/// @return handled Always true because this helper executed the command.
|
|
159
160
|
/// @return output Empty output state.
|
|
160
161
|
/// @return credit Zero native budget credit.
|
|
161
162
|
function executeRepay(
|
|
@@ -163,7 +164,7 @@ abstract contract RepayInternal is Repay {
|
|
|
163
164
|
bytes memory state,
|
|
164
165
|
bytes calldata input,
|
|
165
166
|
uint value
|
|
166
|
-
) internal returns (bytes memory, uint) {
|
|
167
|
+
) internal returns (bool handled, bytes memory output, uint credit) {
|
|
167
168
|
if (value != 0) revert ValueNotAllowed();
|
|
168
169
|
if (input.length != 0) revert UnexpectedInput();
|
|
169
170
|
if (state.length == 0) revert Blocks.EmptyRun();
|
|
@@ -177,6 +178,6 @@ abstract contract RepayInternal is Repay {
|
|
|
177
178
|
}
|
|
178
179
|
}
|
|
179
180
|
|
|
180
|
-
return ("", 0);
|
|
181
|
+
return (true, "", 0);
|
|
181
182
|
}
|
|
182
183
|
}
|
package/commands/Settle.sol
CHANGED
|
@@ -93,16 +93,17 @@ abstract contract SettlePayable is CommandBase, SettlePayableHook, Action {
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
/// @title
|
|
97
|
-
/// @notice Extends the advertised settle command with memory-state pipeline
|
|
96
|
+
/// @title ExecuteSettle
|
|
97
|
+
/// @notice Extends the advertised settle command with memory-state pipeline execution.
|
|
98
98
|
/// @dev This adapter is not a separate command. It uses the command ID and settlement hook
|
|
99
99
|
/// inherited from `Settle` while accepting the state location used by `Pipeline`.
|
|
100
|
-
abstract contract
|
|
100
|
+
abstract contract ExecuteSettle is Settle {
|
|
101
101
|
/// @notice Execute the inherited settle command from an internal pipeline.
|
|
102
102
|
/// @param account Account for which each position is settled.
|
|
103
103
|
/// @param state POSITION block stream held in pipeline memory.
|
|
104
104
|
/// @param input Empty input required by the command schema.
|
|
105
105
|
/// @param value Native value assigned to the command; must be zero.
|
|
106
|
+
/// @return handled Always true because this helper executed the command.
|
|
106
107
|
/// @return output Empty output state.
|
|
107
108
|
/// @return credit Zero native budget credit.
|
|
108
109
|
function executeSettle(
|
|
@@ -110,7 +111,7 @@ abstract contract SettleInternal is Settle {
|
|
|
110
111
|
bytes memory state,
|
|
111
112
|
bytes calldata input,
|
|
112
113
|
uint value
|
|
113
|
-
) internal returns (bytes memory, uint) {
|
|
114
|
+
) internal returns (bool handled, bytes memory output, uint credit) {
|
|
114
115
|
if (value != 0) revert ValueNotAllowed();
|
|
115
116
|
if (input.length != 0) revert UnexpectedInput();
|
|
116
117
|
if (state.length == 0) revert Blocks.EmptyRun();
|
|
@@ -124,6 +125,6 @@ abstract contract SettleInternal is Settle {
|
|
|
124
125
|
}
|
|
125
126
|
}
|
|
126
127
|
|
|
127
|
-
return ("", 0);
|
|
128
|
+
return (true, "", 0);
|
|
128
129
|
}
|
|
129
130
|
}
|
package/core/Pipeline.sol
CHANGED
|
@@ -21,15 +21,17 @@ abstract contract PipeHook {
|
|
|
21
21
|
|
|
22
22
|
/// @notice Hook implemented by pipeline hosts that execute host-local commands.
|
|
23
23
|
abstract contract ExecuteHook {
|
|
24
|
-
/// @notice
|
|
25
|
-
/// @dev Implementations
|
|
24
|
+
/// @notice Try to execute one command whose node ID targets the current host.
|
|
25
|
+
/// @dev Implementations returning `handled = true` are responsible for
|
|
26
|
+
/// authorizing the command. Return false without side effects to delegate to
|
|
27
|
+
/// the trusted normal external entrypoint. Implementations may revert instead.
|
|
26
28
|
function execute(
|
|
27
29
|
uint cmd,
|
|
28
30
|
bytes32 account,
|
|
29
31
|
bytes memory state,
|
|
30
32
|
bytes calldata input,
|
|
31
33
|
uint value
|
|
32
|
-
) internal virtual returns (bytes memory output, uint credit);
|
|
34
|
+
) internal virtual returns (bool handled, bytes memory output, uint credit);
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
/// @title Pipeline
|
|
@@ -43,7 +45,11 @@ abstract contract Pipeline is TrustAccess, PipeHook, ExecuteHook {
|
|
|
43
45
|
uint value
|
|
44
46
|
) private returns (bytes memory output, uint credit) {
|
|
45
47
|
(bytes4 selector, address target) = unpackCommand(cmd);
|
|
46
|
-
if (target == address(this))
|
|
48
|
+
if (target == address(this)) {
|
|
49
|
+
bool handled;
|
|
50
|
+
(handled, output, credit) = execute(cmd, account, state, input, value);
|
|
51
|
+
if (handled) return (output, credit);
|
|
52
|
+
}
|
|
47
53
|
ensureTrusted(cmd);
|
|
48
54
|
return rawCommandCall(selector, target, value, account, state, input);
|
|
49
55
|
}
|