@rootzero/contracts 0.2.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.
Files changed (101) hide show
  1. package/LICENSE +648 -0
  2. package/README.md +135 -0
  3. package/contracts/Blocks.sol +9 -0
  4. package/contracts/Commands.sol +41 -0
  5. package/contracts/Core.sol +10 -0
  6. package/contracts/Events.sol +18 -0
  7. package/contracts/Utils.sol +12 -0
  8. package/contracts/blocks/Blocks.sol +818 -0
  9. package/contracts/blocks/Keys.sol +24 -0
  10. package/contracts/blocks/Mem.sol +129 -0
  11. package/contracts/blocks/Schema.sol +105 -0
  12. package/contracts/blocks/Writers.sol +209 -0
  13. package/contracts/combinators/AmountToBalance.sol +25 -0
  14. package/contracts/combinators/AmountToCustody.sol +36 -0
  15. package/contracts/combinators/CustodyToBalance.sol +25 -0
  16. package/contracts/combinators/EachRoute.sol +18 -0
  17. package/contracts/combinators/MapBalance.sol +25 -0
  18. package/contracts/combinators/MapCustody.sol +25 -0
  19. package/contracts/combinators/RouteToBalance.sol +27 -0
  20. package/contracts/commands/Base.sol +40 -0
  21. package/contracts/commands/Borrow.sol +89 -0
  22. package/contracts/commands/Burn.sol +33 -0
  23. package/contracts/commands/Create.sol +32 -0
  24. package/contracts/commands/Credit.sol +36 -0
  25. package/contracts/commands/Debit.sol +46 -0
  26. package/contracts/commands/Deposit.sol +45 -0
  27. package/contracts/commands/Liquidate.sol +101 -0
  28. package/contracts/commands/Liquidity.sol +179 -0
  29. package/contracts/commands/Mint.sol +42 -0
  30. package/contracts/commands/Pipe.sol +55 -0
  31. package/contracts/commands/Provision.sol +73 -0
  32. package/contracts/commands/Reclaim.sol +48 -0
  33. package/contracts/commands/Redeem.sol +101 -0
  34. package/contracts/commands/Remove.sol +32 -0
  35. package/contracts/commands/Repay.sol +101 -0
  36. package/contracts/commands/Settle.sol +32 -0
  37. package/contracts/commands/Stake.sol +121 -0
  38. package/contracts/commands/Supply.sol +33 -0
  39. package/contracts/commands/Swap.sol +88 -0
  40. package/contracts/commands/Transfer.sol +44 -0
  41. package/contracts/commands/Unstake.sol +49 -0
  42. package/contracts/commands/Withdraw.sol +37 -0
  43. package/contracts/commands/admin/Allocate.sol +32 -0
  44. package/contracts/commands/admin/AllowAssets.sol +34 -0
  45. package/contracts/commands/admin/Authorize.sol +30 -0
  46. package/contracts/commands/admin/DenyAssets.sol +34 -0
  47. package/contracts/commands/admin/Destroy.sol +27 -0
  48. package/contracts/commands/admin/Init.sol +26 -0
  49. package/contracts/commands/admin/Relocate.sol +30 -0
  50. package/contracts/commands/admin/Unauthorize.sol +30 -0
  51. package/contracts/core/Access.sol +50 -0
  52. package/contracts/core/Balances.sol +23 -0
  53. package/contracts/core/Host.sol +25 -0
  54. package/contracts/core/Operation.sol +32 -0
  55. package/contracts/core/Validator.sol +31 -0
  56. package/contracts/events/Access.sol +14 -0
  57. package/contracts/events/Asset.sol +14 -0
  58. package/contracts/events/Balance.sol +14 -0
  59. package/contracts/events/Collateral.sol +15 -0
  60. package/contracts/events/Command.sol +14 -0
  61. package/contracts/events/Debt.sol +15 -0
  62. package/contracts/events/Deposit.sol +14 -0
  63. package/contracts/events/Emitter.sol +7 -0
  64. package/contracts/events/Governed.sol +14 -0
  65. package/contracts/events/HostAnnounced.sol +14 -0
  66. package/contracts/events/Listing.sol +14 -0
  67. package/contracts/events/Peer.sol +14 -0
  68. package/contracts/events/Quote.sol +14 -0
  69. package/contracts/events/RootZero.sol +14 -0
  70. package/contracts/events/Withdraw.sol +14 -0
  71. package/contracts/interfaces/IHostDiscovery.sol +6 -0
  72. package/contracts/peer/AllowAssets.sol +30 -0
  73. package/contracts/peer/Base.sol +17 -0
  74. package/contracts/peer/DenyAssets.sol +30 -0
  75. package/contracts/peer/Pull.sol +30 -0
  76. package/contracts/peer/Push.sol +30 -0
  77. package/contracts/test/TestBlockHelper.sol +261 -0
  78. package/contracts/test/TestBorrowHost.sol +47 -0
  79. package/contracts/test/TestBurnHost.sol +28 -0
  80. package/contracts/test/TestCreateHost.sol +26 -0
  81. package/contracts/test/TestDiscovery.sol +6 -0
  82. package/contracts/test/TestECDSA.sol +16 -0
  83. package/contracts/test/TestHost.sol +199 -0
  84. package/contracts/test/TestLiquidityHost.sol +145 -0
  85. package/contracts/test/TestMintHost.sol +40 -0
  86. package/contracts/test/TestPeerHost.sol +34 -0
  87. package/contracts/test/TestReclaimHost.sol +48 -0
  88. package/contracts/test/TestRejectEther.sol +8 -0
  89. package/contracts/test/TestRemoveHost.sol +26 -0
  90. package/contracts/test/TestSwapHost.sol +44 -0
  91. package/contracts/test/TestUtils.sol +169 -0
  92. package/contracts/test/TestValidator.sol +10 -0
  93. package/contracts/utils/Accounts.sol +40 -0
  94. package/contracts/utils/Assets.sol +76 -0
  95. package/contracts/utils/Channels.sol +11 -0
  96. package/contracts/utils/ECDSA.sol +36 -0
  97. package/contracts/utils/Ids.sol +75 -0
  98. package/contracts/utils/Layout.sol +22 -0
  99. package/contracts/utils/Utils.sol +126 -0
  100. package/contracts/utils/Value.sol +20 -0
  101. package/package.json +33 -0
