@rootzero/contracts 1.19.0 → 1.21.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 +73 -0
- package/Codec.sol +1 -1
- package/Commands.sol +1 -0
- package/Endpoints.sol +5 -4
- package/Events.sol +3 -2
- package/README.md +18 -12
- package/Utils.sol +0 -1
- package/codec/Decoders.sol +9 -1
- package/codec/Descriptors.sol +28 -28
- package/codec/Schema.sol +5 -5
- package/codec/Specs.sol +9 -27
- package/commands/Allocate.sol +1 -1
- package/commands/Base.sol +4 -10
- package/commands/Burn.sol +1 -1
- package/commands/Credit.sol +3 -3
- package/commands/Debit.sol +3 -3
- package/commands/Deposit.sol +3 -10
- package/commands/Payout.sol +1 -1
- package/commands/Provision.sol +3 -3
- package/commands/Recover.sol +3 -3
- package/commands/Relay.sol +20 -15
- package/commands/Repay.sol +3 -3
- package/commands/Settle.sol +5 -5
- package/commands/Withdraw.sol +1 -1
- package/commands/admin/AllowAssets.sol +2 -2
- package/commands/admin/Allowance.sol +2 -2
- package/commands/admin/Annotate.sol +2 -2
- package/commands/admin/Appoint.sol +2 -2
- package/commands/admin/Authorize.sol +2 -2
- package/commands/admin/Base.sol +1 -1
- package/commands/admin/DenyAssets.sol +2 -8
- package/commands/admin/Dismiss.sol +2 -2
- package/commands/admin/Execute.sol +2 -2
- package/commands/admin/Unauthorize.sol +2 -2
- package/core/Portal.sol +11 -8
- package/docs/Schema.md +53 -29
- package/events/Relay.sol +20 -0
- package/events/Resolved.sol +17 -0
- package/events/Unresolved.sol +18 -0
- package/execution/Execution.sol +10 -1
- package/guards/Base.sol +1 -2
- package/package.json +1 -1
- package/ports/AllowAssets.sol +1 -1
- package/ports/Allowance.sol +1 -1
- package/ports/Base.sol +4 -5
- package/ports/Credit.sol +1 -1
- package/ports/Debit.sol +1 -1
- package/ports/DenyAssets.sol +1 -1
- package/ports/Dispatch.sol +19 -7
- package/ports/Pipe.sol +2 -1
- package/ports/Post.sol +1 -1
- package/ports/Redeem.sol +1 -1
- package/queries/Base.sol +1 -2
- package/utils/Nodes.sol +21 -16
- package/events/Recovered.sol +0 -17
- package/events/Undelivered.sol +0 -18
- package/utils/Selectors.sol +0 -49
package/commands/Provision.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 {Execution, Executions, CommandBase, HostAmount, Lanes, Specs} from "./Base.sol";
|
|
4
|
+
import {Execution, Executions, CommandBase, Flags, HostAmount, Lanes, Specs} from "./Base.sol";
|
|
5
5
|
using Executions for Execution;
|
|
6
6
|
|
|
7
7
|
/// @notice Shared provision hook used by `Provision`.
|
|
@@ -32,7 +32,7 @@ abstract contract Provision is CommandBase, ProvisionHook {
|
|
|
32
32
|
uint private immutable descriptor;
|
|
33
33
|
|
|
34
34
|
constructor() {
|
|
35
|
-
(, descriptor) = command("provision", Specs.Empty, Specs.Allocation, Specs.Custody, 0,
|
|
35
|
+
(, descriptor) = command("provision", Specs.Empty, Specs.Allocation, Specs.Custody, 0, 0);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/// @notice Provision ALLOCATION input blocks and output matching CUSTODY state blocks.
|
|
@@ -64,7 +64,7 @@ abstract contract ProvisionPayable is CommandBase, ProvisionPayableHook {
|
|
|
64
64
|
uint private immutable descriptor;
|
|
65
65
|
|
|
66
66
|
constructor() {
|
|
67
|
-
(, descriptor) = command("provisionPayable", Specs.Empty, Specs.Allocation, Specs.Custody, 0,
|
|
67
|
+
(, descriptor) = command("provisionPayable", Specs.Empty, Specs.Allocation, Specs.Custody, 0, Flags.Funded);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/// @notice Provision ALLOCATION input blocks with access to a mutable native-value budget.
|
package/commands/Recover.sol
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {Execution, Executions, CommandBase, Lanes, Specs} from "./Base.sol";
|
|
4
|
+
import {Execution, Executions, CommandBase, Flags, Lanes, Specs} from "./Base.sol";
|
|
5
5
|
|
|
6
6
|
using Executions for Execution;
|
|
7
7
|
|
|
8
|
-
/// @notice Hook implemented by hosts that recover previously
|
|
8
|
+
/// @notice Hook implemented by hosts that recover previously unresolved payloads.
|
|
9
9
|
abstract contract RecoverPayableHook {
|
|
10
10
|
/// @notice Override to recover a witness through `handler`.
|
|
11
11
|
/// @param handler Port that should attempt recovery.
|
|
@@ -31,7 +31,7 @@ abstract contract RecoverPayable is CommandBase, RecoverPayableHook {
|
|
|
31
31
|
uint private immutable descriptor;
|
|
32
32
|
|
|
33
33
|
constructor() {
|
|
34
|
-
(, descriptor) = command("recoverPayable", Specs.Empty, Specs.Recover, Specs.Empty, 0,
|
|
34
|
+
(, descriptor) = command("recoverPayable", Specs.Empty, Specs.Recover, Specs.Empty, 0, Flags.Funded);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
/// @notice Recover each recover block in the command input.
|
package/commands/Relay.sol
CHANGED
|
@@ -1,20 +1,29 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {Execution, Executions, CommandBase, Flags, Lanes, Specs} from "./Base.sol";
|
|
5
5
|
|
|
6
6
|
using Executions for Execution;
|
|
7
7
|
|
|
8
|
-
/// @notice Hook implemented by hosts that
|
|
8
|
+
/// @notice Hook implemented by hosts that relay command contexts.
|
|
9
9
|
abstract contract RelayPayableHook {
|
|
10
|
-
/// @notice Override to relay
|
|
10
|
+
/// @notice Override to relay a command context to `portal`.
|
|
11
11
|
/// @param portal Destination portal identifier, often the destination host ID.
|
|
12
12
|
/// @param resources Chain-specific destination resources. EVM adapters
|
|
13
13
|
/// may interpret this as packed execution gas and destination value.
|
|
14
|
-
/// @param
|
|
14
|
+
/// @param account Destination command account.
|
|
15
|
+
/// @param state State forwarded into the destination context.
|
|
16
|
+
/// @param input Input forwarded into the destination context.
|
|
15
17
|
/// @param funds Execution used for source value available for transport fees
|
|
16
18
|
/// and destination resource funding.
|
|
17
|
-
function
|
|
19
|
+
function relay(
|
|
20
|
+
uint portal,
|
|
21
|
+
uint resources,
|
|
22
|
+
bytes32 account,
|
|
23
|
+
bytes calldata state,
|
|
24
|
+
bytes calldata input,
|
|
25
|
+
Execution memory funds
|
|
26
|
+
) internal virtual;
|
|
18
27
|
}
|
|
19
28
|
|
|
20
29
|
/// @title RelayPayable
|
|
@@ -23,7 +32,7 @@ abstract contract RelayPayable is CommandBase, RelayPayableHook {
|
|
|
23
32
|
uint private immutable descriptor;
|
|
24
33
|
|
|
25
34
|
constructor() {
|
|
26
|
-
(, descriptor) = command("relayPayable", Specs.Empty, Specs.Relay, Specs.Empty, 0,
|
|
35
|
+
(, descriptor) = command("relayPayable", Specs.Empty, Specs.Relay, Specs.Empty, 0, Flags.Funded);
|
|
27
36
|
}
|
|
28
37
|
|
|
29
38
|
/// @notice Relay one RELAY input block with the command account and empty state.
|
|
@@ -33,10 +42,8 @@ abstract contract RelayPayable is CommandBase, RelayPayableHook {
|
|
|
33
42
|
bytes calldata input
|
|
34
43
|
) external payable onlyCommand returns (bytes memory, bytes memory) {
|
|
35
44
|
Execution memory exec = openCommand(state, input, descriptor, 1);
|
|
36
|
-
(uint portal, uint resources, bytes calldata
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
relayTo(portal, resources, context, exec);
|
|
45
|
+
(uint portal, uint resources, bytes calldata relayInput) = exec.unpackRelay(Lanes.Input);
|
|
46
|
+
relay(portal, resources, account, state, relayInput, exec);
|
|
40
47
|
|
|
41
48
|
return close(exec, account);
|
|
42
49
|
}
|
|
@@ -51,7 +58,7 @@ abstract contract RelayBalancePayable is CommandBase, RelayPayableHook {
|
|
|
51
58
|
uint private immutable descriptor;
|
|
52
59
|
|
|
53
60
|
constructor() {
|
|
54
|
-
(, descriptor) = command("relayBalancePayable", Specs.Balance, Specs.Relay, Specs.Empty, 0,
|
|
61
|
+
(, descriptor) = command("relayBalancePayable", Specs.Balance, Specs.Relay, Specs.Empty, 0, Flags.Funded);
|
|
55
62
|
}
|
|
56
63
|
|
|
57
64
|
/// @notice Relay one RELAY input block with the command account and current state.
|
|
@@ -65,10 +72,8 @@ abstract contract RelayBalancePayable is CommandBase, RelayPayableHook {
|
|
|
65
72
|
bytes calldata input
|
|
66
73
|
) external payable onlyCommand returns (bytes memory, bytes memory) {
|
|
67
74
|
Execution memory exec = openCommand(state, input, descriptor, 1);
|
|
68
|
-
(uint portal, uint resources, bytes calldata
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
relayTo(portal, resources, context, exec);
|
|
75
|
+
(uint portal, uint resources, bytes calldata relayInput) = exec.unpackRelay(Lanes.Input);
|
|
76
|
+
relay(portal, resources, account, state, relayInput, exec);
|
|
72
77
|
|
|
73
78
|
return close(exec, account);
|
|
74
79
|
}
|
package/commands/Repay.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 {Execution, Executions, CommandBase, Lanes, Specs} from "./Base.sol";
|
|
4
|
+
import {Execution, Executions, CommandBase, Flags, Lanes, Specs} from "./Base.sol";
|
|
5
5
|
import {RepayHook} from "../core/Settlement.sol";
|
|
6
6
|
import {Action} from "../annotations/Action.sol";
|
|
7
7
|
import {Actions} from "../utils/Actions.sol";
|
|
@@ -25,7 +25,7 @@ abstract contract Repay is CommandBase, RepayHook, Action {
|
|
|
25
25
|
|
|
26
26
|
constructor() {
|
|
27
27
|
uint id;
|
|
28
|
-
(id, descriptor) = command("repay", Specs.Position, Specs.Empty, Specs.Balance, 0,
|
|
28
|
+
(id, descriptor) = command("repay", Specs.Position, Specs.Empty, Specs.Balance, 0, 0);
|
|
29
29
|
action(id, Actions.Settle);
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -57,7 +57,7 @@ abstract contract RepayPayable is CommandBase, RepayPayableHook, Action {
|
|
|
57
57
|
|
|
58
58
|
constructor() {
|
|
59
59
|
uint id;
|
|
60
|
-
(id, descriptor) = command("repayPayable", Specs.Position, Specs.Empty, Specs.Balance, 0,
|
|
60
|
+
(id, descriptor) = command("repayPayable", Specs.Position, Specs.Empty, Specs.Balance, 0, Flags.Funded);
|
|
61
61
|
action(id, Actions.Settle);
|
|
62
62
|
}
|
|
63
63
|
|
package/commands/Settle.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 {Execution, Executions, CommandBase, Lanes, Specs} from "./Base.sol";
|
|
4
|
+
import {Execution, Executions, CommandBase, Flags, Lanes, Specs} from "./Base.sol";
|
|
5
5
|
import {SettleHook} from "../core/Settlement.sol";
|
|
6
6
|
import {Action} from "../annotations/Action.sol";
|
|
7
7
|
import {Actions} from "../utils/Actions.sol";
|
|
@@ -37,7 +37,7 @@ abstract contract Settle is CommandBase, SettleHook, Action {
|
|
|
37
37
|
uint private immutable id;
|
|
38
38
|
|
|
39
39
|
constructor() {
|
|
40
|
-
(id, descriptor) = command("settle", Specs.Position, Specs.Empty, Specs.Empty, 0,
|
|
40
|
+
(id, descriptor) = command("settle", Specs.Position, Specs.Empty, Specs.Empty, 0, 0);
|
|
41
41
|
action(id, Actions.Settle);
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -73,7 +73,7 @@ abstract contract SettlePayable is CommandBase, SettlePayableHook, Action {
|
|
|
73
73
|
|
|
74
74
|
constructor() {
|
|
75
75
|
uint id;
|
|
76
|
-
(id, descriptor) = command("settlePayable", Specs.Position, Specs.Empty, Specs.Empty, 0,
|
|
76
|
+
(id, descriptor) = command("settlePayable", Specs.Position, Specs.Empty, Specs.Empty, 0, Flags.Funded);
|
|
77
77
|
action(id, Actions.Settle);
|
|
78
78
|
}
|
|
79
79
|
|
|
@@ -97,11 +97,11 @@ abstract contract SettlePayable is CommandBase, SettlePayableHook, Action {
|
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
/// @title
|
|
100
|
+
/// @title SettleInternal
|
|
101
101
|
/// @notice Extends the advertised settle command with memory-state pipeline dispatch.
|
|
102
102
|
/// @dev This adapter is not a separate command. It uses the command ID and settlement hook
|
|
103
103
|
/// inherited from `Settle` while accepting the state location used by `Pipeline`.
|
|
104
|
-
abstract contract
|
|
104
|
+
abstract contract SettleInternal is Settle {
|
|
105
105
|
/// @notice Execute the inherited settle command from an internal pipeline.
|
|
106
106
|
/// @param account Account for which each position is settled.
|
|
107
107
|
/// @param state POSITION block stream held in pipeline memory.
|
package/commands/Withdraw.sol
CHANGED
|
@@ -25,7 +25,7 @@ abstract contract Withdraw is CommandBase, WithdrawHook, Action {
|
|
|
25
25
|
|
|
26
26
|
constructor() {
|
|
27
27
|
uint id;
|
|
28
|
-
(id, descriptor) = command("withdraw", Specs.Balance, Specs.Empty, Specs.Empty, 0,
|
|
28
|
+
(id, descriptor) = command("withdraw", Specs.Balance, Specs.Empty, Specs.Empty, 0, 0);
|
|
29
29
|
action(id, Actions.Withdraw);
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import { AdminBase, Execution, Executions, Lanes, Specs } from "./Base.sol";
|
|
4
|
+
import { AdminBase, Execution, Executions, Flags, Lanes, Specs } from "./Base.sol";
|
|
5
5
|
using Executions for Execution;
|
|
6
6
|
|
|
7
7
|
/// @notice Hook implemented by hosts that allow assets.
|
|
@@ -19,7 +19,7 @@ abstract contract AllowAssets is AdminBase, AllowAssetsHook {
|
|
|
19
19
|
uint private immutable descriptor;
|
|
20
20
|
|
|
21
21
|
constructor() {
|
|
22
|
-
(, descriptor) = command("allowAssets", Specs.Empty, Specs.Asset, Specs.Empty, 0,
|
|
22
|
+
(, descriptor) = command("allowAssets", Specs.Empty, Specs.Asset, Specs.Empty, 0, Flags.Admin);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/// @notice Allow each ASSET block in the admin input.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {AdminBase, Execution, Executions, Lanes, Specs} from "./Base.sol";
|
|
4
|
+
import {AdminBase, Execution, Executions, Flags, Lanes, Specs} from "./Base.sol";
|
|
5
5
|
using Executions for Execution;
|
|
6
6
|
|
|
7
7
|
/// @notice Hook implemented by hosts that configure peer asset allowances.
|
|
@@ -23,7 +23,7 @@ abstract contract Allowance is AdminBase, AllowanceHook {
|
|
|
23
23
|
uint private immutable descriptor;
|
|
24
24
|
|
|
25
25
|
constructor() {
|
|
26
|
-
(, descriptor) = command("allowance", Specs.Empty, Specs.Allowance, Specs.Empty, 0,
|
|
26
|
+
(, descriptor) = command("allowance", Specs.Empty, Specs.Allowance, Specs.Empty, 0, Flags.Admin);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/// @notice Apply each ALLOWANCE block in the admin input.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {AdminBase, Execution, Executions, Lanes, Specs} from "./Base.sol";
|
|
4
|
+
import {AdminBase, Execution, Executions, Flags, Lanes, Specs} from "./Base.sol";
|
|
5
5
|
using Executions for Execution;
|
|
6
6
|
|
|
7
7
|
/// @title Annotate
|
|
@@ -12,7 +12,7 @@ abstract contract Annotate is AdminBase {
|
|
|
12
12
|
uint private immutable descriptor;
|
|
13
13
|
|
|
14
14
|
constructor() {
|
|
15
|
-
(, descriptor) = command("annotate", Specs.Empty, Specs.Annotation, Specs.Empty, 0,
|
|
15
|
+
(, descriptor) = command("annotate", Specs.Empty, Specs.Annotation, Specs.Empty, 0, Flags.Admin);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
/// @notice Publish each ANNOTATION block in the admin input.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import { AdminBase, Execution, Executions, Lanes, Specs } from "./Base.sol";
|
|
4
|
+
import { AdminBase, Execution, Executions, Flags, Lanes, Specs } from "./Base.sol";
|
|
5
5
|
import { GuardianAccess } from "../../core/Access.sol";
|
|
6
6
|
using Executions for Execution;
|
|
7
7
|
|
|
@@ -13,7 +13,7 @@ abstract contract Appoint is GuardianAccess, AdminBase {
|
|
|
13
13
|
uint private immutable descriptor;
|
|
14
14
|
|
|
15
15
|
constructor() {
|
|
16
|
-
(, descriptor) = command("appoint", Specs.Empty, Specs.Account, Specs.Empty, 0,
|
|
16
|
+
(, descriptor) = command("appoint", Specs.Empty, Specs.Account, Specs.Empty, 0, Flags.Admin);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/// @notice Appoint each user ACCOUNT block in the admin input as a guardian.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {AdminBase, Execution, Executions, Lanes, Specs} from "./Base.sol";
|
|
4
|
+
import {AdminBase, Execution, Executions, Flags, Lanes, Specs} from "./Base.sol";
|
|
5
5
|
using Executions for Execution;
|
|
6
6
|
|
|
7
7
|
/// @title Authorize
|
|
@@ -13,7 +13,7 @@ abstract contract Authorize is AdminBase {
|
|
|
13
13
|
uint private immutable id;
|
|
14
14
|
|
|
15
15
|
constructor() {
|
|
16
|
-
(id, descriptor) = command("authorize", Specs.Empty, Specs.Node, Specs.Empty, 0,
|
|
16
|
+
(id, descriptor) = command("authorize", Specs.Empty, Specs.Node, Specs.Empty, 0, Flags.Admin);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/// @notice Return the registered AUTHORIZE command ID.
|
package/commands/admin/Base.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 {CommandBase, Execution, Executions, Lanes, Specs} from "../Base.sol";
|
|
4
|
+
import {CommandBase, Execution, Executions, Flags, Lanes, Specs} from "../Base.sol";
|
|
5
5
|
import {NodeAccess} from "../../core/Access.sol";
|
|
6
6
|
|
|
7
7
|
/// @title AdminBase
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {AdminBase, Execution, Executions, Flags, Lanes, Specs} from "./Base.sol";
|
|
5
5
|
using Executions for Execution;
|
|
6
6
|
|
|
7
7
|
/// @notice Hook implemented by hosts that deny assets.
|
|
@@ -19,7 +19,7 @@ abstract contract DenyAssets is AdminBase, DenyAssetsHook {
|
|
|
19
19
|
uint private immutable descriptor;
|
|
20
20
|
|
|
21
21
|
constructor() {
|
|
22
|
-
(, descriptor) = command("denyAssets", Specs.Empty, Specs.Asset, Specs.Empty, 0,
|
|
22
|
+
(, descriptor) = command("denyAssets", Specs.Empty, Specs.Asset, Specs.Empty, 0, Flags.Admin);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/// @notice Deny each ASSET block in the admin input.
|
|
@@ -41,9 +41,3 @@ abstract contract DenyAssets is AdminBase, DenyAssetsHook {
|
|
|
41
41
|
return close(exec, account);
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import { AdminBase, Execution, Executions, Lanes, Specs } from "./Base.sol";
|
|
4
|
+
import { AdminBase, Execution, Executions, Flags, Lanes, Specs } from "./Base.sol";
|
|
5
5
|
import { GuardianAccess } from "../../core/Access.sol";
|
|
6
6
|
using Executions for Execution;
|
|
7
7
|
|
|
@@ -13,7 +13,7 @@ abstract contract Dismiss is GuardianAccess, AdminBase {
|
|
|
13
13
|
uint private immutable descriptor;
|
|
14
14
|
|
|
15
15
|
constructor() {
|
|
16
|
-
(, descriptor) = command("dismiss", Specs.Empty, Specs.Account, Specs.Empty, 0,
|
|
16
|
+
(, descriptor) = command("dismiss", Specs.Empty, Specs.Account, Specs.Empty, 0, Flags.Admin);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/// @notice Dismiss each user ACCOUNT block in the admin input from guardian status.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {AdminBase, Execution, Executions, Lanes, Specs} from "./Base.sol";
|
|
4
|
+
import {AdminBase, Execution, Executions, Flags, Lanes, Specs} from "./Base.sol";
|
|
5
5
|
import {RawNodeCalls} from "../../core/Calls.sol";
|
|
6
6
|
|
|
7
7
|
using Executions for Execution;
|
|
@@ -15,7 +15,7 @@ abstract contract ExecutePayable is RawNodeCalls, AdminBase {
|
|
|
15
15
|
uint private immutable descriptor;
|
|
16
16
|
|
|
17
17
|
constructor() {
|
|
18
|
-
(, descriptor) = command("executePayable", Specs.Empty, Specs.Call, Specs.Empty, 0,
|
|
18
|
+
(, descriptor) = command("executePayable", Specs.Empty, Specs.Call, Specs.Empty, 0, Flags.AdminFunded);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/// @notice Execute each CALL block in the admin input.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
|
-
import {AdminBase, Execution, Executions, Lanes, Specs} from "./Base.sol";
|
|
4
|
+
import {AdminBase, Execution, Executions, Flags, Lanes, Specs} from "./Base.sol";
|
|
5
5
|
using Executions for Execution;
|
|
6
6
|
|
|
7
7
|
/// @title Unauthorize
|
|
@@ -13,7 +13,7 @@ abstract contract Unauthorize is AdminBase {
|
|
|
13
13
|
uint private immutable id;
|
|
14
14
|
|
|
15
15
|
constructor() {
|
|
16
|
-
(id, descriptor) = command("unauthorize", Specs.Empty, Specs.Node, Specs.Empty, 0,
|
|
16
|
+
(id, descriptor) = command("unauthorize", Specs.Empty, Specs.Node, Specs.Empty, 0, Flags.Admin);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/// @notice Return the registered UNAUTHORIZE command ID.
|
package/core/Portal.sol
CHANGED
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
pragma solidity ^0.8.33;
|
|
3
3
|
|
|
4
4
|
import {PortCalls} from "./Calls.sol";
|
|
5
|
+
import {NodeAccess} from "./Access.sol";
|
|
6
|
+
import {ResolvedEvent} from "../events/Resolved.sol";
|
|
7
|
+
import {UnresolvedEvent} from "../events/Unresolved.sol";
|
|
5
8
|
|
|
6
9
|
/// @title Portal
|
|
7
10
|
/// @notice Base contract for hosts that route payloads through portal adapters.
|
|
8
|
-
abstract contract Portal is PortCalls {
|
|
11
|
+
abstract contract Portal is PortCalls, NodeAccess, UnresolvedEvent, ResolvedEvent {
|
|
9
12
|
error BadWitness();
|
|
10
13
|
|
|
11
|
-
mapping(bytes32 key => bytes32 digest) internal
|
|
14
|
+
mapping(bytes32 key => bytes32 digest) internal unresolved;
|
|
12
15
|
|
|
13
16
|
/// @notice Try to forward `message` to `port`.
|
|
14
17
|
/// @dev Records and returns `keccak256(message)` under `key` only when forwarding fails.
|
|
@@ -21,19 +24,19 @@ abstract contract Portal is PortCalls {
|
|
|
21
24
|
if (tryCallPort(port, value, message)) return bytes32(0);
|
|
22
25
|
|
|
23
26
|
miss = keccak256(message);
|
|
24
|
-
|
|
27
|
+
unresolved[key] = miss;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
/// @notice
|
|
30
|
+
/// @notice Resolve a previously unresolved witness through `port`.
|
|
28
31
|
/// @dev The witness must hash to the digest stored under `key`.
|
|
29
32
|
/// @param port Port that should attempt recovery.
|
|
30
33
|
/// @param key Recovery lookup key.
|
|
31
34
|
/// @param witness Witness payload used to prove and replay recovery.
|
|
32
|
-
/// @param value Native EVM value assigned to the
|
|
33
|
-
function
|
|
34
|
-
if (
|
|
35
|
+
/// @param value Native EVM value assigned to the resolution attempt.
|
|
36
|
+
function resolve(uint port, bytes32 key, bytes calldata witness, uint128 value) internal virtual {
|
|
37
|
+
if (unresolved[key] != keccak256(witness)) revert BadWitness();
|
|
35
38
|
|
|
36
|
-
delete
|
|
39
|
+
delete unresolved[key];
|
|
37
40
|
callPort(port, value, witness);
|
|
38
41
|
}
|
|
39
42
|
}
|
package/docs/Schema.md
CHANGED
|
@@ -50,8 +50,16 @@ overloaded in the relevant host/schema context.
|
|
|
50
50
|
|
|
51
51
|
## Block Syntax
|
|
52
52
|
|
|
53
|
-
A block definition has an event alias and a schema body.
|
|
54
|
-
|
|
53
|
+
A block definition has an event alias and a schema body. A schema body is one
|
|
54
|
+
of three forms:
|
|
55
|
+
|
|
56
|
+
```txt
|
|
57
|
+
"" empty or raw payload
|
|
58
|
+
{ fields } structured payload
|
|
59
|
+
many #item top-level custom list payload
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Fixed fields are written in braces:
|
|
55
63
|
|
|
56
64
|
```txt
|
|
57
65
|
alias: amount
|
|
@@ -66,9 +74,11 @@ A block body can reference another block alias as a child item with `#`:
|
|
|
66
74
|
|
|
67
75
|
The empty schema string `""` means the block has no structured payload. This is
|
|
68
76
|
used for zero-payload blocks such as `#unit` and raw dynamic blocks such as
|
|
69
|
-
`#bytes`.
|
|
77
|
+
`#bytes`. A root `many #item` body is reserved for an emitted custom schema
|
|
78
|
+
whose own key identifies the outer list block.
|
|
70
79
|
|
|
71
|
-
A schema body is a comma-separated list of items. Order is
|
|
80
|
+
A structured schema body is a comma-separated list of items. Order is
|
|
81
|
+
significant.
|
|
72
82
|
|
|
73
83
|
```txt
|
|
74
84
|
{ #amount, maybe #account as recipient }
|
|
@@ -110,11 +120,30 @@ maybe many #balance
|
|
|
110
120
|
|
|
111
121
|
- no prefix: one required item
|
|
112
122
|
- `maybe`: optional item
|
|
113
|
-
- `many`:
|
|
123
|
+
- `many`: a list whose payload contains repeated items
|
|
114
124
|
- `maybe many`: optional `#list` block
|
|
115
125
|
|
|
116
|
-
`maybe` emits no placeholder when absent.
|
|
117
|
-
generic list block; it does not repeat the
|
|
126
|
+
`maybe` emits no placeholder when absent. Inside a structured schema body,
|
|
127
|
+
`many` wraps repeated items in one generic `#list` block; it does not repeat the
|
|
128
|
+
item in place:
|
|
129
|
+
|
|
130
|
+
```txt
|
|
131
|
+
{ uint id, many #asset as assets }
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
When an emitted custom schema consists entirely of a top-level `many` item, the
|
|
135
|
+
custom schema key identifies the outer list block instead. Its payload contains
|
|
136
|
+
the repeated items directly:
|
|
137
|
+
|
|
138
|
+
```txt
|
|
139
|
+
schema key: 0x00000001
|
|
140
|
+
schema body: many #asset
|
|
141
|
+
wire value: [0x00000001][length][ASSET][ASSET]...
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
This convention gives a top-level list a discoverable, context-local type while
|
|
145
|
+
retaining the generic `#list` key for lists whose type is supplied by an
|
|
146
|
+
enclosing schema.
|
|
118
147
|
|
|
119
148
|
## Endpoint Lanes
|
|
120
149
|
|
|
@@ -128,33 +157,28 @@ The packed descriptor uses these lane layouts:
|
|
|
128
157
|
|
|
129
158
|
```txt
|
|
130
159
|
state [key:4][group:1]
|
|
131
|
-
input [key:4][
|
|
132
|
-
output [key:4][min:4][max:4][hint:
|
|
160
|
+
input [key:4][group:1]
|
|
161
|
+
output [key:4][min:4][max:4][hint:3][group:1]
|
|
162
|
+
reserve [reserved:4]
|
|
163
|
+
tx [transactions:1]
|
|
164
|
+
flags [flags:1]
|
|
133
165
|
```
|
|
134
166
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
spec
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
output decoder returns this as a left-aligned, writer-ready spec that retains
|
|
143
|
-
its encoded group. Its container and reserved fields are cleared. `Specs.group`
|
|
144
|
-
returns the effective group, interpreting an encoded zero as one for a
|
|
145
|
-
non-empty spec.
|
|
167
|
+
Each lane directly identifies its top-level block key. Output lanes retain their
|
|
168
|
+
size bounds and allocation hint so execution can reconstruct the output spec and
|
|
169
|
+
initialize its writer directly. Four descriptor-level bytes are reserved after
|
|
170
|
+
the lane metadata. The Solidity output decoder returns a left-aligned,
|
|
171
|
+
writer-ready spec that retains its encoded group and clears its reserved fields.
|
|
172
|
+
`Specs.group` returns the effective group, interpreting an encoded zero as one
|
|
173
|
+
for a non-empty spec.
|
|
146
174
|
|
|
147
175
|
Any non-empty lane resolves its key to a block alias and schema body through the
|
|
148
|
-
active schema context.
|
|
149
|
-
|
|
150
|
-
discovery metadata because it does not say what the list contains; indexers
|
|
151
|
-
should reject it for self-describing endpoints.
|
|
176
|
+
active schema context. A top-level list lane uses the key of its emitted custom
|
|
177
|
+
`many` schema; the descriptor treats it like every other direct lane spec.
|
|
152
178
|
|
|
153
179
|
The lane key is the prime item. Prime items may repeat at the top level for
|
|
154
|
-
batching.
|
|
155
|
-
|
|
156
|
-
top-level items are globals for the whole batch and are not counted as
|
|
157
|
-
per-operation prime blocks.
|
|
180
|
+
batching. Later top-level items are globals for the whole batch and are not
|
|
181
|
+
counted as per-operation prime blocks.
|
|
158
182
|
|
|
159
183
|
The prime item cannot be optional. If an endpoint needs a per-operation marker
|
|
160
184
|
with no payload, use a zero-payload block such as `#unit`.
|
|
@@ -369,7 +393,7 @@ invalid in any path segment.
|
|
|
369
393
|
|
|
370
394
|
- `#bytes`: raw dynamic bytes, written without a body
|
|
371
395
|
- `#string`: UTF-8 string bytes, written without a body
|
|
372
|
-
- `#list`: generic list wrapper emitted by `many`
|
|
396
|
+
- `#list`: generic list wrapper emitted by nested `many`
|
|
373
397
|
|
|
374
398
|
Custom input shapes should define their own context-local block spec and publish
|
|
375
399
|
it with a `#schema` annotation. Endpoint contracts can use `schema(...)` to
|
package/events/Relay.sol
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
pragma solidity ^0.8.33;
|
|
3
|
+
|
|
4
|
+
import {EventEmitter} from "./Emitter.sol";
|
|
5
|
+
|
|
6
|
+
/// @notice Emitted when an account records an outbound relay reference.
|
|
7
|
+
abstract contract RelayEvent is EventEmitter {
|
|
8
|
+
string private constant ABI = "event Relay(bytes32 indexed account, uint portal, uint resources, bytes32 key, bytes32 digest)";
|
|
9
|
+
|
|
10
|
+
/// @param account Account that owns the relayed context.
|
|
11
|
+
/// @param portal Destination portal identifier, often the destination host ID.
|
|
12
|
+
/// @param resources Chain-specific resources assigned to the relay.
|
|
13
|
+
/// @param key Relay correlation or recovery lookup key.
|
|
14
|
+
/// @param digest Digest of the relayed payload or canonical envelope.
|
|
15
|
+
event Relay(bytes32 indexed account, uint portal, uint resources, bytes32 key, bytes32 digest);
|
|
16
|
+
|
|
17
|
+
constructor() {
|
|
18
|
+
emit EventAbi(ABI);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
pragma solidity ^0.8.33;
|
|
3
|
+
|
|
4
|
+
import {EventEmitter} from "./Emitter.sol";
|
|
5
|
+
|
|
6
|
+
/// @notice Emitted when a host resolves a previously recorded key.
|
|
7
|
+
abstract contract ResolvedEvent is EventEmitter {
|
|
8
|
+
string private constant ABI = "event Resolved(uint indexed host, bytes32 key)";
|
|
9
|
+
|
|
10
|
+
/// @param host Host node ID that owns the resolved key.
|
|
11
|
+
/// @param key Resolution lookup key.
|
|
12
|
+
event Resolved(uint indexed host, bytes32 key);
|
|
13
|
+
|
|
14
|
+
constructor() {
|
|
15
|
+
emit EventAbi(ABI);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
pragma solidity ^0.8.33;
|
|
3
|
+
|
|
4
|
+
import {EventEmitter} from "./Emitter.sol";
|
|
5
|
+
|
|
6
|
+
/// @notice Emitted when a host records a portal message awaiting resolution.
|
|
7
|
+
abstract contract UnresolvedEvent is EventEmitter {
|
|
8
|
+
string private constant ABI = "event Unresolved(uint indexed host, bytes32 key, bytes32 digest)";
|
|
9
|
+
|
|
10
|
+
/// @param host Host node ID that owns the unresolved message.
|
|
11
|
+
/// @param key Resolution lookup key.
|
|
12
|
+
/// @param digest Digest of the unresolved message.
|
|
13
|
+
event Unresolved(uint indexed host, bytes32 key, bytes32 digest);
|
|
14
|
+
|
|
15
|
+
constructor() {
|
|
16
|
+
emit EventAbi(ABI);
|
|
17
|
+
}
|
|
18
|
+
}
|
package/execution/Execution.sol
CHANGED
|
@@ -227,7 +227,16 @@ library Executions {
|
|
|
227
227
|
/// @param lane Decoder lane containing the LIST block.
|
|
228
228
|
/// @return items Cursor over the nested list items.
|
|
229
229
|
function list(Execution memory exec, uint8 lane) internal pure returns (Cur memory items) {
|
|
230
|
-
|
|
230
|
+
return list(exec, Specs.List, lane);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/// @notice Consume a list block described by `spec` and return a cursor scoped to its payload.
|
|
234
|
+
/// @param exec Execution whose decoder is advanced.
|
|
235
|
+
/// @param spec Custom list block specification.
|
|
236
|
+
/// @param lane Decoder lane containing the list block.
|
|
237
|
+
/// @return items Cursor over the nested list items.
|
|
238
|
+
function list(Execution memory exec, uint spec, uint8 lane) internal pure returns (Cur memory items) {
|
|
239
|
+
(uint abs, uint end) = consume(exec, lane, spec);
|
|
231
240
|
items.state = Cursors.create(abs, end - abs, 0, 0, 0);
|
|
232
241
|
}
|
|
233
242
|
|