@rootzero/contracts 1.24.0 → 1.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +140 -0
- package/Codec.sol +1 -2
- package/Core.sol +1 -1
- package/Endpoints.sol +3 -0
- package/README.md +66 -51
- package/Utils.sol +2 -1
- package/codec/Blocks.sol +354 -108
- package/codec/Buffers.sol +24 -20
- package/codec/Decoders.sol +49 -31
- package/codec/Descriptors.sol +75 -72
- package/codec/Keys.sol +5 -1
- package/codec/Schema.sol +5 -1
- package/codec/Specs.sol +19 -9
- package/codec/Writers.sol +14 -19
- package/commands/Allocate.sol +8 -7
- package/commands/Base.sol +14 -52
- package/commands/Bootstrap.sol +95 -0
- package/commands/Burn.sol +7 -7
- package/commands/Cashout.sol +85 -0
- package/commands/Credit.sol +18 -16
- package/commands/Debit.sol +22 -21
- package/commands/Deposit.sol +13 -13
- package/commands/Payout.sol +8 -8
- package/commands/Provision.sol +13 -13
- package/commands/Recover.sol +7 -7
- package/commands/Relay.sol +22 -23
- package/commands/Repay.sol +36 -34
- package/commands/Settle.sol +24 -22
- package/commands/Withdraw.sol +7 -7
- package/commands/admin/AllowAssets.sol +7 -7
- package/commands/admin/Allowance.sol +7 -7
- package/commands/admin/Annotate.sol +7 -7
- package/commands/admin/Appoint.sol +7 -7
- package/commands/admin/Authorize.sol +7 -7
- package/commands/admin/Base.sol +5 -11
- package/commands/admin/DenyAssets.sol +7 -7
- package/commands/admin/Dismiss.sol +7 -7
- package/commands/admin/Execute.sol +8 -8
- package/commands/admin/Unauthorize.sol +7 -7
- package/core/Calls.sol +3 -3
- package/core/Endpoint.sol +7 -7
- package/core/Pipeline.sol +40 -22
- package/execution/Budget.sol +24 -3
- package/execution/Execution.sol +289 -506
- package/guards/Base.sol +1 -1
- package/guards/Revoke.sol +7 -7
- package/package.json +1 -1
- package/ports/Allowance.sol +3 -3
- package/ports/Assets.sol +7 -7
- package/ports/Base.sol +1 -1
- package/ports/Credit.sol +3 -3
- package/ports/Debit.sol +3 -3
- package/ports/Dispatch.sol +3 -3
- package/ports/Pipe.sol +7 -8
- package/ports/Post.sol +3 -3
- package/ports/Redeem.sol +3 -3
- package/queries/Assets.sol +3 -3
- package/queries/Balances.sol +3 -3
- package/queries/Base.sol +1 -1
- package/utils/Accounts.sol +1 -3
- package/utils/Actions.sol +2 -0
- package/utils/Assets.sol +1 -10
- package/utils/Cursors.sol +60 -116
- package/utils/Errors.sol +50 -0
- package/utils/Ids.sol +2 -5
- package/utils/Lanes.sol +0 -2
- package/utils/Nodes.sol +1 -3
- package/utils/Utils.sol +2 -9
- package/codec/Readers.sol +0 -190
package/codec/Blocks.sol
CHANGED
|
@@ -100,16 +100,38 @@ library Blocks {
|
|
|
100
100
|
end = body + len;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
/// @notice Validate a known block key and return its payload bounds.
|
|
104
|
+
/// @dev DANGER: This performs an unchecked calldata read and validates only
|
|
105
|
+
/// the key. The caller must validate the known payload shape and returned end.
|
|
106
|
+
/// @param abs Absolute calldata position of the header.
|
|
107
|
+
/// @param key Expected block key.
|
|
108
|
+
/// @return body Absolute position of the first payload byte.
|
|
109
|
+
/// @return end Absolute position immediately after the payload.
|
|
110
|
+
function expectKey(uint abs, bytes4 key) internal pure returns (uint body, uint end) {
|
|
111
|
+
uint head;
|
|
112
|
+
assembly ("memory-safe") {
|
|
113
|
+
head := calldataload(abs)
|
|
114
|
+
}
|
|
115
|
+
if (uint32(head >> 224) != uint32(key)) revert InvalidBlock();
|
|
116
|
+
uint len = uint32(head >> 192);
|
|
117
|
+
unchecked {
|
|
118
|
+
body = abs + Sizes.Header;
|
|
119
|
+
end = body + len;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
103
123
|
/// @dev Validate the key and exact payload size of a fixed-width block.
|
|
104
124
|
/// @param abs Absolute calldata position of the header.
|
|
105
|
-
/// @param
|
|
125
|
+
/// @param key Expected block key.
|
|
106
126
|
/// @param size Expected payload length.
|
|
107
127
|
/// @return body Absolute position of the payload.
|
|
108
128
|
/// @return end Absolute position after the payload.
|
|
109
|
-
function expectFixed(uint abs,
|
|
110
|
-
if (header(abs,
|
|
111
|
-
|
|
112
|
-
|
|
129
|
+
function expectFixed(uint abs, bytes4 key, uint size) private pure returns (uint body, uint end) {
|
|
130
|
+
if (header(abs, key) != size) revert InvalidBlock();
|
|
131
|
+
unchecked {
|
|
132
|
+
body = abs + Sizes.Header;
|
|
133
|
+
end = body + size;
|
|
134
|
+
}
|
|
113
135
|
}
|
|
114
136
|
|
|
115
137
|
/// @notice Validate an empty block at an absolute calldata position.
|
|
@@ -139,8 +161,9 @@ library Blocks {
|
|
|
139
161
|
/// @param key Expected block key.
|
|
140
162
|
/// @return Whether the expected key occurs with a zero-length payload.
|
|
141
163
|
function isEmpty(uint abs, uint end, bytes4 key) internal pure returns (bool) {
|
|
142
|
-
if (
|
|
143
|
-
|
|
164
|
+
if (abs > end || Sizes.Header > end - abs) return false;
|
|
165
|
+
uint head = uint(read32(abs));
|
|
166
|
+
return uint32(head >> 224) == uint32(key) && uint32(head >> 192) == 0;
|
|
144
167
|
}
|
|
145
168
|
|
|
146
169
|
/// @notice Find the first block with `key` at or after absolute position `abs`.
|
|
@@ -178,6 +201,31 @@ library Blocks {
|
|
|
178
201
|
}
|
|
179
202
|
}
|
|
180
203
|
|
|
204
|
+
/// @notice Count consecutive blocks with `key` using a minimal hint-only scan.
|
|
205
|
+
/// @dev DANGER: This is not validation. It stops on a different key or when the
|
|
206
|
+
/// next declared block end exceeds `limit`; malformed or trailing data does not
|
|
207
|
+
/// revert. Use only for optional allocation hints whose result is later validated
|
|
208
|
+
/// by normal decoding and execution finalization.
|
|
209
|
+
/// @param abs Absolute start position.
|
|
210
|
+
/// @param limit Absolute region boundary.
|
|
211
|
+
/// @param key Block key forming the run.
|
|
212
|
+
/// @return total Number of complete consecutive matching blocks.
|
|
213
|
+
function runCount(uint abs, uint limit, bytes4 key) internal pure returns (uint total) {
|
|
214
|
+
uint expected = uint32(key);
|
|
215
|
+
assembly ("memory-safe") {
|
|
216
|
+
for { } lt(abs, limit) { } {
|
|
217
|
+
let head := calldataload(abs)
|
|
218
|
+
if iszero(eq(shr(224, head), expected)) { break }
|
|
219
|
+
|
|
220
|
+
let next := add(add(abs, 8), and(shr(192, head), 0xffffffff))
|
|
221
|
+
if gt(next, limit) { break }
|
|
222
|
+
|
|
223
|
+
abs := next
|
|
224
|
+
total := add(total, 1)
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
181
229
|
/// @notice Count a run that must consume the complete region.
|
|
182
230
|
/// @dev Reverts when any well-formed trailing block has a different key.
|
|
183
231
|
/// @param abs Absolute start position.
|
|
@@ -332,6 +380,20 @@ library Blocks {
|
|
|
332
380
|
}
|
|
333
381
|
}
|
|
334
382
|
|
|
383
|
+
/// @notice Write a CASHOUT block at `i`.
|
|
384
|
+
/// @dev DANGER: Unchecked memory write. Reserve `Sizes.Cashout` bytes first.
|
|
385
|
+
/// @param dst Destination buffer.
|
|
386
|
+
/// @param i Relative write position.
|
|
387
|
+
/// @param amount Native-asset amount to withdraw.
|
|
388
|
+
function writeCashout(bytes memory dst, uint i, uint amount) internal pure {
|
|
389
|
+
uint spec = Specs.Cashout;
|
|
390
|
+
assembly ("memory-safe") {
|
|
391
|
+
let p := add(add(dst, 0x20), i)
|
|
392
|
+
mstore(p, spec)
|
|
393
|
+
mstore(add(p, 0x08), amount)
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
335
397
|
// Two-word payloads
|
|
336
398
|
|
|
337
399
|
/// @notice Write an AMOUNT block at `i`.
|
|
@@ -416,6 +478,24 @@ library Blocks {
|
|
|
416
478
|
|
|
417
479
|
// Three-word payloads
|
|
418
480
|
|
|
481
|
+
/// @notice Write a BOOTSTRAP block at `i`.
|
|
482
|
+
/// @dev DANGER: Unchecked memory write. Reserve `Sizes.Bootstrap` bytes first.
|
|
483
|
+
/// @param dst Destination buffer.
|
|
484
|
+
/// @param i Relative write position.
|
|
485
|
+
/// @param asset Asset identifier to bootstrap.
|
|
486
|
+
/// @param amount Balance amount to source.
|
|
487
|
+
/// @param budget Native-value budget to source.
|
|
488
|
+
function writeBootstrap(bytes memory dst, uint i, bytes32 asset, uint amount, uint budget) internal pure {
|
|
489
|
+
uint spec = Specs.Bootstrap;
|
|
490
|
+
assembly ("memory-safe") {
|
|
491
|
+
let p := add(add(dst, 0x20), i)
|
|
492
|
+
mstore(p, spec)
|
|
493
|
+
mstore(add(p, 0x08), asset)
|
|
494
|
+
mstore(add(p, 0x28), amount)
|
|
495
|
+
mstore(add(p, 0x48), budget)
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
419
499
|
/// @notice Write an ALLOCATION block at `i`.
|
|
420
500
|
/// @dev DANGER: Unchecked memory write. Reserve `Sizes.B96` bytes first.
|
|
421
501
|
/// @param dst Destination buffer.
|
|
@@ -679,19 +759,19 @@ library Blocks {
|
|
|
679
759
|
/// @param dst Destination buffer.
|
|
680
760
|
/// @param i Relative write position.
|
|
681
761
|
/// @param cmd Command identifier.
|
|
682
|
-
/// @param
|
|
762
|
+
/// @param value Native value assigned to the step.
|
|
683
763
|
/// @param input Command input.
|
|
684
|
-
function writeStep(bytes memory dst, uint i, uint cmd,
|
|
685
|
-
uint len =
|
|
764
|
+
function writeStep(bytes memory dst, uint i, uint cmd, uint128 value, bytes memory input) internal pure {
|
|
765
|
+
uint len = 48 + Sizes.Header + input.length;
|
|
686
766
|
uint key = uint32(Keys.Step);
|
|
687
767
|
uint byteskey = uint32(Keys.Bytes);
|
|
688
768
|
assembly ("memory-safe") {
|
|
689
769
|
let p := add(add(dst, 0x20), i)
|
|
690
770
|
mstore(p, or(shl(224, key), shl(192, len)))
|
|
691
771
|
mstore(add(p, 0x08), cmd)
|
|
692
|
-
mstore(add(p, 0x28),
|
|
772
|
+
mstore(add(p, 0x28), shl(128, value))
|
|
693
773
|
|
|
694
|
-
let q := add(p,
|
|
774
|
+
let q := add(p, 0x38)
|
|
695
775
|
let inputlen := mload(input)
|
|
696
776
|
mstore(q, or(shl(224, byteskey), shl(192, inputlen)))
|
|
697
777
|
mcopy(add(q, 0x08), add(input, 0x20), inputlen)
|
|
@@ -951,8 +1031,21 @@ library Blocks {
|
|
|
951
1031
|
}
|
|
952
1032
|
|
|
953
1033
|
/// @notice Encode a STEP block at `i`, copying its nested input from calldata.
|
|
954
|
-
function copyStep(bytes memory dst, uint i, uint cmd,
|
|
955
|
-
|
|
1034
|
+
function copyStep(bytes memory dst, uint i, uint cmd, uint128 value, bytes calldata input) internal pure {
|
|
1035
|
+
uint len = max32(48 + Sizes.Header + input.length);
|
|
1036
|
+
uint key = uint32(Keys.Step);
|
|
1037
|
+
uint byteskey = uint32(Keys.Bytes);
|
|
1038
|
+
assembly ("memory-safe") {
|
|
1039
|
+
let p := add(add(dst, 0x20), i)
|
|
1040
|
+
mstore(p, or(shl(224, key), shl(192, len)))
|
|
1041
|
+
mstore(add(p, 0x08), cmd)
|
|
1042
|
+
mstore(add(p, 0x28), shl(128, value))
|
|
1043
|
+
|
|
1044
|
+
let q := add(p, 0x38)
|
|
1045
|
+
let inputlen := input.length
|
|
1046
|
+
mstore(q, or(shl(224, byteskey), shl(192, inputlen)))
|
|
1047
|
+
calldatacopy(add(q, 0x08), input.offset, inputlen)
|
|
1048
|
+
}
|
|
956
1049
|
}
|
|
957
1050
|
|
|
958
1051
|
/// @notice Encode a CALL block at `i`, copying its nested payload from calldata.
|
|
@@ -1080,6 +1173,46 @@ library Blocks {
|
|
|
1080
1173
|
}
|
|
1081
1174
|
}
|
|
1082
1175
|
|
|
1176
|
+
/// @notice Require the byte at an absolute calldata position to match `expected`.
|
|
1177
|
+
/// @dev DANGER: Unchecked calldata read. Values beyond calldata are zero-padded.
|
|
1178
|
+
/// @param abs Absolute calldata position.
|
|
1179
|
+
/// @param expected Expected byte.
|
|
1180
|
+
function require1(uint abs, bytes1 expected) internal pure {
|
|
1181
|
+
if (read1(abs) != expected) revert UnexpectedValue();
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
/// @notice Require the two bytes at an absolute calldata position to match `expected`.
|
|
1185
|
+
/// @dev DANGER: Unchecked calldata read. Values beyond calldata are zero-padded.
|
|
1186
|
+
/// @param abs Absolute calldata position.
|
|
1187
|
+
/// @param expected Expected two-byte value.
|
|
1188
|
+
function require2(uint abs, bytes2 expected) internal pure {
|
|
1189
|
+
if (read2(abs) != expected) revert UnexpectedValue();
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
/// @notice Require the four bytes at an absolute calldata position to match `expected`.
|
|
1193
|
+
/// @dev DANGER: Unchecked calldata read. Values beyond calldata are zero-padded.
|
|
1194
|
+
/// @param abs Absolute calldata position.
|
|
1195
|
+
/// @param expected Expected four-byte value.
|
|
1196
|
+
function require4(uint abs, bytes4 expected) internal pure {
|
|
1197
|
+
if (read4(abs) != expected) revert UnexpectedValue();
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
/// @notice Require the eight bytes at an absolute calldata position to match `expected`.
|
|
1201
|
+
/// @dev DANGER: Unchecked calldata read. Values beyond calldata are zero-padded.
|
|
1202
|
+
/// @param abs Absolute calldata position.
|
|
1203
|
+
/// @param expected Expected eight-byte value.
|
|
1204
|
+
function require8(uint abs, bytes8 expected) internal pure {
|
|
1205
|
+
if (read8(abs) != expected) revert UnexpectedValue();
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
/// @notice Require the sixteen bytes at an absolute calldata position to match `expected`.
|
|
1209
|
+
/// @dev DANGER: Unchecked calldata read. Values beyond calldata are zero-padded.
|
|
1210
|
+
/// @param abs Absolute calldata position.
|
|
1211
|
+
/// @param expected Expected sixteen-byte value.
|
|
1212
|
+
function require16(uint abs, bytes16 expected) internal pure {
|
|
1213
|
+
if (read16(abs) != expected) revert UnexpectedValue();
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1083
1216
|
/// @notice Require the word at an absolute calldata position to match `expected`.
|
|
1084
1217
|
/// @dev DANGER: Unchecked calldata read. Values beyond calldata are zero-padded.
|
|
1085
1218
|
/// @param abs Absolute calldata position.
|
|
@@ -1106,7 +1239,7 @@ library Blocks {
|
|
|
1106
1239
|
/// @return a First payload word.
|
|
1107
1240
|
/// @return end Absolute position after the block.
|
|
1108
1241
|
function unpack32(uint abs, uint spec) internal pure returns (bytes32 a, uint end) {
|
|
1109
|
-
(abs, end) = expectFixed(abs, spec, 32);
|
|
1242
|
+
(abs, end) = expectFixed(abs, Specs.key(spec), 32);
|
|
1110
1243
|
a = read32(abs);
|
|
1111
1244
|
}
|
|
1112
1245
|
|
|
@@ -1117,7 +1250,7 @@ library Blocks {
|
|
|
1117
1250
|
/// @return b Second payload word.
|
|
1118
1251
|
/// @return end Absolute position after the block.
|
|
1119
1252
|
function unpack64(uint abs, uint spec) internal pure returns (bytes32 a, bytes32 b, uint end) {
|
|
1120
|
-
(abs, end) = expectFixed(abs, spec, 64);
|
|
1253
|
+
(abs, end) = expectFixed(abs, Specs.key(spec), 64);
|
|
1121
1254
|
assembly ("memory-safe") {
|
|
1122
1255
|
a := calldataload(abs)
|
|
1123
1256
|
b := calldataload(add(abs, 0x20))
|
|
@@ -1135,7 +1268,7 @@ library Blocks {
|
|
|
1135
1268
|
uint abs,
|
|
1136
1269
|
uint spec
|
|
1137
1270
|
) internal pure returns (bytes32 a, bytes32 b, bytes32 c, uint end) {
|
|
1138
|
-
(abs, end) = expectFixed(abs, spec, 96);
|
|
1271
|
+
(abs, end) = expectFixed(abs, Specs.key(spec), 96);
|
|
1139
1272
|
assembly ("memory-safe") {
|
|
1140
1273
|
a := calldataload(abs)
|
|
1141
1274
|
b := calldataload(add(abs, 0x20))
|
|
@@ -1155,7 +1288,7 @@ library Blocks {
|
|
|
1155
1288
|
uint abs,
|
|
1156
1289
|
uint spec
|
|
1157
1290
|
) internal pure returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, uint end) {
|
|
1158
|
-
(abs, end) = expectFixed(abs, spec, 128);
|
|
1291
|
+
(abs, end) = expectFixed(abs, Specs.key(spec), 128);
|
|
1159
1292
|
assembly ("memory-safe") {
|
|
1160
1293
|
a := calldataload(abs)
|
|
1161
1294
|
b := calldataload(add(abs, 0x20))
|
|
@@ -1177,7 +1310,7 @@ library Blocks {
|
|
|
1177
1310
|
uint abs,
|
|
1178
1311
|
uint spec
|
|
1179
1312
|
) internal pure returns (bytes32 a, bytes32 b, bytes32 c, bytes32 d, bytes32 e, uint end) {
|
|
1180
|
-
(abs, end) = expectFixed(abs, spec, 160);
|
|
1313
|
+
(abs, end) = expectFixed(abs, Specs.key(spec), 160);
|
|
1181
1314
|
assembly ("memory-safe") {
|
|
1182
1315
|
a := calldataload(abs)
|
|
1183
1316
|
b := calldataload(add(abs, 0x20))
|
|
@@ -1284,11 +1417,9 @@ library Blocks {
|
|
|
1284
1417
|
uint head;
|
|
1285
1418
|
assembly ("memory-safe") {
|
|
1286
1419
|
head := calldataload(abs)
|
|
1287
|
-
}
|
|
1288
|
-
if (head >> 192 != Specs.Account >> 192) revert InvalidBlock();
|
|
1289
|
-
assembly ("memory-safe") {
|
|
1290
1420
|
account := calldataload(add(abs, 0x08))
|
|
1291
1421
|
}
|
|
1422
|
+
if (head >> 192 != Specs.Account >> 192) revert InvalidBlock();
|
|
1292
1423
|
}
|
|
1293
1424
|
|
|
1294
1425
|
/// @notice Decode a low-level fixed-width ASSET block at `abs`.
|
|
@@ -1298,11 +1429,9 @@ library Blocks {
|
|
|
1298
1429
|
uint head;
|
|
1299
1430
|
assembly ("memory-safe") {
|
|
1300
1431
|
head := calldataload(abs)
|
|
1301
|
-
}
|
|
1302
|
-
if (head >> 192 != Specs.Asset >> 192) revert InvalidBlock();
|
|
1303
|
-
assembly ("memory-safe") {
|
|
1304
1432
|
asset := calldataload(add(abs, 0x08))
|
|
1305
1433
|
}
|
|
1434
|
+
if (head >> 192 != Specs.Asset >> 192) revert InvalidBlock();
|
|
1306
1435
|
}
|
|
1307
1436
|
|
|
1308
1437
|
/// @notice Decode a low-level fixed-width NODE block at `abs`.
|
|
@@ -1312,11 +1441,9 @@ library Blocks {
|
|
|
1312
1441
|
uint head;
|
|
1313
1442
|
assembly ("memory-safe") {
|
|
1314
1443
|
head := calldataload(abs)
|
|
1315
|
-
}
|
|
1316
|
-
if (head >> 192 != Specs.Node >> 192) revert InvalidBlock();
|
|
1317
|
-
assembly ("memory-safe") {
|
|
1318
1444
|
node := calldataload(add(abs, 0x08))
|
|
1319
1445
|
}
|
|
1446
|
+
if (head >> 192 != Specs.Node >> 192) revert InvalidBlock();
|
|
1320
1447
|
}
|
|
1321
1448
|
|
|
1322
1449
|
/// @notice Decode a low-level fixed-width STATUS block at `abs`.
|
|
@@ -1326,11 +1453,21 @@ library Blocks {
|
|
|
1326
1453
|
uint head;
|
|
1327
1454
|
assembly ("memory-safe") {
|
|
1328
1455
|
head := calldataload(abs)
|
|
1456
|
+
code := calldataload(add(abs, 0x08))
|
|
1329
1457
|
}
|
|
1330
1458
|
if (head >> 192 != Specs.Status >> 192) revert InvalidBlock();
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
/// @notice Decode a low-level fixed-width CASHOUT block at `abs`.
|
|
1462
|
+
/// @param abs Absolute block position.
|
|
1463
|
+
/// @return amount Native-asset amount to withdraw.
|
|
1464
|
+
function unpackCashout(uint abs) internal pure returns (uint amount) {
|
|
1465
|
+
uint head;
|
|
1331
1466
|
assembly ("memory-safe") {
|
|
1332
|
-
|
|
1467
|
+
head := calldataload(abs)
|
|
1468
|
+
amount := calldataload(add(abs, 0x08))
|
|
1333
1469
|
}
|
|
1470
|
+
if (head >> 192 != Specs.Cashout >> 192) revert InvalidBlock();
|
|
1334
1471
|
}
|
|
1335
1472
|
|
|
1336
1473
|
// Two-word payloads
|
|
@@ -1343,12 +1480,10 @@ library Blocks {
|
|
|
1343
1480
|
uint head;
|
|
1344
1481
|
assembly ("memory-safe") {
|
|
1345
1482
|
head := calldataload(abs)
|
|
1346
|
-
}
|
|
1347
|
-
if (head >> 192 != Specs.Amount >> 192) revert InvalidBlock();
|
|
1348
|
-
assembly ("memory-safe") {
|
|
1349
1483
|
asset := calldataload(add(abs, 0x08))
|
|
1350
1484
|
amount := calldataload(add(abs, 0x28))
|
|
1351
1485
|
}
|
|
1486
|
+
if (head >> 192 != Specs.Amount >> 192) revert InvalidBlock();
|
|
1352
1487
|
}
|
|
1353
1488
|
|
|
1354
1489
|
/// @notice Decode a low-level fixed-width BALANCE block at `abs`.
|
|
@@ -1359,13 +1494,10 @@ library Blocks {
|
|
|
1359
1494
|
uint head;
|
|
1360
1495
|
assembly ("memory-safe") {
|
|
1361
1496
|
head := calldataload(abs)
|
|
1362
|
-
}
|
|
1363
|
-
if (head >> 192 != Specs.Balance >> 192) revert InvalidBlock();
|
|
1364
|
-
|
|
1365
|
-
assembly ("memory-safe") {
|
|
1366
1497
|
asset := calldataload(add(abs, 0x08))
|
|
1367
1498
|
amount := calldataload(add(abs, 0x28))
|
|
1368
1499
|
}
|
|
1500
|
+
if (head >> 192 != Specs.Balance >> 192) revert InvalidBlock();
|
|
1369
1501
|
}
|
|
1370
1502
|
|
|
1371
1503
|
/// @notice Decode a low-level fixed-width DEBT block at `abs`.
|
|
@@ -1376,12 +1508,10 @@ library Blocks {
|
|
|
1376
1508
|
uint head;
|
|
1377
1509
|
assembly ("memory-safe") {
|
|
1378
1510
|
head := calldataload(abs)
|
|
1379
|
-
}
|
|
1380
|
-
if (head >> 192 != Specs.Debt >> 192) revert InvalidBlock();
|
|
1381
|
-
assembly ("memory-safe") {
|
|
1382
1511
|
liability := calldataload(add(abs, 0x08))
|
|
1383
1512
|
debt := calldataload(add(abs, 0x28))
|
|
1384
1513
|
}
|
|
1514
|
+
if (head >> 192 != Specs.Debt >> 192) revert InvalidBlock();
|
|
1385
1515
|
}
|
|
1386
1516
|
|
|
1387
1517
|
/// @notice Decode a low-level fixed-width ACCOUNT_ASSET block at `abs`.
|
|
@@ -1392,16 +1522,30 @@ library Blocks {
|
|
|
1392
1522
|
uint head;
|
|
1393
1523
|
assembly ("memory-safe") {
|
|
1394
1524
|
head := calldataload(abs)
|
|
1395
|
-
}
|
|
1396
|
-
if (head >> 192 != Specs.AccountAsset >> 192) revert InvalidBlock();
|
|
1397
|
-
assembly ("memory-safe") {
|
|
1398
1525
|
account := calldataload(add(abs, 0x08))
|
|
1399
1526
|
asset := calldataload(add(abs, 0x28))
|
|
1400
1527
|
}
|
|
1528
|
+
if (head >> 192 != Specs.AccountAsset >> 192) revert InvalidBlock();
|
|
1401
1529
|
}
|
|
1402
1530
|
|
|
1403
1531
|
// Three-word payloads
|
|
1404
1532
|
|
|
1533
|
+
/// @notice Decode a low-level fixed-width BOOTSTRAP block at `abs`.
|
|
1534
|
+
/// @param abs Absolute block position.
|
|
1535
|
+
/// @return asset Decoded asset identifier.
|
|
1536
|
+
/// @return amount Decoded balance amount.
|
|
1537
|
+
/// @return budget Decoded native-value budget contribution.
|
|
1538
|
+
function unpackBootstrap(uint abs) internal pure returns (bytes32 asset, uint amount, uint budget) {
|
|
1539
|
+
uint head;
|
|
1540
|
+
assembly ("memory-safe") {
|
|
1541
|
+
head := calldataload(abs)
|
|
1542
|
+
asset := calldataload(add(abs, 0x08))
|
|
1543
|
+
amount := calldataload(add(abs, 0x28))
|
|
1544
|
+
budget := calldataload(add(abs, 0x48))
|
|
1545
|
+
}
|
|
1546
|
+
if (head >> 192 != Specs.Bootstrap >> 192) revert InvalidBlock();
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1405
1549
|
/// @notice Decode a low-level fixed-width ALLOCATION block at `abs`.
|
|
1406
1550
|
/// @param abs Absolute block position.
|
|
1407
1551
|
/// @return host Decoded host identifier.
|
|
@@ -1411,13 +1555,11 @@ library Blocks {
|
|
|
1411
1555
|
uint head;
|
|
1412
1556
|
assembly ("memory-safe") {
|
|
1413
1557
|
head := calldataload(abs)
|
|
1414
|
-
}
|
|
1415
|
-
if (head >> 192 != Specs.Allocation >> 192) revert InvalidBlock();
|
|
1416
|
-
assembly ("memory-safe") {
|
|
1417
1558
|
host := calldataload(add(abs, 0x08))
|
|
1418
1559
|
asset := calldataload(add(abs, 0x28))
|
|
1419
1560
|
amount := calldataload(add(abs, 0x48))
|
|
1420
1561
|
}
|
|
1562
|
+
if (head >> 192 != Specs.Allocation >> 192) revert InvalidBlock();
|
|
1421
1563
|
}
|
|
1422
1564
|
|
|
1423
1565
|
/// @notice Decode a low-level fixed-width ALLOWANCE block at `abs`.
|
|
@@ -1429,13 +1571,11 @@ library Blocks {
|
|
|
1429
1571
|
uint head;
|
|
1430
1572
|
assembly ("memory-safe") {
|
|
1431
1573
|
head := calldataload(abs)
|
|
1432
|
-
}
|
|
1433
|
-
if (head >> 192 != Specs.Allowance >> 192) revert InvalidBlock();
|
|
1434
|
-
assembly ("memory-safe") {
|
|
1435
1574
|
host := calldataload(add(abs, 0x08))
|
|
1436
1575
|
asset := calldataload(add(abs, 0x28))
|
|
1437
1576
|
amount := calldataload(add(abs, 0x48))
|
|
1438
1577
|
}
|
|
1578
|
+
if (head >> 192 != Specs.Allowance >> 192) revert InvalidBlock();
|
|
1439
1579
|
}
|
|
1440
1580
|
|
|
1441
1581
|
/// @notice Decode a low-level fixed-width CUSTODY block at `abs`.
|
|
@@ -1447,13 +1587,11 @@ library Blocks {
|
|
|
1447
1587
|
uint head;
|
|
1448
1588
|
assembly ("memory-safe") {
|
|
1449
1589
|
head := calldataload(abs)
|
|
1450
|
-
}
|
|
1451
|
-
if (head >> 192 != Specs.Custody >> 192) revert InvalidBlock();
|
|
1452
|
-
assembly ("memory-safe") {
|
|
1453
1590
|
host := calldataload(add(abs, 0x08))
|
|
1454
1591
|
asset := calldataload(add(abs, 0x28))
|
|
1455
1592
|
amount := calldataload(add(abs, 0x48))
|
|
1456
1593
|
}
|
|
1594
|
+
if (head >> 192 != Specs.Custody >> 192) revert InvalidBlock();
|
|
1457
1595
|
}
|
|
1458
1596
|
|
|
1459
1597
|
/// @notice Decode a low-level fixed-width ACCOUNT_AMOUNT block at `abs`.
|
|
@@ -1465,13 +1603,11 @@ library Blocks {
|
|
|
1465
1603
|
uint head;
|
|
1466
1604
|
assembly ("memory-safe") {
|
|
1467
1605
|
head := calldataload(abs)
|
|
1468
|
-
}
|
|
1469
|
-
if (head >> 192 != Specs.AccountAmount >> 192) revert InvalidBlock();
|
|
1470
|
-
assembly ("memory-safe") {
|
|
1471
1606
|
account := calldataload(add(abs, 0x08))
|
|
1472
1607
|
asset := calldataload(add(abs, 0x28))
|
|
1473
1608
|
amount := calldataload(add(abs, 0x48))
|
|
1474
1609
|
}
|
|
1610
|
+
if (head >> 192 != Specs.AccountAmount >> 192) revert InvalidBlock();
|
|
1475
1611
|
}
|
|
1476
1612
|
|
|
1477
1613
|
/// @notice Decode a low-level fixed-width HOST_AMOUNT block at `abs`.
|
|
@@ -1483,13 +1619,11 @@ library Blocks {
|
|
|
1483
1619
|
uint head;
|
|
1484
1620
|
assembly ("memory-safe") {
|
|
1485
1621
|
head := calldataload(abs)
|
|
1486
|
-
}
|
|
1487
|
-
if (head >> 192 != Specs.HostAmount >> 192) revert InvalidBlock();
|
|
1488
|
-
assembly ("memory-safe") {
|
|
1489
1622
|
host := calldataload(add(abs, 0x08))
|
|
1490
1623
|
asset := calldataload(add(abs, 0x28))
|
|
1491
1624
|
amount := calldataload(add(abs, 0x48))
|
|
1492
1625
|
}
|
|
1626
|
+
if (head >> 192 != Specs.HostAmount >> 192) revert InvalidBlock();
|
|
1493
1627
|
}
|
|
1494
1628
|
|
|
1495
1629
|
/// @notice Decode a low-level fixed-width HOST_ACCOUNT_ASSET block at `abs`.
|
|
@@ -1501,13 +1635,11 @@ library Blocks {
|
|
|
1501
1635
|
uint head;
|
|
1502
1636
|
assembly ("memory-safe") {
|
|
1503
1637
|
head := calldataload(abs)
|
|
1504
|
-
}
|
|
1505
|
-
if (head >> 192 != Specs.HostAccountAsset >> 192) revert InvalidBlock();
|
|
1506
|
-
assembly ("memory-safe") {
|
|
1507
1638
|
host := calldataload(add(abs, 0x08))
|
|
1508
1639
|
account := calldataload(add(abs, 0x28))
|
|
1509
1640
|
asset := calldataload(add(abs, 0x48))
|
|
1510
1641
|
}
|
|
1642
|
+
if (head >> 192 != Specs.HostAccountAsset >> 192) revert InvalidBlock();
|
|
1511
1643
|
}
|
|
1512
1644
|
|
|
1513
1645
|
// Four-word payloads
|
|
@@ -1524,14 +1656,12 @@ library Blocks {
|
|
|
1524
1656
|
uint head;
|
|
1525
1657
|
assembly ("memory-safe") {
|
|
1526
1658
|
head := calldataload(abs)
|
|
1527
|
-
}
|
|
1528
|
-
if (head >> 192 != Specs.Position >> 192) revert InvalidBlock();
|
|
1529
|
-
assembly ("memory-safe") {
|
|
1530
1659
|
asset := calldataload(add(abs, 0x08))
|
|
1531
1660
|
amount := calldataload(add(abs, 0x28))
|
|
1532
1661
|
liability := calldataload(add(abs, 0x48))
|
|
1533
1662
|
debt := calldataload(add(abs, 0x68))
|
|
1534
1663
|
}
|
|
1664
|
+
if (head >> 192 != Specs.Position >> 192) revert InvalidBlock();
|
|
1535
1665
|
}
|
|
1536
1666
|
|
|
1537
1667
|
/// @notice Decode a low-level fixed-width HOST_ASSET block at `abs`.
|
|
@@ -1542,12 +1672,10 @@ library Blocks {
|
|
|
1542
1672
|
uint head;
|
|
1543
1673
|
assembly ("memory-safe") {
|
|
1544
1674
|
head := calldataload(abs)
|
|
1545
|
-
}
|
|
1546
|
-
if (head >> 192 != Specs.HostAsset >> 192) revert InvalidBlock();
|
|
1547
|
-
assembly ("memory-safe") {
|
|
1548
1675
|
host := calldataload(add(abs, 0x08))
|
|
1549
1676
|
asset := calldataload(add(abs, 0x28))
|
|
1550
1677
|
}
|
|
1678
|
+
if (head >> 192 != Specs.HostAsset >> 192) revert InvalidBlock();
|
|
1551
1679
|
}
|
|
1552
1680
|
|
|
1553
1681
|
/// @notice Decode a low-level fixed-width TRANSACTION block at `abs`.
|
|
@@ -1560,14 +1688,12 @@ library Blocks {
|
|
|
1560
1688
|
uint head;
|
|
1561
1689
|
assembly ("memory-safe") {
|
|
1562
1690
|
head := calldataload(abs)
|
|
1563
|
-
}
|
|
1564
|
-
if (head >> 192 != Specs.Transaction >> 192) revert InvalidBlock();
|
|
1565
|
-
assembly ("memory-safe") {
|
|
1566
1691
|
from := calldataload(add(abs, 0x08))
|
|
1567
1692
|
to := calldataload(add(abs, 0x28))
|
|
1568
1693
|
asset := calldataload(add(abs, 0x48))
|
|
1569
1694
|
amount := calldataload(add(abs, 0x68))
|
|
1570
1695
|
}
|
|
1696
|
+
if (head >> 192 != Specs.Transaction >> 192) revert InvalidBlock();
|
|
1571
1697
|
}
|
|
1572
1698
|
|
|
1573
1699
|
/// @notice Decode a low-level fixed-width HOST_ACCOUNT_AMOUNT block at `abs`.
|
|
@@ -1582,14 +1708,12 @@ library Blocks {
|
|
|
1582
1708
|
uint head;
|
|
1583
1709
|
assembly ("memory-safe") {
|
|
1584
1710
|
head := calldataload(abs)
|
|
1585
|
-
}
|
|
1586
|
-
if (head >> 192 != Specs.HostAccountAmount >> 192) revert InvalidBlock();
|
|
1587
|
-
assembly ("memory-safe") {
|
|
1588
1711
|
host := calldataload(add(abs, 0x08))
|
|
1589
1712
|
account := calldataload(add(abs, 0x28))
|
|
1590
1713
|
asset := calldataload(add(abs, 0x48))
|
|
1591
1714
|
amount := calldataload(add(abs, 0x68))
|
|
1592
1715
|
}
|
|
1716
|
+
if (head >> 192 != Specs.HostAccountAmount >> 192) revert InvalidBlock();
|
|
1593
1717
|
}
|
|
1594
1718
|
|
|
1595
1719
|
// Dynamic leaf blocks
|
|
@@ -1599,7 +1723,16 @@ library Blocks {
|
|
|
1599
1723
|
/// @return value Decoded list payload.
|
|
1600
1724
|
/// @return end Absolute position after the block.
|
|
1601
1725
|
function unpackList(uint abs) internal pure returns (bytes calldata value, uint end) {
|
|
1602
|
-
|
|
1726
|
+
uint head;
|
|
1727
|
+
uint len;
|
|
1728
|
+
assembly ("memory-safe") {
|
|
1729
|
+
head := calldataload(abs)
|
|
1730
|
+
len := and(shr(192, head), 0xffffffff)
|
|
1731
|
+
value.offset := add(abs, 0x08)
|
|
1732
|
+
value.length := len
|
|
1733
|
+
}
|
|
1734
|
+
if (uint32(head >> 224) != uint32(Keys.List)) revert InvalidBlock();
|
|
1735
|
+
end = abs + Sizes.Header + len;
|
|
1603
1736
|
}
|
|
1604
1737
|
|
|
1605
1738
|
/// @notice Decode one EVM payload and its absolute end position.
|
|
@@ -1607,7 +1740,16 @@ library Blocks {
|
|
|
1607
1740
|
/// @return value Decoded EVM payload.
|
|
1608
1741
|
/// @return end Absolute position after the block.
|
|
1609
1742
|
function unpackEvm(uint abs) internal pure returns (bytes calldata value, uint end) {
|
|
1610
|
-
|
|
1743
|
+
uint head;
|
|
1744
|
+
uint len;
|
|
1745
|
+
assembly ("memory-safe") {
|
|
1746
|
+
head := calldataload(abs)
|
|
1747
|
+
len := and(shr(192, head), 0xffffffff)
|
|
1748
|
+
value.offset := add(abs, 0x08)
|
|
1749
|
+
value.length := len
|
|
1750
|
+
}
|
|
1751
|
+
if (uint32(head >> 224) != uint32(Keys.Evm)) revert InvalidBlock();
|
|
1752
|
+
end = abs + Sizes.Header + len;
|
|
1611
1753
|
}
|
|
1612
1754
|
|
|
1613
1755
|
/// @notice Decode one BYTES payload and its absolute end position.
|
|
@@ -1615,7 +1757,16 @@ library Blocks {
|
|
|
1615
1757
|
/// @return value Decoded byte payload.
|
|
1616
1758
|
/// @return end Absolute position after the block.
|
|
1617
1759
|
function unpackBytes(uint abs) internal pure returns (bytes calldata value, uint end) {
|
|
1618
|
-
|
|
1760
|
+
uint head;
|
|
1761
|
+
uint len;
|
|
1762
|
+
assembly ("memory-safe") {
|
|
1763
|
+
head := calldataload(abs)
|
|
1764
|
+
len := and(shr(192, head), 0xffffffff)
|
|
1765
|
+
value.offset := add(abs, 0x08)
|
|
1766
|
+
value.length := len
|
|
1767
|
+
}
|
|
1768
|
+
if (uint32(head >> 224) != uint32(Keys.Bytes)) revert InvalidBlock();
|
|
1769
|
+
end = abs + Sizes.Header + len;
|
|
1619
1770
|
}
|
|
1620
1771
|
|
|
1621
1772
|
/// @notice Decode one STRING payload and its absolute end position.
|
|
@@ -1623,20 +1774,15 @@ library Blocks {
|
|
|
1623
1774
|
/// @return value Decoded string bytes.
|
|
1624
1775
|
/// @return end Absolute position after the block.
|
|
1625
1776
|
function unpackString(uint abs) internal pure returns (bytes calldata value, uint end) {
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
/// @dev Decode a dynamic leaf block after validating its key.
|
|
1630
|
-
/// @param abs Absolute block position.
|
|
1631
|
-
/// @param expected Expected block key.
|
|
1632
|
-
/// @return value Decoded payload.
|
|
1633
|
-
/// @return end Absolute position after the block.
|
|
1634
|
-
function unpackRaw(uint abs, bytes4 expected) private pure returns (bytes calldata value, uint end) {
|
|
1635
|
-
uint len = header(abs, expected);
|
|
1777
|
+
uint head;
|
|
1778
|
+
uint len;
|
|
1636
1779
|
assembly ("memory-safe") {
|
|
1780
|
+
head := calldataload(abs)
|
|
1781
|
+
len := and(shr(192, head), 0xffffffff)
|
|
1637
1782
|
value.offset := add(abs, 0x08)
|
|
1638
1783
|
value.length := len
|
|
1639
1784
|
}
|
|
1785
|
+
if (uint32(head >> 224) != uint32(Keys.String)) revert InvalidBlock();
|
|
1640
1786
|
end = abs + Sizes.Header + len;
|
|
1641
1787
|
}
|
|
1642
1788
|
|
|
@@ -1653,7 +1799,7 @@ library Blocks {
|
|
|
1653
1799
|
uint abs
|
|
1654
1800
|
) internal pure returns (uint entity, bytes calldata stream, uint end) {
|
|
1655
1801
|
uint limit;
|
|
1656
|
-
(abs, limit) =
|
|
1802
|
+
(abs, limit) = expectKey(abs, Keys.Annotation);
|
|
1657
1803
|
assembly ("memory-safe") {
|
|
1658
1804
|
entity := calldataload(abs)
|
|
1659
1805
|
}
|
|
@@ -1671,7 +1817,7 @@ library Blocks {
|
|
|
1671
1817
|
uint abs
|
|
1672
1818
|
) internal pure returns (bytes32 account, bytes calldata state, bytes calldata input, uint end) {
|
|
1673
1819
|
uint limit;
|
|
1674
|
-
(abs, limit) =
|
|
1820
|
+
(abs, limit) = expectKey(abs, Keys.Context);
|
|
1675
1821
|
assembly ("memory-safe") {
|
|
1676
1822
|
account := calldataload(abs)
|
|
1677
1823
|
}
|
|
@@ -1685,19 +1831,19 @@ library Blocks {
|
|
|
1685
1831
|
/// @notice Decode one STEP block and its nested input.
|
|
1686
1832
|
/// @param abs Absolute block position.
|
|
1687
1833
|
/// @return cmd Decoded command identifier.
|
|
1688
|
-
/// @return
|
|
1834
|
+
/// @return value Decoded native value.
|
|
1689
1835
|
/// @return input Decoded command input.
|
|
1690
1836
|
/// @return end Absolute position after the block.
|
|
1691
1837
|
function unpackStep(
|
|
1692
1838
|
uint abs
|
|
1693
|
-
) internal pure returns (uint cmd,
|
|
1839
|
+
) internal pure returns (uint cmd, uint128 value, bytes calldata input, uint end) {
|
|
1694
1840
|
uint limit;
|
|
1695
|
-
(abs, limit) =
|
|
1841
|
+
(abs, limit) = expectKey(abs, Keys.Step);
|
|
1696
1842
|
assembly ("memory-safe") {
|
|
1697
1843
|
cmd := calldataload(abs)
|
|
1698
|
-
|
|
1844
|
+
value := shr(128, calldataload(add(abs, 0x20)))
|
|
1699
1845
|
}
|
|
1700
|
-
(input, end) = unpackBytes(abs +
|
|
1846
|
+
(input, end) = unpackBytes(abs + 48);
|
|
1701
1847
|
if (end != limit) revert InvalidBlock();
|
|
1702
1848
|
}
|
|
1703
1849
|
|
|
@@ -1711,7 +1857,7 @@ library Blocks {
|
|
|
1711
1857
|
uint abs
|
|
1712
1858
|
) internal pure returns (uint target, uint resources, bytes calldata payload, uint end) {
|
|
1713
1859
|
uint limit;
|
|
1714
|
-
(abs, limit) =
|
|
1860
|
+
(abs, limit) = expectKey(abs, Keys.Call);
|
|
1715
1861
|
assembly ("memory-safe") {
|
|
1716
1862
|
target := calldataload(abs)
|
|
1717
1863
|
resources := calldataload(add(abs, 0x20))
|
|
@@ -1730,7 +1876,7 @@ library Blocks {
|
|
|
1730
1876
|
uint abs
|
|
1731
1877
|
) internal pure returns (uint portal, uint resources, bytes calldata input, uint end) {
|
|
1732
1878
|
uint limit;
|
|
1733
|
-
(abs, limit) =
|
|
1879
|
+
(abs, limit) = expectKey(abs, Keys.Relay);
|
|
1734
1880
|
assembly ("memory-safe") {
|
|
1735
1881
|
portal := calldataload(abs)
|
|
1736
1882
|
resources := calldataload(add(abs, 0x20))
|
|
@@ -1749,7 +1895,7 @@ library Blocks {
|
|
|
1749
1895
|
uint abs
|
|
1750
1896
|
) internal pure returns (uint portal, uint resources, bytes calldata payload, uint end) {
|
|
1751
1897
|
uint limit;
|
|
1752
|
-
(abs, limit) =
|
|
1898
|
+
(abs, limit) = expectKey(abs, Keys.Dispatch);
|
|
1753
1899
|
assembly ("memory-safe") {
|
|
1754
1900
|
portal := calldataload(abs)
|
|
1755
1901
|
resources := calldataload(add(abs, 0x20))
|
|
@@ -1765,7 +1911,7 @@ library Blocks {
|
|
|
1765
1911
|
/// @return end Absolute position after the block.
|
|
1766
1912
|
function unpackLabel(uint abs) internal pure returns (bytes32 namespace, string memory name, uint end) {
|
|
1767
1913
|
uint limit;
|
|
1768
|
-
(abs, limit) =
|
|
1914
|
+
(abs, limit) = expectKey(abs, Keys.Label);
|
|
1769
1915
|
assembly ("memory-safe") {
|
|
1770
1916
|
namespace := calldataload(abs)
|
|
1771
1917
|
}
|
|
@@ -1783,7 +1929,7 @@ library Blocks {
|
|
|
1783
1929
|
/// @return end Absolute position after the block.
|
|
1784
1930
|
function unpackSchema(uint abs) internal pure returns (uint spec, string memory body, bytes32 name, uint end) {
|
|
1785
1931
|
uint limit;
|
|
1786
|
-
(abs, limit) =
|
|
1932
|
+
(abs, limit) = expectKey(abs, Keys.Schema);
|
|
1787
1933
|
assembly ("memory-safe") {
|
|
1788
1934
|
spec := calldataload(abs)
|
|
1789
1935
|
}
|
|
@@ -1810,7 +1956,7 @@ library Blocks {
|
|
|
1810
1956
|
uint abs
|
|
1811
1957
|
) internal pure returns (uint handler, uint resources, bytes32 key, bytes calldata witness, uint end) {
|
|
1812
1958
|
uint limit;
|
|
1813
|
-
(abs, limit) =
|
|
1959
|
+
(abs, limit) = expectKey(abs, Keys.Recover);
|
|
1814
1960
|
assembly ("memory-safe") {
|
|
1815
1961
|
handler := calldataload(abs)
|
|
1816
1962
|
resources := calldataload(add(abs, 0x20))
|
|
@@ -1963,6 +2109,24 @@ library Blocks {
|
|
|
1963
2109
|
|
|
1964
2110
|
// Fixed-width factories
|
|
1965
2111
|
|
|
2112
|
+
/// @notice Encode a BOOTSTRAP block.
|
|
2113
|
+
/// @param asset Asset identifier.
|
|
2114
|
+
/// @param amount Balance amount to source.
|
|
2115
|
+
/// @param budget Native-value budget to source.
|
|
2116
|
+
/// @return value Encoded BOOTSTRAP block bytes.
|
|
2117
|
+
function createBootstrap(bytes32 asset, uint amount, uint budget) internal pure returns (bytes memory value) {
|
|
2118
|
+
value = allocate(Sizes.Bootstrap);
|
|
2119
|
+
writeBootstrap(value, 0, asset, amount, budget);
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2122
|
+
/// @notice Encode a CASHOUT block.
|
|
2123
|
+
/// @param amount Native-asset amount to withdraw.
|
|
2124
|
+
/// @return value Encoded CASHOUT block bytes.
|
|
2125
|
+
function createCashout(uint amount) internal pure returns (bytes memory value) {
|
|
2126
|
+
value = allocate(Sizes.Cashout);
|
|
2127
|
+
writeCashout(value, 0, amount);
|
|
2128
|
+
}
|
|
2129
|
+
|
|
1966
2130
|
/// @notice Encode an AMOUNT block.
|
|
1967
2131
|
/// @param asset Asset identifier.
|
|
1968
2132
|
/// @param amount Token amount.
|
|
@@ -2036,20 +2200,20 @@ library Blocks {
|
|
|
2036
2200
|
|
|
2037
2201
|
/// @notice Encode a STEP block.
|
|
2038
2202
|
/// @param cmd Command identifier.
|
|
2039
|
-
/// @param
|
|
2203
|
+
/// @param value Native value assigned to the step.
|
|
2040
2204
|
/// @param input Raw nested input payload.
|
|
2041
|
-
/// @return
|
|
2042
|
-
function createStep(uint cmd,
|
|
2043
|
-
uint len = max32(Sizes.
|
|
2044
|
-
|
|
2045
|
-
writeStep(
|
|
2205
|
+
/// @return encoded Encoded STEP block bytes.
|
|
2206
|
+
function createStep(uint cmd, uint128 value, bytes memory input) internal pure returns (bytes memory encoded) {
|
|
2207
|
+
uint len = max32(Sizes.Step + input.length);
|
|
2208
|
+
encoded = allocate(len);
|
|
2209
|
+
writeStep(encoded, 0, cmd, value, input);
|
|
2046
2210
|
}
|
|
2047
2211
|
|
|
2048
2212
|
/// @notice Encode a STEP block by copying its nested input from calldata.
|
|
2049
|
-
function createStepCopy(uint cmd,
|
|
2050
|
-
uint len = max32(Sizes.
|
|
2051
|
-
|
|
2052
|
-
copyStep(
|
|
2213
|
+
function createStepCopy(uint cmd, uint128 value, bytes calldata input) internal pure returns (bytes memory encoded) {
|
|
2214
|
+
uint len = max32(Sizes.Step + input.length);
|
|
2215
|
+
encoded = allocate(len);
|
|
2216
|
+
copyStep(encoded, 0, cmd, value, input);
|
|
2053
2217
|
}
|
|
2054
2218
|
|
|
2055
2219
|
/// @notice Encode a CALL block.
|
|
@@ -2158,3 +2322,85 @@ library Blocks {
|
|
|
2158
2322
|
copyRecover(value, 0, handler, resources, recoverykey, witness);
|
|
2159
2323
|
}
|
|
2160
2324
|
}
|
|
2325
|
+
|
|
2326
|
+
/// @title Memory
|
|
2327
|
+
/// @notice Fixed-stride decoding for homogeneous block streams held in memory.
|
|
2328
|
+
/// @dev The unpackers are intentionally unchecked beyond their exact header
|
|
2329
|
+
/// comparison. Callers must obtain bounds with `bounds`, advance by the matching
|
|
2330
|
+
/// complete encoded block size, and stop at the returned end position.
|
|
2331
|
+
library Memory {
|
|
2332
|
+
uint64 private constant BalanceHeader = (uint64(uint32(Keys.Balance)) << 32) | 64;
|
|
2333
|
+
uint64 private constant DebtHeader = (uint64(uint32(Keys.Debt)) << 32) | 64;
|
|
2334
|
+
uint64 private constant PositionHeader = (uint64(uint32(Keys.Position)) << 32) | 128;
|
|
2335
|
+
uint64 private constant TransactionHeader = (uint64(uint32(Keys.Transaction)) << 32) | 128;
|
|
2336
|
+
|
|
2337
|
+
/// @notice Return absolute bounds for a fixed-stride memory block stream.
|
|
2338
|
+
/// @dev DANGER: Empty streams are valid and `size` must be nonzero. The size
|
|
2339
|
+
/// must include the complete block header and payload.
|
|
2340
|
+
/// @param source Memory block stream.
|
|
2341
|
+
/// @param size Complete encoded size of each block.
|
|
2342
|
+
/// @return abs Absolute memory position of the first block header.
|
|
2343
|
+
/// @return end Absolute memory position immediately after the source.
|
|
2344
|
+
function bounds(bytes memory source, uint size) internal pure returns (uint abs, uint end) {
|
|
2345
|
+
uint len = source.length;
|
|
2346
|
+
uint remainder;
|
|
2347
|
+
assembly ("memory-safe") {
|
|
2348
|
+
remainder := mod(len, size)
|
|
2349
|
+
abs := add(source, 0x20)
|
|
2350
|
+
end := add(abs, len)
|
|
2351
|
+
}
|
|
2352
|
+
if (remainder != 0) revert Blocks.InvalidBlock();
|
|
2353
|
+
}
|
|
2354
|
+
|
|
2355
|
+
/// @notice Decode a BALANCE block at an in-bounds absolute memory position.
|
|
2356
|
+
function unpackBalance(uint abs) internal pure returns (bytes32 asset, uint amount) {
|
|
2357
|
+
uint64 actual;
|
|
2358
|
+
assembly ("memory-safe") {
|
|
2359
|
+
actual := shr(192, mload(abs))
|
|
2360
|
+
asset := mload(add(abs, 0x08))
|
|
2361
|
+
amount := mload(add(abs, 0x28))
|
|
2362
|
+
}
|
|
2363
|
+
if (actual != BalanceHeader) revert Blocks.InvalidBlock();
|
|
2364
|
+
}
|
|
2365
|
+
|
|
2366
|
+
/// @notice Decode a DEBT block at an in-bounds absolute memory position.
|
|
2367
|
+
function unpackDebt(uint abs) internal pure returns (bytes32 liability, uint debt) {
|
|
2368
|
+
uint64 actual;
|
|
2369
|
+
assembly ("memory-safe") {
|
|
2370
|
+
actual := shr(192, mload(abs))
|
|
2371
|
+
liability := mload(add(abs, 0x08))
|
|
2372
|
+
debt := mload(add(abs, 0x28))
|
|
2373
|
+
}
|
|
2374
|
+
if (actual != DebtHeader) revert Blocks.InvalidBlock();
|
|
2375
|
+
}
|
|
2376
|
+
|
|
2377
|
+
/// @notice Decode a POSITION block at an in-bounds absolute memory position.
|
|
2378
|
+
function unpackPosition(
|
|
2379
|
+
uint abs
|
|
2380
|
+
) internal pure returns (bytes32 asset, uint amount, bytes32 liability, uint debt) {
|
|
2381
|
+
uint64 actual;
|
|
2382
|
+
assembly ("memory-safe") {
|
|
2383
|
+
actual := shr(192, mload(abs))
|
|
2384
|
+
asset := mload(add(abs, 0x08))
|
|
2385
|
+
amount := mload(add(abs, 0x28))
|
|
2386
|
+
liability := mload(add(abs, 0x48))
|
|
2387
|
+
debt := mload(add(abs, 0x68))
|
|
2388
|
+
}
|
|
2389
|
+
if (actual != PositionHeader) revert Blocks.InvalidBlock();
|
|
2390
|
+
}
|
|
2391
|
+
|
|
2392
|
+
/// @notice Decode a TRANSACTION block at an in-bounds absolute memory position.
|
|
2393
|
+
function unpackTransaction(
|
|
2394
|
+
uint abs
|
|
2395
|
+
) internal pure returns (bytes32 from, bytes32 to, bytes32 asset, uint amount) {
|
|
2396
|
+
uint64 actual;
|
|
2397
|
+
assembly ("memory-safe") {
|
|
2398
|
+
actual := shr(192, mload(abs))
|
|
2399
|
+
from := mload(add(abs, 0x08))
|
|
2400
|
+
to := mload(add(abs, 0x28))
|
|
2401
|
+
asset := mload(add(abs, 0x48))
|
|
2402
|
+
amount := mload(add(abs, 0x68))
|
|
2403
|
+
}
|
|
2404
|
+
if (actual != TransactionHeader) revert Blocks.InvalidBlock();
|
|
2405
|
+
}
|
|
2406
|
+
}
|