@rootzero/contracts 1.25.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 +101 -0
- package/Codec.sol +1 -2
- package/Endpoints.sol +2 -0
- package/README.md +61 -51
- package/Utils.sol +2 -1
- package/codec/Blocks.sol +276 -88
- package/codec/Buffers.sol +24 -20
- package/codec/Decoders.sol +35 -37
- 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 -49
- 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 +23 -19
- 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 -8
- 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 +19 -20
- package/execution/Budget.sol +2 -3
- package/execution/Execution.sol +271 -509
- 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 +3 -3
- 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
|
@@ -108,7 +108,12 @@ library Blocks {
|
|
|
108
108
|
/// @return body Absolute position of the first payload byte.
|
|
109
109
|
/// @return end Absolute position immediately after the payload.
|
|
110
110
|
function expectKey(uint abs, bytes4 key) internal pure returns (uint body, uint end) {
|
|
111
|
-
uint
|
|
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);
|
|
112
117
|
unchecked {
|
|
113
118
|
body = abs + Sizes.Header;
|
|
114
119
|
end = body + len;
|
|
@@ -196,6 +201,31 @@ library Blocks {
|
|
|
196
201
|
}
|
|
197
202
|
}
|
|
198
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
|
+
|
|
199
229
|
/// @notice Count a run that must consume the complete region.
|
|
200
230
|
/// @dev Reverts when any well-formed trailing block has a different key.
|
|
201
231
|
/// @param abs Absolute start position.
|
|
@@ -350,6 +380,20 @@ library Blocks {
|
|
|
350
380
|
}
|
|
351
381
|
}
|
|
352
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
|
+
|
|
353
397
|
// Two-word payloads
|
|
354
398
|
|
|
355
399
|
/// @notice Write an AMOUNT block at `i`.
|
|
@@ -434,6 +478,24 @@ library Blocks {
|
|
|
434
478
|
|
|
435
479
|
// Three-word payloads
|
|
436
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
|
+
|
|
437
499
|
/// @notice Write an ALLOCATION block at `i`.
|
|
438
500
|
/// @dev DANGER: Unchecked memory write. Reserve `Sizes.B96` bytes first.
|
|
439
501
|
/// @param dst Destination buffer.
|
|
@@ -697,19 +759,19 @@ library Blocks {
|
|
|
697
759
|
/// @param dst Destination buffer.
|
|
698
760
|
/// @param i Relative write position.
|
|
699
761
|
/// @param cmd Command identifier.
|
|
700
|
-
/// @param
|
|
762
|
+
/// @param value Native value assigned to the step.
|
|
701
763
|
/// @param input Command input.
|
|
702
|
-
function writeStep(bytes memory dst, uint i, uint cmd,
|
|
703
|
-
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;
|
|
704
766
|
uint key = uint32(Keys.Step);
|
|
705
767
|
uint byteskey = uint32(Keys.Bytes);
|
|
706
768
|
assembly ("memory-safe") {
|
|
707
769
|
let p := add(add(dst, 0x20), i)
|
|
708
770
|
mstore(p, or(shl(224, key), shl(192, len)))
|
|
709
771
|
mstore(add(p, 0x08), cmd)
|
|
710
|
-
mstore(add(p, 0x28),
|
|
772
|
+
mstore(add(p, 0x28), shl(128, value))
|
|
711
773
|
|
|
712
|
-
let q := add(p,
|
|
774
|
+
let q := add(p, 0x38)
|
|
713
775
|
let inputlen := mload(input)
|
|
714
776
|
mstore(q, or(shl(224, byteskey), shl(192, inputlen)))
|
|
715
777
|
mcopy(add(q, 0x08), add(input, 0x20), inputlen)
|
|
@@ -969,8 +1031,21 @@ library Blocks {
|
|
|
969
1031
|
}
|
|
970
1032
|
|
|
971
1033
|
/// @notice Encode a STEP block at `i`, copying its nested input from calldata.
|
|
972
|
-
function copyStep(bytes memory dst, uint i, uint cmd,
|
|
973
|
-
|
|
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
|
+
}
|
|
974
1049
|
}
|
|
975
1050
|
|
|
976
1051
|
/// @notice Encode a CALL block at `i`, copying its nested payload from calldata.
|
|
@@ -1342,11 +1417,9 @@ library Blocks {
|
|
|
1342
1417
|
uint head;
|
|
1343
1418
|
assembly ("memory-safe") {
|
|
1344
1419
|
head := calldataload(abs)
|
|
1345
|
-
}
|
|
1346
|
-
if (head >> 192 != Specs.Account >> 192) revert InvalidBlock();
|
|
1347
|
-
assembly ("memory-safe") {
|
|
1348
1420
|
account := calldataload(add(abs, 0x08))
|
|
1349
1421
|
}
|
|
1422
|
+
if (head >> 192 != Specs.Account >> 192) revert InvalidBlock();
|
|
1350
1423
|
}
|
|
1351
1424
|
|
|
1352
1425
|
/// @notice Decode a low-level fixed-width ASSET block at `abs`.
|
|
@@ -1356,11 +1429,9 @@ library Blocks {
|
|
|
1356
1429
|
uint head;
|
|
1357
1430
|
assembly ("memory-safe") {
|
|
1358
1431
|
head := calldataload(abs)
|
|
1359
|
-
}
|
|
1360
|
-
if (head >> 192 != Specs.Asset >> 192) revert InvalidBlock();
|
|
1361
|
-
assembly ("memory-safe") {
|
|
1362
1432
|
asset := calldataload(add(abs, 0x08))
|
|
1363
1433
|
}
|
|
1434
|
+
if (head >> 192 != Specs.Asset >> 192) revert InvalidBlock();
|
|
1364
1435
|
}
|
|
1365
1436
|
|
|
1366
1437
|
/// @notice Decode a low-level fixed-width NODE block at `abs`.
|
|
@@ -1370,11 +1441,9 @@ library Blocks {
|
|
|
1370
1441
|
uint head;
|
|
1371
1442
|
assembly ("memory-safe") {
|
|
1372
1443
|
head := calldataload(abs)
|
|
1373
|
-
}
|
|
1374
|
-
if (head >> 192 != Specs.Node >> 192) revert InvalidBlock();
|
|
1375
|
-
assembly ("memory-safe") {
|
|
1376
1444
|
node := calldataload(add(abs, 0x08))
|
|
1377
1445
|
}
|
|
1446
|
+
if (head >> 192 != Specs.Node >> 192) revert InvalidBlock();
|
|
1378
1447
|
}
|
|
1379
1448
|
|
|
1380
1449
|
/// @notice Decode a low-level fixed-width STATUS block at `abs`.
|
|
@@ -1384,11 +1453,21 @@ library Blocks {
|
|
|
1384
1453
|
uint head;
|
|
1385
1454
|
assembly ("memory-safe") {
|
|
1386
1455
|
head := calldataload(abs)
|
|
1456
|
+
code := calldataload(add(abs, 0x08))
|
|
1387
1457
|
}
|
|
1388
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;
|
|
1389
1466
|
assembly ("memory-safe") {
|
|
1390
|
-
|
|
1467
|
+
head := calldataload(abs)
|
|
1468
|
+
amount := calldataload(add(abs, 0x08))
|
|
1391
1469
|
}
|
|
1470
|
+
if (head >> 192 != Specs.Cashout >> 192) revert InvalidBlock();
|
|
1392
1471
|
}
|
|
1393
1472
|
|
|
1394
1473
|
// Two-word payloads
|
|
@@ -1401,12 +1480,10 @@ library Blocks {
|
|
|
1401
1480
|
uint head;
|
|
1402
1481
|
assembly ("memory-safe") {
|
|
1403
1482
|
head := calldataload(abs)
|
|
1404
|
-
}
|
|
1405
|
-
if (head >> 192 != Specs.Amount >> 192) revert InvalidBlock();
|
|
1406
|
-
assembly ("memory-safe") {
|
|
1407
1483
|
asset := calldataload(add(abs, 0x08))
|
|
1408
1484
|
amount := calldataload(add(abs, 0x28))
|
|
1409
1485
|
}
|
|
1486
|
+
if (head >> 192 != Specs.Amount >> 192) revert InvalidBlock();
|
|
1410
1487
|
}
|
|
1411
1488
|
|
|
1412
1489
|
/// @notice Decode a low-level fixed-width BALANCE block at `abs`.
|
|
@@ -1417,13 +1494,10 @@ library Blocks {
|
|
|
1417
1494
|
uint head;
|
|
1418
1495
|
assembly ("memory-safe") {
|
|
1419
1496
|
head := calldataload(abs)
|
|
1420
|
-
}
|
|
1421
|
-
if (head >> 192 != Specs.Balance >> 192) revert InvalidBlock();
|
|
1422
|
-
|
|
1423
|
-
assembly ("memory-safe") {
|
|
1424
1497
|
asset := calldataload(add(abs, 0x08))
|
|
1425
1498
|
amount := calldataload(add(abs, 0x28))
|
|
1426
1499
|
}
|
|
1500
|
+
if (head >> 192 != Specs.Balance >> 192) revert InvalidBlock();
|
|
1427
1501
|
}
|
|
1428
1502
|
|
|
1429
1503
|
/// @notice Decode a low-level fixed-width DEBT block at `abs`.
|
|
@@ -1434,12 +1508,10 @@ library Blocks {
|
|
|
1434
1508
|
uint head;
|
|
1435
1509
|
assembly ("memory-safe") {
|
|
1436
1510
|
head := calldataload(abs)
|
|
1437
|
-
}
|
|
1438
|
-
if (head >> 192 != Specs.Debt >> 192) revert InvalidBlock();
|
|
1439
|
-
assembly ("memory-safe") {
|
|
1440
1511
|
liability := calldataload(add(abs, 0x08))
|
|
1441
1512
|
debt := calldataload(add(abs, 0x28))
|
|
1442
1513
|
}
|
|
1514
|
+
if (head >> 192 != Specs.Debt >> 192) revert InvalidBlock();
|
|
1443
1515
|
}
|
|
1444
1516
|
|
|
1445
1517
|
/// @notice Decode a low-level fixed-width ACCOUNT_ASSET block at `abs`.
|
|
@@ -1450,16 +1522,30 @@ library Blocks {
|
|
|
1450
1522
|
uint head;
|
|
1451
1523
|
assembly ("memory-safe") {
|
|
1452
1524
|
head := calldataload(abs)
|
|
1453
|
-
}
|
|
1454
|
-
if (head >> 192 != Specs.AccountAsset >> 192) revert InvalidBlock();
|
|
1455
|
-
assembly ("memory-safe") {
|
|
1456
1525
|
account := calldataload(add(abs, 0x08))
|
|
1457
1526
|
asset := calldataload(add(abs, 0x28))
|
|
1458
1527
|
}
|
|
1528
|
+
if (head >> 192 != Specs.AccountAsset >> 192) revert InvalidBlock();
|
|
1459
1529
|
}
|
|
1460
1530
|
|
|
1461
1531
|
// Three-word payloads
|
|
1462
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
|
+
|
|
1463
1549
|
/// @notice Decode a low-level fixed-width ALLOCATION block at `abs`.
|
|
1464
1550
|
/// @param abs Absolute block position.
|
|
1465
1551
|
/// @return host Decoded host identifier.
|
|
@@ -1469,13 +1555,11 @@ library Blocks {
|
|
|
1469
1555
|
uint head;
|
|
1470
1556
|
assembly ("memory-safe") {
|
|
1471
1557
|
head := calldataload(abs)
|
|
1472
|
-
}
|
|
1473
|
-
if (head >> 192 != Specs.Allocation >> 192) revert InvalidBlock();
|
|
1474
|
-
assembly ("memory-safe") {
|
|
1475
1558
|
host := calldataload(add(abs, 0x08))
|
|
1476
1559
|
asset := calldataload(add(abs, 0x28))
|
|
1477
1560
|
amount := calldataload(add(abs, 0x48))
|
|
1478
1561
|
}
|
|
1562
|
+
if (head >> 192 != Specs.Allocation >> 192) revert InvalidBlock();
|
|
1479
1563
|
}
|
|
1480
1564
|
|
|
1481
1565
|
/// @notice Decode a low-level fixed-width ALLOWANCE block at `abs`.
|
|
@@ -1487,13 +1571,11 @@ library Blocks {
|
|
|
1487
1571
|
uint head;
|
|
1488
1572
|
assembly ("memory-safe") {
|
|
1489
1573
|
head := calldataload(abs)
|
|
1490
|
-
}
|
|
1491
|
-
if (head >> 192 != Specs.Allowance >> 192) revert InvalidBlock();
|
|
1492
|
-
assembly ("memory-safe") {
|
|
1493
1574
|
host := calldataload(add(abs, 0x08))
|
|
1494
1575
|
asset := calldataload(add(abs, 0x28))
|
|
1495
1576
|
amount := calldataload(add(abs, 0x48))
|
|
1496
1577
|
}
|
|
1578
|
+
if (head >> 192 != Specs.Allowance >> 192) revert InvalidBlock();
|
|
1497
1579
|
}
|
|
1498
1580
|
|
|
1499
1581
|
/// @notice Decode a low-level fixed-width CUSTODY block at `abs`.
|
|
@@ -1505,13 +1587,11 @@ library Blocks {
|
|
|
1505
1587
|
uint head;
|
|
1506
1588
|
assembly ("memory-safe") {
|
|
1507
1589
|
head := calldataload(abs)
|
|
1508
|
-
}
|
|
1509
|
-
if (head >> 192 != Specs.Custody >> 192) revert InvalidBlock();
|
|
1510
|
-
assembly ("memory-safe") {
|
|
1511
1590
|
host := calldataload(add(abs, 0x08))
|
|
1512
1591
|
asset := calldataload(add(abs, 0x28))
|
|
1513
1592
|
amount := calldataload(add(abs, 0x48))
|
|
1514
1593
|
}
|
|
1594
|
+
if (head >> 192 != Specs.Custody >> 192) revert InvalidBlock();
|
|
1515
1595
|
}
|
|
1516
1596
|
|
|
1517
1597
|
/// @notice Decode a low-level fixed-width ACCOUNT_AMOUNT block at `abs`.
|
|
@@ -1523,13 +1603,11 @@ library Blocks {
|
|
|
1523
1603
|
uint head;
|
|
1524
1604
|
assembly ("memory-safe") {
|
|
1525
1605
|
head := calldataload(abs)
|
|
1526
|
-
}
|
|
1527
|
-
if (head >> 192 != Specs.AccountAmount >> 192) revert InvalidBlock();
|
|
1528
|
-
assembly ("memory-safe") {
|
|
1529
1606
|
account := calldataload(add(abs, 0x08))
|
|
1530
1607
|
asset := calldataload(add(abs, 0x28))
|
|
1531
1608
|
amount := calldataload(add(abs, 0x48))
|
|
1532
1609
|
}
|
|
1610
|
+
if (head >> 192 != Specs.AccountAmount >> 192) revert InvalidBlock();
|
|
1533
1611
|
}
|
|
1534
1612
|
|
|
1535
1613
|
/// @notice Decode a low-level fixed-width HOST_AMOUNT block at `abs`.
|
|
@@ -1541,13 +1619,11 @@ library Blocks {
|
|
|
1541
1619
|
uint head;
|
|
1542
1620
|
assembly ("memory-safe") {
|
|
1543
1621
|
head := calldataload(abs)
|
|
1544
|
-
}
|
|
1545
|
-
if (head >> 192 != Specs.HostAmount >> 192) revert InvalidBlock();
|
|
1546
|
-
assembly ("memory-safe") {
|
|
1547
1622
|
host := calldataload(add(abs, 0x08))
|
|
1548
1623
|
asset := calldataload(add(abs, 0x28))
|
|
1549
1624
|
amount := calldataload(add(abs, 0x48))
|
|
1550
1625
|
}
|
|
1626
|
+
if (head >> 192 != Specs.HostAmount >> 192) revert InvalidBlock();
|
|
1551
1627
|
}
|
|
1552
1628
|
|
|
1553
1629
|
/// @notice Decode a low-level fixed-width HOST_ACCOUNT_ASSET block at `abs`.
|
|
@@ -1559,13 +1635,11 @@ library Blocks {
|
|
|
1559
1635
|
uint head;
|
|
1560
1636
|
assembly ("memory-safe") {
|
|
1561
1637
|
head := calldataload(abs)
|
|
1562
|
-
}
|
|
1563
|
-
if (head >> 192 != Specs.HostAccountAsset >> 192) revert InvalidBlock();
|
|
1564
|
-
assembly ("memory-safe") {
|
|
1565
1638
|
host := calldataload(add(abs, 0x08))
|
|
1566
1639
|
account := calldataload(add(abs, 0x28))
|
|
1567
1640
|
asset := calldataload(add(abs, 0x48))
|
|
1568
1641
|
}
|
|
1642
|
+
if (head >> 192 != Specs.HostAccountAsset >> 192) revert InvalidBlock();
|
|
1569
1643
|
}
|
|
1570
1644
|
|
|
1571
1645
|
// Four-word payloads
|
|
@@ -1582,14 +1656,12 @@ library Blocks {
|
|
|
1582
1656
|
uint head;
|
|
1583
1657
|
assembly ("memory-safe") {
|
|
1584
1658
|
head := calldataload(abs)
|
|
1585
|
-
}
|
|
1586
|
-
if (head >> 192 != Specs.Position >> 192) revert InvalidBlock();
|
|
1587
|
-
assembly ("memory-safe") {
|
|
1588
1659
|
asset := calldataload(add(abs, 0x08))
|
|
1589
1660
|
amount := calldataload(add(abs, 0x28))
|
|
1590
1661
|
liability := calldataload(add(abs, 0x48))
|
|
1591
1662
|
debt := calldataload(add(abs, 0x68))
|
|
1592
1663
|
}
|
|
1664
|
+
if (head >> 192 != Specs.Position >> 192) revert InvalidBlock();
|
|
1593
1665
|
}
|
|
1594
1666
|
|
|
1595
1667
|
/// @notice Decode a low-level fixed-width HOST_ASSET block at `abs`.
|
|
@@ -1600,12 +1672,10 @@ library Blocks {
|
|
|
1600
1672
|
uint head;
|
|
1601
1673
|
assembly ("memory-safe") {
|
|
1602
1674
|
head := calldataload(abs)
|
|
1603
|
-
}
|
|
1604
|
-
if (head >> 192 != Specs.HostAsset >> 192) revert InvalidBlock();
|
|
1605
|
-
assembly ("memory-safe") {
|
|
1606
1675
|
host := calldataload(add(abs, 0x08))
|
|
1607
1676
|
asset := calldataload(add(abs, 0x28))
|
|
1608
1677
|
}
|
|
1678
|
+
if (head >> 192 != Specs.HostAsset >> 192) revert InvalidBlock();
|
|
1609
1679
|
}
|
|
1610
1680
|
|
|
1611
1681
|
/// @notice Decode a low-level fixed-width TRANSACTION block at `abs`.
|
|
@@ -1618,14 +1688,12 @@ library Blocks {
|
|
|
1618
1688
|
uint head;
|
|
1619
1689
|
assembly ("memory-safe") {
|
|
1620
1690
|
head := calldataload(abs)
|
|
1621
|
-
}
|
|
1622
|
-
if (head >> 192 != Specs.Transaction >> 192) revert InvalidBlock();
|
|
1623
|
-
assembly ("memory-safe") {
|
|
1624
1691
|
from := calldataload(add(abs, 0x08))
|
|
1625
1692
|
to := calldataload(add(abs, 0x28))
|
|
1626
1693
|
asset := calldataload(add(abs, 0x48))
|
|
1627
1694
|
amount := calldataload(add(abs, 0x68))
|
|
1628
1695
|
}
|
|
1696
|
+
if (head >> 192 != Specs.Transaction >> 192) revert InvalidBlock();
|
|
1629
1697
|
}
|
|
1630
1698
|
|
|
1631
1699
|
/// @notice Decode a low-level fixed-width HOST_ACCOUNT_AMOUNT block at `abs`.
|
|
@@ -1640,14 +1708,12 @@ library Blocks {
|
|
|
1640
1708
|
uint head;
|
|
1641
1709
|
assembly ("memory-safe") {
|
|
1642
1710
|
head := calldataload(abs)
|
|
1643
|
-
}
|
|
1644
|
-
if (head >> 192 != Specs.HostAccountAmount >> 192) revert InvalidBlock();
|
|
1645
|
-
assembly ("memory-safe") {
|
|
1646
1711
|
host := calldataload(add(abs, 0x08))
|
|
1647
1712
|
account := calldataload(add(abs, 0x28))
|
|
1648
1713
|
asset := calldataload(add(abs, 0x48))
|
|
1649
1714
|
amount := calldataload(add(abs, 0x68))
|
|
1650
1715
|
}
|
|
1716
|
+
if (head >> 192 != Specs.HostAccountAmount >> 192) revert InvalidBlock();
|
|
1651
1717
|
}
|
|
1652
1718
|
|
|
1653
1719
|
// Dynamic leaf blocks
|
|
@@ -1657,7 +1723,16 @@ library Blocks {
|
|
|
1657
1723
|
/// @return value Decoded list payload.
|
|
1658
1724
|
/// @return end Absolute position after the block.
|
|
1659
1725
|
function unpackList(uint abs) internal pure returns (bytes calldata value, uint end) {
|
|
1660
|
-
|
|
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;
|
|
1661
1736
|
}
|
|
1662
1737
|
|
|
1663
1738
|
/// @notice Decode one EVM payload and its absolute end position.
|
|
@@ -1665,7 +1740,16 @@ library Blocks {
|
|
|
1665
1740
|
/// @return value Decoded EVM payload.
|
|
1666
1741
|
/// @return end Absolute position after the block.
|
|
1667
1742
|
function unpackEvm(uint abs) internal pure returns (bytes calldata value, uint end) {
|
|
1668
|
-
|
|
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;
|
|
1669
1753
|
}
|
|
1670
1754
|
|
|
1671
1755
|
/// @notice Decode one BYTES payload and its absolute end position.
|
|
@@ -1673,7 +1757,16 @@ library Blocks {
|
|
|
1673
1757
|
/// @return value Decoded byte payload.
|
|
1674
1758
|
/// @return end Absolute position after the block.
|
|
1675
1759
|
function unpackBytes(uint abs) internal pure returns (bytes calldata value, uint end) {
|
|
1676
|
-
|
|
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;
|
|
1677
1770
|
}
|
|
1678
1771
|
|
|
1679
1772
|
/// @notice Decode one STRING payload and its absolute end position.
|
|
@@ -1681,20 +1774,15 @@ library Blocks {
|
|
|
1681
1774
|
/// @return value Decoded string bytes.
|
|
1682
1775
|
/// @return end Absolute position after the block.
|
|
1683
1776
|
function unpackString(uint abs) internal pure returns (bytes calldata value, uint end) {
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
/// @dev Decode a dynamic leaf block after validating its key.
|
|
1688
|
-
/// @param abs Absolute block position.
|
|
1689
|
-
/// @param expected Expected block key.
|
|
1690
|
-
/// @return value Decoded payload.
|
|
1691
|
-
/// @return end Absolute position after the block.
|
|
1692
|
-
function unpackRaw(uint abs, bytes4 expected) private pure returns (bytes calldata value, uint end) {
|
|
1693
|
-
uint len = header(abs, expected);
|
|
1777
|
+
uint head;
|
|
1778
|
+
uint len;
|
|
1694
1779
|
assembly ("memory-safe") {
|
|
1780
|
+
head := calldataload(abs)
|
|
1781
|
+
len := and(shr(192, head), 0xffffffff)
|
|
1695
1782
|
value.offset := add(abs, 0x08)
|
|
1696
1783
|
value.length := len
|
|
1697
1784
|
}
|
|
1785
|
+
if (uint32(head >> 224) != uint32(Keys.String)) revert InvalidBlock();
|
|
1698
1786
|
end = abs + Sizes.Header + len;
|
|
1699
1787
|
}
|
|
1700
1788
|
|
|
@@ -1743,19 +1831,19 @@ library Blocks {
|
|
|
1743
1831
|
/// @notice Decode one STEP block and its nested input.
|
|
1744
1832
|
/// @param abs Absolute block position.
|
|
1745
1833
|
/// @return cmd Decoded command identifier.
|
|
1746
|
-
/// @return
|
|
1834
|
+
/// @return value Decoded native value.
|
|
1747
1835
|
/// @return input Decoded command input.
|
|
1748
1836
|
/// @return end Absolute position after the block.
|
|
1749
1837
|
function unpackStep(
|
|
1750
1838
|
uint abs
|
|
1751
|
-
) internal pure returns (uint cmd,
|
|
1839
|
+
) internal pure returns (uint cmd, uint128 value, bytes calldata input, uint end) {
|
|
1752
1840
|
uint limit;
|
|
1753
1841
|
(abs, limit) = expectKey(abs, Keys.Step);
|
|
1754
1842
|
assembly ("memory-safe") {
|
|
1755
1843
|
cmd := calldataload(abs)
|
|
1756
|
-
|
|
1844
|
+
value := shr(128, calldataload(add(abs, 0x20)))
|
|
1757
1845
|
}
|
|
1758
|
-
(input, end) = unpackBytes(abs +
|
|
1846
|
+
(input, end) = unpackBytes(abs + 48);
|
|
1759
1847
|
if (end != limit) revert InvalidBlock();
|
|
1760
1848
|
}
|
|
1761
1849
|
|
|
@@ -2021,6 +2109,24 @@ library Blocks {
|
|
|
2021
2109
|
|
|
2022
2110
|
// Fixed-width factories
|
|
2023
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
|
+
|
|
2024
2130
|
/// @notice Encode an AMOUNT block.
|
|
2025
2131
|
/// @param asset Asset identifier.
|
|
2026
2132
|
/// @param amount Token amount.
|
|
@@ -2094,20 +2200,20 @@ library Blocks {
|
|
|
2094
2200
|
|
|
2095
2201
|
/// @notice Encode a STEP block.
|
|
2096
2202
|
/// @param cmd Command identifier.
|
|
2097
|
-
/// @param
|
|
2203
|
+
/// @param value Native value assigned to the step.
|
|
2098
2204
|
/// @param input Raw nested input payload.
|
|
2099
|
-
/// @return
|
|
2100
|
-
function createStep(uint cmd,
|
|
2101
|
-
uint len = max32(Sizes.
|
|
2102
|
-
|
|
2103
|
-
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);
|
|
2104
2210
|
}
|
|
2105
2211
|
|
|
2106
2212
|
/// @notice Encode a STEP block by copying its nested input from calldata.
|
|
2107
|
-
function createStepCopy(uint cmd,
|
|
2108
|
-
uint len = max32(Sizes.
|
|
2109
|
-
|
|
2110
|
-
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);
|
|
2111
2217
|
}
|
|
2112
2218
|
|
|
2113
2219
|
/// @notice Encode a CALL block.
|
|
@@ -2216,3 +2322,85 @@ library Blocks {
|
|
|
2216
2322
|
copyRecover(value, 0, handler, resources, recoverykey, witness);
|
|
2217
2323
|
}
|
|
2218
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
|
+
}
|