@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,40 @@
1
+ // SPDX-License-Identifier: GPL-3.0-only
2
+ pragma solidity ^0.8.33;
3
+
4
+ import { OperationBase } from "../core/Operation.sol";
5
+ import { CommandEvent } from "../events/Command.sol";
6
+ import { Channels } from "../utils/Channels.sol";
7
+ import { Ids, Selectors } from "../utils/Ids.sol";
8
+
9
+ struct CommandContext {
10
+ uint target;
11
+ bytes32 account;
12
+ bytes state;
13
+ bytes request;
14
+ }
15
+
16
+ abstract contract CommandBase is OperationBase, CommandEvent {
17
+ error Expired();
18
+ error NotAdmin(bytes32 value);
19
+ error UnexpectedEndpoint();
20
+
21
+ modifier onlyAdmin(bytes32 account) {
22
+ if (account != adminAccount) revert NotAdmin(account);
23
+ _;
24
+ }
25
+
26
+ modifier onlyCommand(uint cid, uint target) {
27
+ if (target != 0 && target != cid) revert UnexpectedEndpoint();
28
+ enforceCaller(msg.sender);
29
+ _;
30
+ }
31
+
32
+ modifier onlyActive(uint deadline) {
33
+ if (deadline < block.timestamp) revert Expired();
34
+ _;
35
+ }
36
+
37
+ function commandId(string memory name) internal view returns (uint) {
38
+ return Ids.toCommand(Selectors.command(name), address(this));
39
+ }
40
+ }
@@ -0,0 +1,89 @@
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 BABTB = "borrowAgainstBalanceToBalance";
8
+ string constant BACTB = "borrowAgainstCustodyToBalance";
9
+
10
+ using Blocks for Block;
11
+ using Writers for Writer;
12
+
13
+ abstract contract BorrowAgainstCustodyToBalance is CommandBase {
14
+ uint internal immutable borrowAgainstCustodyToBalanceId = commandId(BACTB);
15
+
16
+ constructor(string memory maybeRoute) {
17
+ string memory schema = Schemas.route1(maybeRoute, Schemas.Amount);
18
+ emit Command(host, BACTB, schema, borrowAgainstCustodyToBalanceId, Channels.Custodies, Channels.Balances);
19
+ }
20
+
21
+ /// @dev Override to borrow against a custody position.
22
+ /// Implementations extract the requested borrow amount from
23
+ /// `rawRoute.innerAmount()`.
24
+ function borrowAgainstCustodyToBalance(
25
+ bytes32 account,
26
+ HostAmount memory custody,
27
+ Block memory rawRoute
28
+ ) internal virtual returns (AssetAmount memory);
29
+
30
+ function borrowAgainstCustodyToBalance(
31
+ CommandContext calldata c
32
+ ) external payable onlyCommand(borrowAgainstCustodyToBalanceId, c.target) returns (bytes memory) {
33
+ uint i = 0;
34
+ uint q = 0;
35
+ (Writer memory writer, uint end) = Writers.allocBalancesFrom(c.state, i, Keys.Custody);
36
+
37
+ while (i < end) {
38
+ Block memory route;
39
+ route = Blocks.routeFrom(c.request, q);
40
+ q = route.cursor;
41
+ Block memory ref = Blocks.from(c.state, i);
42
+ HostAmount memory custody = ref.toCustodyValue();
43
+ AssetAmount memory out = borrowAgainstCustodyToBalance(c.account, custody, route);
44
+ writer.appendNonZeroBalance(out);
45
+ i = ref.cursor;
46
+ }
47
+
48
+ return writer.finish();
49
+ }
50
+ }
51
+
52
+ abstract contract BorrowAgainstBalanceToBalance is CommandBase {
53
+ uint internal immutable borrowAgainstBalanceToBalanceId = commandId(BABTB);
54
+
55
+ constructor(string memory maybeRoute) {
56
+ string memory schema = Schemas.route1(maybeRoute, Schemas.Amount);
57
+ emit Command(host, BABTB, schema, borrowAgainstBalanceToBalanceId, Channels.Balances, Channels.Balances);
58
+ }
59
+
60
+ /// @dev Override to borrow against a balance position.
61
+ /// Implementations extract the requested borrow amount from
62
+ /// `rawRoute.innerAmount()`.
63
+ function borrowAgainstBalanceToBalance(
64
+ bytes32 account,
65
+ AssetAmount memory balance,
66
+ Block memory rawRoute
67
+ ) internal virtual returns (AssetAmount memory);
68
+
69
+ function borrowAgainstBalanceToBalance(
70
+ CommandContext calldata c
71
+ ) external payable onlyCommand(borrowAgainstBalanceToBalanceId, c.target) returns (bytes memory) {
72
+ uint i = 0;
73
+ uint q = 0;
74
+ (Writer memory writer, uint end) = Writers.allocBalancesFrom(c.state, i, Keys.Balance);
75
+
76
+ while (i < end) {
77
+ Block memory route;
78
+ route = Blocks.routeFrom(c.request, q);
79
+ q = route.cursor;
80
+ Block memory ref = Blocks.from(c.state, i);
81
+ AssetAmount memory balance = ref.toBalanceValue();
82
+ AssetAmount memory out = borrowAgainstBalanceToBalance(c.account, balance, route);
83
+ writer.appendNonZeroBalance(out);
84
+ i = ref.cursor;
85
+ }
86
+
87
+ return writer.finish();
88
+ }
89
+ }
@@ -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, Keys } from "../Blocks.sol";
6
+ using Blocks for Block;
7
+
8
+ string constant NAME = "burn";
9
+
10
+ abstract contract Burn is CommandBase {
11
+ uint internal immutable burnId = commandId(NAME);
12
+
13
+ constructor(string memory route) {
14
+ emit Command(host, NAME, route, burnId, Channels.Balances, Channels.Setup);
15
+ }
16
+
17
+ /// @dev Override to burn or consume the provided balance amount.
18
+ /// Called once per BALANCE block in state.
19
+ function burn(bytes32 account, bytes32 asset, bytes32 meta, uint amount) internal virtual returns (uint);
20
+
21
+ function burn(CommandContext calldata c) external payable onlyCommand(burnId, 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.Balance) break;
26
+ (bytes32 asset, bytes32 meta, uint amount) = ref.unpackBalance();
27
+ burn(c.account, asset, meta, amount);
28
+ i = ref.cursor;
29
+ }
30
+
31
+ return done(0, i);
32
+ }
33
+ }
@@ -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 = "create";
9
+
10
+ abstract contract Create is CommandBase {
11
+ uint internal immutable createId = commandId(NAME);
12
+
13
+ constructor(string memory route) {
14
+ emit Command(host, NAME, route, createId, Channels.Setup, Channels.Setup);
15
+ }
16
+
17
+ /// @dev Override to create or initialize an object described by `rawRoute`.
18
+ /// Called once per ROUTE block in the request.
19
+ function create(bytes32 account, Block memory rawRoute) internal virtual;
20
+
21
+ function create(CommandContext calldata c) external payable onlyCommand(createId, 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
+ create(c.account, ref);
27
+ q = ref.cursor;
28
+ }
29
+
30
+ return done(0, q);
31
+ }
32
+ }
@@ -0,0 +1,36 @@
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 { Keys, Schemas, Blocks, Block } from "../Blocks.sol";
6
+ string constant NAME = "creditAccount";
7
+
8
+ using Blocks for Block;
9
+
10
+ abstract contract CreditAccount is CommandBase {
11
+ uint internal immutable creditAccountId = commandId(NAME);
12
+
13
+ constructor() {
14
+ emit Command(host, NAME, Schemas.Recipient, creditAccountId, Channels.Balances, Channels.Setup);
15
+ }
16
+
17
+ /// @dev Override to credit externally managed funds to `account`.
18
+ /// Called once per BALANCE block in state.
19
+ function creditAccount(bytes32 account, bytes32 asset, bytes32 meta, uint amount) internal virtual;
20
+
21
+ function creditAccount(
22
+ CommandContext calldata c
23
+ ) external payable onlyCommand(creditAccountId, c.target) returns (bytes memory) {
24
+ bytes32 to = Blocks.resolveRecipient(c.request, 0, c.request.length, c.account);
25
+ uint i = 0;
26
+ while (i < c.state.length) {
27
+ Block memory ref = Blocks.from(c.state, i);
28
+ if (ref.key != Keys.Balance) break;
29
+ (bytes32 asset, bytes32 meta, uint amount) = ref.unpackBalance();
30
+ creditAccount(to, asset, meta, amount);
31
+ i = ref.cursor;
32
+ }
33
+
34
+ return done(0, i);
35
+ }
36
+ }
@@ -0,0 +1,46 @@
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 { Writer, Keys, Schemas, Blocks, Block, Writers } from "../Blocks.sol";
6
+
7
+ string constant NAME = "debitAccount";
8
+
9
+ using Blocks for Block;
10
+ using Writers for Writer;
11
+
12
+ abstract contract DebitAccount is CommandBase {
13
+ uint internal immutable debitAccountId = commandId(NAME);
14
+
15
+ constructor() {
16
+ emit Command(host, NAME, Schemas.Amount, debitAccountId, Channels.Setup, Channels.Balances);
17
+ }
18
+
19
+ /// @dev Override to debit externally managed funds from `account`.
20
+ /// Called once per AMOUNT block before a matching BALANCE is emitted.
21
+ function debitAccount(bytes32 account, bytes32 asset, bytes32 meta, uint amount) internal virtual;
22
+
23
+ /// @dev Override to customize request parsing or batching for debits.
24
+ /// The default implementation iterates AMOUNT blocks, calls
25
+ /// `debitAccount`, and emits matching BALANCE blocks.
26
+ function debitAccount(bytes32 from, bytes calldata request) internal virtual returns (bytes memory) {
27
+ uint q = 0;
28
+ (Writer memory writer, uint end) = Writers.allocBalancesFrom(request, q, Keys.Amount);
29
+
30
+ while (q < end) {
31
+ Block memory ref = Blocks.from(request, q);
32
+ (bytes32 asset, bytes32 meta, uint amount) = ref.unpackAmount();
33
+ debitAccount(from, asset, meta, amount);
34
+ writer.appendBalance(asset, meta, amount);
35
+ q = ref.cursor;
36
+ }
37
+
38
+ return writer.done();
39
+ }
40
+
41
+ function debitAccount(
42
+ CommandContext calldata c
43
+ ) external payable onlyCommand(debitAccountId, c.target) returns (bytes memory) {
44
+ return debitAccount(c.account, c.request);
45
+ }
46
+ }
@@ -0,0 +1,45 @@
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 { Writer, Keys, Schemas, Blocks, Block, Writers } from "../Blocks.sol";
6
+
7
+ string constant NAME = "deposit";
8
+
9
+ using Blocks for Block;
10
+ using Writers for Writer;
11
+
12
+ // @dev Use `deposit` for externally sourced assets; use `debitAccountToBalance` for internal balance deductions.
13
+ abstract contract Deposit is CommandBase {
14
+ uint internal immutable depositId = commandId(NAME);
15
+
16
+ constructor() {
17
+ emit Command(host, NAME, Schemas.Amount, depositId, Channels.Setup, Channels.Balances);
18
+ }
19
+
20
+ /// @dev Override to receive externally sourced funds for `account`.
21
+ /// Called once per AMOUNT block and followed by a matching BALANCE output.
22
+ function deposit(
23
+ bytes32 account,
24
+ bytes32 asset,
25
+ bytes32 meta,
26
+ uint amount
27
+ ) internal virtual;
28
+
29
+ function deposit(
30
+ CommandContext calldata c
31
+ ) external payable onlyCommand(depositId, c.target) returns (bytes memory) {
32
+ uint q = 0;
33
+ (Writer memory writer, uint next) = Writers.allocBalancesFrom(c.request, q, Keys.Amount);
34
+
35
+ while (q < next) {
36
+ Block memory ref = Blocks.from(c.request, q);
37
+ (bytes32 asset, bytes32 meta, uint amount) = ref.unpackAmount();
38
+ deposit(c.account, asset, meta, amount);
39
+ writer.appendBalance(asset, meta, amount);
40
+ q = ref.cursor;
41
+ }
42
+
43
+ return writer.done();
44
+ }
45
+ }
@@ -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 LFBTB = "liquidateFromBalanceToBalances";
8
+ string constant LFCTB = "liquidateFromCustodyToBalances";
9
+
10
+ using Blocks for Block;
11
+ using Writers for Writer;
12
+
13
+ abstract contract LiquidateFromBalanceToBalances is CommandBase {
14
+ uint internal immutable liquidateFromBalanceToBalancesId = commandId(LFBTB);
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, LFBTB, maybeRoute, liquidateFromBalanceToBalancesId, Channels.Balances, Channels.Balances);
22
+ }
23
+
24
+ /// @dev Override to liquidate using a balance repayment 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 liquidateFromBalanceToBalances(
29
+ bytes32 account,
30
+ AssetAmount memory balance,
31
+ Block memory rawRoute,
32
+ Writer memory out
33
+ ) internal virtual;
34
+
35
+ function liquidateFromBalanceToBalances(
36
+ CommandContext calldata c
37
+ ) external payable onlyCommand(liquidateFromBalanceToBalancesId, 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
+ liquidateFromBalanceToBalances(c.account, balance, route, writer);
51
+ i = ref.cursor;
52
+ }
53
+
54
+ return writer.finish();
55
+ }
56
+ }
57
+
58
+ abstract contract LiquidateFromCustodyToBalances is CommandBase {
59
+ uint internal immutable liquidateFromCustodyToBalancesId = commandId(LFCTB);
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, LFCTB, maybeRoute, liquidateFromCustodyToBalancesId, Channels.Custodies, Channels.Balances);
67
+ }
68
+
69
+ /// @dev Override to liquidate using a custody repayment 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 liquidateFromCustodyToBalances(
74
+ bytes32 account,
75
+ HostAmount memory custody,
76
+ Block memory rawRoute,
77
+ Writer memory out
78
+ ) internal virtual;
79
+
80
+ function liquidateFromCustodyToBalances(
81
+ CommandContext calldata c
82
+ ) external payable onlyCommand(liquidateFromCustodyToBalancesId, 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
+ liquidateFromCustodyToBalances(c.account, custody, route, writer);
96
+ i = ref.cursor;
97
+ }
98
+
99
+ return writer.finish();
100
+ }
101
+ }
@@ -0,0 +1,179 @@
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, BlockPair, Writers, Writer } from "../Blocks.sol";
6
+
7
+ using Blocks for Block;
8
+ using Writers for Writer;
9
+
10
+ string constant ALFCTB = "addLiquidityFromCustodiesToBalances";
11
+ string constant ALFBTB = "addLiquidityFromBalancesToBalances";
12
+ string constant RLFCTB = "removeLiquidityFromCustodyToBalances";
13
+ string constant RLFBTB = "removeLiquidityFromBalanceToBalances";
14
+
15
+ abstract contract AddLiquidityFromCustodiesToBalances is CommandBase {
16
+ uint internal immutable addLiquidityFromCustodiesToBalancesId = commandId(ALFCTB);
17
+ uint private immutable outScale;
18
+
19
+ constructor(string memory maybeRoute, uint scaledRatio) {
20
+ outScale = scaledRatio;
21
+ string memory schema = Schemas.route1(maybeRoute, Schemas.Minimum);
22
+ emit Command(host, ALFCTB, schema, addLiquidityFromCustodiesToBalancesId, Channels.Custodies, Channels.Balances);
23
+ }
24
+
25
+ /// @dev Override to add liquidity from two custody inputs.
26
+ /// Implementations extract the requested minimum liquidity output from
27
+ /// `rawRoute.innerMinimum()` and may append up to three BALANCE blocks to
28
+ /// `out`: two refunds plus the liquidity receipt.
29
+ function addLiquidityFromCustodiesToBalances(
30
+ bytes32 account,
31
+ BlockPair memory rawCustodies,
32
+ Block memory rawRoute,
33
+ Writer memory out
34
+ ) internal virtual;
35
+
36
+ function addLiquidityFromCustodiesToBalances(
37
+ CommandContext calldata c
38
+ ) external payable onlyCommand(addLiquidityFromCustodiesToBalancesId, c.target) returns (bytes memory) {
39
+ uint i = 0;
40
+ uint q = 0;
41
+ (Writer memory writer, uint end) = Writers.allocScaledBalancesFrom(c.state, i, Keys.Custody, outScale);
42
+
43
+ while (i < end) {
44
+ Block memory route;
45
+ route = Blocks.routeFrom(c.request, q);
46
+ q = route.cursor;
47
+ BlockPair memory custodies;
48
+ custodies = Blocks.twoFrom(c.state, i);
49
+ i = custodies.b.cursor;
50
+ addLiquidityFromCustodiesToBalances(c.account, custodies, route, writer);
51
+ }
52
+
53
+ return writer.finish();
54
+ }
55
+ }
56
+
57
+ abstract contract RemoveLiquidityFromCustodyToBalances is CommandBase {
58
+ uint internal immutable removeLiquidityFromCustodyToBalancesId = commandId(RLFCTB);
59
+ uint private immutable outScale;
60
+
61
+ constructor(string memory maybeRoute, uint scaledRatio) {
62
+ outScale = scaledRatio;
63
+ string memory schema = Schemas.route2(maybeRoute, Schemas.Minimum, Schemas.Minimum);
64
+ emit Command(host, RLFCTB, schema, removeLiquidityFromCustodyToBalancesId, Channels.Custodies, Channels.Balances);
65
+ }
66
+
67
+ /// @dev Override to remove liquidity from a custody position.
68
+ /// Implementations extract requested minimum outputs from `rawRoute` and
69
+ /// may append up to two BALANCE blocks to `out`.
70
+ function removeLiquidityFromCustodyToBalances(
71
+ bytes32 account,
72
+ HostAmount memory custody,
73
+ Block memory rawRoute,
74
+ Writer memory out
75
+ ) internal virtual;
76
+
77
+ function removeLiquidityFromCustodyToBalances(
78
+ CommandContext calldata c
79
+ ) external payable onlyCommand(removeLiquidityFromCustodyToBalancesId, c.target) returns (bytes memory) {
80
+ uint i = 0;
81
+ uint q = 0;
82
+ (Writer memory writer, uint end) = Writers.allocScaledBalancesFrom(c.state, i, Keys.Custody, outScale);
83
+
84
+ while (i < end) {
85
+ Block memory route;
86
+ route = Blocks.routeFrom(c.request, q);
87
+ q = route.cursor;
88
+ Block memory ref = Blocks.from(c.state, i);
89
+ HostAmount memory custody = ref.toCustodyValue();
90
+ removeLiquidityFromCustodyToBalances(c.account, custody, route, writer);
91
+ i = ref.cursor;
92
+ }
93
+
94
+ return writer.finish();
95
+ }
96
+ }
97
+
98
+ abstract contract AddLiquidityFromBalancesToBalances is CommandBase {
99
+ uint internal immutable addLiquidityFromBalancesToBalancesId = commandId(ALFBTB);
100
+ uint private immutable outScale;
101
+
102
+ constructor(string memory maybeRoute, uint scaledRatio) {
103
+ outScale = scaledRatio;
104
+ string memory schema = Schemas.route1(maybeRoute, Schemas.Minimum);
105
+ emit Command(host, ALFBTB, schema, addLiquidityFromBalancesToBalancesId, Channels.Balances, Channels.Balances);
106
+ }
107
+
108
+ /// @dev Override to add liquidity from two balance inputs.
109
+ /// Implementations extract the requested minimum liquidity output from
110
+ /// `rawRoute.innerMinimum()` and may append up to three BALANCE blocks to
111
+ /// `out`: two refunds plus the liquidity receipt.
112
+ function addLiquidityFromBalancesToBalances(
113
+ bytes32 account,
114
+ BlockPair memory rawBalances,
115
+ Block memory rawRoute,
116
+ Writer memory out
117
+ ) internal virtual;
118
+
119
+ function addLiquidityFromBalancesToBalances(
120
+ CommandContext calldata c
121
+ ) external payable onlyCommand(addLiquidityFromBalancesToBalancesId, c.target) returns (bytes memory) {
122
+ uint i = 0;
123
+ uint q = 0;
124
+ (Writer memory writer, uint end) = Writers.allocScaledBalancesFrom(c.state, i, Keys.Balance, outScale);
125
+
126
+ while (i < end) {
127
+ Block memory route;
128
+ route = Blocks.routeFrom(c.request, q);
129
+ q = route.cursor;
130
+ BlockPair memory balances;
131
+ balances = Blocks.twoFrom(c.state, i);
132
+ i = balances.b.cursor;
133
+ addLiquidityFromBalancesToBalances(c.account, balances, route, writer);
134
+ }
135
+
136
+ return writer.finish();
137
+ }
138
+ }
139
+
140
+ abstract contract RemoveLiquidityFromBalanceToBalances is CommandBase {
141
+ uint internal immutable removeLiquidityFromBalanceToBalancesId = commandId(RLFBTB);
142
+ uint private immutable outScale;
143
+
144
+ constructor(string memory maybeRoute, uint scaledRatio) {
145
+ outScale = scaledRatio;
146
+ string memory schema = Schemas.route2(maybeRoute, Schemas.Minimum, Schemas.Minimum);
147
+ emit Command(host, RLFBTB, schema, removeLiquidityFromBalanceToBalancesId, Channels.Balances, Channels.Balances);
148
+ }
149
+
150
+ /// @dev Override to remove liquidity from a balance position.
151
+ /// Implementations extract requested minimum outputs from `rawRoute` and
152
+ /// may append up to two BALANCE blocks to `out`.
153
+ function removeLiquidityFromBalanceToBalances(
154
+ bytes32 account,
155
+ AssetAmount memory balance,
156
+ Block memory rawRoute,
157
+ Writer memory out
158
+ ) internal virtual;
159
+
160
+ function removeLiquidityFromBalanceToBalances(
161
+ CommandContext calldata c
162
+ ) external payable onlyCommand(removeLiquidityFromBalanceToBalancesId, c.target) returns (bytes memory) {
163
+ uint i = 0;
164
+ uint q = 0;
165
+ (Writer memory writer, uint end) = Writers.allocScaledBalancesFrom(c.state, i, Keys.Balance, outScale);
166
+
167
+ while (i < end) {
168
+ Block memory route;
169
+ route = Blocks.routeFrom(c.request, q);
170
+ q = route.cursor;
171
+ Block memory ref = Blocks.from(c.state, i);
172
+ AssetAmount memory balance = ref.toBalanceValue();
173
+ removeLiquidityFromBalanceToBalances(c.account, balance, route, writer);
174
+ i = ref.cursor;
175
+ }
176
+
177
+ return writer.finish();
178
+ }
179
+ }
@@ -0,0 +1,42 @@
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, Writers, Writer, Keys } from "../Blocks.sol";
6
+ using Writers for Writer;
7
+
8
+ string constant NAME = "mintToBalances";
9
+
10
+ abstract contract MintToBalances is CommandBase {
11
+ uint internal immutable mintToBalancesId = commandId(NAME);
12
+ uint private immutable outScale;
13
+
14
+ constructor(string memory route, uint scaledRatio) {
15
+ outScale = scaledRatio;
16
+ emit Command(host, NAME, route, mintToBalancesId, Channels.Setup, Channels.Balances);
17
+ }
18
+
19
+ /// @dev Override to mint balances described by `rawRoute` for `account`.
20
+ /// Implementations may append one or more BALANCE blocks to `out`.
21
+ function mintToBalances(
22
+ bytes32 account,
23
+ Block memory rawRoute,
24
+ Writer memory out
25
+ ) internal virtual;
26
+
27
+ function mintToBalances(
28
+ CommandContext calldata c
29
+ ) external payable onlyCommand(mintToBalancesId, c.target) returns (bytes memory) {
30
+ uint q = 0;
31
+ (Writer memory writer, uint end) = Writers.allocScaledBalancesFrom(c.request, q, Keys.Route, outScale);
32
+
33
+ while (q < end) {
34
+ Block memory route;
35
+ route = Blocks.routeFrom(c.request, q);
36
+ q = route.cursor;
37
+ mintToBalances(c.account, route, writer);
38
+ }
39
+
40
+ return writer.finish();
41
+ }
42
+ }