@rootzero/contracts 1.16.0 → 1.18.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 +59 -0
- package/Codec.sol +1 -1
- package/Commands.sol +1 -1
- package/Core.sol +4 -4
- package/Endpoints.sol +12 -5
- package/README.md +8 -4
- package/Utils.sol +1 -1
- package/codec/Blocks.sol +32 -0
- package/codec/Decoders.sol +18 -1
- package/codec/Keys.sol +2 -0
- package/codec/Readers.sol +12 -0
- package/codec/Schema.sol +1 -0
- package/codec/Specs.sol +3 -0
- package/codec/Writers.sol +9 -0
- package/commands/Base.sol +2 -0
- package/commands/Credit.sol +4 -1
- package/commands/Debit.sol +4 -1
- package/commands/Repay.sol +83 -0
- package/commands/Settle.sol +54 -1
- package/commands/admin/Allowance.sol +1 -1
- package/core/Settlement.sol +15 -8
- package/core/Types.sol +8 -0
- package/execution/Execution.sol +35 -1
- package/guards/Revoke.sol +43 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,63 @@
|
|
|
3
3
|
Until the protocol reaches integration-stable status, minor versions may include
|
|
4
4
|
breaking API changes. Breaking changes are called out explicitly.
|
|
5
5
|
|
|
6
|
+
## 1.18.0
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- Added the non-funded `repay` and funded `repayPayable` commands. Both consume
|
|
11
|
+
`Position` state, settle only its liability side, and return the released
|
|
12
|
+
asset side as `Balance` state.
|
|
13
|
+
- Added the reusable non-funded `RepayHook` settlement primitive and the
|
|
14
|
+
execution-funded `RepayPayableHook`.
|
|
15
|
+
- Added the opt-in `RevokeAsset` guardian endpoint, which accepts `Asset`
|
|
16
|
+
entries and denies each asset through the existing `DenyAssetsHook`.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- `Settlement.settle` now delegates its liability leg to the virtual `repay`
|
|
21
|
+
primitive. The default behavior remains a nonzero `debitAccount` call, while
|
|
22
|
+
derived settlement implementations can customize repayment in one place.
|
|
23
|
+
- Exported the repayment commands and hooks and the asset-revocation guard from
|
|
24
|
+
their corresponding public barrels.
|
|
25
|
+
|
|
26
|
+
### Upgrade Compatibility
|
|
27
|
+
|
|
28
|
+
- Hosts inheriting `Settlement` retain the previous default settlement
|
|
29
|
+
behavior. Hosts that already declare an internal
|
|
30
|
+
`repay(bytes32,bytes32,uint)` function may need to mark it as an override or
|
|
31
|
+
rename it when upgrading.
|
|
32
|
+
|
|
33
|
+
## 1.17.0
|
|
34
|
+
|
|
35
|
+
### Breaking Changes
|
|
36
|
+
|
|
37
|
+
- `executeDebitAccount`, `executeCreditAccount`, and `executeSettle` now require
|
|
38
|
+
the pipeline step's `uint128 value` argument and reject nonzero value inside
|
|
39
|
+
the internal adapter.
|
|
40
|
+
- `AllowanceHook` implementations must treat an amount of zero as revocation.
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
|
|
44
|
+
- Added the `HostAsset` structural block and complete codec support for
|
|
45
|
+
host-scoped asset references.
|
|
46
|
+
- Added the opt-in `RevokeAllowance` guardian endpoint, which accepts
|
|
47
|
+
`HostAsset` entries and revokes each allowance through `AllowanceHook`.
|
|
48
|
+
- Added the funded `settlePayable` command and `SettlePayableHook` for settlement
|
|
49
|
+
implementations that require access to the command's native-value budget.
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
|
|
53
|
+
- Completed the endpoint barrel with `CommandBase` and exported the new command,
|
|
54
|
+
guard, hook, internal adapter, and structural type surfaces from their
|
|
55
|
+
corresponding package barrels.
|
|
56
|
+
|
|
57
|
+
### Upgrade Compatibility
|
|
58
|
+
|
|
59
|
+
- Pipeline hosts using the internal debit, credit, or settle adapters must pass
|
|
60
|
+
each step's assigned value into the adapter. Existing non-funded steps should
|
|
61
|
+
continue to pass zero.
|
|
62
|
+
|
|
6
63
|
## 1.16.0
|
|
7
64
|
|
|
8
65
|
### Breaking Changes
|
|
@@ -54,6 +111,8 @@ breaking API changes. Breaking changes are called out explicitly.
|
|
|
54
111
|
- Pipeline transaction streams are posted before the next step, and position
|
|
55
112
|
state is settled separately through the scalar asset, amount, liability, and
|
|
56
113
|
debt hook.
|
|
114
|
+
- Completed the public barrel exports for internal command adapters,
|
|
115
|
+
input-only endpoint bases, access errors, and low-level utility helpers.
|
|
57
116
|
|
|
58
117
|
### Upgrade Compatibility
|
|
59
118
|
|
package/Codec.sol
CHANGED
|
@@ -4,7 +4,7 @@ pragma solidity ^0.8.33;
|
|
|
4
4
|
// Aggregator: re-exports the complete block encoding and decoding surface.
|
|
5
5
|
// Import this file for low-level codec extensions and direct stream processing.
|
|
6
6
|
|
|
7
|
-
import { AssetAmount, AccountAsset, AccountAmount, HostAmount, HostAccountAsset, HostAccountAmount, Position, Tx } from "./core/Types.sol";
|
|
7
|
+
import { AssetAmount, AccountAsset, HostAsset, AccountAmount, HostAmount, HostAccountAsset, HostAccountAmount, Position, Tx } from "./core/Types.sol";
|
|
8
8
|
import { Keys } from "./codec/Keys.sol";
|
|
9
9
|
import { Sizes, Specs } from "./codec/Specs.sol";
|
|
10
10
|
import { Descriptors } from "./codec/Descriptors.sol";
|
package/Commands.sol
CHANGED
|
@@ -11,4 +11,4 @@ import {Blocks} from "./codec/Blocks.sol";
|
|
|
11
11
|
import {Sizes, Specs} from "./codec/Specs.sol";
|
|
12
12
|
import {Decoders} from "./codec/Decoders.sol";
|
|
13
13
|
import {Cursors, Cur} from "./utils/Cursors.sol";
|
|
14
|
-
import {AssetAmount, AccountAsset, AccountAmount, HostAmount, HostAccountAsset, HostAccountAmount, Position, Tx} from "./core/Types.sol";
|
|
14
|
+
import {AssetAmount, AccountAsset, HostAsset, AccountAmount, HostAmount, HostAccountAsset, HostAccountAmount, Position, Tx} from "./core/Types.sol";
|
package/Core.sol
CHANGED
|
@@ -7,18 +7,18 @@ pragma solidity ^0.8.33;
|
|
|
7
7
|
import { Action } from "./annotations/Action.sol";
|
|
8
8
|
import { Label } from "./annotations/Label.sol";
|
|
9
9
|
import { Schema } from "./annotations/Schema.sol";
|
|
10
|
-
import { AdminAccess, CallerAccess, CommanderAccess, GuardianAccess, NodeAccess, TrustAccess } from "./core/Access.sol";
|
|
10
|
+
import { AccessDenied, AdminAccess, CallerAccess, CommanderAccess, CommanderNotAllowed, GuardianAccess, NodeAccess, TrustAccess } from "./core/Access.sol";
|
|
11
11
|
import { Balances, InsufficientFunds } from "./core/Balances.sol";
|
|
12
12
|
import { Escrows, InsufficientEscrow } from "./core/Escrows.sol";
|
|
13
13
|
import { NativeAsset, Runtime } from "./core/Runtime.sol";
|
|
14
14
|
import { Admins, CommandHost, Guardians, Host, HostIntroduction, IHostIntroduction } from "./core/Host.sol";
|
|
15
15
|
import { CommandCalls, FailedCall, NodeCalls, PortCalls, RawNodeCalls } from "./core/Calls.sol";
|
|
16
|
-
import { EndpointBase } from "./core/Endpoint.sol";
|
|
16
|
+
import { EndpointBase, InputEndpointBase } from "./core/Endpoint.sol";
|
|
17
17
|
import { Pipeline } from "./core/Pipeline.sol";
|
|
18
18
|
import { Budget, Budgets } from "./execution/Budget.sol";
|
|
19
|
-
import { CreditAccountHook, DebitAccountHook, PostHook, SettleHook, Settlement } from "./core/Settlement.sol";
|
|
19
|
+
import { CreditAccountHook, DebitAccountHook, PostHook, RepayHook, SettleHook, Settlement } from "./core/Settlement.sol";
|
|
20
20
|
import { Portal } from "./core/Portal.sol";
|
|
21
|
-
import { AssetAmount, AccountAsset, AccountAmount, HostAmount, HostAccountAsset, HostAccountAmount, Position, Tx } from "./core/Types.sol";
|
|
21
|
+
import { AssetAmount, AccountAsset, HostAsset, AccountAmount, HostAmount, HostAccountAsset, HostAccountAmount, Position, Tx } from "./core/Types.sol";
|
|
22
22
|
import { Validator } from "./core/Validator.sol";
|
|
23
23
|
|
|
24
24
|
|
package/Endpoints.sol
CHANGED
|
@@ -5,19 +5,26 @@ pragma solidity ^0.8.33;
|
|
|
5
5
|
// Import this file to inherit from the full rootzero callable host surface without managing individual paths.
|
|
6
6
|
|
|
7
7
|
// Shared endpoint hooks
|
|
8
|
-
import { CreditAccountHook, DebitAccountHook, PostHook, SettleHook } from "./core/Settlement.sol";
|
|
8
|
+
import { CreditAccountHook, DebitAccountHook, PostHook, RepayHook, SettleHook } from "./core/Settlement.sol";
|
|
9
9
|
|
|
10
10
|
// Commands
|
|
11
|
+
import { CommandBase } from "./commands/Base.sol";
|
|
11
12
|
import { Allocate, AllocateHook } from "./commands/Allocate.sol";
|
|
12
13
|
import { Burn, BurnHook } from "./commands/Burn.sol";
|
|
13
|
-
import { CreditAccount } from "./commands/Credit.sol";
|
|
14
|
-
import { DebitAccount } from "./commands/Debit.sol";
|
|
14
|
+
import { CreditAccount, InternalCreditAccount } from "./commands/Credit.sol";
|
|
15
|
+
import { DebitAccount, InternalDebitAccount } from "./commands/Debit.sol";
|
|
15
16
|
import { Deposit, DepositHook, DepositPayable, DepositPayableHook } from "./commands/Deposit.sol";
|
|
16
17
|
import { Payout, PayoutHook } from "./commands/Payout.sol";
|
|
17
18
|
import { Provision, ProvisionHook, ProvisionPayable, ProvisionPayableHook } from "./commands/Provision.sol";
|
|
18
19
|
import { RecoverPayable, RecoverPayableHook } from "./commands/Recover.sol";
|
|
20
|
+
import { Repay, RepayPayable, RepayPayableHook } from "./commands/Repay.sol";
|
|
19
21
|
import { RelayPayable, RelayBalancePayable, RelayPayableHook } from "./commands/Relay.sol";
|
|
20
|
-
import {
|
|
22
|
+
import {
|
|
23
|
+
InternalSettle,
|
|
24
|
+
Settle,
|
|
25
|
+
SettlePayable,
|
|
26
|
+
SettlePayableHook
|
|
27
|
+
} from "./commands/Settle.sol";
|
|
21
28
|
import { Withdraw, WithdrawHook } from "./commands/Withdraw.sol";
|
|
22
29
|
|
|
23
30
|
// Admin commands
|
|
@@ -46,7 +53,7 @@ import { PortPost } from "./ports/Post.sol";
|
|
|
46
53
|
|
|
47
54
|
// Guard endpoints
|
|
48
55
|
import { GuardBase } from "./guards/Base.sol";
|
|
49
|
-
import { Revoke } from "./guards/Revoke.sol";
|
|
56
|
+
import { Revoke, RevokeAllowance, RevokeAsset } from "./guards/Revoke.sol";
|
|
50
57
|
|
|
51
58
|
// Query endpoints
|
|
52
59
|
import { QueryBase } from "./queries/Base.sol";
|
package/README.md
CHANGED
|
@@ -219,7 +219,10 @@ pipeline.
|
|
|
219
219
|
|
|
220
220
|
The built-in surface is also available as two independent feature bundles:
|
|
221
221
|
`Admins` provides annotate, authorize, unauthorize, and executePayable;
|
|
222
|
-
`Guardians` provides appoint, dismiss, and
|
|
222
|
+
`Guardians` provides appoint, dismiss, and node revocation. Hosts that implement
|
|
223
|
+
the allowance hook can additionally inherit the opt-in `RevokeAllowance` guard,
|
|
224
|
+
which accepts `hostAsset { uint host, bytes32 asset }` entries and always applies
|
|
225
|
+
a zero allowance. The full `Host` composes
|
|
223
226
|
both, while smaller hosts can inherit either bundle separately.
|
|
224
227
|
|
|
225
228
|
Trust is explicit and minimal. Each host has an immutable **commander**
|
|
@@ -325,7 +328,8 @@ abstract contract MyCommand is CommandBase {
|
|
|
325
328
|
```
|
|
326
329
|
|
|
327
330
|
The standard commands cover the common ledger movements: `deposit` and
|
|
328
|
-
`depositPayable` (external funds in), `
|
|
331
|
+
`depositPayable` (external funds in), `settlePayable` (funded settlement),
|
|
332
|
+
`withdraw` and `burn` (funds out),
|
|
329
333
|
`debitAccount` and `creditAccount` (internal movements), `payout` (deliver
|
|
330
334
|
state to other accounts), `allocate` (turn balance state into custody),
|
|
331
335
|
`provision` (provision custody from an external allocation), `settle` (consume
|
|
@@ -378,8 +382,8 @@ Hosts that implement a pipeline locally can inherit `InternalDebitAccount`,
|
|
|
378
382
|
`InternalCreditAccount`, and `InternalSettle` to advertise the canonical command
|
|
379
383
|
endpoints while routing their local command IDs through `executeDebitAccount`,
|
|
380
384
|
`executeCreditAccount`, and `executeSettle`. These adapters consume the
|
|
381
|
-
memory-backed pipeline state directly and avoid an external self-call.
|
|
382
|
-
|
|
385
|
+
memory-backed pipeline state directly and avoid an external self-call. Pass the
|
|
386
|
+
step value into each adapter; all three reject nonzero value because the
|
|
383
387
|
commands are non-funded.
|
|
384
388
|
|
|
385
389
|
Positions also support backward-composed pipelines. In an exact-output route,
|
package/Utils.sol
CHANGED
|
@@ -13,7 +13,7 @@ import { Ids } from "./utils/Ids.sol";
|
|
|
13
13
|
import { Nodes } from "./utils/Nodes.sol";
|
|
14
14
|
import { Selectors } from "./utils/Selectors.sol";
|
|
15
15
|
import { Layout } from "./utils/Layout.sol";
|
|
16
|
-
import { addrOr, applyBps, beforeBps, bytes32ToInt, bytes32ToString, divisible, hash32, intToBytes32, isFamily, matchesBase, MAX_BPS, max8, max16, max24, max32, max40, max64, max96, max128, max160, NotDivisible, retryTicket, toLocalBase, toUnspecifiedBase, ValueOverflow } from "./utils/Utils.sol";
|
|
16
|
+
import { addrOr, applyBps, beforeBps, bytes32ToInt, bytes32ToString, clear8, clear16, clear32, clear64, divisible, ensureAddr, hash32, intToBytes32, isFamily, matchesBase, MAX_BPS, max8, max16, max24, max32, max40, max64, max96, max128, max160, NotDivisible, replace8, replace16, replace32, replace64, retryTicket, toLocalBase, toUnspecifiedBase, ValueOverflow, ZeroAddress } from "./utils/Utils.sol";
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
|
package/codec/Blocks.sol
CHANGED
|
@@ -335,6 +335,22 @@ library Blocks {
|
|
|
335
335
|
}
|
|
336
336
|
}
|
|
337
337
|
|
|
338
|
+
/// @notice Write a HOST_ASSET block at `i`.
|
|
339
|
+
/// @dev DANGER: Unchecked memory write. Reserve `Sizes.B64` bytes first.
|
|
340
|
+
/// @param dst Destination buffer.
|
|
341
|
+
/// @param i Relative write position.
|
|
342
|
+
/// @param host Host identifier to encode.
|
|
343
|
+
/// @param asset Asset identifier to encode.
|
|
344
|
+
function writeHostAsset(bytes memory dst, uint i, uint host, bytes32 asset) internal pure {
|
|
345
|
+
uint spec = Specs.HostAsset;
|
|
346
|
+
assembly ("memory-safe") {
|
|
347
|
+
let p := add(add(dst, 0x20), i)
|
|
348
|
+
mstore(p, spec)
|
|
349
|
+
mstore(add(p, 0x08), host)
|
|
350
|
+
mstore(add(p, 0x28), asset)
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
338
354
|
// Three-word payloads
|
|
339
355
|
|
|
340
356
|
/// @notice Write an ALLOCATION block at `i`.
|
|
@@ -1285,6 +1301,22 @@ library Blocks {
|
|
|
1285
1301
|
}
|
|
1286
1302
|
}
|
|
1287
1303
|
|
|
1304
|
+
/// @notice Decode a low-level fixed-width HOST_ASSET block at `abs`.
|
|
1305
|
+
/// @param abs Absolute block position.
|
|
1306
|
+
/// @return host Decoded host identifier.
|
|
1307
|
+
/// @return asset Decoded asset identifier.
|
|
1308
|
+
function unpackHostAsset(uint abs) internal pure returns (uint host, bytes32 asset) {
|
|
1309
|
+
uint head;
|
|
1310
|
+
assembly ("memory-safe") {
|
|
1311
|
+
head := calldataload(abs)
|
|
1312
|
+
}
|
|
1313
|
+
if (head >> 192 != Specs.HostAsset >> 192) revert InvalidBlock();
|
|
1314
|
+
assembly ("memory-safe") {
|
|
1315
|
+
host := calldataload(add(abs, 0x08))
|
|
1316
|
+
asset := calldataload(add(abs, 0x28))
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1288
1320
|
/// @notice Decode a low-level fixed-width TRANSACTION block at `abs`.
|
|
1289
1321
|
/// @param abs Absolute block position.
|
|
1290
1322
|
/// @return from Decoded debit account.
|
package/codec/Decoders.sol
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {AssetAmount, AccountAsset, AccountAmount, HostAmount, HostAccountAsset, Position, Tx} from "../core/Types.sol";
|
|
4
|
+
import {AssetAmount, AccountAsset, HostAsset, AccountAmount, HostAmount, HostAccountAsset, Position, Tx} from "../core/Types.sol";
|
|
5
5
|
import {Blocks} from "./Blocks.sol";
|
|
6
6
|
import {Sizes, Specs} from "./Specs.sol";
|
|
7
7
|
import {Cursors, Cur} from "../utils/Cursors.sol";
|
|
@@ -276,6 +276,16 @@ library Decoders {
|
|
|
276
276
|
(account, asset) = Blocks.unpackAccountAsset(abs);
|
|
277
277
|
}
|
|
278
278
|
|
|
279
|
+
/// @notice Decode and consume one HOST_ASSET block.
|
|
280
|
+
/// @param cur Cursor advanced past the block.
|
|
281
|
+
/// @return host Decoded host identifier.
|
|
282
|
+
/// @return asset Decoded asset identifier.
|
|
283
|
+
function unpackHostAsset(Cur memory cur) internal pure returns (uint host, bytes32 asset) {
|
|
284
|
+
uint abs;
|
|
285
|
+
(cur.state, abs) = cur.state.consume(Sizes.HostAsset);
|
|
286
|
+
(host, asset) = Blocks.unpackHostAsset(abs);
|
|
287
|
+
}
|
|
288
|
+
|
|
279
289
|
/// @notice Decode and consume one AMOUNT block.
|
|
280
290
|
/// @param cur Cursor advanced past the block.
|
|
281
291
|
/// @return asset Decoded asset identifier.
|
|
@@ -462,6 +472,13 @@ library Decoders {
|
|
|
462
472
|
(value.account, value.asset) = unpackAccountAsset(cur);
|
|
463
473
|
}
|
|
464
474
|
|
|
475
|
+
/// @notice Decode one HOST_ASSET block into its structured value.
|
|
476
|
+
/// @param cur Cursor advanced past the block.
|
|
477
|
+
/// @return value Structured host and asset.
|
|
478
|
+
function unpackHostAssetValue(Cur memory cur) internal pure returns (HostAsset memory value) {
|
|
479
|
+
(value.host, value.asset) = unpackHostAsset(cur);
|
|
480
|
+
}
|
|
481
|
+
|
|
465
482
|
/// @notice Decode one AMOUNT block into its structured value.
|
|
466
483
|
/// @param cur Cursor advanced past the block.
|
|
467
484
|
/// @return value Structured asset amount.
|
package/codec/Keys.sol
CHANGED
|
@@ -62,6 +62,8 @@ library Keys {
|
|
|
62
62
|
bytes4 constant Status = bytes4(keccak256("#status"));
|
|
63
63
|
/// @dev Structural account asset form - (bytes32 account, bytes32 asset)
|
|
64
64
|
bytes4 constant AccountAsset = bytes4(keccak256("#accountAsset"));
|
|
65
|
+
/// @dev Structural host asset form - (uint host, bytes32 asset)
|
|
66
|
+
bytes4 constant HostAsset = bytes4(keccak256("#hostAsset"));
|
|
65
67
|
/// @dev Structural account amount form - (bytes32 account, bytes32 asset, uint amount)
|
|
66
68
|
bytes4 constant AccountAmount = bytes4(keccak256("#accountAmount"));
|
|
67
69
|
/// @dev Structural host amount form - (uint host, bytes32 asset, uint amount)
|
package/codec/Readers.sol
CHANGED
|
@@ -94,6 +94,18 @@ library Readers {
|
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
/// @notice Consume a HOST_ASSET block and return its fields.
|
|
98
|
+
/// @param cur Reader; advanced past the block.
|
|
99
|
+
/// @return host Host identifier.
|
|
100
|
+
/// @return asset Asset identifier.
|
|
101
|
+
function unpackHostAsset(Reader memory cur) internal pure returns (uint host, bytes32 asset) {
|
|
102
|
+
uint abs = consume(cur, Keys.HostAsset, 64, 64);
|
|
103
|
+
assembly ("memory-safe") {
|
|
104
|
+
host := mload(abs)
|
|
105
|
+
asset := mload(add(abs, 0x20))
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
97
109
|
/// @notice Consume a POSITION block and return its fields.
|
|
98
110
|
function unpackPosition(
|
|
99
111
|
Reader memory cur
|
package/codec/Schema.sol
CHANGED
|
@@ -81,6 +81,7 @@ library Schemas {
|
|
|
81
81
|
string constant Amount = "{ bytes32 asset, uint amount }";
|
|
82
82
|
string constant Balance = "{ bytes32 asset, uint amount }";
|
|
83
83
|
string constant AccountAsset = "{ bytes32 account, bytes32 asset }";
|
|
84
|
+
string constant HostAsset = "{ uint host, bytes32 asset }";
|
|
84
85
|
|
|
85
86
|
// Three-word payloads
|
|
86
87
|
|
package/codec/Specs.sol
CHANGED
|
@@ -27,6 +27,8 @@ library Sizes {
|
|
|
27
27
|
uint constant Amount = B64;
|
|
28
28
|
/// @dev BALANCE block: 8 header + 32 asset + 32 amount = 72 bytes
|
|
29
29
|
uint constant Balance = B64;
|
|
30
|
+
/// @dev HOST_ASSET block: 8 header + 32 host + 32 asset = 72 bytes
|
|
31
|
+
uint constant HostAsset = B64;
|
|
30
32
|
/// @dev ALLOCATION/CUSTODY block: 8 header + 32 host + 32 asset + 32 amount = 104 bytes
|
|
31
33
|
uint constant HostAmount = B96;
|
|
32
34
|
/// @dev TRANSACTION block: 8 header + 32 from + 32 to + 32 asset + 32 amount = 136 bytes
|
|
@@ -88,6 +90,7 @@ library Specs {
|
|
|
88
90
|
|
|
89
91
|
uint constant Status = uint(bytes32(Keys.Status)) | Exact32;
|
|
90
92
|
uint constant AccountAsset = uint(bytes32(Keys.AccountAsset)) | Exact64;
|
|
93
|
+
uint constant HostAsset = uint(bytes32(Keys.HostAsset)) | Exact64;
|
|
91
94
|
uint constant AccountAmount = uint(bytes32(Keys.AccountAmount)) | Exact96;
|
|
92
95
|
uint constant HostAmount = uint(bytes32(Keys.HostAmount)) | Exact96;
|
|
93
96
|
uint constant HostAccountAsset = uint(bytes32(Keys.HostAccountAsset)) | Exact96;
|
package/codec/Writers.sol
CHANGED
|
@@ -204,6 +204,15 @@ library Writers {
|
|
|
204
204
|
Blocks.writeAccountAsset(writer.dst, i, account, asset);
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
+
/// @notice Append a HOST_ASSET block.
|
|
208
|
+
/// @param writer Destination writer.
|
|
209
|
+
/// @param host Host identifier to encode.
|
|
210
|
+
/// @param asset Asset identifier to encode.
|
|
211
|
+
function appendHostAsset(Writer memory writer, uint host, bytes32 asset) internal pure {
|
|
212
|
+
uint i = reserve(writer, Sizes.HostAsset);
|
|
213
|
+
Blocks.writeHostAsset(writer.dst, i, host, asset);
|
|
214
|
+
}
|
|
215
|
+
|
|
207
216
|
/// @notice Append an ALLOCATION block.
|
|
208
217
|
/// @param writer Destination writer.
|
|
209
218
|
/// @param host Host identifier to encode.
|
package/commands/Base.sol
CHANGED
|
@@ -22,6 +22,8 @@ using Executions for Execution;
|
|
|
22
22
|
abstract contract CommandBase is CallerAccess, EndpointBase, ReceivedEvent {
|
|
23
23
|
/// @dev Thrown when `onlyActive` finds that `deadline` has already passed.
|
|
24
24
|
error Expired();
|
|
25
|
+
/// @dev Thrown when a non-funded internal command receives native value.
|
|
26
|
+
error ValueNotAllowed();
|
|
25
27
|
|
|
26
28
|
/// @dev Restrict execution to trusted callers.
|
|
27
29
|
modifier onlyCommand() {
|
package/commands/Credit.sol
CHANGED
|
@@ -54,13 +54,16 @@ abstract contract InternalCreditAccount is CreditAccount {
|
|
|
54
54
|
/// @param account Account credited by each balance.
|
|
55
55
|
/// @param state BALANCE block stream held in pipeline memory.
|
|
56
56
|
/// @param input Empty input required by the command schema.
|
|
57
|
+
/// @param value Native value assigned to the command; must be zero.
|
|
57
58
|
/// @return output Empty output state.
|
|
58
59
|
/// @return transactions Empty transaction stream.
|
|
59
60
|
function executeCreditAccount(
|
|
60
61
|
bytes32 account,
|
|
61
62
|
bytes memory state,
|
|
62
|
-
bytes calldata input
|
|
63
|
+
bytes calldata input,
|
|
64
|
+
uint128 value
|
|
63
65
|
) internal returns (bytes memory, bytes memory) {
|
|
66
|
+
if (value != 0) revert ValueNotAllowed();
|
|
64
67
|
if (input.length != 0) revert Executions.ZeroStride();
|
|
65
68
|
if (state.length == 0) revert Blocks.EmptyRun();
|
|
66
69
|
|
package/commands/Debit.sol
CHANGED
|
@@ -58,13 +58,16 @@ abstract contract InternalDebitAccount is DebitAccount {
|
|
|
58
58
|
/// @param account Account whose funds are debited.
|
|
59
59
|
/// @param state Empty pipeline state required by the command schema.
|
|
60
60
|
/// @param input AMOUNT block stream.
|
|
61
|
+
/// @param value Native value assigned to the command; must be zero.
|
|
61
62
|
/// @return output BALANCE block stream matching the debited amounts.
|
|
62
63
|
/// @return transactions Empty transaction stream.
|
|
63
64
|
function executeDebitAccount(
|
|
64
65
|
bytes32 account,
|
|
65
66
|
bytes memory state,
|
|
66
|
-
bytes calldata input
|
|
67
|
+
bytes calldata input,
|
|
68
|
+
uint128 value
|
|
67
69
|
) internal returns (bytes memory, bytes memory) {
|
|
70
|
+
if (value != 0) revert ValueNotAllowed();
|
|
68
71
|
if (state.length != 0) revert Executions.ZeroStride();
|
|
69
72
|
if (input.length == 0) revert Blocks.EmptyRun();
|
|
70
73
|
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
pragma solidity ^0.8.33;
|
|
3
|
+
|
|
4
|
+
import {Execution, Executions, CommandBase, Lanes, Specs} from "./Base.sol";
|
|
5
|
+
import {RepayHook} from "../core/Settlement.sol";
|
|
6
|
+
import {Action} from "../annotations/Action.sol";
|
|
7
|
+
import {Actions} from "../utils/Actions.sol";
|
|
8
|
+
|
|
9
|
+
using Executions for Execution;
|
|
10
|
+
|
|
11
|
+
/// @notice Hook implemented by hosts that repay position liabilities using native value.
|
|
12
|
+
abstract contract RepayPayableHook {
|
|
13
|
+
/// @notice Override to repay one liability for `account` with a shared value budget.
|
|
14
|
+
/// @param account Account whose liability is being repaid.
|
|
15
|
+
/// @param liability Identifier for the liability side.
|
|
16
|
+
/// @param debt Quantity on the liability side.
|
|
17
|
+
/// @param funds Mutable execution used only for its remaining native-value budget.
|
|
18
|
+
function repay(bytes32 account, bytes32 liability, uint debt, Execution memory funds) internal virtual;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/// @title Repay
|
|
22
|
+
/// @notice Command that repays POSITION liabilities and returns their assets as BALANCE state.
|
|
23
|
+
abstract contract Repay is CommandBase, RepayHook, Action {
|
|
24
|
+
uint private immutable descriptor;
|
|
25
|
+
|
|
26
|
+
constructor() {
|
|
27
|
+
uint id;
|
|
28
|
+
(id, descriptor) = command("repay", Specs.Position, Specs.Empty, Specs.Balance, 0, false, false);
|
|
29
|
+
action(id, Actions.Settle);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/// @notice Repay each POSITION liability and return its asset as BALANCE state.
|
|
33
|
+
/// @param state POSITION block stream.
|
|
34
|
+
/// @return BALANCE output state containing each released asset side.
|
|
35
|
+
/// @return Empty transaction stream.
|
|
36
|
+
function repay(
|
|
37
|
+
bytes32 account,
|
|
38
|
+
bytes calldata state,
|
|
39
|
+
bytes calldata input
|
|
40
|
+
) external onlyCommand returns (bytes memory, bytes memory) {
|
|
41
|
+
Execution memory exec = openCommand(state, input, descriptor, 0);
|
|
42
|
+
|
|
43
|
+
while (exec.more()) {
|
|
44
|
+
(bytes32 asset, uint amount, bytes32 liability, uint debt) = exec.unpackPosition(Lanes.State);
|
|
45
|
+
repay(account, liability, debt);
|
|
46
|
+
exec.outputBalance(asset, amount);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return close(exec, account);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/// @title RepayPayable
|
|
54
|
+
/// @notice Funded command that repays POSITION liabilities and returns their assets as BALANCE state.
|
|
55
|
+
abstract contract RepayPayable is CommandBase, RepayPayableHook, Action {
|
|
56
|
+
uint private immutable descriptor;
|
|
57
|
+
|
|
58
|
+
constructor() {
|
|
59
|
+
uint id;
|
|
60
|
+
(id, descriptor) = command("repayPayable", Specs.Position, Specs.Empty, Specs.Balance, 0, true, false);
|
|
61
|
+
action(id, Actions.Settle);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/// @notice Repay each POSITION liability and return its asset as BALANCE state.
|
|
65
|
+
/// @param state POSITION block stream.
|
|
66
|
+
/// @return BALANCE output state containing each released asset side.
|
|
67
|
+
/// @return Remaining native value as a refund transaction stream.
|
|
68
|
+
function repayPayable(
|
|
69
|
+
bytes32 account,
|
|
70
|
+
bytes calldata state,
|
|
71
|
+
bytes calldata input
|
|
72
|
+
) external payable onlyCommand returns (bytes memory, bytes memory) {
|
|
73
|
+
Execution memory exec = openCommand(state, input, descriptor, 0);
|
|
74
|
+
|
|
75
|
+
while (exec.more()) {
|
|
76
|
+
(bytes32 asset, uint amount, bytes32 liability, uint debt) = exec.unpackPosition(Lanes.State);
|
|
77
|
+
repay(account, liability, debt, exec);
|
|
78
|
+
exec.outputBalance(asset, amount);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return close(exec, account);
|
|
82
|
+
}
|
|
83
|
+
}
|
package/commands/Settle.sol
CHANGED
|
@@ -11,6 +11,25 @@ import {Reader, Readers} from "../codec/Readers.sol";
|
|
|
11
11
|
using Executions for Execution;
|
|
12
12
|
using Readers for Reader;
|
|
13
13
|
|
|
14
|
+
/// @notice Hook implemented by hosts that settle positions using native value.
|
|
15
|
+
abstract contract SettlePayableHook {
|
|
16
|
+
/// @notice Override to settle one position for `account` with a shared value budget.
|
|
17
|
+
/// @param account Account whose position is being settled.
|
|
18
|
+
/// @param asset Identifier for the asset side.
|
|
19
|
+
/// @param amount Quantity on the asset side.
|
|
20
|
+
/// @param liability Identifier for the liability side.
|
|
21
|
+
/// @param debt Quantity on the liability side.
|
|
22
|
+
/// @param funds Mutable execution used only for its remaining native-value budget.
|
|
23
|
+
function settle(
|
|
24
|
+
bytes32 account,
|
|
25
|
+
bytes32 asset,
|
|
26
|
+
uint amount,
|
|
27
|
+
bytes32 liability,
|
|
28
|
+
uint debt,
|
|
29
|
+
Execution memory funds
|
|
30
|
+
) internal virtual;
|
|
31
|
+
}
|
|
32
|
+
|
|
14
33
|
/// @title Settle
|
|
15
34
|
/// @notice Command that consumes POSITION state blocks through a virtual hook.
|
|
16
35
|
abstract contract Settle is CommandBase, SettleHook, Action {
|
|
@@ -47,6 +66,37 @@ abstract contract Settle is CommandBase, SettleHook, Action {
|
|
|
47
66
|
}
|
|
48
67
|
}
|
|
49
68
|
|
|
69
|
+
/// @title SettlePayable
|
|
70
|
+
/// @notice Funded command that consumes POSITION state blocks through a virtual hook.
|
|
71
|
+
abstract contract SettlePayable is CommandBase, SettlePayableHook, Action {
|
|
72
|
+
uint private immutable descriptor;
|
|
73
|
+
|
|
74
|
+
constructor() {
|
|
75
|
+
uint id;
|
|
76
|
+
(id, descriptor) = command("settlePayable", Specs.Position, Specs.Empty, Specs.Empty, 0, true, false);
|
|
77
|
+
action(id, Actions.Settle);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/// @notice Settle each POSITION block with access to a shared native-value budget.
|
|
81
|
+
/// @param state POSITION block stream.
|
|
82
|
+
/// @return Empty output state.
|
|
83
|
+
/// @return Remaining native value as a refund transaction stream.
|
|
84
|
+
function settlePayable(
|
|
85
|
+
bytes32 account,
|
|
86
|
+
bytes calldata state,
|
|
87
|
+
bytes calldata input
|
|
88
|
+
) external payable onlyCommand returns (bytes memory, bytes memory) {
|
|
89
|
+
Execution memory exec = openCommand(state, input, descriptor, 0);
|
|
90
|
+
|
|
91
|
+
while (exec.more()) {
|
|
92
|
+
(bytes32 asset, uint amount, bytes32 liability, uint debt) = exec.unpackPosition(Lanes.State);
|
|
93
|
+
settle(account, asset, amount, liability, debt, exec);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return close(exec, account);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
50
100
|
/// @title InternalSettle
|
|
51
101
|
/// @notice Extends the advertised settle command with memory-state pipeline dispatch.
|
|
52
102
|
/// @dev This adapter is not a separate command. It uses the command ID and settlement hook
|
|
@@ -56,13 +106,16 @@ abstract contract InternalSettle is Settle {
|
|
|
56
106
|
/// @param account Account for which each position is settled.
|
|
57
107
|
/// @param state POSITION block stream held in pipeline memory.
|
|
58
108
|
/// @param input Empty input required by the command schema.
|
|
109
|
+
/// @param value Native value assigned to the command; must be zero.
|
|
59
110
|
/// @return output Empty output state.
|
|
60
111
|
/// @return transactions Empty transaction stream.
|
|
61
112
|
function executeSettle(
|
|
62
113
|
bytes32 account,
|
|
63
114
|
bytes memory state,
|
|
64
|
-
bytes calldata input
|
|
115
|
+
bytes calldata input,
|
|
116
|
+
uint128 value
|
|
65
117
|
) internal returns (bytes memory, bytes memory) {
|
|
118
|
+
if (value != 0) revert ValueNotAllowed();
|
|
66
119
|
if (input.length != 0) revert Executions.ZeroStride();
|
|
67
120
|
if (state.length == 0) revert Blocks.EmptyRun();
|
|
68
121
|
|
|
@@ -12,7 +12,7 @@ abstract contract AllowanceHook {
|
|
|
12
12
|
/// or another host-specific authorization record.
|
|
13
13
|
/// @param peer Host node receiving the allowed cap.
|
|
14
14
|
/// @param asset Asset identifier.
|
|
15
|
-
/// @param amount Allowed cap amount.
|
|
15
|
+
/// @param amount Allowed cap amount. A zero amount MUST revoke the allowance.
|
|
16
16
|
function allowance(uint peer, bytes32 asset, uint amount) internal virtual;
|
|
17
17
|
}
|
|
18
18
|
|
package/core/Settlement.sol
CHANGED
|
@@ -28,22 +28,23 @@ abstract contract PostHook {
|
|
|
28
28
|
function post(bytes32 from, bytes32 to, bytes32 asset, uint amount) internal virtual;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
/// @title RepayHook
|
|
32
|
+
/// @notice Hook for repaying one account liability.
|
|
33
|
+
abstract contract RepayHook {
|
|
34
|
+
/// @notice Override to repay `debt` denominated in `liability` for `account`.
|
|
35
|
+
function repay(bytes32 account, bytes32 liability, uint debt) internal virtual;
|
|
36
|
+
}
|
|
37
|
+
|
|
31
38
|
/// @title SettleHook
|
|
32
39
|
/// @notice Hook for settling one asset-liability position.
|
|
33
40
|
abstract contract SettleHook {
|
|
34
41
|
/// @notice Override to settle one position for `account`.
|
|
35
|
-
function settle(
|
|
36
|
-
bytes32 account,
|
|
37
|
-
bytes32 asset,
|
|
38
|
-
uint amount,
|
|
39
|
-
bytes32 liability,
|
|
40
|
-
uint debt
|
|
41
|
-
) internal virtual;
|
|
42
|
+
function settle(bytes32 account, bytes32 asset, uint amount, bytes32 liability, uint debt) internal virtual;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
/// @title Settlement
|
|
45
46
|
/// @notice Default account-hook implementation for transaction posting and position settlement.
|
|
46
|
-
abstract contract Settlement is PostHook, SettleHook, DebitAccountHook, CreditAccountHook {
|
|
47
|
+
abstract contract Settlement is PostHook, SettleHook, RepayHook, DebitAccountHook, CreditAccountHook {
|
|
47
48
|
/// @notice Post one transaction by debiting its source and crediting its destination.
|
|
48
49
|
/// Returns without calling either hook when `amount` is zero and skips either
|
|
49
50
|
/// operation when the corresponding account is zero.
|
|
@@ -53,6 +54,12 @@ abstract contract Settlement is PostHook, SettleHook, DebitAccountHook, CreditAc
|
|
|
53
54
|
if (to != 0) creditAccount(to, asset, amount);
|
|
54
55
|
}
|
|
55
56
|
|
|
57
|
+
/// @notice Repay one liability by debiting it from the account.
|
|
58
|
+
/// Skips the debit when `debt` is zero.
|
|
59
|
+
function repay(bytes32 account, bytes32 liability, uint debt) internal virtual override {
|
|
60
|
+
if (debt != 0) debitAccount(account, liability, debt);
|
|
61
|
+
}
|
|
62
|
+
|
|
56
63
|
/// @notice Settle one position by crediting its asset and debiting its liability.
|
|
57
64
|
/// Skips either operation when its corresponding amount is zero.
|
|
58
65
|
function settle(
|
package/core/Types.sol
CHANGED
|
@@ -27,6 +27,14 @@ struct AccountAmount {
|
|
|
27
27
|
uint amount;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/// @notice Host-scoped asset shape.
|
|
31
|
+
struct HostAsset {
|
|
32
|
+
/// @dev Host node identifier.
|
|
33
|
+
uint host;
|
|
34
|
+
/// @dev Asset identifier.
|
|
35
|
+
bytes32 asset;
|
|
36
|
+
}
|
|
37
|
+
|
|
30
38
|
/// @notice Host-scoped asset and amount shape.
|
|
31
39
|
struct HostAmount {
|
|
32
40
|
/// @dev Host node identifier.
|
package/execution/Execution.sol
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {AssetAmount, AccountAsset, AccountAmount, HostAmount, HostAccountAsset, Position, Tx} from "../core/Types.sol";
|
|
4
|
+
import {AssetAmount, AccountAsset, HostAsset, AccountAmount, HostAmount, HostAccountAsset, Position, Tx} from "../core/Types.sol";
|
|
5
5
|
import {Blocks} from "../codec/Blocks.sol";
|
|
6
6
|
import {Buffers} from "../codec/Buffers.sol";
|
|
7
7
|
import {Sizes, Specs} from "../codec/Specs.sol";
|
|
@@ -287,6 +287,31 @@ library Executions {
|
|
|
287
287
|
(value.account, value.asset) = unpackAccountAsset(exec, lane);
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
+
/// @notice Decode and consume one HOST_ASSET block from `lane`.
|
|
291
|
+
/// @param exec Execution whose decoder is advanced.
|
|
292
|
+
/// @param lane Decoder lane to consume.
|
|
293
|
+
/// @return host Decoded host identifier.
|
|
294
|
+
/// @return asset Decoded asset identifier.
|
|
295
|
+
function unpackHostAsset(
|
|
296
|
+
Execution memory exec,
|
|
297
|
+
uint8 lane
|
|
298
|
+
) internal pure returns (uint host, bytes32 asset) {
|
|
299
|
+
uint abs;
|
|
300
|
+
(exec.decoders, abs) = exec.decoders.consume(lane, Sizes.HostAsset);
|
|
301
|
+
(host, asset) = Blocks.unpackHostAsset(abs);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/// @notice Decode one HOST_ASSET block into its structured value.
|
|
305
|
+
/// @param exec Execution whose decoder is advanced.
|
|
306
|
+
/// @param lane Decoder lane to consume.
|
|
307
|
+
/// @return value Decoded host and asset.
|
|
308
|
+
function unpackHostAssetValue(
|
|
309
|
+
Execution memory exec,
|
|
310
|
+
uint8 lane
|
|
311
|
+
) internal pure returns (HostAsset memory value) {
|
|
312
|
+
(value.host, value.asset) = unpackHostAsset(exec, lane);
|
|
313
|
+
}
|
|
314
|
+
|
|
290
315
|
/// @notice Decode and consume one AMOUNT block from `lane`.
|
|
291
316
|
/// @param exec Execution whose decoder is advanced.
|
|
292
317
|
/// @param lane Decoder lane to consume.
|
|
@@ -805,6 +830,15 @@ library Executions {
|
|
|
805
830
|
Blocks.writeAccountAsset(exec.output, i, account, asset);
|
|
806
831
|
}
|
|
807
832
|
|
|
833
|
+
/// @notice Append a HOST_ASSET block to execution output.
|
|
834
|
+
/// @param exec Execution receiving the block.
|
|
835
|
+
/// @param host Host identifier to encode.
|
|
836
|
+
/// @param asset Asset identifier to encode.
|
|
837
|
+
function outputHostAsset(Execution memory exec, uint host, bytes32 asset) internal pure {
|
|
838
|
+
uint i = reserve(exec, Sizes.HostAsset);
|
|
839
|
+
Blocks.writeHostAsset(exec.output, i, host, asset);
|
|
840
|
+
}
|
|
841
|
+
|
|
808
842
|
/// @notice Append an ALLOCATION block to execution output.
|
|
809
843
|
/// @param exec Execution receiving the block.
|
|
810
844
|
/// @param host Host identifier to encode.
|
package/guards/Revoke.sol
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
+
import {AllowanceHook} from "../commands/admin/Allowance.sol";
|
|
5
|
+
import {DenyAssetsHook} from "../commands/admin/DenyAssets.sol";
|
|
4
6
|
import {GuardBase} from "./Base.sol";
|
|
5
7
|
import {Specs} from "../Codec.sol";
|
|
6
8
|
import {Execution, Executions, Lanes} from "../execution/Execution.sol";
|
|
@@ -25,6 +27,47 @@ abstract contract Revoke is GuardBase {
|
|
|
25
27
|
uint node = exec.unpackNode(Lanes.Input);
|
|
26
28
|
setNode(node, false);
|
|
27
29
|
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/// @title RevokeAllowance
|
|
34
|
+
/// @notice Guardian action that revokes host-scoped asset allowances.
|
|
35
|
+
/// @dev Opt-in guard. Hosts expose it by inheriting this contract and implementing AllowanceHook.
|
|
36
|
+
abstract contract RevokeAllowance is GuardBase, AllowanceHook {
|
|
37
|
+
uint private immutable descriptor;
|
|
38
|
+
|
|
39
|
+
constructor() {
|
|
40
|
+
(, descriptor) = guard("revokeAllowance", Specs.HostAsset);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/// @notice Revoke every HOST_ASSET allowance in `input` as the active guardian.
|
|
44
|
+
function revokeAllowance(bytes calldata input) external onlyGuardian {
|
|
45
|
+
Execution memory exec = openInput(input, descriptor, 0);
|
|
28
46
|
|
|
47
|
+
while (exec.more()) {
|
|
48
|
+
(uint peer, bytes32 asset) = exec.unpackHostAsset(Lanes.Input);
|
|
49
|
+
allowance(peer, asset, 0);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/// @title RevokeAsset
|
|
55
|
+
/// @notice Guardian action that denies assets through the host's existing asset hook.
|
|
56
|
+
/// @dev Opt-in guard. Hosts expose it by inheriting this contract and implementing DenyAssetsHook.
|
|
57
|
+
abstract contract RevokeAsset is GuardBase, DenyAssetsHook {
|
|
58
|
+
uint private immutable descriptor;
|
|
59
|
+
|
|
60
|
+
constructor() {
|
|
61
|
+
(, descriptor) = guard("revokeAsset", Specs.Asset);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/// @notice Deny every ASSET block in `input` as the active guardian.
|
|
65
|
+
function revokeAsset(bytes calldata input) external onlyGuardian {
|
|
66
|
+
Execution memory exec = openInput(input, descriptor, 0);
|
|
67
|
+
|
|
68
|
+
while (exec.more()) {
|
|
69
|
+
bytes32 asset = exec.unpackAsset(Lanes.Input);
|
|
70
|
+
denyAsset(asset);
|
|
71
|
+
}
|
|
29
72
|
}
|
|
30
73
|
}
|