@rootzero/contracts 0.9.1 → 0.9.3
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/Commands.sol +16 -16
- package/Cursors.sol +1 -1
- package/Events.sol +3 -3
- package/Utils.sol +1 -1
- package/blocks/Cursors.sol +51 -9
- package/blocks/Keys.sol +1 -1
- package/blocks/Schema.sol +98 -4
- package/blocks/Writers.sol +21 -125
- package/commands/Base.sol +0 -19
- package/commands/Burn.sol +2 -2
- package/commands/Credit.sol +3 -2
- package/commands/Debit.sol +3 -3
- package/commands/Deposit.sol +6 -6
- package/commands/Pipe.sol +17 -12
- package/commands/Provision.sol +8 -8
- package/commands/Transfer.sol +2 -2
- package/commands/Withdraw.sol +3 -2
- package/commands/{control → admin}/AllowAssets.sol +5 -5
- package/commands/{control → admin}/Allowance.sol +9 -9
- package/commands/{control → admin}/Authorize.sol +5 -5
- package/commands/{control → admin}/DenyAssets.sol +5 -5
- package/commands/{control → admin}/Destroy.sol +4 -4
- package/commands/{control → admin}/Execute.sol +5 -5
- package/commands/{control → admin}/Init.sol +4 -4
- package/commands/{control → admin}/Unauthorize.sol +5 -5
- package/core/Access.sol +2 -2
- package/core/Calls.sol +16 -2
- package/core/Context.sol +10 -11
- package/core/Host.sol +4 -4
- package/core/Types.sol +1 -1
- package/events/{Control.sol → Admin.sol} +9 -5
- package/events/Command.sol +7 -2
- package/events/Listing.sol +3 -4
- package/events/Peer.sol +26 -0
- package/events/{RootZero.sol → Piped.sol} +3 -3
- package/events/Query.sol +5 -2
- package/package.json +1 -1
- package/peer/AllowAssets.sol +38 -0
- package/peer/Allowance.sol +35 -0
- package/peer/BalancePull.sol +43 -0
- package/peer/Base.sol +40 -0
- package/peer/DenyAssets.sol +38 -0
- package/peer/Settle.sol +32 -0
- package/queries/Assets.sol +4 -5
- package/queries/Balances.sol +4 -5
- package/queries/Positions.sol +4 -5
- package/utils/Accounts.sol +8 -0
- package/utils/Ids.sol +35 -30
- package/utils/Layout.sol +3 -3
- package/utils/Utils.sol +2 -2
- package/events/Remote.sol +0 -24
- package/remote/AllowAssets.sol +0 -39
- package/remote/Allowance.sol +0 -36
- package/remote/AssetPull.sol +0 -44
- package/remote/Base.sol +0 -40
- package/remote/DenyAssets.sol +0 -39
- package/remote/Settle.sol +0 -33
package/Commands.sol
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
// Aggregator: re-exports command,
|
|
4
|
+
// Aggregator: re-exports command, admin, and peer abstractions.
|
|
5
5
|
// Import this file to inherit from the full rootzero command surface without managing individual paths.
|
|
6
6
|
|
|
7
|
-
import { CommandBase, CommandContext, CommandPayable
|
|
7
|
+
import { CommandBase, CommandContext, CommandPayable } from "./commands/Base.sol";
|
|
8
8
|
import { Keys } from "./blocks/Keys.sol";
|
|
9
9
|
import { Burn, BurnHook } from "./commands/Burn.sol";
|
|
10
10
|
import { CreditAccount, CreditAccountHook } from "./commands/Credit.sol";
|
|
@@ -14,20 +14,20 @@ import { PipePayable, PipePayableHook } from "./commands/Pipe.sol";
|
|
|
14
14
|
import { Provision, ProvisionHook, ProvisionPayable, ProvisionPayableHook } from "./commands/Provision.sol";
|
|
15
15
|
import { Transfer, TransferHook } from "./commands/Transfer.sol";
|
|
16
16
|
import { Withdraw, WithdrawHook } from "./commands/Withdraw.sol";
|
|
17
|
-
import { AllowAssets, AllowAssetsHook } from "./commands/
|
|
18
|
-
import { Destroy, DestroyHook } from "./commands/
|
|
19
|
-
import { ExecutePayable } from "./commands/
|
|
20
|
-
import { Authorize } from "./commands/
|
|
21
|
-
import { DenyAssets, DenyAssetsHook } from "./commands/
|
|
22
|
-
import { Init, InitHook } from "./commands/
|
|
23
|
-
import { Allowance, AllowanceHook } from "./commands/
|
|
24
|
-
import { Unauthorize } from "./commands/
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
17
|
+
import { AllowAssets, AllowAssetsHook } from "./commands/admin/AllowAssets.sol";
|
|
18
|
+
import { Destroy, DestroyHook } from "./commands/admin/Destroy.sol";
|
|
19
|
+
import { ExecutePayable } from "./commands/admin/Execute.sol";
|
|
20
|
+
import { Authorize } from "./commands/admin/Authorize.sol";
|
|
21
|
+
import { DenyAssets, DenyAssetsHook } from "./commands/admin/DenyAssets.sol";
|
|
22
|
+
import { Init, InitHook } from "./commands/admin/Init.sol";
|
|
23
|
+
import { Allowance, AllowanceHook } from "./commands/admin/Allowance.sol";
|
|
24
|
+
import { Unauthorize } from "./commands/admin/Unauthorize.sol";
|
|
25
|
+
import { PeerBase, encodePeerCall } from "./peer/Base.sol";
|
|
26
|
+
import { PeerAllowance } from "./peer/Allowance.sol";
|
|
27
|
+
import { PeerBalancePull, BalancePullHook } from "./peer/BalancePull.sol";
|
|
28
|
+
import { PeerAllowAssets } from "./peer/AllowAssets.sol";
|
|
29
|
+
import { PeerDenyAssets } from "./peer/DenyAssets.sol";
|
|
30
|
+
import { PeerSettle } from "./peer/Settle.sol";
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
|
package/Cursors.sol
CHANGED
|
@@ -9,7 +9,7 @@ import { Forms, Sizes } from "./blocks/Schema.sol";
|
|
|
9
9
|
import { Keys } from "./blocks/Keys.sol";
|
|
10
10
|
import { Schemas } from "./blocks/Schema.sol";
|
|
11
11
|
import { Cursors, Cur } from "./blocks/Cursors.sol";
|
|
12
|
-
import {
|
|
12
|
+
import { Writer, Writers } from "./blocks/Writers.sol";
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
|
package/Events.sol
CHANGED
|
@@ -5,7 +5,7 @@ pragma solidity ^0.8.33;
|
|
|
5
5
|
// Import this file to get access to every event emitter in one import.
|
|
6
6
|
|
|
7
7
|
import { AccessEvent } from "./events/Access.sol";
|
|
8
|
-
import {
|
|
8
|
+
import { AdminEvent } from "./events/Admin.sol";
|
|
9
9
|
import { AssetEvent } from "./events/Asset.sol";
|
|
10
10
|
import { BalanceEvent } from "./events/Balance.sol";
|
|
11
11
|
import { CollateralEvent } from "./events/Collateral.sol";
|
|
@@ -17,9 +17,9 @@ import { EventEmitter } from "./events/Emitter.sol";
|
|
|
17
17
|
import { GovernedEvent } from "./events/Governed.sol";
|
|
18
18
|
import { HostAnnouncedEvent } from "./events/Host.sol";
|
|
19
19
|
import { ListingEvent } from "./events/Listing.sol";
|
|
20
|
-
import {
|
|
20
|
+
import { PeerEvent } from "./events/Peer.sol";
|
|
21
21
|
import { QueryEvent } from "./events/Query.sol";
|
|
22
|
-
import {
|
|
22
|
+
import { PipedEvent } from "./events/Piped.sol";
|
|
23
23
|
import { SwapEvent } from "./events/Swap.sol";
|
|
24
24
|
import { WithdrawalEvent } from "./events/Withdraw.sol";
|
|
25
25
|
|
package/Utils.sol
CHANGED
|
@@ -11,7 +11,7 @@ import { ECDSA } from "./utils/ECDSA.sol";
|
|
|
11
11
|
import { Ids, Selectors } from "./utils/Ids.sol";
|
|
12
12
|
import { Layout } from "./utils/Layout.sol";
|
|
13
13
|
import { Schemas } from "./blocks/Schema.sol";
|
|
14
|
-
import { addrOr, applyBps, beforeBps, bytes32ToInt, bytes32ToString, divisible, hash32, intToBytes32, isFamily,
|
|
14
|
+
import { addrOr, applyBps, beforeBps, bytes32ToInt, bytes32ToString, divisible, hash32, intToBytes32, isFamily, isLocalChain, isLocalFamily, matchesBase, MAX_BPS, max8, max16, max24, max32, max40, max64, max96, max128, max160, NotDivisible, retryTicket, toLocalBase, toLocalFamily, toUnspecifiedBase, ValueOverflow } from "./utils/Utils.sol";
|
|
15
15
|
import { Budget, Values } from "./utils/Value.sol";
|
|
16
16
|
|
|
17
17
|
|
package/blocks/Cursors.sol
CHANGED
|
@@ -4,7 +4,7 @@ pragma solidity ^0.8.33;
|
|
|
4
4
|
import {AssetAmount, AccountAsset, AccountAmount, HostAmount, HostAccountAsset, Tx} from "../core/Types.sol";
|
|
5
5
|
import {Sizes} from "./Schema.sol";
|
|
6
6
|
import {Keys} from "./Keys.sol";
|
|
7
|
-
import {
|
|
7
|
+
import {Writer, Writers} from "./Writers.sol";
|
|
8
8
|
|
|
9
9
|
/// @notice Zero-copy view into a calldata block stream.
|
|
10
10
|
/// All positions (`i`, `bound`) are byte offsets relative to the start of the source region.
|
|
@@ -45,7 +45,7 @@ library Cursors {
|
|
|
45
45
|
error ZeroNode();
|
|
46
46
|
/// @dev A field value did not match the expected value.
|
|
47
47
|
error UnexpectedValue();
|
|
48
|
-
/// @dev
|
|
48
|
+
/// @dev Prime block counts are not divisible by, or do not match, their declared group sizes.
|
|
49
49
|
error BadRatio();
|
|
50
50
|
// -------------------------------------------------------------------------
|
|
51
51
|
// Cursor construction and navigation
|
|
@@ -87,6 +87,25 @@ library Cursors {
|
|
|
87
87
|
out.len = to - from;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
/// @notice Return the full cursor region as a calldata slice.
|
|
91
|
+
/// Does not advance the cursor; `cur.i` and `cur.bound` are ignored.
|
|
92
|
+
/// @param cur Cursor whose backing region should be returned.
|
|
93
|
+
/// @return data Calldata view over `[cur.offset, cur.offset + cur.len)`.
|
|
94
|
+
function raw(Cur memory cur) internal pure returns (bytes calldata data) {
|
|
95
|
+
if (cur.len > msg.data.length || cur.offset > msg.data.length - cur.len) revert MalformedBlocks();
|
|
96
|
+
data = msg.data[cur.offset:cur.offset + cur.len];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/// @notice Return a sub-range of the cursor region as a calldata slice.
|
|
100
|
+
/// Does not advance the cursor; `cur.i` and `cur.bound` are ignored.
|
|
101
|
+
/// @param cur Source cursor.
|
|
102
|
+
/// @param from Start byte offset within the source region (inclusive).
|
|
103
|
+
/// @param to End byte offset within the source region (exclusive).
|
|
104
|
+
/// @return data Calldata view over the requested sub-range.
|
|
105
|
+
function raw(Cur memory cur, uint from, uint to) internal pure returns (bytes calldata data) {
|
|
106
|
+
data = cur.slice(from, to).raw();
|
|
107
|
+
}
|
|
108
|
+
|
|
90
109
|
/// @notice Read a block header at position `i` without advancing the cursor.
|
|
91
110
|
/// @param cur Source cursor.
|
|
92
111
|
/// @param i Byte offset of the block header within the source region.
|
|
@@ -109,17 +128,30 @@ library Cursors {
|
|
|
109
128
|
return cur.i + Sizes.Header + len;
|
|
110
129
|
}
|
|
111
130
|
|
|
112
|
-
/// @notice Return true if the current cursor position
|
|
131
|
+
/// @notice Return true if the current cursor position is at a block header with the given key.
|
|
113
132
|
/// Returns false when `cur.i` is out of bounds or the key differs.
|
|
114
133
|
/// @param cur Source cursor.
|
|
115
134
|
/// @param key Expected block type identifier.
|
|
116
135
|
/// @return Whether the block header at `cur.i` uses `key`.
|
|
117
|
-
function
|
|
136
|
+
function isAt(Cur memory cur, bytes4 key) internal pure returns (bool) {
|
|
118
137
|
if (cur.i + 8 > cur.len) return false;
|
|
119
138
|
uint abs = cur.offset + cur.i;
|
|
120
139
|
return bytes4(msg.data[abs:abs + 4]) == key;
|
|
121
140
|
}
|
|
122
141
|
|
|
142
|
+
/// @notice Return whether the remaining cursor region is empty or exactly one block with `key`.
|
|
143
|
+
/// Returns false for an empty remaining region. Reverts if the next block has another key or
|
|
144
|
+
/// if a matching block is followed by trailing bytes.
|
|
145
|
+
/// @param cur Source cursor.
|
|
146
|
+
/// @param key Expected optional block key.
|
|
147
|
+
/// @return Whether the remaining region contains exactly one block with `key`.
|
|
148
|
+
function maybeOnly(Cur memory cur, bytes4 key) internal pure returns (bool) {
|
|
149
|
+
if (cur.i == cur.len) return false;
|
|
150
|
+
if (!cur.isAt(key)) revert InvalidBlock();
|
|
151
|
+
if (cur.past() != cur.len) revert IncompleteCursor();
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
|
|
123
155
|
/// @notice Validate a block at position `i` and return its payload location.
|
|
124
156
|
/// Does not advance the cursor.
|
|
125
157
|
/// @param cur Source cursor.
|
|
@@ -249,23 +281,33 @@ library Cursors {
|
|
|
249
281
|
cur.i = next;
|
|
250
282
|
}
|
|
251
283
|
|
|
284
|
+
/// @notice Consume an optional block with the given key and return a cursor over the full block slice.
|
|
285
|
+
/// If the current block key does not match, returns an empty cursor and leaves `cur.i` unchanged.
|
|
286
|
+
/// Otherwise behaves like `take(cur, key)`.
|
|
287
|
+
/// @param cur Cursor positioned at an optional block.
|
|
288
|
+
/// @param key Optional block type key.
|
|
289
|
+
/// @return out Cursor scoped to the full matching block, or empty when no matching block is present.
|
|
290
|
+
function maybeTake(Cur memory cur, bytes4 key) internal pure returns (Cur memory out) {
|
|
291
|
+
return cur.isAt(key) ? take(cur, key) : cur.slice(cur.i, cur.i);
|
|
292
|
+
}
|
|
293
|
+
|
|
252
294
|
/// @notice Consume an optional ROUTE block at the current position and return a cursor over the full block slice.
|
|
253
295
|
/// If the current block is not ROUTE, returns an empty cursor and leaves `cur.i` unchanged.
|
|
254
296
|
/// Otherwise behaves like `take(cur, Keys.Route)`.
|
|
255
297
|
/// @param cur Cursor positioned at an optional ROUTE block.
|
|
256
298
|
/// @return out Cursor scoped to the full ROUTE block, or empty when no ROUTE block is present.
|
|
257
299
|
function maybeRoute(Cur memory cur) internal pure returns (Cur memory out) {
|
|
258
|
-
return
|
|
300
|
+
return maybeTake(cur, Keys.Route);
|
|
259
301
|
}
|
|
260
302
|
|
|
261
|
-
/// @notice Enter a List block, prime its member run, and return the
|
|
303
|
+
/// @notice Enter a List block, prime its member run, and return the group count.
|
|
262
304
|
/// @param cur Cursor positioned at a list block; advanced past the 8-byte header.
|
|
263
305
|
/// @param group Expected block group size for the list item stream.
|
|
264
|
-
/// @return
|
|
306
|
+
/// @return groups Number of block groups in the list payload.
|
|
265
307
|
/// @return next Byte offset immediately after the list payload.
|
|
266
|
-
function list(Cur memory cur, uint group) internal pure returns (uint
|
|
308
|
+
function list(Cur memory cur, uint group) internal pure returns (uint groups, uint next) {
|
|
267
309
|
next = list(cur);
|
|
268
|
-
(,
|
|
310
|
+
(, , groups) = cur.primeRun(group);
|
|
269
311
|
if (cur.bound != next) revert IncompleteCursor();
|
|
270
312
|
}
|
|
271
313
|
|
package/blocks/Keys.sol
CHANGED
|
@@ -34,7 +34,7 @@ library Keys {
|
|
|
34
34
|
bytes4 constant Bundle = bytes4(keccak256("bundle(bytes data)"));
|
|
35
35
|
/// @dev List wrapper - (bytes data); payload is an embedded repeated block stream
|
|
36
36
|
bytes4 constant List = bytes4(keccak256("list(bytes data)"));
|
|
37
|
-
/// @dev Frame wrapper - (bytes data); payload is schema-defined
|
|
37
|
+
/// @dev Frame wrapper - (bytes data); payload is schema-defined fields, optionally followed by block-stream items
|
|
38
38
|
bytes4 constant Frame = bytes4(keccak256("frame(bytes data)"));
|
|
39
39
|
/// @dev Extensible routing field - (bytes data); layout is command-defined
|
|
40
40
|
bytes4 constant Route = bytes4(keccak256("route(bytes data)"));
|
package/blocks/Schema.sol
CHANGED
|
@@ -16,24 +16,73 @@ pragma solidity ^0.8.33;
|
|
|
16
16
|
// and can be decoded with `abi.decode`
|
|
17
17
|
// - chain-specific payload blocks are request-only escape hatches and should never be used for pipeline state
|
|
18
18
|
// - prefer ordinary protocol blocks whenever possible; chain-specific payload blocks should be a last resort
|
|
19
|
+
// - prefer frames for typed custom payloads; reserved extensible blocks such as `route(...)` and `item(...)`
|
|
20
|
+
// should be used only when a stable protocol-level key or opaque escape hatch is needed
|
|
19
21
|
//
|
|
20
22
|
// Schema DSL:
|
|
21
|
-
// - `;` separates top-level
|
|
23
|
+
// - `;` separates top-level items
|
|
24
|
+
// - command, peer, and query schemas have the top-level form `prime`, `prime; global; global`,
|
|
25
|
+
// `empty; global; global`, or `""` for no request items at all
|
|
26
|
+
// - the first top-level item is the prime item unless it is the schema-only `empty` sentinel
|
|
27
|
+
// - the prime item must have one runtime key; helpers consume the consecutive run of blocks with
|
|
28
|
+
// that key as the per-operation batch, and `Command.shape` is defined over those prime runs
|
|
29
|
+
// - `empty` emits no block, has no runtime key, and must only appear as the first top-level item
|
|
30
|
+
// before global blocks; it means the schema has no prime item
|
|
31
|
+
// - top-level items after the prime item or `empty` are global batch support blocks: they apply to
|
|
32
|
+
// the whole batch, may be searched or consumed separately by the command, and are not counted as
|
|
33
|
+
// per-operation prime blocks
|
|
22
34
|
// - `&` bundles adjacent blocks into one bundle block
|
|
23
35
|
// - `+` frames adjacent fixed-layout block payloads into one frame block
|
|
24
|
-
// -
|
|
36
|
+
// - `+&` appends adjacent blocks to a frame as full block-stream items, preserving their headers
|
|
37
|
+
// - leading `&` is shorthand for an anonymous bundle
|
|
38
|
+
// - leading `+&` is shorthand for an anonymous frame with only a block-stream tail
|
|
39
|
+
// - `&`, `+`, and `+&` follow the same grouping and normalization rules, except they emit different payload forms
|
|
25
40
|
// - `name = a & b` introduces a named bundle item with a local key derived from the raw input string
|
|
26
41
|
// - `name = a + b` introduces a named frame item with a local key derived from the raw input string
|
|
42
|
+
// - `alias: item` attaches a presentation alias to the following schema item for off-chain APIs,
|
|
43
|
+
// docs, and UI labels
|
|
27
44
|
// - `bundle = a & b` introduces an anonymous child bundle item
|
|
28
45
|
// - `frame = a + b` introduces an anonymous child frame item, like `bundle = ...` and `list = ...`
|
|
46
|
+
// - `(fields...)` in item position is shorthand for an anonymous frame with those fields
|
|
47
|
+
// - `(fields...)` inside an existing frame introduces anonymous flattened frame fields without a nested frame key
|
|
29
48
|
// - postfix `[]` marks a repeated list in the simple suffix form, e.g. `asset(...)[]`
|
|
49
|
+
// - postfix `?` marks an optional item, e.g. `account(...)?`
|
|
30
50
|
// - `name[] = a & b` introduces a named list with a local key derived from the raw input string
|
|
51
|
+
// - `name? = a & b` introduces an optional named structural item
|
|
52
|
+
// - `name[]? = a & b` introduces an optional named list; `?[]` is invalid
|
|
31
53
|
// - `list = a & b` introduces an anonymous list whose repeated item is the bundled shape `a & b`
|
|
54
|
+
// - `bundle? = a & b`, `frame? = a + b`, and `list? = a & b` introduce optional anonymous structural items
|
|
32
55
|
// - empty entries are ignored, but structural markers are preserved after normalization
|
|
56
|
+
// - aliases are presentation metadata: they do not add bytes, headers, fields, or wrappers,
|
|
57
|
+
// and they do not change the payload layout of the item they label
|
|
58
|
+
// - aliases are not stripped before on-chain local-key derivation; when a named structural item is keyed by
|
|
59
|
+
// bytes4(keccak256(bytes(rawSchemaInput))), any alias text present in that raw string is part of identity
|
|
60
|
+
// - off-chain presentation should use `alias:` when present, otherwise the schema item name when available
|
|
61
|
+
// - if sibling presentation names collide, off-chain tools should append zero-based suffixes in encounter order,
|
|
62
|
+
// e.g. `amount(...) + amount(...)` presents as `amount0` and `amount1`
|
|
63
|
+
// - when possible, off-chain tools should preserve item grouping for repeated schemas, e.g. `amount0.asset`,
|
|
64
|
+
// `amount0.meta`, `amount0.amount`, then `amount1.asset`, `amount1.meta`, `amount1.amount`
|
|
65
|
+
// - if fields within one presentation group collide, off-chain tools should suffix those field names in
|
|
66
|
+
// encounter order, e.g. `(uint amount, uint amount)` presents as `amount0` and `amount1`
|
|
67
|
+
// - optionality is schema metadata only; when an optional item is present, it uses the same encoding as the
|
|
68
|
+
// non-optional form, and when absent, no placeholder block is emitted
|
|
69
|
+
// - optional children inside a present bundle, list item, or `+&` frame tail may be absent while the
|
|
70
|
+
// parent structural block is still emitted; for example `& account(...)?` and `+& account(...)?`
|
|
71
|
+
// can encode as an empty BUNDLE or empty FRAME when the account child is absent
|
|
72
|
+
// - optional `?` is not allowed on flattened `+` frame members because frame fields have no child key or length;
|
|
73
|
+
// use `(fields...)?` as an optional frame item, make the whole frame optional, or use `+&` for
|
|
74
|
+
// optional block-stream tail items
|
|
33
75
|
// - grouping parentheses are not part of the DSL; parentheses are only used in block field lists
|
|
76
|
+
// and anonymous frame field groups
|
|
77
|
+
// - anonymous frame field groups in item position are promoted to anonymous frame items, so `(fields...)[]`
|
|
78
|
+
// means a list of anonymous frame items and `(fields...)?` means an optional anonymous frame item
|
|
79
|
+
// - anonymous frame field groups inside an existing frame are flattened fields, not nested frame items, and
|
|
80
|
+
// cannot be appended with `+&`
|
|
34
81
|
// - `+` binds tighter than `&`, so `a & b + c` normalizes as `a & (b + c)`
|
|
82
|
+
// - `+&` binds like `+`, so `a & b +& c` normalizes as `a & (b +& c)`
|
|
35
83
|
// - if `&` appears, the result remains a bundle even when only one non-empty child remains
|
|
36
84
|
// - if `+` appears, the result remains a frame even when only one non-empty child remains
|
|
85
|
+
// - if `+&` appears, the result remains a frame even when only one non-empty child remains
|
|
37
86
|
// - after ignoring empty entries, repeated adjacent separators collapse while preserving bundle/frame/list shape
|
|
38
87
|
// - bundled blocks preserve member order, so `a & b` differs from `b & a`
|
|
39
88
|
// - a bundle block's self payload is an embedded normal block stream of its bundled members
|
|
@@ -42,14 +91,20 @@ pragma solidity ^0.8.33;
|
|
|
42
91
|
// - a frame block's self payload is the concatenated payload fields of its framed members
|
|
43
92
|
// - framed members do not keep their ordinary block headers; the emitted schema defines the frame layout
|
|
44
93
|
// - framed members must be fixed-layout block forms because frame payloads contain no child lengths or block keys
|
|
94
|
+
// - anonymous frame field groups must also be fixed-layout and contribute only their fields, in order
|
|
95
|
+
// - `+&` members keep their ordinary block encoding inside the frame payload, so dynamic blocks are allowed there
|
|
96
|
+
// - `+&` starts a block-stream tail inside the frame; fixed-layout `+` members may not follow it
|
|
45
97
|
// - frames may be bundled like ordinary block items, but bundles/lists cannot be framed
|
|
46
|
-
// -
|
|
47
|
-
// - primary / driving blocks should
|
|
98
|
+
// - prime blocks of the same type should be grouped together so the prime run is contiguous
|
|
99
|
+
// - primary / driving blocks should be the prime item; auxiliary batch-wide blocks should follow
|
|
100
|
+
// as global `;` siblings
|
|
48
101
|
// - `route(<fields...>)`, `item(<fields...>)`, `evm(<fields...>)`, `query(<fields...>)`,
|
|
49
102
|
// and `response(<fields...>)` are reserved extensible schema forms whose keys are always
|
|
50
103
|
// `Keys.Route`, `Keys.Item`, `Keys.Evm`, `Keys.Query`, and `Keys.Response` respectively
|
|
51
104
|
// - these extensible forms work like dynamic `bytes` blocks: they may carry arbitrary
|
|
52
105
|
// payload bytes while keeping one fixed key per semantic block type
|
|
106
|
+
// - prefer `frame = ...`, `(fields...)`, and `+&` tails over `route(...)` and `item(...)` when the payload
|
|
107
|
+
// can be described by the schema DSL; frames give off-chain tools typed layouts and better generated APIs
|
|
53
108
|
// - `evm(<fields...>)` differs from bundle/list payloads: its bytes are not an embedded block stream
|
|
54
109
|
// - `evm(uint foo, uint bar)` is a schema declaration only; on-chain the block key is still `Keys.Evm`
|
|
55
110
|
// and the payload can be decoded from `bytes data` using the local runtime's native decoder
|
|
@@ -57,21 +112,59 @@ pragma solidity ^0.8.33;
|
|
|
57
112
|
// - anonymous `&` compiles to a `Keys.Bundle` block whose self payload is the bundled member block stream
|
|
58
113
|
// - anonymous `[]` compiles to a `Keys.List` block whose self payload is the repeated item block stream
|
|
59
114
|
// - anonymous `+` compiles to a `Keys.Frame` block whose self payload is the framed member payload fields
|
|
115
|
+
// - anonymous `+&` compiles to a `Keys.Frame` block whose self payload is fixed framed fields
|
|
116
|
+
// followed by an embedded normal block-stream tail
|
|
117
|
+
// - bare `(fields...)` compiles to a `Keys.Frame` block whose self payload is those fields
|
|
60
118
|
// - named lists, bundles, and frames use bytes4(keccak256(bytes(rawSchemaInput))) as their block key
|
|
61
119
|
// - named structural keys are custom/local identifiers, not global protocol keys; formatting is part of identity
|
|
120
|
+
// - `payment: frame = amount(...) +& fee(...)` means an anonymous frame whose runtime key is still `Keys.Frame`,
|
|
121
|
+
// with `payment` as its off-chain presentation name
|
|
122
|
+
// - `quote: payment = amount(...) + fee(...)` means a named frame with presentation alias `quote`;
|
|
123
|
+
// its local runtime key is derived from the full raw schema string including `quote:`
|
|
124
|
+
// - `frame = debit: amount(...) + credit: amount(...)` means the two flattened amount groups should be
|
|
125
|
+
// presented off-chain as `debit` and `credit`, while encoding remains the same as without aliases
|
|
126
|
+
// - `frame = amount(...) + amount(...)` has the same encoding as the aliased form above, but off-chain tools
|
|
127
|
+
// should present the groups as `amount0` and `amount1`
|
|
62
128
|
// - `asset(...)[]` means a list whose repeated item is the block `asset(...)`
|
|
129
|
+
// - `account(...)?` means an optional account block
|
|
63
130
|
// - `steps[] = asset(...) & account(...)` means a named list whose repeated item is the bundle
|
|
64
131
|
// `asset(...) & account(...)`
|
|
132
|
+
// - `steps[]? = asset(...) & account(...)` means that named list may be absent
|
|
133
|
+
// - `memo? = evm(bytes data)` means an optional named local item whose payload, when present, is EVM-encoded
|
|
65
134
|
// - `payment = amount(...) + fee(...)` means a named frame whose payload is
|
|
66
135
|
// `asset | meta | amount | fee` and whose on-chain key is derived from that raw schema string
|
|
136
|
+
// - `payment = amount(...) + (uint fee, uint rate)` means a named frame whose payload is
|
|
137
|
+
// `asset | meta | amount | fee | rate`, without inventing a child block name for the extra fields
|
|
138
|
+
// - `payment = (uint fee, uint rate)` means a named frame whose payload is `fee | rate`
|
|
139
|
+
// - `payment = amount(...) +& fee(...)` means a named frame whose payload is
|
|
140
|
+
// `asset | meta | amount | [fee key | fee len | fee amount]`
|
|
141
|
+
// - `payment = amount(...) +& fee(...)?` means a named frame with an amount prefix and optional fee block tail
|
|
142
|
+
// - `payment = amount(...) +& list? = fee(...)` means a named frame with an amount prefix and
|
|
143
|
+
// an optional anonymous list block tail
|
|
144
|
+
// - `payment = amount(...)? + fee(...)` is invalid because `amount(...)` would be an optional flattened frame member
|
|
145
|
+
// - `(uint fee)` means an anonymous frame with one `fee` field
|
|
146
|
+
// - `(uint fee)[]` means a list of anonymous frames whose repeated item has one `fee` field
|
|
147
|
+
// - `(uint fee)?` means an optional anonymous frame with one `fee` field
|
|
148
|
+
// - `amount(...) & (uint fee)` means a bundle containing an amount block and an anonymous fee frame
|
|
149
|
+
// - `amount(...) +& (uint fee)` is invalid because `+&` appends existing block-stream items, not field groups
|
|
67
150
|
// - `amount(...) & fee(...) + account(...)` means `amount(...) & (fee(...) + account(...))`;
|
|
68
151
|
// it compiles to a bundle containing one amount block followed by one frame block
|
|
152
|
+
// - `amount(...) & fee(...) +& account(...)` means `amount(...) & (fee(...) +& account(...))`;
|
|
153
|
+
// it compiles to a bundle containing one amount block followed by one frame block with an account block tail
|
|
69
154
|
// - `bundle = account(...) & evm(bytes routeData)` means an anonymous child bundle with those bundled members
|
|
155
|
+
// - `bundle? = account(...) & auth(...)` means that anonymous bundle may be absent
|
|
70
156
|
// - `frame = amount(...) + fee(...)` means an anonymous child frame with those framed payload fields
|
|
157
|
+
// - `frame? = amount(...) + fee(...)` means that anonymous frame may be absent
|
|
158
|
+
// - `frame = amount(...) +& fee(...)` means an anonymous child frame with amount fields plus a fee block tail
|
|
71
159
|
// - `list = asset(...) & account(...)` means an anonymous child list whose repeated item is the
|
|
72
160
|
// bundle `asset(...) & account(...)`
|
|
161
|
+
// - `list? = fee(...)` means that anonymous list may be absent
|
|
73
162
|
// - `"amount(...) &"` and `"& amount(...)"` both normalize to a bundle containing one `amount(...)` child
|
|
163
|
+
// - `"& account(...)?"` normalizes to a bundle containing one optional `account(...)` child
|
|
74
164
|
// - `"amount(...) +"` and `"+ amount(...)"` both normalize to a frame containing one `amount(...)` payload
|
|
165
|
+
// - `"amount(...) +&"` and `"+& amount(...)"` both normalize to a frame containing one `amount(...)` block
|
|
166
|
+
// - `"+& account(...)?"` normalizes to a frame containing an optional `account(...)` block-stream tail
|
|
167
|
+
// - `"amount(...)?"` normalizes to an optional amount block; `"amount(...)?[]"` is invalid
|
|
75
168
|
// - canonical blocks are `amount(...)` for request amounts, `balance(...)` for state balances,
|
|
76
169
|
// `allocation(...)` for host-scoped provision requests, `allowance(...)` for host-scoped caps,
|
|
77
170
|
// `custody(...)` for host-scoped state,
|
|
@@ -102,6 +195,7 @@ pragma solidity ^0.8.33;
|
|
|
102
195
|
/// These strings are the canonical source from which `Keys` constants are derived
|
|
103
196
|
/// and are used when emitting schema descriptors in command events.
|
|
104
197
|
library Schemas {
|
|
198
|
+
string constant Empty = "empty";
|
|
105
199
|
string constant Node = "node(uint id)";
|
|
106
200
|
string constant Account = "account(bytes32 account)";
|
|
107
201
|
string constant Asset = "asset(bytes32 asset, bytes32 meta)";
|
package/blocks/Writers.sol
CHANGED
|
@@ -17,11 +17,6 @@ struct Writer {
|
|
|
17
17
|
bytes dst;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
// Fixed-point scaling denominator for output-count allocation.
|
|
21
|
-
// A `scaledRatio` of `ALLOC_SCALE` means 1:1 (one output block per input block).
|
|
22
|
-
// `2 * ALLOC_SCALE` means 2:1; non-integer ratios revert with `BadWriterRatio`.
|
|
23
|
-
uint constant ALLOC_SCALE = 10_000;
|
|
24
|
-
|
|
25
20
|
/// @title Writers
|
|
26
21
|
/// @notice Response block stream builder for the rootzero protocol.
|
|
27
22
|
/// Allocates a fixed-size memory buffer up front and writes binary-encoded
|
|
@@ -36,8 +31,6 @@ library Writers {
|
|
|
36
31
|
error IncompleteWriter();
|
|
37
32
|
/// @dev An alloc function received a zero count, or `finish` found no bytes written.
|
|
38
33
|
error EmptyRequest();
|
|
39
|
-
/// @dev `scaledRatio * count` is not evenly divisible by `ALLOC_SCALE`.
|
|
40
|
-
error BadWriterRatio();
|
|
41
34
|
/// @dev A fixed-width low-level writer received an invalid final-word keep length.
|
|
42
35
|
error InvalidKeep();
|
|
43
36
|
|
|
@@ -58,21 +51,13 @@ library Writers {
|
|
|
58
51
|
}
|
|
59
52
|
|
|
60
53
|
/// @notice Core allocation routine used by all counted `alloc*` helpers.
|
|
61
|
-
/// Computes `
|
|
62
|
-
/// @param count Number of
|
|
63
|
-
/// @param scaledRatio Output-to-input ratio in `ALLOC_SCALE` units.
|
|
54
|
+
/// Computes `count * blockLen` and allocates that many bytes.
|
|
55
|
+
/// @param count Number of output blocks.
|
|
64
56
|
/// @param blockLen Logical byte size of each output block (including 8-byte header).
|
|
65
57
|
/// @return writer Allocated writer.
|
|
66
|
-
function
|
|
67
|
-
uint count,
|
|
68
|
-
uint scaledRatio,
|
|
69
|
-
uint blockLen
|
|
70
|
-
) internal pure returns (Writer memory writer) {
|
|
58
|
+
function allocFromCount(uint count, uint blockLen) internal pure returns (Writer memory writer) {
|
|
71
59
|
if (count == 0) revert EmptyRequest();
|
|
72
|
-
|
|
73
|
-
if (scaledCount % ALLOC_SCALE != 0) revert BadWriterRatio();
|
|
74
|
-
uint len = (scaledCount / ALLOC_SCALE) * blockLen;
|
|
75
|
-
writer = alloc(len);
|
|
60
|
+
writer = alloc(count * blockLen);
|
|
76
61
|
}
|
|
77
62
|
|
|
78
63
|
/// @notice Allocate a writer sized for exactly `count` dynamic blocks with a shared payload length.
|
|
@@ -81,96 +66,42 @@ library Writers {
|
|
|
81
66
|
/// @param payloadLen Payload byte length for each block.
|
|
82
67
|
/// @return writer Allocated writer.
|
|
83
68
|
function allocBytes(uint count, uint payloadLen) internal pure returns (Writer memory writer) {
|
|
84
|
-
return
|
|
69
|
+
return allocFromCount(count, Sizes.Header + payloadLen);
|
|
85
70
|
}
|
|
86
71
|
|
|
87
|
-
/// @notice Allocate a writer sized for exactly `count` 32-byte-payload blocks
|
|
72
|
+
/// @notice Allocate a writer sized for exactly `count` 32-byte-payload blocks.
|
|
88
73
|
/// @param count Number of blocks to allocate space for.
|
|
89
74
|
/// @return writer Allocated writer.
|
|
90
75
|
function alloc32s(uint count) internal pure returns (Writer memory writer) {
|
|
91
|
-
return
|
|
76
|
+
return allocFromCount(count, Sizes.B32);
|
|
92
77
|
}
|
|
93
78
|
|
|
94
|
-
/// @notice Allocate a writer sized for exactly `count` 64-byte-payload blocks
|
|
79
|
+
/// @notice Allocate a writer sized for exactly `count` 64-byte-payload blocks.
|
|
95
80
|
/// @param count Number of blocks to allocate space for.
|
|
96
81
|
/// @return writer Allocated writer.
|
|
97
82
|
function alloc64s(uint count) internal pure returns (Writer memory writer) {
|
|
98
|
-
return
|
|
83
|
+
return allocFromCount(count, Sizes.B64);
|
|
99
84
|
}
|
|
100
85
|
|
|
101
|
-
/// @notice Allocate a writer sized for exactly `count` 96-byte-payload blocks
|
|
86
|
+
/// @notice Allocate a writer sized for exactly `count` 96-byte-payload blocks.
|
|
102
87
|
/// @param count Number of blocks to allocate space for.
|
|
103
88
|
/// @return writer Allocated writer.
|
|
104
89
|
function alloc96s(uint count) internal pure returns (Writer memory writer) {
|
|
105
|
-
return
|
|
90
|
+
return allocFromCount(count, Sizes.B96);
|
|
106
91
|
}
|
|
107
92
|
|
|
108
|
-
/// @notice Allocate a writer sized for exactly `count` 128-byte-payload blocks
|
|
93
|
+
/// @notice Allocate a writer sized for exactly `count` 128-byte-payload blocks.
|
|
109
94
|
/// @param count Number of blocks to allocate space for.
|
|
110
95
|
/// @return writer Allocated writer.
|
|
111
96
|
function alloc128s(uint count) internal pure returns (Writer memory writer) {
|
|
112
|
-
return
|
|
97
|
+
return allocFromCount(count, Sizes.B128);
|
|
113
98
|
}
|
|
114
99
|
|
|
115
|
-
/// @notice Allocate a writer sized for exactly `count` 160-byte-payload blocks
|
|
100
|
+
/// @notice Allocate a writer sized for exactly `count` 160-byte-payload blocks.
|
|
116
101
|
/// @param count Number of blocks to allocate space for.
|
|
117
102
|
/// @return writer Allocated writer.
|
|
118
103
|
function alloc160s(uint count) internal pure returns (Writer memory writer) {
|
|
119
|
-
return
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/// @notice Allocate a writer for dynamic blocks with a shared payload length and custom output ratio.
|
|
123
|
-
/// Each block reserves `Sizes.Header + payloadLen` bytes.
|
|
124
|
-
/// @param count Number of input blocks.
|
|
125
|
-
/// @param scaledRatio Output count multiplier expressed in `ALLOC_SCALE` units.
|
|
126
|
-
/// @param payloadLen Payload byte length for each block.
|
|
127
|
-
/// @return writer Allocated writer.
|
|
128
|
-
function allocScaledBytes(
|
|
129
|
-
uint count,
|
|
130
|
-
uint scaledRatio,
|
|
131
|
-
uint payloadLen
|
|
132
|
-
) internal pure returns (Writer memory writer) {
|
|
133
|
-
return allocFromScaledCount(count, scaledRatio, Sizes.Header + payloadLen);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/// @notice Allocate a writer for 32-byte-payload blocks with a custom output-to-input ratio.
|
|
137
|
-
/// @param count Number of input blocks.
|
|
138
|
-
/// @param scaledRatio Output count multiplier expressed in `ALLOC_SCALE` units.
|
|
139
|
-
/// @return writer Allocated writer.
|
|
140
|
-
function allocScaled32s(uint count, uint scaledRatio) internal pure returns (Writer memory writer) {
|
|
141
|
-
return allocFromScaledCount(count, scaledRatio, Sizes.B32);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/// @notice Allocate a writer for 64-byte-payload blocks with a custom output-to-input ratio.
|
|
145
|
-
/// @param count Number of input blocks.
|
|
146
|
-
/// @param scaledRatio Output count multiplier expressed in `ALLOC_SCALE` units.
|
|
147
|
-
/// @return writer Allocated writer.
|
|
148
|
-
function allocScaled64s(uint count, uint scaledRatio) internal pure returns (Writer memory writer) {
|
|
149
|
-
return allocFromScaledCount(count, scaledRatio, Sizes.B64);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/// @notice Allocate a writer for 96-byte-payload blocks with a custom output-to-input ratio.
|
|
153
|
-
/// @param count Number of input blocks.
|
|
154
|
-
/// @param scaledRatio Output count multiplier expressed in `ALLOC_SCALE` units.
|
|
155
|
-
/// @return writer Allocated writer.
|
|
156
|
-
function allocScaled96s(uint count, uint scaledRatio) internal pure returns (Writer memory writer) {
|
|
157
|
-
return allocFromScaledCount(count, scaledRatio, Sizes.B96);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/// @notice Allocate a writer for 128-byte-payload blocks with a custom output-to-input ratio.
|
|
161
|
-
/// @param count Number of input blocks.
|
|
162
|
-
/// @param scaledRatio Output count multiplier expressed in `ALLOC_SCALE` units.
|
|
163
|
-
/// @return writer Allocated writer.
|
|
164
|
-
function allocScaled128s(uint count, uint scaledRatio) internal pure returns (Writer memory writer) {
|
|
165
|
-
return allocFromScaledCount(count, scaledRatio, Sizes.B128);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/// @notice Allocate a writer for 160-byte-payload blocks with a custom output-to-input ratio.
|
|
169
|
-
/// @param count Number of input blocks.
|
|
170
|
-
/// @param scaledRatio Output count multiplier expressed in `ALLOC_SCALE` units.
|
|
171
|
-
/// @return writer Allocated writer.
|
|
172
|
-
function allocScaled160s(uint count, uint scaledRatio) internal pure returns (Writer memory writer) {
|
|
173
|
-
return allocFromScaledCount(count, scaledRatio, Sizes.B160);
|
|
104
|
+
return allocFromCount(count, Sizes.B160);
|
|
174
105
|
}
|
|
175
106
|
|
|
176
107
|
/// @notice Allocate a writer sized for exactly `count` STATUS form blocks.
|
|
@@ -180,83 +111,48 @@ library Writers {
|
|
|
180
111
|
return alloc32s(count);
|
|
181
112
|
}
|
|
182
113
|
|
|
183
|
-
/// @notice Allocate a writer sized for exactly `count` ASSET blocks
|
|
114
|
+
/// @notice Allocate a writer sized for exactly `count` ASSET blocks.
|
|
184
115
|
/// @param count Number of asset blocks to allocate space for.
|
|
185
116
|
/// @return writer Allocated writer.
|
|
186
117
|
function allocAssets(uint count) internal pure returns (Writer memory writer) {
|
|
187
118
|
return alloc64s(count);
|
|
188
119
|
}
|
|
189
120
|
|
|
190
|
-
/// @notice Allocate a writer sized for exactly `count` AMOUNT blocks
|
|
121
|
+
/// @notice Allocate a writer sized for exactly `count` AMOUNT blocks.
|
|
191
122
|
/// @param count Number of amount blocks to allocate space for.
|
|
192
123
|
/// @return writer Allocated writer.
|
|
193
124
|
function allocAmounts(uint count) internal pure returns (Writer memory writer) {
|
|
194
125
|
return alloc96s(count);
|
|
195
126
|
}
|
|
196
127
|
|
|
197
|
-
/// @notice Allocate a writer sized for exactly `count` BALANCE blocks
|
|
128
|
+
/// @notice Allocate a writer sized for exactly `count` BALANCE blocks.
|
|
198
129
|
/// @param count Number of balance blocks to allocate space for.
|
|
199
130
|
/// @return writer Allocated writer.
|
|
200
131
|
function allocBalances(uint count) internal pure returns (Writer memory writer) {
|
|
201
132
|
return alloc96s(count);
|
|
202
133
|
}
|
|
203
134
|
|
|
204
|
-
/// @notice Allocate a writer sized for exactly `count` ACCOUNT_AMOUNT form blocks
|
|
135
|
+
/// @notice Allocate a writer sized for exactly `count` ACCOUNT_AMOUNT form blocks.
|
|
205
136
|
/// @param count Number of account amount blocks to allocate space for.
|
|
206
137
|
/// @return writer Allocated writer.
|
|
207
138
|
function allocAccountAmounts(uint count) internal pure returns (Writer memory writer) {
|
|
208
139
|
return alloc128s(count);
|
|
209
140
|
}
|
|
210
141
|
|
|
211
|
-
/// @notice Allocate a writer sized for exactly `count` CUSTODY blocks
|
|
142
|
+
/// @notice Allocate a writer sized for exactly `count` CUSTODY blocks.
|
|
212
143
|
/// @param count Number of custody blocks to allocate space for.
|
|
213
144
|
/// @return writer Allocated writer.
|
|
214
145
|
function allocCustodies(uint count) internal pure returns (Writer memory writer) {
|
|
215
146
|
return alloc128s(count);
|
|
216
147
|
}
|
|
217
148
|
|
|
218
|
-
/// @notice Allocate a writer sized for exactly `count` TRANSACTION blocks
|
|
149
|
+
/// @notice Allocate a writer sized for exactly `count` TRANSACTION blocks.
|
|
219
150
|
/// @param count Number of transaction blocks to allocate space for.
|
|
220
151
|
/// @return writer Allocated writer.
|
|
221
152
|
function allocTransactions(uint count) internal pure returns (Writer memory writer) {
|
|
222
153
|
return alloc160s(count);
|
|
223
154
|
}
|
|
224
155
|
|
|
225
|
-
/// @notice Allocate a writer for ASSET blocks with a custom output-to-input ratio.
|
|
226
|
-
/// @param count Number of input blocks.
|
|
227
|
-
/// @param scaledRatio Output count multiplier expressed in `ALLOC_SCALE` units
|
|
228
|
-
/// (e.g. `ALLOC_SCALE` = 1:1, `2 * ALLOC_SCALE` = 2:1).
|
|
229
|
-
/// @return writer Allocated writer.
|
|
230
|
-
function allocScaledAssets(uint count, uint scaledRatio) internal pure returns (Writer memory writer) {
|
|
231
|
-
return allocScaled64s(count, scaledRatio);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/// @notice Allocate a writer for AMOUNT blocks with a custom output-to-input ratio.
|
|
235
|
-
/// @param count Number of input blocks.
|
|
236
|
-
/// @param scaledRatio Output count multiplier expressed in `ALLOC_SCALE` units
|
|
237
|
-
/// (e.g. `ALLOC_SCALE` = 1:1, `2 * ALLOC_SCALE` = 2:1).
|
|
238
|
-
/// @return writer Allocated writer.
|
|
239
|
-
function allocScaledAmounts(uint count, uint scaledRatio) internal pure returns (Writer memory writer) {
|
|
240
|
-
return allocScaled96s(count, scaledRatio);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/// @notice Allocate a writer for BALANCE blocks with a custom output-to-input ratio.
|
|
244
|
-
/// @param count Number of input blocks.
|
|
245
|
-
/// @param scaledRatio Output count multiplier expressed in `ALLOC_SCALE` units
|
|
246
|
-
/// (e.g. `ALLOC_SCALE` = 1:1, `2 * ALLOC_SCALE` = 2:1).
|
|
247
|
-
/// @return writer Allocated writer.
|
|
248
|
-
function allocScaledBalances(uint count, uint scaledRatio) internal pure returns (Writer memory writer) {
|
|
249
|
-
return allocScaled96s(count, scaledRatio);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/// @notice Allocate a writer for CUSTODY blocks with a custom output-to-input ratio.
|
|
253
|
-
/// @param count Number of input blocks.
|
|
254
|
-
/// @param scaledRatio Output count multiplier in `ALLOC_SCALE` units.
|
|
255
|
-
/// @return writer Allocated writer.
|
|
256
|
-
function allocScaledCustodies(uint count, uint scaledRatio) internal pure returns (Writer memory writer) {
|
|
257
|
-
return allocScaled128s(count, scaledRatio);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
156
|
// -------------------------------------------------------------------------
|
|
261
157
|
// Fixed-width write helpers
|
|
262
158
|
// -------------------------------------------------------------------------
|