@@ -0,0 +1,55 @@
1
+ // SPDX-License-Identifier: GPL-3.0-only
2
+ pragma solidity ^0.8.33;
3
+
4
+ import { CommandBase, CommandContext } from "./Base.sol";
5
+ import { Keys, Schemas, Blocks, Block } from "../Blocks.sol";
6
+ import { Accounts } from "../utils/Accounts.sol";
7
+ import { Values } from "../utils/Value.sol";
8
+
9
+ using Blocks for Block;
10
+
11
+ string constant NAME = "pipe";
12
+
13
+ abstract contract Pipe is CommandBase {
14
+ uint internal immutable pipeId = commandId(NAME);
15
+
16
+ constructor() {
17
+ emit Command(host, NAME, Schemas.Step, pipeId, 0, 0);
18
+ }
19
+
20
+ /// @dev Override to execute a single STEP target and return the next
21
+ /// threaded state for the pipe.
22
+ function dispatchStep(
23
+ uint target,
24
+ bytes32 account,
25
+ bytes memory state,
26
+ bytes calldata request,
27
+ uint value
28
+ ) internal virtual returns (bytes memory);
29
+
30
+ function pipe(
31
+ bytes32 account,
32
+ bytes memory state,
33
+ bytes calldata steps,
34
+ Values.Budget memory budget
35
+ ) internal returns (bytes memory) {
36
+ uint i = 0;
37
+ while (i < steps.length) {
38
+ Block memory ref = Blocks.from(steps, i);
39
+ if (ref.key != Keys.Step) break;
40
+ (uint target, uint value, bytes calldata request) = ref.unpackStep();
41
+ uint spend = Values.use(budget, value);
42
+ state = dispatchStep(target, account, state, request, spend);
43
+ i = ref.cursor;
44
+ }
45
+
46
+ return done(state, 0, i);
47
+ }
48
+
49
+ // Any unused value will not be credited back to the account using this path.
50
+ function pipe(CommandContext calldata c) external payable onlyCommand(pipeId, c.target) returns (bytes memory) {
51
+ if (Accounts.isAdmin(c.account)) revert Accounts.InvalidAccount();
52
+ Values.Budget memory budget = Values.fromMsg();
53
+ return pipe(c.account, c.state, c.request, budget);
54
+ }
55
+ }
@@ -0,0 +1,73 @@
1
+ // SPDX-License-Identifier: GPL-3.0-only
2
+ pragma solidity ^0.8.33;
3
+
4
+ import { CommandContext, CommandBase, Channels } from "./Base.sol";
5
+ import { Keys, Schemas, Blocks, Block, Writers, Writer } from "../Blocks.sol";
6
+ using Blocks for Block;
7
+ using Writers for Writer;
8
+
9
+ string constant PROVISION = "provision";
10
+ string constant PFB = "provisionFromBalance";
11
+
12
+ string constant REQUEST = string.concat(Schemas.Amount, ">", Schemas.Node);
13
+
14
+ abstract contract ProvisionHook {
15
+ /// @dev Override this hook to send or provision funds to `host`.
16
+ /// Called by both `Provision` and `ProvisionFromBalance`.
17
+ /// Implementations should only perform the side effect and must not
18
+ /// encode or append output blocks.
19
+ function provision(bytes32 account, uint host, bytes32 asset, bytes32 meta, uint amount) internal virtual;
20
+ }
21
+
22
+ abstract contract Provision is CommandBase, ProvisionHook {
23
+ uint internal immutable provisionId = commandId(PROVISION);
24
+
25
+ constructor() {
26
+ emit Command(host, PROVISION, REQUEST, provisionId, Channels.Setup, Channels.Custodies);
27
+ }
28
+
29
+ function provision(
30
+ CommandContext calldata c
31
+ ) external payable onlyCommand(provisionId, c.target) returns (bytes memory) {
32
+ uint q = 0;
33
+ (Writer memory writer, uint end) = Writers.allocCustodiesFrom(c.request, q, Keys.Amount);
34
+
35
+ while (q < end) {
36
+ Block memory ref = Blocks.from(c.request, q);
37
+ (bytes32 asset, bytes32 meta, uint amount) = ref.unpackAmount();
38
+ uint toHost = ref.innerNode();
39
+ provision(c.account, toHost, asset, meta, amount);
40
+ writer.appendCustody(toHost, asset, meta, amount);
41
+ q = ref.cursor;
42
+ }
43
+
44
+ return writer.done();
45
+ }
46
+ }
47
+
48
+ // @dev Converts BALANCE state into CUSTODY state for a destination host.
49
+ abstract contract ProvisionFromBalance is CommandBase, ProvisionHook {
50
+ uint internal immutable provisionFromBalanceId = commandId(PFB);
51
+
52
+ constructor() {
53
+ emit Command(host, PFB, Schemas.Node, provisionFromBalanceId, Channels.Balances, Channels.Custodies);
54
+ }
55
+
56
+ function provisionFromBalance(
57
+ CommandContext calldata c
58
+ ) external payable onlyCommand(provisionFromBalanceId, c.target) returns (bytes memory) {
59
+ uint toHost = Blocks.resolveNode(c.request, 0, c.request.length, 0);
60
+ uint i = 0;
61
+ (Writer memory writer, uint end) = Writers.allocCustodiesFrom(c.state, i, Keys.Balance);
62
+
63
+ while (i < end) {
64
+ Block memory ref = Blocks.from(c.state, i);
65
+ (bytes32 asset, bytes32 meta, uint amount) = ref.unpackBalance();
66
+ provision(c.account, toHost, asset, meta, amount);
67
+ writer.appendCustody(toHost, asset, meta, amount);
68
+ i = ref.cursor;
69
+ }
70
+
71
+ return writer.done();
72
+ }
73
+ }
@@ -0,0 +1,48 @@
1
+ // SPDX-License-Identifier: GPL-3.0-only
2
+ pragma solidity ^0.8.33;
3
+
4
+ import { CommandContext, CommandBase, Channels } from "./Base.sol";
5
+ import { AssetAmount, Schemas, Blocks, Block, Writers, Writer, Keys } from "../Blocks.sol";
6
+
7
+ string constant NAME = "reclaimToBalances";
8
+
9
+ using Blocks for Block;
10
+ using Writers for Writer;
11
+
12
+ abstract contract ReclaimToBalances is CommandBase {
13
+ uint internal immutable reclaimToBalancesId = commandId(NAME);
14
+ uint private immutable outScale;
15
+
16
+ constructor(string memory maybeRoute, uint scaledRatio) {
17
+ outScale = scaledRatio;
18
+ string memory schema = Schemas.route1(maybeRoute, Schemas.Amount);
19
+ emit Command(host, NAME, schema, reclaimToBalancesId, Channels.Setup, Channels.Balances);
20
+ }
21
+
22
+ /// @dev Override to reclaim balances described by `rawRoute`.
23
+ /// `amount` is extracted from the route and implementations may append one
24
+ /// or more BALANCE blocks to `out`.
25
+ function reclaimToBalances(
26
+ bytes32 account,
27
+ AssetAmount memory amount,
28
+ Block memory rawRoute,
29
+ Writer memory out
30
+ ) internal virtual;
31
+
32
+ function reclaimToBalances(
33
+ CommandContext calldata c
34
+ ) external payable onlyCommand(reclaimToBalancesId, c.target) returns (bytes memory) {
35
+ uint q = 0;
36
+ (Writer memory writer, uint end) = Writers.allocScaledBalancesFrom(c.request, q, Keys.Route, outScale);
37
+
38
+ while (q < end) {
39
+ Block memory route;
40
+ route = Blocks.routeFrom(c.request, q);
41
+ q = route.cursor;
42
+ AssetAmount memory value = route.innerAmountValue();
43
+ reclaimToBalances(c.account, value, route, writer);
44
+ }
45
+
46
+ return writer.finish();
47
+ }
48
+ }
@@ -0,0 +1,101 @@
1
+ // SPDX-License-Identifier: GPL-3.0-only
2
+ pragma solidity ^0.8.33;
3
+
4
+ import { CommandContext, CommandBase, Channels } from "./Base.sol";
5
+ import { AssetAmount, HostAmount, Blocks, Block, Writers, Writer, Keys } from "../Blocks.sol";
6
+
7
+ string constant RDBTB = "redeemFromBalanceToBalances";
8
+ string constant RDCTB = "redeemFromCustodyToBalances";
9
+
10
+ using Blocks for Block;
11
+ using Writers for Writer;
12
+
13
+ abstract contract RedeemFromBalanceToBalances is CommandBase {
14
+ uint internal immutable redeemFromBalanceToBalancesId = commandId(RDBTB);
15
+ uint private immutable outScale;
16
+ bool private immutable useRoute;
17
+
18
+ constructor(string memory maybeRoute, uint scaledRatio) {
19
+ outScale = scaledRatio;
20
+ useRoute = bytes(maybeRoute).length > 0;
21
+ emit Command(host, RDBTB, maybeRoute, redeemFromBalanceToBalancesId, Channels.Balances, Channels.Balances);
22
+ }
23
+
24
+ /// @dev Override to redeem a balance position into balances.
25
+ /// `rawRoute` is zero-initialized and should be ignored when
26
+ /// `maybeRoute` is empty. Implementations may append one or more BALANCE
27
+ /// blocks to `out`.
28
+ function redeemFromBalanceToBalances(
29
+ bytes32 account,
30
+ AssetAmount memory balance,
31
+ Block memory rawRoute,
32
+ Writer memory out
33
+ ) internal virtual;
34
+
35
+ function redeemFromBalanceToBalances(
36
+ CommandContext calldata c
37
+ ) external payable onlyCommand(redeemFromBalanceToBalancesId, c.target) returns (bytes memory) {
38
+ uint i = 0;
39
+ uint q = 0;
40
+ (Writer memory writer, uint end) = Writers.allocScaledBalancesFrom(c.state, i, Keys.Balance, outScale);
41
+
42
+ while (i < end) {
43
+ Block memory route;
44
+ if (useRoute) {
45
+ route = Blocks.routeFrom(c.request, q);
46
+ q = route.cursor;
47
+ }
48
+ Block memory ref = Blocks.from(c.state, i);
49
+ AssetAmount memory balance = ref.toBalanceValue();
50
+ redeemFromBalanceToBalances(c.account, balance, route, writer);
51
+ i = ref.cursor;
52
+ }
53
+
54
+ return writer.finish();
55
+ }
56
+ }
57
+
58
+ abstract contract RedeemFromCustodyToBalances is CommandBase {
59
+ uint internal immutable redeemFromCustodyToBalancesId = commandId(RDCTB);
60
+ uint private immutable outScale;
61
+ bool private immutable useRoute;
62
+
63
+ constructor(string memory maybeRoute, uint scaledRatio) {
64
+ outScale = scaledRatio;
65
+ useRoute = bytes(maybeRoute).length > 0;
66
+ emit Command(host, RDCTB, maybeRoute, redeemFromCustodyToBalancesId, Channels.Custodies, Channels.Balances);
67
+ }
68
+
69
+ /// @dev Override to redeem a custody position into balances.
70
+ /// `rawRoute` is zero-initialized and should be ignored when
71
+ /// `maybeRoute` is empty. Implementations may append one or more BALANCE
72
+ /// blocks to `out`.
73
+ function redeemFromCustodyToBalances(
74
+ bytes32 account,
75
+ HostAmount memory custody,
76
+ Block memory rawRoute,
77
+ Writer memory out
78
+ ) internal virtual;
79
+
80
+ function redeemFromCustodyToBalances(
81
+ CommandContext calldata c
82
+ ) external payable onlyCommand(redeemFromCustodyToBalancesId, c.target) returns (bytes memory) {
83
+ uint i = 0;
84
+ uint q = 0;
85
+ (Writer memory writer, uint end) = Writers.allocScaledBalancesFrom(c.state, i, Keys.Custody, outScale);
86
+
87
+ while (i < end) {
88
+ Block memory route;
89
+ if (useRoute) {
90
+ route = Blocks.routeFrom(c.request, q);
91
+ q = route.cursor;
92
+ }
93
+ Block memory ref = Blocks.from(c.state, i);
94
+ HostAmount memory custody = ref.toCustodyValue();
95
+ redeemFromCustodyToBalances(c.account, custody, route, writer);
96
+ i = ref.cursor;
97
+ }
98
+
99
+ return writer.finish();
100
+ }
101
+ }
@@ -0,0 +1,32 @@
1
+ // SPDX-License-Identifier: GPL-3.0-only
2
+ pragma solidity ^0.8.33;
3
+
4
+ import { CommandBase, CommandContext, Channels } from "./Base.sol";
5
+ import { Blocks, Block, Keys } from "../Blocks.sol";
6
+ using Blocks for Block;
7
+
8
+ string constant NAME = "remove";
9
+
10
+ abstract contract Remove is CommandBase {
11
+ uint internal immutable removeId = commandId(NAME);
12
+
13
+ constructor(string memory route) {
14
+ emit Command(host, NAME, route, removeId, Channels.Setup, Channels.Setup);
15
+ }
16
+
17
+ /// @dev Override to remove or dismantle an object described by `rawRoute`.
18
+ /// Called once per ROUTE block in the request.
19
+ function remove(bytes32 account, Block memory rawRoute) internal virtual;
20
+
21
+ function remove(CommandContext calldata c) external payable onlyCommand(removeId, c.target) returns (bytes memory) {
22
+ uint q = 0;
23
+ while (q < c.request.length) {
24
+ Block memory ref = Blocks.from(c.request, q);
25
+ if (ref.key != Keys.Route) break;
26
+ remove(c.account, ref);
27
+ q = ref.cursor;
28
+ }
29
+
30
+ return done(0, q);
31
+ }
32
+ }
@@ -0,0 +1,101 @@
1
+ // SPDX-License-Identifier: GPL-3.0-only
2
+ pragma solidity ^0.8.33;
3
+
4
+ import { CommandContext, CommandBase, Channels } from "./Base.sol";
5
+ import { AssetAmount, HostAmount, Schemas, Blocks, Block, Writers, Writer, Keys } from "../Blocks.sol";
6
+
7
+ string constant RFBTB = "repayFromBalanceToBalances";
8
+ string constant RFCTB = "repayFromCustodyToBalances";
9
+
10
+ using Blocks for Block;
11
+ using Writers for Writer;
12
+
13
+ abstract contract RepayFromBalanceToBalances is CommandBase {
14
+ uint internal immutable repayFromBalanceToBalancesId = commandId(RFBTB);
15
+ uint private immutable outScale;
16
+ bool private immutable useRoute;
17
+
18
+ constructor(string memory maybeRoute, uint scaledRatio) {
19
+ outScale = scaledRatio;
20
+ useRoute = bytes(maybeRoute).length > 0;
21
+ emit Command(host, RFBTB, maybeRoute, repayFromBalanceToBalancesId, Channels.Balances, Channels.Balances);
22
+ }
23
+
24
+ /// @dev Override to repay debt using a balance amount.
25
+ /// `rawRoute` is zero-initialized and should be ignored when
26
+ /// `maybeRoute` is empty. Implementations may append returned balances to
27
+ /// `out`.
28
+ function repayFromBalanceToBalances(
29
+ bytes32 account,
30
+ AssetAmount memory balance,
31
+ Block memory rawRoute,
32
+ Writer memory out
33
+ ) internal virtual;
34
+
35
+ function repayFromBalanceToBalances(
36
+ CommandContext calldata c
37
+ ) external payable onlyCommand(repayFromBalanceToBalancesId, c.target) returns (bytes memory) {
38
+ uint i = 0;
39
+ uint q = 0;
40
+ (Writer memory writer, uint end) = Writers.allocScaledBalancesFrom(c.state, i, Keys.Balance, outScale);
41
+
42
+ while (i < end) {
43
+ Block memory route;
44
+ if (useRoute) {
45
+ route = Blocks.routeFrom(c.request, q);
46
+ q = route.cursor;
47
+ }
48
+ Block memory ref = Blocks.from(c.state, i);
49
+ AssetAmount memory balance = ref.toBalanceValue();
50
+ repayFromBalanceToBalances(c.account, balance, route, writer);
51
+ i = ref.cursor;
52
+ }
53
+
54
+ return writer.finish();
55
+ }
56
+ }
57
+
58
+ abstract contract RepayFromCustodyToBalances is CommandBase {
59
+ uint internal immutable repayFromCustodyToBalancesId = commandId(RFCTB);
60
+ uint private immutable outScale;
61
+ bool private immutable useRoute;
62
+
63
+ constructor(string memory maybeRoute, uint scaledRatio) {
64
+ outScale = scaledRatio;
65
+ useRoute = bytes(maybeRoute).length > 0;
66
+ emit Command(host, RFCTB, maybeRoute, repayFromCustodyToBalancesId, Channels.Custodies, Channels.Balances);
67
+ }
68
+
69
+ /// @dev Override to repay debt using a custody amount.
70
+ /// `rawRoute` is zero-initialized and should be ignored when
71
+ /// `maybeRoute` is empty. Implementations may append returned balances to
72
+ /// `out`.
73
+ function repayFromCustodyToBalances(
74
+ bytes32 account,
75
+ HostAmount memory custody,
76
+ Block memory rawRoute,
77
+ Writer memory out
78
+ ) internal virtual;
79
+
80
+ function repayFromCustodyToBalances(
81
+ CommandContext calldata c
82
+ ) external payable onlyCommand(repayFromCustodyToBalancesId, c.target) returns (bytes memory) {
83
+ uint i = 0;
84
+ uint q = 0;
85
+ (Writer memory writer, uint end) = Writers.allocScaledBalancesFrom(c.state, i, Keys.Custody, outScale);
86
+
87
+ while (i < end) {
88
+ Block memory route;
89
+ if (useRoute) {
90
+ route = Blocks.routeFrom(c.request, q);
91
+ q = route.cursor;
92
+ }
93
+ Block memory ref = Blocks.from(c.state, i);
94
+ HostAmount memory custody = ref.toCustodyValue();
95
+ repayFromCustodyToBalances(c.account, custody, route, writer);
96
+ i = ref.cursor;
97
+ }
98
+
99
+ return writer.finish();
100
+ }
101
+ }
@@ -0,0 +1,32 @@
1
+ // SPDX-License-Identifier: GPL-3.0-only
2
+ pragma solidity ^0.8.33;
3
+
4
+ import { CommandContext, CommandBase, Channels } from "./Base.sol";
5
+ import { Tx, Keys, Blocks, Block } from "../Blocks.sol";
6
+ using Blocks for Block;
7
+
8
+ string constant NAME = "settle";
9
+
10
+ abstract contract Settle is CommandBase {
11
+ uint internal immutable settleId = commandId(NAME);
12
+
13
+ constructor() {
14
+ emit Command(host, NAME, "", settleId, Channels.Transactions, Channels.Setup);
15
+ }
16
+
17
+ /// @dev Override to settle a single transaction block.
18
+ /// Called once per TX block in state.
19
+ function settle(Tx memory value) internal virtual;
20
+
21
+ function settle(CommandContext calldata c) external payable onlyCommand(settleId, c.target) returns (bytes memory) {
22
+ uint i = 0;
23
+ while (i < c.state.length) {
24
+ Block memory ref = Blocks.from(c.state, i);
25
+ if (ref.key != Keys.Transaction) break;
26
+ Tx memory value = ref.toTxValue();
27
+ settle(value);
28
+ i = ref.cursor;
29
+ }
30
+ return done(0, i);
31
+ }
32
+ }
@@ -0,0 +1,121 @@
1
+ // SPDX-License-Identifier: GPL-3.0-only
2
+ pragma solidity ^0.8.33;
3
+
4
+ import { CommandContext, CommandBase, Channels } from "./Base.sol";
5
+ import { AssetAmount, HostAmount, Blocks, Block, Writers, Writer, Keys } from "../Blocks.sol";
6
+
7
+ string constant SBTB = "stakeBalanceToBalances";
8
+ string constant SCTB = "stakeCustodyToBalances";
9
+ string constant SCTP = "stakeCustodyToPosition";
10
+
11
+ using Blocks for Block;
12
+ using Writers for Writer;
13
+
14
+ abstract contract StakeBalanceToBalances is CommandBase {
15
+ uint internal immutable stakeBalanceToBalancesId = commandId(SBTB);
16
+ uint private immutable outScale;
17
+
18
+ constructor(string memory route, uint scaledRatio) {
19
+ outScale = scaledRatio;
20
+ emit Command(host, SBTB, route, stakeBalanceToBalancesId, Channels.Balances, Channels.Balances);
21
+ }
22
+
23
+ /// @dev Override to stake a balance position and append resulting balances
24
+ /// to `out`.
25
+ function stakeBalanceToBalances(
26
+ bytes32 account,
27
+ AssetAmount memory balance,
28
+ Block memory rawRoute,
29
+ Writer memory out
30
+ ) internal virtual;
31
+
32
+ function stakeBalanceToBalances(
33
+ CommandContext calldata c
34
+ ) external payable onlyCommand(stakeBalanceToBalancesId, c.target) returns (bytes memory) {
35
+ uint i = 0;
36
+ uint q = 0;
37
+ (Writer memory writer, uint end) = Writers.allocScaledBalancesFrom(c.state, i, Keys.Balance, outScale);
38
+
39
+ while (i < end) {
40
+ Block memory route;
41
+ route = Blocks.routeFrom(c.request, q);
42
+ q = route.cursor;
43
+ Block memory ref = Blocks.from(c.state, i);
44
+ AssetAmount memory balance = ref.toBalanceValue();
45
+ stakeBalanceToBalances(c.account, balance, route, writer);
46
+ i = ref.cursor;
47
+ }
48
+
49
+ return writer.finish();
50
+ }
51
+ }
52
+
53
+ abstract contract StakeCustodyToBalances is CommandBase {
54
+ uint internal immutable stakeCustodyToBalancesId = commandId(SCTB);
55
+ uint private immutable outScale;
56
+
57
+ constructor(string memory route, uint scaledRatio) {
58
+ outScale = scaledRatio;
59
+ emit Command(host, SCTB, route, stakeCustodyToBalancesId, Channels.Custodies, Channels.Balances);
60
+ }
61
+
62
+ /// @dev Override to stake a custody position and append resulting balances
63
+ /// to `out`.
64
+ function stakeCustodyToBalances(
65
+ bytes32 account,
66
+ HostAmount memory custody,
67
+ Block memory rawRoute,
68
+ Writer memory out
69
+ ) internal virtual;
70
+
71
+ function stakeCustodyToBalances(
72
+ CommandContext calldata c
73
+ ) external payable onlyCommand(stakeCustodyToBalancesId, c.target) returns (bytes memory) {
74
+ uint i = 0;
75
+ uint q = 0;
76
+ (Writer memory writer, uint end) = Writers.allocScaledBalancesFrom(c.state, i, Keys.Custody, outScale);
77
+
78
+ while (i < end) {
79
+ Block memory route;
80
+ route = Blocks.routeFrom(c.request, q);
81
+ q = route.cursor;
82
+ Block memory ref = Blocks.from(c.state, i);
83
+ HostAmount memory custody = ref.toCustodyValue();
84
+ stakeCustodyToBalances(c.account, custody, route, writer);
85
+ i = ref.cursor;
86
+ }
87
+
88
+ return writer.finish();
89
+ }
90
+ }
91
+
92
+ abstract contract StakeCustodyToPosition is CommandBase {
93
+ uint internal immutable stakeCustodyToPositionId = commandId(SCTP);
94
+
95
+ constructor(string memory route) {
96
+ emit Command(host, SCTP, route, stakeCustodyToPositionId, Channels.Custodies, Channels.Setup);
97
+ }
98
+
99
+ /// @dev Override to stake a custody position into a non-balance setup
100
+ /// target described by `rawRoute`.
101
+ function stakeCustodyToPosition(bytes32 account, HostAmount memory custody, Block memory rawRoute) internal virtual;
102
+
103
+ function stakeCustodyToPosition(
104
+ CommandContext calldata c
105
+ ) external payable onlyCommand(stakeCustodyToPositionId, c.target) returns (bytes memory) {
106
+ uint i = 0;
107
+ uint q = 0;
108
+ while (i < c.state.length) {
109
+ Block memory ref = Blocks.from(c.state, i);
110
+ if (ref.key != Keys.Custody) break;
111
+ HostAmount memory custody = ref.toCustodyValue();
112
+ Block memory route;
113
+ route = Blocks.routeFrom(c.request, q);
114
+ q = route.cursor;
115
+ stakeCustodyToPosition(c.account, custody, route);
116
+ i = ref.cursor;
117
+ }
118
+
119
+ return done(0, i);
120
+ }
121
+ }
@@ -0,0 +1,33 @@
1
+ // SPDX-License-Identifier: GPL-3.0-only
2
+ pragma solidity ^0.8.33;
3
+
4
+ import { CommandBase, CommandContext, Channels } from "./Base.sol";
5
+ import { Blocks, Block, HostAmount, Keys } from "../Blocks.sol";
6
+ string constant NAME = "supply";
7
+
8
+ using Blocks for Block;
9
+
10
+ abstract contract Supply is CommandBase {
11
+ uint internal immutable supplyId = commandId(NAME);
12
+
13
+ constructor() {
14
+ emit Command(host, NAME, "", supplyId, Channels.Custodies, Channels.Setup);
15
+ }
16
+
17
+ /// @dev Override to consume or supply a single custody position.
18
+ /// Called once per CUSTODY block in state.
19
+ function supply(bytes32 account, HostAmount memory value) internal virtual;
20
+
21
+ function supply(CommandContext calldata c) external payable onlyCommand(supplyId, c.target) returns (bytes memory) {
22
+ uint i = 0;
23
+ while (i < c.state.length) {
24
+ Block memory ref = Blocks.from(c.state, i);
25
+ if (ref.key != Keys.Custody) break;
26
+ HostAmount memory value = ref.toCustodyValue();
27
+ supply(c.account, value);
28
+ i = ref.cursor;
29
+ }
30
+
31
+ return done(0, i);
32
+ }
33
+ }
@@ -0,0 +1,88 @@
1
+ // SPDX-License-Identifier: GPL-3.0-only
2
+ pragma solidity ^0.8.33;
3
+
4
+ import { CommandContext, CommandBase, Channels } from "./Base.sol";
5
+ import { AssetAmount, HostAmount, Keys, Schemas, Blocks, Block, Writers, Writer } from "../Blocks.sol";
6
+ using Blocks for Block;
7
+ using Writers for Writer;
8
+
9
+ string constant SEBTB = "swapExactBalanceToBalance";
10
+ string constant SECTB = "swapExactCustodyToBalance";
11
+
12
+ abstract contract SwapExactBalanceToBalance is CommandBase {
13
+ uint internal immutable swapExactBalanceToBalanceId = commandId(SEBTB);
14
+
15
+ constructor(string memory maybeRoute) {
16
+ string memory schema = Schemas.route1(maybeRoute, Schemas.Minimum);
17
+ emit Command(host, SEBTB, schema, swapExactBalanceToBalanceId, Channels.Balances, Channels.Balances);
18
+ }
19
+
20
+ /// @dev Override to swap an exact balance input into a balance output.
21
+ /// Implementations extract the requested minimum from
22
+ /// `rawRoute.innerMinimum()`.
23
+ function swapExactBalanceToBalance(
24
+ bytes32 account,
25
+ AssetAmount memory balance,
26
+ Block memory rawRoute
27
+ ) internal virtual returns (AssetAmount memory out);
28
+
29
+ function swapExactBalanceToBalance(
30
+ CommandContext calldata c
31
+ ) external payable onlyCommand(swapExactBalanceToBalanceId, c.target) returns (bytes memory) {
32
+ uint i = 0;
33
+ uint q = 0;
34
+ (Writer memory writer, uint end) = Writers.allocBalancesFrom(c.state, i, Keys.Balance);
35
+
36
+ while (i < end) {
37
+ Block memory route;
38
+ route = Blocks.routeFrom(c.request, q);
39
+ q = route.cursor;
40
+ Block memory ref = Blocks.from(c.state, i);
41
+ AssetAmount memory balance = ref.toBalanceValue();
42
+ AssetAmount memory out = swapExactBalanceToBalance(c.account, balance, route);
43
+ writer.appendNonZeroBalance(out);
44
+ i = ref.cursor;
45
+ }
46
+
47
+ return writer.finish();
48
+ }
49
+ }
50
+
51
+ abstract contract SwapExactCustodyToBalance is CommandBase {
52
+ uint internal immutable swapExactCustodyToBalanceId = commandId(SECTB);
53
+
54
+ constructor(string memory maybeRoute) {
55
+ string memory schema = Schemas.route1(maybeRoute, Schemas.Minimum);
56
+ emit Command(host, SECTB, schema, swapExactCustodyToBalanceId, Channels.Custodies, Channels.Balances);
57
+ }
58
+
59
+ /// @dev Override to swap an exact custody input into a balance output.
60
+ /// Implementations extract the requested minimum from
61
+ /// `rawRoute.innerMinimum()`.
62
+ function swapExactCustodyToBalance(
63
+ bytes32 account,
64
+ HostAmount memory custody,
65
+ Block memory rawRoute
66
+ ) internal virtual returns (AssetAmount memory out);
67
+
68
+ function swapExactCustodyToBalance(
69
+ CommandContext calldata c
70
+ ) external payable onlyCommand(swapExactCustodyToBalanceId, c.target) returns (bytes memory) {
71
+ uint i = 0;
72
+ uint q = 0;
73
+ (Writer memory writer, uint end) = Writers.allocBalancesFrom(c.state, i, Keys.Custody);
74
+
75
+ while (i < end) {
76
+ Block memory route;
77
+ route = Blocks.routeFrom(c.request, q);
78
+ q = route.cursor;
79
+ Block memory ref = Blocks.from(c.state, i);
80
+ HostAmount memory custody = ref.toCustodyValue();
81
+ AssetAmount memory out = swapExactCustodyToBalance(c.account, custody, route);
82
+ writer.appendNonZeroBalance(out);
83
+ i = ref.cursor;
84
+ }
85
+
86
+ return writer.finish();
87
+ }
88
+ }