@rootzero/contracts 1.28.0 → 1.30.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 +77 -0
- package/Codec.sol +2 -1
- package/Commands.sol +1 -1
- package/Core.sol +1 -1
- package/Endpoints.sol +7 -7
- package/README.md +97 -43
- package/Utils.sol +2 -1
- package/codec/Blocks.sol +41 -67
- package/codec/Decoders.sol +12 -20
- package/codec/Descriptors.sol +3 -14
- package/codec/Keys.sol +1 -3
- package/codec/Schema.sol +1 -3
- package/codec/Specs.sol +2 -4
- package/codec/Writers.sol +8 -9
- package/commands/Base.sol +3 -2
- package/commands/Bootstrap.sol +3 -1
- package/commands/Cashout.sol +24 -21
- package/commands/Credit.sol +6 -5
- package/commands/Debit.sol +7 -6
- package/commands/Relay.sol +14 -15
- package/commands/Repay.sol +6 -5
- package/commands/Settle.sol +6 -5
- package/commands/admin/Execute.sol +2 -2
- package/core/Access.sol +14 -12
- package/core/Calls.sol +90 -102
- package/core/Host.sol +13 -11
- package/core/Pipeline.sol +179 -19
- package/core/Settlement.sol +1 -1
- package/execution/Execution.sol +25 -37
- package/package.json +1 -1
- package/ports/Allowance.sol +7 -17
- package/ports/Base.sol +4 -1
- package/ports/Dispatch.sol +1 -1
- package/ports/Pipe.sol +1 -1
- package/queries/Base.sol +1 -1
- package/utils/Accounts.sol +4 -4
- package/utils/Assets.sol +4 -5
- package/utils/Cursors.sol +24 -1
- package/utils/Flags.sol +18 -0
- package/utils/Layout.sol +3 -3
- package/utils/Nodes.sol +36 -31
- package/utils/Utils.sol +5 -5
package/codec/Decoders.sol
CHANGED
|
@@ -22,7 +22,7 @@ library Decoders {
|
|
|
22
22
|
/// @param source Calldata region to open.
|
|
23
23
|
/// @return cur Cursor spanning the complete source.
|
|
24
24
|
function open(bytes calldata source) internal pure returns (Cur memory cur) {
|
|
25
|
-
cur.state = Cursors.wrap(source
|
|
25
|
+
cur.state = Cursors.wrap(source);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/// @notice Return whether `cur` has unread bytes.
|
|
@@ -138,13 +138,15 @@ library Decoders {
|
|
|
138
138
|
out.state = cur.state.slice(from, to, 0);
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
/// @notice Return the
|
|
141
|
+
/// @notice Return the unread calldata region represented by `cur`.
|
|
142
142
|
/// @param cur Cursor whose calldata is returned.
|
|
143
|
-
/// @return
|
|
144
|
-
function raw(Cur memory cur) internal pure returns (bytes calldata) {
|
|
145
|
-
(uint
|
|
146
|
-
if (
|
|
147
|
-
|
|
143
|
+
/// @return data Unread cursor region from its current position.
|
|
144
|
+
function raw(Cur memory cur) internal pure returns (bytes calldata data) {
|
|
145
|
+
(uint i, uint offset, uint len) = cur.state.decode();
|
|
146
|
+
if (len > msg.data.length || offset > msg.data.length - len) {
|
|
147
|
+
revert Blocks.MalformedBlocks();
|
|
148
|
+
}
|
|
149
|
+
data = msg.data[offset + i:offset + len];
|
|
148
150
|
}
|
|
149
151
|
|
|
150
152
|
/// @notice Return relative calldata range `[from, to)` from `cur`.
|
|
@@ -376,15 +378,6 @@ library Decoders {
|
|
|
376
378
|
node = Blocks.unpackNode(abs);
|
|
377
379
|
}
|
|
378
380
|
|
|
379
|
-
/// @notice Decode and consume one CASHOUT block.
|
|
380
|
-
/// @param cur Cursor advanced past the block.
|
|
381
|
-
/// @return amount Native-asset amount to withdraw.
|
|
382
|
-
function unpackCashout(Cur memory cur) internal pure returns (uint amount) {
|
|
383
|
-
uint abs;
|
|
384
|
-
(cur.state, abs) = cur.state.consume(Sizes.Cashout);
|
|
385
|
-
amount = Blocks.unpackCashout(abs);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
381
|
/// @notice Decode and consume one BOOTSTRAP block.
|
|
389
382
|
/// @param cur Cursor advanced past the block.
|
|
390
383
|
/// @return asset Decoded asset identifier.
|
|
@@ -749,15 +742,14 @@ library Decoders {
|
|
|
749
742
|
|
|
750
743
|
/// @notice Decode and consume one RELAY block.
|
|
751
744
|
/// @param cur Cursor advanced past the block.
|
|
752
|
-
/// @return portal Decoded destination portal.
|
|
753
|
-
/// @return resources Decoded packed resources.
|
|
754
745
|
/// @return input Decoded relay input.
|
|
746
|
+
/// @return steps Decoded remaining pipeline steps.
|
|
755
747
|
function unpackRelay(
|
|
756
748
|
Cur memory cur
|
|
757
|
-
) internal pure returns (
|
|
749
|
+
) internal pure returns (bytes calldata input, bytes calldata steps) {
|
|
758
750
|
uint abs = cur.state.absolute();
|
|
759
751
|
uint end;
|
|
760
|
-
(
|
|
752
|
+
(input, steps, end) = Blocks.unpackRelay(abs);
|
|
761
753
|
cur.state = cur.state.seekAbs(end);
|
|
762
754
|
}
|
|
763
755
|
|
package/codec/Descriptors.sol
CHANGED
|
@@ -5,18 +5,7 @@ import {Blocks} from "./Blocks.sol";
|
|
|
5
5
|
import {Buffers} from "./Buffers.sol";
|
|
6
6
|
import {Sizes, Specs} from "./Specs.sol";
|
|
7
7
|
import {Lanes} from "../utils/Lanes.sol";
|
|
8
|
-
|
|
9
|
-
/// @title Flags
|
|
10
|
-
/// @notice Packed endpoint behavior flags.
|
|
11
|
-
/// @dev Bits 6 and 7 are reserved for endpoint-defined custom flags.
|
|
12
|
-
library Flags {
|
|
13
|
-
/// @dev Endpoint accepts nonzero native value.
|
|
14
|
-
uint8 internal constant Funded = 1 << 0;
|
|
15
|
-
/// @dev Endpoint is restricted to the admin account.
|
|
16
|
-
uint8 internal constant Admin = 1 << 1;
|
|
17
|
-
/// @dev Endpoint accepts nonzero native value and is restricted to the admin account.
|
|
18
|
-
uint8 internal constant AdminFunded = Admin | Funded;
|
|
19
|
-
}
|
|
8
|
+
import {Flags} from "../utils/Flags.sol";
|
|
20
9
|
|
|
21
10
|
/// @title Descriptors
|
|
22
11
|
/// @notice Packing and lane metadata helpers for endpoint descriptors.
|
|
@@ -26,8 +15,8 @@ library Descriptors {
|
|
|
26
15
|
/// `[input key:4][stride:1]`
|
|
27
16
|
/// `[output key:4][min:4][max:4][hint:3][stride:1]`
|
|
28
17
|
/// `[reserved:5]`
|
|
29
|
-
/// `[flags:1]`. Flag bits: funded = 0, admin = 1
|
|
30
|
-
/// reserved for endpoint-defined custom
|
|
18
|
+
/// `[flags:1]`. Flag bits: funded = 0, admin = 1, handoff = 7;
|
|
19
|
+
/// bit 6 is reserved for endpoint-defined custom behavior.
|
|
31
20
|
/// @dev TODO: Add per-lane cardinality metadata so off-chain consumers can
|
|
32
21
|
/// distinguish exactly-one lanes from batches. Command decoding must remain
|
|
33
22
|
/// the runtime source of truth; this metadata should not restore eager scans.
|
package/codec/Keys.sol
CHANGED
|
@@ -11,8 +11,6 @@ library Keys {
|
|
|
11
11
|
bytes4 constant Empty = bytes4(0);
|
|
12
12
|
/// @dev Input amount - (bytes32 asset, uint amount)
|
|
13
13
|
bytes4 constant Amount = bytes4(keccak256("#amount"));
|
|
14
|
-
/// @dev Native-asset cashout request - (uint amount)
|
|
15
|
-
bytes4 constant Cashout = bytes4(keccak256("#cashout"));
|
|
16
14
|
/// @dev Pipeline bootstrap request - (bytes32 asset, uint amount, uint budget)
|
|
17
15
|
bytes4 constant Bootstrap = bytes4(keccak256("#bootstrap"));
|
|
18
16
|
/// @dev Ledger balance - (bytes32 asset, uint amount)
|
|
@@ -41,7 +39,7 @@ library Keys {
|
|
|
41
39
|
bytes4 constant Transaction = bytes4(keccak256("#transaction"));
|
|
42
40
|
/// @dev Sub-command invocation - (uint cmd, uint value, #bytes as input)
|
|
43
41
|
bytes4 constant Step = bytes4(keccak256("#step"));
|
|
44
|
-
/// @dev
|
|
42
|
+
/// @dev Pipeline handoff envelope - (#bytes as input, #bytes as steps)
|
|
45
43
|
bytes4 constant Relay = bytes4(keccak256("#relay"));
|
|
46
44
|
/// @dev Command context transport - (bytes32 account, #bytes as state, #bytes as input)
|
|
47
45
|
bytes4 constant Context = bytes4(keccak256("#context"));
|
package/codec/Schema.sol
CHANGED
|
@@ -89,8 +89,6 @@ library Schemas {
|
|
|
89
89
|
string constant Account = "bytes32 account";
|
|
90
90
|
string constant Asset = "bytes32 asset";
|
|
91
91
|
string constant Status = "uint code";
|
|
92
|
-
string constant Cashout = "uint amount";
|
|
93
|
-
|
|
94
92
|
// Two-word payloads
|
|
95
93
|
|
|
96
94
|
string constant Amount = "bytes32 asset, uint amount";
|
|
@@ -119,7 +117,7 @@ library Schemas {
|
|
|
119
117
|
|
|
120
118
|
string constant Step = "uint cmd, uint value, #bytes as input";
|
|
121
119
|
string constant Call = "uint target, uint resources, #bytes as payload";
|
|
122
|
-
string constant Relay = "
|
|
120
|
+
string constant Relay = "#bytes as input, #bytes as steps";
|
|
123
121
|
string constant Dispatch = "uint portal, uint resources, #bytes as payload";
|
|
124
122
|
string constant Context = "bytes32 account, #bytes as state, #bytes as input";
|
|
125
123
|
string constant Recover = "uint handler, uint resources, bytes32 key, #bytes as witness";
|
package/codec/Specs.sol
CHANGED
|
@@ -25,8 +25,6 @@ library Sizes {
|
|
|
25
25
|
uint constant Step = 2 * Header + 2 * Word;
|
|
26
26
|
/// @dev STATUS block: 8 header + 32 status code = 40 bytes
|
|
27
27
|
uint constant Status = B32;
|
|
28
|
-
/// @dev CASHOUT block: 8 header + 32 native-asset amount = 40 bytes
|
|
29
|
-
uint constant Cashout = B32;
|
|
30
28
|
/// @dev BOOTSTRAP block: 8 header + 32 asset + 32 amount + 32 budget = 104 bytes
|
|
31
29
|
uint constant Bootstrap = B96;
|
|
32
30
|
/// @dev AMOUNT block: 8 header + 32 asset + 32 amount = 72 bytes
|
|
@@ -63,13 +61,13 @@ library Specs {
|
|
|
63
61
|
uint private constant Exact96 = 96 * SizeFields;
|
|
64
62
|
uint private constant Exact128 = 128 * SizeFields;
|
|
65
63
|
uint private constant UnboundedHint128 = uint(128) << 136;
|
|
64
|
+
uint private constant UnboundedMin16Hint256 = (uint(16) << 192) | (uint(256) << 136);
|
|
66
65
|
uint private constant UnboundedMin40Hint256 = (uint(40) << 192) | (uint(256) << 136);
|
|
67
66
|
uint private constant UnboundedMin72Hint256 = (uint(72) << 192) | (uint(256) << 136);
|
|
68
67
|
uint private constant UnboundedMin48Hint512 = (uint(48) << 192) | (uint(512) << 136);
|
|
69
68
|
uint private constant UnboundedMin104Hint256 = (uint(104) << 192) | (uint(256) << 136);
|
|
70
69
|
|
|
71
70
|
uint constant Empty = uint(bytes32(Keys.Empty));
|
|
72
|
-
uint constant Cashout = uint(bytes32(Keys.Cashout)) | Exact32;
|
|
73
71
|
uint constant Bootstrap = uint(bytes32(Keys.Bootstrap)) | Exact96;
|
|
74
72
|
uint constant Amount = uint(bytes32(Keys.Amount)) | Exact64;
|
|
75
73
|
uint constant Balance = uint(bytes32(Keys.Balance)) | Exact64;
|
|
@@ -85,7 +83,7 @@ library Specs {
|
|
|
85
83
|
uint constant Account = uint(bytes32(Keys.Account)) | Exact32;
|
|
86
84
|
uint constant Transaction = uint(bytes32(Keys.Transaction)) | Exact128;
|
|
87
85
|
uint constant Step = uint(bytes32(Keys.Step)) | UnboundedMin72Hint256;
|
|
88
|
-
uint constant Relay = uint(bytes32(Keys.Relay)) |
|
|
86
|
+
uint constant Relay = uint(bytes32(Keys.Relay)) | UnboundedMin16Hint256;
|
|
89
87
|
uint constant Context = uint(bytes32(Keys.Context)) | UnboundedMin48Hint512;
|
|
90
88
|
uint constant Recover = uint(bytes32(Keys.Recover)) | UnboundedMin104Hint256;
|
|
91
89
|
uint constant Dispatch = uint(bytes32(Keys.Dispatch)) | UnboundedMin72Hint256;
|
package/codec/Writers.sol
CHANGED
|
@@ -433,13 +433,12 @@ library Writers {
|
|
|
433
433
|
|
|
434
434
|
/// @notice Append a RELAY block.
|
|
435
435
|
/// @param writer Destination writer.
|
|
436
|
-
/// @param portal Destination portal to encode.
|
|
437
|
-
/// @param resources Packed resources to encode.
|
|
438
436
|
/// @param input Relay input to encode.
|
|
439
|
-
|
|
440
|
-
|
|
437
|
+
/// @param steps Remaining steps to encode.
|
|
438
|
+
function appendRelay(Writer memory writer, bytes memory input, bytes memory steps) internal pure {
|
|
439
|
+
uint size = 3 * Sizes.Header + input.length + steps.length;
|
|
441
440
|
uint i = reserve(writer, size);
|
|
442
|
-
Blocks.writeRelay(writer.dst, i,
|
|
441
|
+
Blocks.writeRelay(writer.dst, i, input, steps);
|
|
443
442
|
}
|
|
444
443
|
|
|
445
444
|
/// @notice Append a DISPATCH block.
|
|
@@ -574,11 +573,11 @@ library Writers {
|
|
|
574
573
|
Blocks.copyCall(writer.dst, i, target, resources, payload);
|
|
575
574
|
}
|
|
576
575
|
|
|
577
|
-
/// @notice Append a RELAY block by copying its nested
|
|
578
|
-
function copyRelay(Writer memory writer,
|
|
579
|
-
uint size =
|
|
576
|
+
/// @notice Append a RELAY block by copying its nested streams from calldata.
|
|
577
|
+
function copyRelay(Writer memory writer, bytes calldata input, bytes calldata steps) internal pure {
|
|
578
|
+
uint size = 3 * Sizes.Header + input.length + steps.length;
|
|
580
579
|
uint i = reserve(writer, size);
|
|
581
|
-
Blocks.copyRelay(writer.dst, i,
|
|
580
|
+
Blocks.copyRelay(writer.dst, i, input, steps);
|
|
582
581
|
}
|
|
583
582
|
|
|
584
583
|
/// @notice Append a DISPATCH block by copying its nested payload from calldata.
|
package/commands/Base.sol
CHANGED
|
@@ -7,7 +7,8 @@ import {Blocks} from "../codec/Blocks.sol";
|
|
|
7
7
|
import {Specs} from "../codec/Specs.sol";
|
|
8
8
|
import {HostAmount, Position} from "../core/Types.sol";
|
|
9
9
|
import {Execution, Executions} from "../execution/Execution.sol";
|
|
10
|
-
import {Descriptors
|
|
10
|
+
import {Descriptors} from "../codec/Descriptors.sol";
|
|
11
|
+
import {Flags} from "../utils/Flags.sol";
|
|
11
12
|
import {Nodes} from "../utils/Nodes.sol";
|
|
12
13
|
|
|
13
14
|
using Executions for Execution;
|
|
@@ -62,7 +63,7 @@ abstract contract CommandBase is CallerAccess, EndpointBase {
|
|
|
62
63
|
/// @return id Command node ID.
|
|
63
64
|
/// @return published Published endpoint descriptor.
|
|
64
65
|
function command(string memory name, uint descriptor) internal returns (uint id, uint published) {
|
|
65
|
-
id = Nodes.toCommand(name, address(this));
|
|
66
|
+
id = Nodes.toCommand(name, address(this), uint8(descriptor));
|
|
66
67
|
published = endpoint(id, name, descriptor);
|
|
67
68
|
}
|
|
68
69
|
|
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
|
@@ -2,19 +2,18 @@
|
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
4
|
import {Execution, Executions, CommandBase, Specs} from "./Base.sol";
|
|
5
|
-
import {
|
|
5
|
+
import {Memory} from "../codec/Blocks.sol";
|
|
6
6
|
import {Sizes} from "../codec/Specs.sol";
|
|
7
|
-
import {Cursors} from "../utils/Cursors.sol";
|
|
8
7
|
import {Action} from "../annotations/Action.sol";
|
|
9
8
|
import {Actions} from "../utils/Actions.sol";
|
|
10
|
-
import {
|
|
9
|
+
import {InvalidAsset, UnexpectedInput} from "../utils/Errors.sol";
|
|
11
10
|
|
|
12
11
|
using Executions for Execution;
|
|
13
12
|
|
|
14
13
|
/// @notice Hook implemented by hosts that withdraw native assets from accounts.
|
|
15
14
|
abstract contract CashoutHook {
|
|
16
15
|
/// @notice Withdraw an exact native-asset amount from `account`.
|
|
17
|
-
/// Called once per
|
|
16
|
+
/// Called once per native BALANCE block in state.
|
|
18
17
|
/// @dev Implementations must revert when the requested amount cannot be withdrawn.
|
|
19
18
|
/// @param account Account whose native asset is withdrawn.
|
|
20
19
|
/// @param amount Native-asset amount to withdraw.
|
|
@@ -28,7 +27,7 @@ abstract contract Cashout is CommandBase, CashoutHook, Action {
|
|
|
28
27
|
uint private immutable id;
|
|
29
28
|
|
|
30
29
|
constructor() {
|
|
31
|
-
(id, descriptor) = command("cashout", Specs.
|
|
30
|
+
(id, descriptor) = command("cashout", Specs.Balance, Specs.Empty, Specs.Empty, 0);
|
|
32
31
|
action(id, Actions.Cashout);
|
|
33
32
|
}
|
|
34
33
|
|
|
@@ -37,8 +36,8 @@ abstract contract Cashout is CommandBase, CashoutHook, Action {
|
|
|
37
36
|
return id;
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
/// @notice Withdraw native
|
|
41
|
-
/// @param context Command context carrying a
|
|
39
|
+
/// @notice Withdraw native BALANCE state from the command account.
|
|
40
|
+
/// @param context Command context carrying a BALANCE state stream.
|
|
42
41
|
/// @return output Empty output state.
|
|
43
42
|
/// @return credit Zero native budget credit.
|
|
44
43
|
function cashout(
|
|
@@ -47,21 +46,24 @@ abstract contract Cashout is CommandBase, CashoutHook, Action {
|
|
|
47
46
|
Execution memory exec = openCommand(context, descriptor);
|
|
48
47
|
|
|
49
48
|
while (exec.more()) {
|
|
50
|
-
|
|
49
|
+
(bytes32 asset, uint amount) = exec.unpackBalance();
|
|
50
|
+
if (asset != nativeAsset) revert InvalidAsset();
|
|
51
|
+
cashout(exec.account, amount);
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
return exec.close();
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
/// @title
|
|
58
|
-
/// @notice Extends cashout with optimized local pipeline
|
|
59
|
-
abstract contract
|
|
60
|
-
/// @notice Execute cashout directly against
|
|
58
|
+
/// @title ExecuteCashout
|
|
59
|
+
/// @notice Extends cashout with optimized local pipeline execution.
|
|
60
|
+
abstract contract ExecuteCashout is Cashout {
|
|
61
|
+
/// @notice Execute cashout directly against native BALANCE state held in memory.
|
|
61
62
|
/// @param account Account whose native asset is withdrawn.
|
|
62
|
-
/// @param state
|
|
63
|
-
/// @param input
|
|
63
|
+
/// @param state BALANCE block stream held in pipeline memory.
|
|
64
|
+
/// @param input Empty input required by the command schema.
|
|
64
65
|
/// @param value Native value assigned to this command; must be zero.
|
|
66
|
+
/// @return handled Always true because this helper executed the command.
|
|
65
67
|
/// @return output Empty output state.
|
|
66
68
|
/// @return credit Zero native budget credit.
|
|
67
69
|
function executeCashout(
|
|
@@ -69,18 +71,19 @@ abstract contract CashoutInternal is Cashout {
|
|
|
69
71
|
bytes memory state,
|
|
70
72
|
bytes calldata input,
|
|
71
73
|
uint value
|
|
72
|
-
) internal returns (bytes memory, uint) {
|
|
74
|
+
) internal returns (bool handled, bytes memory output, uint credit) {
|
|
73
75
|
if (value != 0) revert ValueNotAllowed();
|
|
74
|
-
if (
|
|
75
|
-
if (input.length % Sizes.Cashout != 0) revert Blocks.InvalidBlock();
|
|
76
|
+
if (input.length != 0) revert UnexpectedInput();
|
|
76
77
|
|
|
77
|
-
(uint abs, uint end) =
|
|
78
|
+
(uint abs, uint end) = Memory.bounds(state, Sizes.Balance);
|
|
78
79
|
while (abs < end) {
|
|
79
|
-
|
|
80
|
+
(bytes32 asset, uint amount) = Memory.unpackBalance(abs);
|
|
81
|
+
if (asset != nativeAsset) revert InvalidAsset();
|
|
82
|
+
cashout(account, amount);
|
|
80
83
|
unchecked {
|
|
81
|
-
abs += Sizes.
|
|
84
|
+
abs += Sizes.Balance;
|
|
82
85
|
}
|
|
83
86
|
}
|
|
84
|
-
return ("", 0);
|
|
87
|
+
return (true, "", 0);
|
|
85
88
|
}
|
|
86
89
|
}
|
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/Relay.sol
CHANGED
|
@@ -7,26 +7,25 @@ using Executions for Execution;
|
|
|
7
7
|
|
|
8
8
|
/// @notice Hook implemented by hosts that relay command contexts.
|
|
9
9
|
abstract contract RelayPayableHook {
|
|
10
|
-
/// @notice Override to relay a command context
|
|
10
|
+
/// @notice Override to relay a command context and its pipeline continuation.
|
|
11
11
|
/// @dev Relay hooks may forward only EMPTY or BALANCE state. They must not
|
|
12
12
|
/// relay DEBT, POSITION, or other state whose destination handling can fail:
|
|
13
13
|
/// the source state is consumed before destination success is known.
|
|
14
|
-
///
|
|
15
|
-
///
|
|
16
|
-
///
|
|
17
|
-
/// plain native value. EVM adapters extract the low 128-bit value lane with
|
|
18
|
-
/// `useResourceValue`; higher bits may encode execution gas or other data.
|
|
14
|
+
/// `funds` contains only this handoff STEP's assigned value, not the source
|
|
15
|
+
/// pipeline's complete remaining budget. Implementations must consume or
|
|
16
|
+
/// forward `state`; the command returns empty state when the hook completes.
|
|
19
17
|
/// @param account Destination command account.
|
|
20
18
|
/// @param state Complete state forwarded into the destination context.
|
|
21
|
-
/// @param input
|
|
19
|
+
/// @param input Command-specific input supplied by the handoff step.
|
|
20
|
+
/// Implementations define and decode this stream according to their transport.
|
|
21
|
+
/// @param steps Remaining STEP stream owned by the handoff.
|
|
22
22
|
/// @param funds Execution carrying value available for transport fees and
|
|
23
23
|
/// destination resource funding.
|
|
24
24
|
function relay(
|
|
25
|
-
uint portal,
|
|
26
|
-
uint resources,
|
|
27
25
|
bytes32 account,
|
|
28
26
|
bytes calldata state,
|
|
29
27
|
bytes calldata input,
|
|
28
|
+
bytes calldata steps,
|
|
30
29
|
Execution memory funds
|
|
31
30
|
) internal virtual;
|
|
32
31
|
}
|
|
@@ -37,14 +36,14 @@ abstract contract RelayPayable is CommandBase, RelayPayableHook {
|
|
|
37
36
|
uint private immutable descriptor;
|
|
38
37
|
|
|
39
38
|
constructor() {
|
|
40
|
-
(, descriptor) = command("relayPayable", Specs.Empty, Specs.Relay, Specs.Empty, Flags.
|
|
39
|
+
(, descriptor) = command("relayPayable", Specs.Empty, Specs.Relay, Specs.Empty, Flags.HandoffFunded);
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
/// @notice Relay one RELAY input block with the command account and empty state.
|
|
44
43
|
function relayPayable(bytes calldata context) external payable onlyCommand returns (bytes memory, uint) {
|
|
45
44
|
Execution memory exec = openCommand(context, descriptor);
|
|
46
|
-
(
|
|
47
|
-
relay(
|
|
45
|
+
(bytes calldata input, bytes calldata steps) = exec.oninput().unpackRelay();
|
|
46
|
+
relay(exec.account, context[0:0], input, steps, exec);
|
|
48
47
|
return exec.close();
|
|
49
48
|
}
|
|
50
49
|
}
|
|
@@ -58,7 +57,7 @@ abstract contract RelayBalancePayable is CommandBase, RelayPayableHook {
|
|
|
58
57
|
uint private immutable descriptor;
|
|
59
58
|
|
|
60
59
|
constructor() {
|
|
61
|
-
(, descriptor) = command("relayBalancePayable", Specs.Balance, Specs.Relay, Specs.Empty, Flags.
|
|
60
|
+
(, descriptor) = command("relayBalancePayable", Specs.Balance, Specs.Relay, Specs.Empty, Flags.HandoffFunded);
|
|
62
61
|
}
|
|
63
62
|
|
|
64
63
|
/// @notice Relay one RELAY input block with the command account and current state.
|
|
@@ -67,8 +66,8 @@ abstract contract RelayBalancePayable is CommandBase, RelayPayableHook {
|
|
|
67
66
|
/// @return Native value to add to the caller's budget.
|
|
68
67
|
function relayBalancePayable(bytes calldata context) external payable onlyCommand returns (bytes memory, uint) {
|
|
69
68
|
Execution memory exec = openCommand(context, descriptor);
|
|
70
|
-
(
|
|
71
|
-
relay(
|
|
69
|
+
(bytes calldata input, bytes calldata steps) = exec.oninput().unpackRelay();
|
|
70
|
+
relay(exec.account, exec.takeRawState(), input, steps, exec);
|
|
72
71
|
return exec.close();
|
|
73
72
|
}
|
|
74
73
|
}
|
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
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
4
|
import {AdminBase, Execution, Executions, Flags, Specs} from "./Base.sol";
|
|
5
|
-
import {
|
|
5
|
+
import {rawCall} from "../../core/Calls.sol";
|
|
6
6
|
|
|
7
7
|
using Executions for Execution;
|
|
8
8
|
|
|
@@ -13,7 +13,7 @@ using Executions for Execution;
|
|
|
13
13
|
/// through `useResourceValue`.
|
|
14
14
|
/// Only callable by the admin account.
|
|
15
15
|
/// Unspent top-level `msg.value` is returned as native budget credit.
|
|
16
|
-
abstract contract ExecutePayable is
|
|
16
|
+
abstract contract ExecutePayable is AdminBase {
|
|
17
17
|
uint private immutable descriptor;
|
|
18
18
|
|
|
19
19
|
constructor() {
|