@bananapus/omnichain-deployers-v6 0.0.27 → 0.0.29
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/ADMINISTRATION.md +10 -59
- package/ARCHITECTURE.md +11 -90
- package/AUDIT_INSTRUCTIONS.md +8 -63
- package/README.md +11 -13
- package/RISKS.md +57 -46
- package/SKILLS.md +10 -29
- package/USER_JOURNEYS.md +31 -110
- package/package.json +7 -7
- package/script/Deploy.s.sol +8 -1
- package/src/JBOmnichainDeployer.sol +20 -7
- package/test/JBOmnichainDeployer.t.sol +2 -12
- package/test/JBOmnichainDeployerGuard.t.sol +1 -0
- package/test/OmnichainDeployerAttacks.t.sol +3 -1
- package/test/OmnichainDeployerEdgeCases.t.sol +4 -11
- package/test/TestAuditGaps.sol +4 -18
- package/test/Tiered721HookComposition.t.sol +2 -4
- package/test/audit/AuditFixesC2H6M14.t.sol +495 -0
- package/test/audit/CarryForwardRejectedHook.t.sol +1 -0
- package/test/audit/CodexNemesisAudit.t.sol +21 -10
- package/test/audit/CodexNemesisDeterministicDrift.t.sol +78 -0
- package/test/audit/CodexNemesisDeterministicPeerDrift.t.sol +79 -0
- package/test/audit/CodexNemesisForwardedPermissions.t.sol +297 -0
- package/test/audit/CodexNemesisNftCashoutSupplyMismatch.t.sol +222 -0
- package/test/audit/JBOmnichainDeployer.t.sol +10 -6
- package/test/audit/WeightScalingComparison.t.sol +3 -1
- package/test/fork/OmnichainForkTestBase.sol +3 -2
- package/test/invariants/CrossChainDeployerInvariant.t.sol +204 -0
- package/test/invariants/handlers/CrossChainDeployerHandler.sol +395 -0
- package/test/regression/EmptyRulesetConfigurations.t.sol +3 -5
- package/test/regression/HookOwnershipTransfer.t.sol +2 -5
- package/test/regression/ValidateController.t.sol +3 -11
package/ADMINISTRATION.md
CHANGED
|
@@ -4,75 +4,26 @@
|
|
|
4
4
|
|
|
5
5
|
| Item | Details |
|
|
6
6
|
| --- | --- |
|
|
7
|
-
| Scope | Omnichain
|
|
8
|
-
| Control posture | Mixed deployer
|
|
9
|
-
| Highest-risk actions |
|
|
10
|
-
| Recovery posture |
|
|
7
|
+
| Scope | Omnichain launch orchestration and wrapper behavior |
|
|
8
|
+
| Control posture | Mixed deployer logic, project permissions, and registry trust |
|
|
9
|
+
| Highest-risk actions | Wrong hook composition, wrong sucker wiring, and bad registry trust |
|
|
10
|
+
| Recovery posture | Often requires redeploying or re-launching around bad wiring |
|
|
11
11
|
|
|
12
12
|
## Purpose
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
This repo controls how omnichain projects are launched and wrapped, not the low-level runtime logic of suckers or 721 hooks.
|
|
15
15
|
|
|
16
16
|
## Control Model
|
|
17
17
|
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
- Sucker deployment requires project-local `DEPLOY_SUCKERS` permission.
|
|
22
|
-
- Hook composition data is stored by ruleset and then used at runtime.
|
|
23
|
-
|
|
24
|
-
## Roles
|
|
25
|
-
|
|
26
|
-
| Role | How Assigned | Scope | Notes |
|
|
27
|
-
| --- | --- | --- | --- |
|
|
28
|
-
| Project owner | `JBProjects.ownerOf(projectId)` | Per project | Can delegate through `JBPermissions` |
|
|
29
|
-
| Project operator | `JBPermissions` grant | Per project | Often `DEPLOY_SUCKERS`, `QUEUE_RULESETS`, `LAUNCH_RULESETS`, `SET_TERMINALS` |
|
|
30
|
-
| `JBOmnichainDeployer` | Immutable singleton | Global | Launch helper and runtime wrapper |
|
|
31
|
-
| `SUCKER_REGISTRY` | Immutable dependency | Global | Receives wildcard `MAP_SUCKER_TOKEN` from the deployer |
|
|
32
|
-
|
|
33
|
-
## Privileged Surfaces
|
|
34
|
-
|
|
35
|
-
| Contract | Function | Who Can Call | Effect |
|
|
36
|
-
| --- | --- | --- | --- |
|
|
37
|
-
| `JBOmnichainDeployer` | `deploySuckersFor(...)` | Project owner or `DEPLOY_SUCKERS` delegate | Extends an existing project with suckers |
|
|
38
|
-
| `JBOmnichainDeployer` | `launchProjectFor(...)` | Anyone | Launches a new omnichain-shaped project |
|
|
39
|
-
| `JBOmnichainDeployer` | `launchRulesetsFor(...)` | Project owner or relevant delegates | Launches rulesets for an existing project |
|
|
40
|
-
| `JBOmnichainDeployer` | `queueRulesetsOf(...)` | Project owner or `QUEUE_RULESETS` delegate | Queues rulesets and stores runtime wrapper config |
|
|
41
|
-
|
|
42
|
-
## Immutable And One-Way
|
|
43
|
-
|
|
44
|
-
- Constructor dependencies are immutable.
|
|
45
|
-
- Ruleset-keyed hook configuration becomes the runtime source of truth once stored.
|
|
46
|
-
- Deterministic sucker deployment assumptions depend on stable salts and deployer config.
|
|
47
|
-
- The deployer's wildcard grant to `SUCKER_REGISTRY` is structural.
|
|
48
|
-
|
|
49
|
-
## Operational Notes
|
|
50
|
-
|
|
51
|
-
- Review launch and runtime-wrapper behavior together for every admin change.
|
|
52
|
-
- Validate controller matching on existing-project flows before launch or queue operations.
|
|
53
|
-
- Treat hook-order changes as runtime behavior changes, not just deployment metadata changes.
|
|
54
|
-
- Arrange token-mapping authority for the registry before using the end-to-end sucker deployment path.
|
|
55
|
-
|
|
56
|
-
## Machine Notes
|
|
57
|
-
|
|
58
|
-
- Do not treat this repo as deployment-only; queued wrapper config is a live runtime input.
|
|
59
|
-
- Inspect `src/JBOmnichainDeployer.sol` alongside project rulesets before assuming current behavior.
|
|
60
|
-
- If directory/controller state and stored wrapper config diverge, stop and resolve the mismatch before further admin actions.
|
|
18
|
+
- launch paths are largely permissionless for new projects
|
|
19
|
+
- later ruleset changes depend on project permissions
|
|
20
|
+
- registry and sucker trust surfaces can widen authority if misconfigured
|
|
61
21
|
|
|
62
22
|
## Recovery
|
|
63
23
|
|
|
64
|
-
-
|
|
65
|
-
- If the wrong deterministic deployment assumptions or constructor dependencies were used, recover with replacement infra.
|
|
24
|
+
- bad launch wiring usually means a new deployment path rather than a local patch
|
|
66
25
|
|
|
67
26
|
## Admin Boundaries
|
|
68
27
|
|
|
69
|
-
-
|
|
70
|
-
- It cannot mutate constructor immutables after deployment.
|
|
71
|
-
- It does not own core treasury accounting or project ownership semantics outside the flows it wraps.
|
|
72
|
-
|
|
73
|
-
## Source Map
|
|
28
|
+
- this repo does not override locked runtime behavior in sibling repos
|
|
74
29
|
|
|
75
|
-
- `src/JBOmnichainDeployer.sol`
|
|
76
|
-
- `src/interfaces/IJBOmnichainDeployer.sol`
|
|
77
|
-
- `src/structs/`
|
|
78
|
-
- `test/`
|
package/ARCHITECTURE.md
CHANGED
|
@@ -2,109 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
## Purpose
|
|
4
4
|
|
|
5
|
-
`nana-omnichain-deployers-v6`
|
|
5
|
+
`nana-omnichain-deployers-v6` packages a Juicebox project, a 721 hook, and sucker deployment into one omnichain launch surface.
|
|
6
6
|
|
|
7
7
|
## System Overview
|
|
8
8
|
|
|
9
|
-
`JBOmnichainDeployer`
|
|
9
|
+
`JBOmnichainDeployer` launches the project, stores per-ruleset hook composition, and wraps sucker behavior so bridge-triggered flows can bypass project-specific logic where intended.
|
|
10
10
|
|
|
11
11
|
## Core Invariants
|
|
12
12
|
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
- This wrapper always becomes the on-chain ruleset data hook and forces both pay and cash-out callbacks through itself before delegating internally.
|
|
18
|
-
- Extra pay hooks must see only the post-721 project amount and the 721-adjusted weight, not the raw terminal payment context.
|
|
19
|
-
- Queue-path carry-forward must prefer the latest approved queued ruleset over the current active ruleset when recovering hook config.
|
|
20
|
-
|
|
21
|
-
## Modules
|
|
22
|
-
|
|
23
|
-
| Module | Responsibility | Notes |
|
|
24
|
-
| --- | --- | --- |
|
|
25
|
-
| `JBOmnichainDeployer` | Launch, queue rulesets, compose hooks, and grant sucker-safe behavior | Deployer and runtime wrapper |
|
|
26
|
-
| config structs | 721 config, extra hook config, and sucker deployment config | Launch-time inputs |
|
|
27
|
-
| `IJBOmnichainDeployer` | External launch and inspection interface | Public surface |
|
|
13
|
+
- launch wiring must match the intended omnichain project shape
|
|
14
|
+
- hook composition must stay consistent with the created ruleset IDs
|
|
15
|
+
- sucker-specific privileged paths must remain limited to trusted suckers
|
|
16
|
+
- project NFT ownership and hook ownership must end in the intended place
|
|
28
17
|
|
|
29
18
|
## Trust Boundaries
|
|
30
19
|
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
- Project-following ownership behavior comes from `nana-ownable-v6`.
|
|
35
|
-
|
|
36
|
-
## Critical Flows
|
|
37
|
-
|
|
38
|
-
### Launch
|
|
39
|
-
|
|
40
|
-
```text
|
|
41
|
-
caller
|
|
42
|
-
-> launches a project or queues rulesets through the deployer
|
|
43
|
-
-> deployer installs itself as the ruleset data hook
|
|
44
|
-
-> deploys or carries forward the 721 hook
|
|
45
|
-
-> optionally deploys sucker pairs with deterministic salts
|
|
46
|
-
-> transfers project ownership to the intended owner
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### Queue With Carry-Forward
|
|
50
|
-
|
|
51
|
-
```text
|
|
52
|
-
caller
|
|
53
|
-
-> queues a new ruleset without new tiers
|
|
54
|
-
-> deployer selects carry-forward hook config from the latest approved queued ruleset when present
|
|
55
|
-
-> otherwise falls back to the current active ruleset
|
|
56
|
-
-> preserves useDataHookForCashOut from the chosen source ruleset
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### Runtime Wrapping
|
|
60
|
-
|
|
61
|
-
```text
|
|
62
|
-
runtime callback
|
|
63
|
-
-> if the actor is a registered sucker, return the bridge-safe tax-free and mint-enabled path
|
|
64
|
-
-> otherwise run the 721 hook first when configured
|
|
65
|
-
-> pass the extra pay hook only the post-split project amount and 721-adjusted weight
|
|
66
|
-
-> then run the optional extra hook
|
|
67
|
-
-> merge and return the resulting specs
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
## Accounting Model
|
|
71
|
-
|
|
72
|
-
This repo does not own the treasury ledger. Its critical state is hook configuration and ruleset-keyed carry-forward data that determine how downstream accounting hooks are composed.
|
|
73
|
-
|
|
74
|
-
The wrapper also computes cross-chain cash-out context for non-sucker paths by augmenting local supply and surplus with remote sucker snapshots. Inner hooks may adjust tax rate or counts, but this repo keeps the omnichain supply/surplus view authoritative.
|
|
20
|
+
- bridge runtime trust lives in `nana-suckers-v6`
|
|
21
|
+
- 721 runtime trust lives in `nana-721-hook-v6`
|
|
22
|
+
- this repo mainly owns orchestration and wrapper semantics
|
|
75
23
|
|
|
76
24
|
## Security Model
|
|
77
25
|
|
|
78
|
-
-
|
|
79
|
-
-
|
|
80
|
-
- The sucker exception path intentionally short-circuits normal composition and should stay easy to reason about.
|
|
81
|
-
- Suckers have two privileged behaviors by design: tax-free bridge cash-outs and unconditional mint permission. Those exceptions must remain tightly scoped to registry-recognized sucker addresses.
|
|
82
|
-
- Salt derivation includes `_msgSender()` for replay protection. Cross-chain deterministic matching therefore depends on using the same sender on each chain.
|
|
83
|
-
- Because this repo is both deployer and runtime hook, permission or hook-order changes can break already-launched projects, not just future launches.
|
|
84
|
-
|
|
85
|
-
## Safe Change Guide
|
|
86
|
-
|
|
87
|
-
- Review launch logic and runtime wrapper logic together.
|
|
88
|
-
- If hook composition changes, test payment and cash-out ordering explicitly.
|
|
89
|
-
- If ruleset prediction changes, test same-block and queued-ruleset edge cases.
|
|
90
|
-
- If sucker exceptions or mint-permission behavior change, re-check bridge flows against normal custom-hook policy.
|
|
91
|
-
- If salt derivation changes, re-check deterministic cross-chain deployment expectations and replay resistance together.
|
|
92
|
-
- If wrapper metadata behavior changes, re-check the forced `useDataHookForPay/useDataHookForCashOut` install path and the extra-hook context shaping together.
|
|
93
|
-
- Keep salt handling stable across chains when deterministic address expectations matter.
|
|
94
|
-
|
|
95
|
-
## Canonical Checks
|
|
96
|
-
|
|
97
|
-
- hook ordering and composition correctness:
|
|
98
|
-
`test/Tiered721HookComposition.t.sol`
|
|
99
|
-
- carry-forward and queued-ruleset recovery behavior:
|
|
100
|
-
`test/audit/CarryForwardRejectedHook.t.sol`
|
|
101
|
-
- wrapper invariants under adversarial sequences:
|
|
102
|
-
`test/invariants/OmnichainDeployerInvariant.t.sol`
|
|
26
|
+
- the main risks are hook composition, ruleset ID prediction, and registry-trusted sucker bypasses
|
|
27
|
+
- this repo is not the source of underlying bridge or 721 behavior, but it can wire them together incorrectly
|
|
103
28
|
|
|
104
29
|
## Source Map
|
|
105
30
|
|
|
106
31
|
- `src/JBOmnichainDeployer.sol`
|
|
107
|
-
- `src/structs/`
|
|
108
|
-
- `test/Tiered721HookComposition.t.sol`
|
|
109
|
-
- `test/audit/CarryForwardRejectedHook.t.sol`
|
|
110
|
-
- `test/invariants/OmnichainDeployerInvariant.t.sol`
|
package/AUDIT_INSTRUCTIONS.md
CHANGED
|
@@ -1,81 +1,26 @@
|
|
|
1
1
|
# Audit Instructions
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Audit this repo as an orchestration layer that composes 721 hooks, suckers, and optional extra data hooks.
|
|
4
4
|
|
|
5
5
|
## Audit Objective
|
|
6
6
|
|
|
7
7
|
Find issues that:
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
- create
|
|
8
|
+
|
|
9
|
+
- launch the wrong project shape
|
|
10
|
+
- miscompose hooks or wrapper behavior
|
|
11
|
+
- grant privileged sucker behavior to the wrong addresses
|
|
12
|
+
- create cross-chain drift or bad deterministic assumptions
|
|
13
13
|
|
|
14
14
|
## Scope
|
|
15
15
|
|
|
16
16
|
In scope:
|
|
17
|
-
- `src/JBOmnichainDeployer.sol`
|
|
18
|
-
- `src/interfaces/`
|
|
19
|
-
- `src/structs/`
|
|
20
|
-
- deployment scripts in `script/`
|
|
21
17
|
|
|
22
|
-
|
|
23
|
-
- `
|
|
24
|
-
- `nana-721-hook-v6`
|
|
25
|
-
- `nana-suckers-v6`
|
|
18
|
+
- `src/JBOmnichainDeployer.sol`
|
|
19
|
+
- related tests under `test/`
|
|
26
20
|
|
|
27
21
|
## Start Here
|
|
28
22
|
|
|
29
23
|
1. `src/JBOmnichainDeployer.sol`
|
|
30
|
-
2. `script/Deploy.s.sol`
|
|
31
|
-
3. `script/helpers/DeployersDeploymentLib.sol`
|
|
32
|
-
|
|
33
|
-
## Security Model
|
|
34
|
-
|
|
35
|
-
`JBOmnichainDeployer` is a launch surface that can:
|
|
36
|
-
- create a new Juicebox project
|
|
37
|
-
- deploy and configure a 721 hook
|
|
38
|
-
- configure rulesets and terminals
|
|
39
|
-
- deploy suckers and register them for the project
|
|
40
|
-
- participate in pay or cash-out accounting as a data hook where needed
|
|
41
|
-
|
|
42
|
-
## Roles And Privileges
|
|
43
|
-
|
|
44
|
-
| Role | Powers | How constrained |
|
|
45
|
-
|------|--------|-----------------|
|
|
46
|
-
| Launch caller | Supply desired project configuration | Should receive exactly the requested state |
|
|
47
|
-
| Omnichain deployer | Create hooks, projects, and sucker composition | Must relinquish setup authority after launch |
|
|
48
|
-
| Sucker registry | Grant omnichain-specific privileges | Must not bless arbitrary contracts |
|
|
49
|
-
|
|
50
|
-
## Integration Assumptions
|
|
51
|
-
|
|
52
|
-
| Dependency | Assumption | What breaks if wrong |
|
|
53
|
-
|------------|------------|----------------------|
|
|
54
|
-
| `nana-core-v6` | Launch and ruleset surfaces are authentic | Deployed economics drift from requested config |
|
|
55
|
-
| `nana-721-hook-v6` | Hook ownership and tier setup complete correctly | Collection state or authority is wrong |
|
|
56
|
-
| `nana-suckers-v6` | Registry identifies genuine peers | Fee or mint exemptions widen incorrectly |
|
|
57
|
-
|
|
58
|
-
## Critical Invariants
|
|
59
|
-
|
|
60
|
-
1. Launch configuration is faithful
|
|
61
|
-
The deployed project must end up with the exact hook, ruleset, and ownership configuration the caller requested.
|
|
62
|
-
|
|
63
|
-
2. Sucker privileges stay restricted
|
|
64
|
-
Zero-tax or mint-permission behavior intended for legitimate suckers must not be reachable by arbitrary contracts or stale registry entries.
|
|
65
|
-
|
|
66
|
-
3. Weight and accounting scaling are correct
|
|
67
|
-
If the deployer proxies or modifies hook outputs, the resulting project token issuance and reclaim math must still match intended economics.
|
|
68
|
-
|
|
69
|
-
4. Ownership transfer is complete
|
|
70
|
-
Deployer-created hooks and helper contracts must not retain silent control after initialization.
|
|
71
|
-
|
|
72
|
-
## Attack Surfaces
|
|
73
|
-
|
|
74
|
-
- malformed launch configuration
|
|
75
|
-
- hook and sucker ownership transfer
|
|
76
|
-
- registry-based privilege spoofing
|
|
77
|
-
- reentrancy around launch and initialization
|
|
78
|
-
- local-only launches versus omnichain launches with optional components disabled
|
|
79
24
|
|
|
80
25
|
## Verification
|
|
81
26
|
|
package/README.md
CHANGED
|
@@ -24,8 +24,6 @@ The wrapper exists so sucker-triggered flows can be exempted from project-specif
|
|
|
24
24
|
|
|
25
25
|
Use this repo when the default project shape is "Juicebox project plus 721 hook plus cross-chain bridge." Do not use it when a project is single-chain or does not need the wrapper semantics around suckers.
|
|
26
26
|
|
|
27
|
-
If the question is "how do suckers bridge?" start in `nana-suckers-v6`. If the question is "how does a 721 hook behave?" start in `nana-721-hook-v6`. This repo is where those components are packaged together and wrapped.
|
|
28
|
-
|
|
29
27
|
## Key Contract
|
|
30
28
|
|
|
31
29
|
| Contract | Role |
|
|
@@ -49,17 +47,17 @@ This repo owns orchestration plus runtime wrapping:
|
|
|
49
47
|
|
|
50
48
|
## Integration Traps
|
|
51
49
|
|
|
52
|
-
- this repo wraps hooks and bridge flows together, so ownership and hook-order assumptions matter as much as
|
|
53
|
-
- ruleset ID prediction is
|
|
54
|
-
- the deployer can carry forward an existing 721 hook shape, so stale
|
|
55
|
-
- bridge-safe wrapper behavior is part of the runtime trust model
|
|
50
|
+
- this repo wraps hooks and bridge flows together, so ownership and hook-order assumptions matter as much as deployment salt
|
|
51
|
+
- ruleset ID prediction is a real implementation dependency
|
|
52
|
+
- the deployer can carry forward an existing 721 hook shape, so stale hook assumptions can leak across deployments
|
|
53
|
+
- bridge-safe wrapper behavior is part of the runtime trust model
|
|
56
54
|
|
|
57
55
|
## Where State Lives
|
|
58
56
|
|
|
59
|
-
- orchestration and wrapper logic
|
|
60
|
-
- bridge runtime state
|
|
61
|
-
- 721 tier state
|
|
62
|
-
-
|
|
57
|
+
- orchestration and wrapper logic: `JBOmnichainDeployer`
|
|
58
|
+
- bridge runtime state: `nana-suckers-v6`
|
|
59
|
+
- 721 tier state: `nana-721-hook-v6`
|
|
60
|
+
- extra hook behavior: the additional repo composed into the deployment
|
|
63
61
|
|
|
64
62
|
## Install
|
|
65
63
|
|
|
@@ -100,10 +98,10 @@ script/
|
|
|
100
98
|
|
|
101
99
|
## Risks And Notes
|
|
102
100
|
|
|
103
|
-
- ruleset ID prediction is part of the implementation strategy
|
|
101
|
+
- ruleset ID prediction is part of the implementation strategy
|
|
104
102
|
- hook composition order matters because the 721 hook runs before any extra custom hook
|
|
105
|
-
-
|
|
106
|
-
- deterministic salts help with cross-chain address alignment
|
|
103
|
+
- default empty-tier 721 config is convenient, but teams should still decide explicitly whether the hook participates in cash-out behavior
|
|
104
|
+
- deterministic salts only help with cross-chain address alignment when sender and configuration match exactly
|
|
107
105
|
|
|
108
106
|
## For AI Agents
|
|
109
107
|
|
package/RISKS.md
CHANGED
|
@@ -1,81 +1,92 @@
|
|
|
1
1
|
# Omnichain Deployers Risk Register
|
|
2
2
|
|
|
3
|
-
This file
|
|
3
|
+
This file covers the risks in the deployer layer that launches Juicebox projects across chains while composing 721 hooks, suckers, and optional custom data hooks.
|
|
4
4
|
|
|
5
|
-
## How
|
|
5
|
+
## How To Use This File
|
|
6
6
|
|
|
7
|
-
- Read `Priority risks` first
|
|
8
|
-
-
|
|
9
|
-
- Treat `Invariants to Verify` as required checks for any new omnichain deployment flow.
|
|
7
|
+
- Read `Priority risks` first. They capture the highest-blast-radius deployment and cash-out assumptions.
|
|
8
|
+
- Treat `Invariants to verify` as required checks for any new omnichain deployment flow.
|
|
10
9
|
|
|
11
|
-
## Priority
|
|
10
|
+
## Priority Risks
|
|
12
11
|
|
|
13
12
|
| Priority | Risk | Why it matters | Primary controls |
|
|
14
13
|
|----------|------|----------------|------------------|
|
|
15
14
|
| P0 | Registry-trusted sucker bypass | This deployer gives suckers privileged cash-out behavior based on registry answers. A bad registry entry can affect many projects. | Registry allowlists, deployment verification, and explicit registry scrutiny. |
|
|
16
15
|
| P1 | Cross-chain deployment drift | Omnichain assumptions fail if chain-specific wiring, peers, or composed hooks do not match. | Deterministic deploy ordering, parity checks, and post-deploy peer verification. |
|
|
17
|
-
| P1 | Data-hook composition mistakes | The deployer wraps or forwards custom data hooks
|
|
18
|
-
|
|
16
|
+
| P1 | Data-hook composition mistakes | The deployer wraps or forwards custom data hooks. A bad composition can alter pay or cash-out semantics unexpectedly. | Integration tests and careful forwarding review. |
|
|
19
17
|
|
|
20
18
|
## 1. Trust Assumptions
|
|
21
19
|
|
|
22
|
-
- **Trusted forwarder
|
|
23
|
-
- **Sucker registry
|
|
24
|
-
- **Controller trust.**
|
|
25
|
-
- **Extra data hooks
|
|
20
|
+
- **Trusted forwarder is trusted.**
|
|
21
|
+
- **Sucker registry answers are trusted.**
|
|
22
|
+
- **Controller trust matters.**
|
|
23
|
+
- **Extra data hooks are trusted code.**
|
|
26
24
|
|
|
27
|
-
## 2. Economic
|
|
25
|
+
## 2. Economic Risks
|
|
28
26
|
|
|
29
|
-
- **Sucker cashout bypass
|
|
30
|
-
- **
|
|
31
|
-
- **721 hook amount splitting
|
|
32
|
-
- **Cross-chain sender dependence
|
|
27
|
+
- **Sucker cashout bypass exists for registered suckers.**
|
|
28
|
+
- **Extra data hooks can manipulate weight or cash-out behavior.**
|
|
29
|
+
- **721 hook amount splitting can zero out project amount in edge cases.**
|
|
30
|
+
- **Cross-chain sender dependence affects deterministic sucker salts.**
|
|
33
31
|
|
|
34
32
|
## 3. Access Control
|
|
35
33
|
|
|
36
|
-
- **Wildcard
|
|
37
|
-
-
|
|
38
|
-
-
|
|
34
|
+
- **Wildcard `MAP_SUCKER_TOKEN` permission is broad.**
|
|
35
|
+
- **`launchRulesetsFor` requires combined permissions.**
|
|
36
|
+
- **`launchProjectFor` is intentionally permissionless for new projects.**
|
|
39
37
|
|
|
40
38
|
## 4. DoS Vectors
|
|
41
39
|
|
|
42
|
-
- **Ruleset ID collision
|
|
43
|
-
- **External hook
|
|
44
|
-
- **721 hook deployment revert
|
|
45
|
-
- **
|
|
40
|
+
- **Ruleset ID collision can block queueing.**
|
|
41
|
+
- **External hook reverts can block pay or cash-out flows.**
|
|
42
|
+
- **721 hook deployment revert blocks launch.**
|
|
43
|
+
- **Non-safe NFT transfers can still strand assets.**
|
|
46
44
|
|
|
47
45
|
## 5. Reentrancy Surface
|
|
48
46
|
|
|
49
|
-
- **`launchProjectFor`
|
|
50
|
-
- **`beforePayRecordedWith` delegates to external hooks.**
|
|
51
|
-
- **`beforeCashOutRecordedWith` delegates to external hooks.**
|
|
52
|
-
- **
|
|
47
|
+
- **`launchProjectFor` makes several external calls in sequence.**
|
|
48
|
+
- **`beforePayRecordedWith` delegates to external hooks.**
|
|
49
|
+
- **`beforeCashOutRecordedWith` delegates to external hooks.**
|
|
50
|
+
- **There is no `ReentrancyGuard`.** The deployer relies on being effectively stateless during pay and cash-out operations.
|
|
53
51
|
|
|
54
52
|
## 6. Integration Risks
|
|
55
53
|
|
|
56
|
-
- **Hook config keyed by predicted
|
|
57
|
-
- **Carried-forward 721 hook on queue
|
|
58
|
-
- **ERC721Receiver
|
|
59
|
-
- **Empty simplified launch config reverts.**
|
|
60
|
-
- **Cross-reference: sucker registration.** The deployer grants `MAP_SUCKER_TOKEN` to `SUCKER_REGISTRY` with `projectId=0` (wildcard). This means the registry can map tokens for ALL projects deployed through this deployer. See [nana-suckers-v6 RISKS.md](../nana-suckers-v6/RISKS.md) for the full sucker lifecycle risks.
|
|
61
|
-
- **Cross-reference: core reentrancy.** The deployer delegates to `JBController` and `JBMultiTerminal` for all fund operations. See [nana-core-v6 RISKS.md](../nana-core-v6/RISKS.md) section 3 for the reentrancy surface of these contracts.
|
|
54
|
+
- **Hook config is keyed by predicted ruleset ID.**
|
|
55
|
+
- **Carried-forward 721 hook behavior on queue depends on prior ruleset state.**
|
|
56
|
+
- **ERC721Receiver restrictions are narrow but non-safe transfers can still strand assets.**
|
|
57
|
+
- **Empty simplified launch config reverts.**
|
|
62
58
|
|
|
63
|
-
## 7. Invariants
|
|
59
|
+
## 7. Invariants To Verify
|
|
64
60
|
|
|
65
|
-
-
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
- Project NFT ownership: after `_launchProjectFor`, the project NFT is owned by `owner`, not the deployer.
|
|
71
|
-
- `deploySuckersFor` uses the same `_msgSender()` on every chain when deterministic cross-chain peer symmetry is expected.
|
|
61
|
+
- launched projects point at the intended controller
|
|
62
|
+
- stored 721 hook config exists for every ruleset created through this deployer
|
|
63
|
+
- sucker cashouts always get the intended zero-tax path
|
|
64
|
+
- self-reference prevention holds after setup
|
|
65
|
+
- the project NFT ends owned by the intended owner
|
|
72
66
|
|
|
73
67
|
## 8. Accepted Behaviors
|
|
74
68
|
|
|
75
|
-
### 8.1 Controller validation skipped during
|
|
69
|
+
### 8.1 Controller validation is skipped during initial launch
|
|
70
|
+
|
|
71
|
+
Pre-launch controller validation is impossible because the project does not yet exist. The accepted safeguard is the post-launch project ID match check.
|
|
72
|
+
|
|
73
|
+
### 8.2 Registered suckers receive 0% cashout tax
|
|
74
|
+
|
|
75
|
+
This is intentional and shares the same trust boundary as the sucker registry.
|
|
76
|
+
|
|
77
|
+
## 9. Accepted Security Risks
|
|
78
|
+
|
|
79
|
+
Documented risks that were reviewed and accepted.
|
|
80
|
+
|
|
81
|
+
### Configuration Risks
|
|
82
|
+
|
|
83
|
+
**Unvalidated extra data hooks can brick live flows.** *(Minor)*
|
|
84
|
+
Extra data hooks provided by the project owner in `_setup721` configuration can fail and brick live pay/cashout flows. Accepted because this is self-inflicted misconfiguration — only the project owner can set these hooks.
|
|
76
85
|
|
|
77
|
-
|
|
86
|
+
**Missing hook721 alias check enables double invocation.** *(Minor)*
|
|
87
|
+
If the project owner configures the 721 hook as both the primary hook and as an extra data hook, it could be invoked twice. Accepted because this is self-inflicted misconfiguration — the deployer correctly processes each hook independently.
|
|
78
88
|
|
|
79
|
-
###
|
|
89
|
+
### Cross-Chain Deployment
|
|
80
90
|
|
|
81
|
-
`
|
|
91
|
+
**`_msgSender()` in deployment salt breaks cross-chain determinism.** *(Minor)*
|
|
92
|
+
`deploySuckersFor` includes `_msgSender()` in the CREATE2 salt, which means the same deployment from different callers produces different addresses across chains. Accepted because this is intentional replay protection — prevents frontrunning of cross-chain deployments.
|
package/SKILLS.md
CHANGED
|
@@ -2,43 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
## Use This File For
|
|
4
4
|
|
|
5
|
-
- Use this file when the task involves
|
|
6
|
-
- Start here, then decide whether the
|
|
5
|
+
- Use this file when the task involves omnichain project launch, sucker deployment, or wrapped 721-hook composition.
|
|
6
|
+
- Start here, then decide whether the issue is in launch orchestration, hook composition, or bridge-specific runtime behavior.
|
|
7
7
|
|
|
8
8
|
## Read This Next
|
|
9
9
|
|
|
10
10
|
| If you need... | Open this next |
|
|
11
11
|
|---|---|
|
|
12
|
-
| Repo overview and
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
| Guard rails, attacks, and hook-composition behavior | [`test/JBOmnichainDeployerGuard.t.sol`](./test/JBOmnichainDeployerGuard.t.sol), [`test/OmnichainDeployerAttacks.t.sol`](./test/OmnichainDeployerAttacks.t.sol), [`test/OmnichainDeployerReentrancy.t.sol`](./test/OmnichainDeployerReentrancy.t.sol), [`test/Tiered721HookComposition.t.sol`](./test/Tiered721HookComposition.t.sol) |
|
|
17
|
-
| Baseline deployment and pinned edge cases | [`test/JBOmnichainDeployer.t.sol`](./test/JBOmnichainDeployer.t.sol), [`test/OmnichainDeployerEdgeCases.t.sol`](./test/OmnichainDeployerEdgeCases.t.sol), [`test/TestAuditGaps.sol`](./test/TestAuditGaps.sol) |
|
|
18
|
-
|
|
19
|
-
## Repo Map
|
|
20
|
-
|
|
21
|
-
| Area | Where to look |
|
|
22
|
-
|---|---|
|
|
23
|
-
| Main contract | [`src/JBOmnichainDeployer.sol`](./src/JBOmnichainDeployer.sol) |
|
|
24
|
-
| Types | [`src/structs/`](./src/structs/), [`src/interfaces/`](./src/interfaces/) |
|
|
25
|
-
| Scripts | [`script/`](./script/) |
|
|
26
|
-
| Tests | [`test/`](./test/) |
|
|
12
|
+
| Repo overview and architecture | [`README.md`](./README.md), [`ARCHITECTURE.md`](./ARCHITECTURE.md) |
|
|
13
|
+
| Main deployer | [`src/JBOmnichainDeployer.sol`](./src/JBOmnichainDeployer.sol) |
|
|
14
|
+
| Bridge runtime | [`../nana-suckers-v6/src/JBSucker.sol`](../nana-suckers-v6/src/JBSucker.sol) |
|
|
15
|
+
| 721 hook runtime | [`../nana-721-hook-v6/src/JB721TiersHook.sol`](../nana-721-hook-v6/src/JB721TiersHook.sol) |
|
|
27
16
|
|
|
28
17
|
## Purpose
|
|
29
18
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
## Reference Files
|
|
33
|
-
|
|
34
|
-
- Open [`references/runtime.md`](./references/runtime.md) when you need hook-composition order, sucker exemptions, per-ruleset storage behavior, or the main runtime invariants.
|
|
35
|
-
- Open [`references/operations.md`](./references/operations.md) when you need launch and queue behavior, permission and salt assumptions, test breadcrumbs, or the common stale-data traps.
|
|
19
|
+
Orchestration and wrapper layer for launching projects with suckers and a 721 hook already wired in.
|
|
36
20
|
|
|
37
21
|
## Working Rules
|
|
38
22
|
|
|
39
|
-
- Start in [`src/JBOmnichainDeployer.sol`](./src/JBOmnichainDeployer.sol)
|
|
40
|
-
- Treat ruleset ID prediction
|
|
41
|
-
-
|
|
42
|
-
- When a bug mentions suckers, tax-free cash outs, or mint permission, verify whether the early-return wrapper behavior is the real cause before changing downstream hooks.
|
|
43
|
-
- Existing-project sucker deployment is not just “deploy clones”; it also depends on token-mapping authority landing correctly through the registry path.
|
|
44
|
-
- If a task mentions 721 or custom-hook behavior, confirm whether the issue lives here or in the composed repo before patching wrapper logic.
|
|
23
|
+
- Start in [`src/JBOmnichainDeployer.sol`](./src/JBOmnichainDeployer.sol).
|
|
24
|
+
- Treat ruleset ID prediction as a real implementation dependency.
|
|
25
|
+
- Keep wrapper behavior and the underlying 721 or sucker behavior separate in your reasoning.
|