@bananapus/omnichain-deployers-v6 0.0.7 → 0.0.8
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 +7 -6
- package/ARCHITECTURE.md +13 -6
- package/README.md +26 -22
- package/RISKS.md +1 -1
- package/SKILLS.md +27 -22
- package/STYLE_GUIDE.md +116 -24
- package/foundry.toml +3 -0
- package/package.json +5 -5
- package/remappings.txt +1 -1
- package/script/Deploy.s.sol +1 -1
- package/script/helpers/DeployersDeploymentLib.sol +1 -1
- package/src/JBOmnichainDeployer.sol +159 -102
- package/src/interfaces/IJBOmnichainDeployer.sol +26 -21
- package/src/structs/JBDeployerHookConfig.sol +1 -1
- package/src/structs/JBTiered721HookConfig.sol +9 -0
- package/test/JBOmnichainDeployer.t.sol +5 -6
- package/test/JBOmnichainDeployerGuard.t.sol +7 -6
- package/test/OmnichainDeployerEdgeCases.t.sol +597 -0
- package/test/OmnichainDeployerReentrancy.t.sol +320 -0
- package/test/Tiered721HookComposition.t.sol +141 -55
- package/test/fork/OmnichainForkTestBase.sol +33 -17
- package/test/fork/TestOmnichain721QueueAndAdjust.t.sol +325 -0
- package/test/fork/TestOmnichainCashOutFork.t.sol +43 -8
- package/test/fork/TestOmnichainStressFork.t.sol +541 -0
- package/test/fork/TestOmnichainWeightFork.t.sol +3 -3
- package/test/invariants/OmnichainDeployerInvariant.t.sol +149 -0
- package/test/invariants/handlers/OmnichainDeployerHandler.sol +262 -0
- package/test/regression/{H20_HookOwnershipTransfer.t.sol → HookOwnershipTransfer.t.sol} +9 -3
- package/test/regression/{L64_ValidateController.t.sol → ValidateController.t.sol} +2 -2
package/ADMINISTRATION.md
CHANGED
|
@@ -30,9 +30,10 @@ Admin privileges and their scope in nana-omnichain-deployers-v6.
|
|
|
30
30
|
| `launchProjectFor` | Anyone | Creates a new project with suckers. The ERC-721 is minted to the specified `owner`. |
|
|
31
31
|
| `launch721ProjectFor` | Anyone | Creates a new project with a 721 tiers hook and suckers. The ERC-721 is minted to the specified `owner`. |
|
|
32
32
|
| `beforePayRecordedWith` | JBMultiTerminal (via controller) | View function: forwards pay data to the stored data hook, or passes through if none configured. |
|
|
33
|
-
| `beforeCashOutRecordedWith` | JBMultiTerminal (via controller) | View function: returns 0% cash-out tax for registered suckers
|
|
34
|
-
| `hasMintPermissionFor` | JBController | View function: returns true for registered suckers, otherwise
|
|
35
|
-
| `
|
|
33
|
+
| `beforeCashOutRecordedWith` | JBMultiTerminal (via controller) | View function: returns 0% cash-out tax for registered suckers. Checks 721 hook (from `_tiered721HookOf`) then custom hook (from `_extraDataHookOf`) — the first with `useDataHookForCashOut: true` handles it. If neither has the flag set, returns original values. |
|
|
34
|
+
| `hasMintPermissionFor` | JBController | View function: returns true for registered suckers, otherwise checks the custom hook in `_extraDataHookOf`. |
|
|
35
|
+
| `extraDataHookOf` | Anyone | View function: returns the stored `JBDeployerHookConfig` for a project/ruleset pair (the custom data hook). |
|
|
36
|
+
| `tiered721HookOf` | Anyone | View function: returns the stored 721 hook and `useDataHookForCashOut` flag for a project/ruleset pair. |
|
|
36
37
|
|
|
37
38
|
## Deployment Administration
|
|
38
39
|
|
|
@@ -75,7 +76,7 @@ These values are set at deployment and cannot be changed:
|
|
|
75
76
|
| Trusted forwarder | `address` | The ERC-2771 trusted forwarder for meta-transactions. |
|
|
76
77
|
| MAP_SUCKER_TOKEN grant | Permission | Granted to SUCKER_REGISTRY at construction for all projects (projectId=0). Cannot be revoked by this contract. |
|
|
77
78
|
|
|
78
|
-
**Data hook mappings** (`
|
|
79
|
+
**Data hook mappings** (`_tiered721HookOf[projectId][rulesetId]` and `_extraDataHookOf[projectId][rulesetId]`) are write-once per ruleset ID. They are set during `_setup` / `_setup721` and never updated or deleted.
|
|
79
80
|
|
|
80
81
|
## Admin Boundaries
|
|
81
82
|
|
|
@@ -83,10 +84,10 @@ What admins **cannot** do:
|
|
|
83
84
|
|
|
84
85
|
- **Cannot upgrade the deployer.** JBOmnichainDeployer has no upgrade mechanism, proxy pattern, or self-destruct.
|
|
85
86
|
- **Cannot change immutable references.** PROJECTS, HOOK_DEPLOYER, SUCKER_REGISTRY, PERMISSIONS, and the trusted forwarder are all immutable.
|
|
86
|
-
- **Cannot modify stored data hooks.** Once a ruleset's
|
|
87
|
+
- **Cannot modify stored data hooks.** Once a ruleset's hooks are stored in `_tiered721HookOf` and `_extraDataHookOf`, they cannot be changed. New rulesets can use different hooks, but existing mappings are permanent.
|
|
87
88
|
- **Cannot bypass permission checks.** All post-deployment admin functions require JBPermissions verification against the project owner.
|
|
88
89
|
- **Cannot revoke sucker privileges.** Once a sucker is registered in JBSuckerRegistry, it automatically gets 0% cash-out tax and mint permission for its project. Revocation must happen at the registry level.
|
|
89
|
-
- **Cannot set the deployer as its own data hook.**
|
|
90
|
+
- **Cannot set the deployer as its own data hook.** Both `_setup` and `_setup721` explicitly revert with `JBOmnichainDeployer_InvalidHook` if a hook is `address(this)`.
|
|
90
91
|
- **Cannot use a controller that doesn't match the project.** `_validateController` reverts with `JBOmnichainDeployer_ControllerMismatch` if the provided controller is not the project's actual controller in the directory.
|
|
91
92
|
- **Cannot steal project ownership during deployment.** The deployer holds the project ERC-721 only transiently and transfers it to the specified owner in the same transaction.
|
|
92
93
|
- **Cannot drain funds.** The deployer never holds or manages token balances. It only orchestrates configuration.
|
package/ARCHITECTURE.md
CHANGED
|
@@ -8,11 +8,12 @@ Omnichain project deployer for Juicebox V6. Wraps the project deployment flow to
|
|
|
8
8
|
|
|
9
9
|
```
|
|
10
10
|
src/
|
|
11
|
-
├── JBOmnichainDeployer.sol — Deploys projects with sucker integration, acts as data hook
|
|
11
|
+
├── JBOmnichainDeployer.sol — Deploys projects with sucker integration, acts as data hook wrapper
|
|
12
12
|
├── interfaces/
|
|
13
13
|
│ └── IJBOmnichainDeployer.sol — Interface
|
|
14
14
|
└── structs/
|
|
15
|
-
├── JBDeployerHookConfig.sol —
|
|
15
|
+
├── JBDeployerHookConfig.sol — Custom hook configuration for deployment
|
|
16
|
+
├── JBTiered721HookConfig.sol — Per-ruleset 721 hook configuration
|
|
16
17
|
└── JBSuckerDeploymentConfig.sol — Sucker deployment parameters
|
|
17
18
|
```
|
|
18
19
|
|
|
@@ -31,12 +32,18 @@ Deployer → JBOmnichainDeployer.deployProjectFor()
|
|
|
31
32
|
### Data Hook Behavior
|
|
32
33
|
```
|
|
33
34
|
Payment → JBOmnichainDeployer.beforePayRecordedWith()
|
|
34
|
-
→
|
|
35
|
-
→
|
|
35
|
+
→ Calls 721 hook first (from _tiered721HookOf) for specs/split amounts
|
|
36
|
+
→ Calls custom hook from _extraDataHookOf (if useDataHookForPay=true)
|
|
37
|
+
→ Custom hook receives reduced amount (payment - splitAmount)
|
|
38
|
+
→ Adjusts weight proportionally for splits
|
|
39
|
+
→ Merges both hook specs (721 first, then custom)
|
|
36
40
|
|
|
37
41
|
Cash Out → JBOmnichainDeployer.beforeCashOutRecordedWith()
|
|
38
|
-
→ If caller is a registered sucker: return 0% cash-out tax
|
|
39
|
-
→
|
|
42
|
+
→ If caller is a registered sucker: return 0% cash-out tax (early return)
|
|
43
|
+
→ Checks 721 hook (from _tiered721HookOf, if useDataHookForCashOut=true)
|
|
44
|
+
→ Then checks custom hook (from _extraDataHookOf, if useDataHookForCashOut=true)
|
|
45
|
+
→ If 721 hook has flag=true and reverts (fungible cashout): revert propagates
|
|
46
|
+
→ If neither hook has the flag set: return original values
|
|
40
47
|
```
|
|
41
48
|
|
|
42
49
|
### Ruleset Management
|
package/README.md
CHANGED
|
@@ -8,11 +8,12 @@ Deploy Juicebox projects with cross-chain suckers and optional 721 tiers hooks i
|
|
|
8
8
|
|
|
9
9
|
Launching a cross-chain Juicebox project normally takes several steps: deploy the project, configure rulesets, set up terminals, deploy suckers, and wire up a data hook that exempts suckers from cash out taxes. `JBOmnichainDeployer` collapses all of this into one transaction.
|
|
10
10
|
|
|
11
|
-
It works by inserting itself as the data hook on every ruleset it touches, storing the
|
|
11
|
+
It works by inserting itself as the data hook on every ruleset it touches, storing hooks in two separate mappings: the 721 tiers hook (if any) is stored per-ruleset in `_tiered721HookOf[projectId][rulesetId]` with its own `useDataHookForCashOut` flag, and an optional custom data hook (e.g., buyback hook) is stored per-ruleset in `_extraDataHookOf[projectId][rulesetId]` with `useDataHookForPay` and `useDataHookForCashOut` flags. When the protocol calls data hook functions during payments and cash outs, the deployer:
|
|
12
12
|
|
|
13
13
|
- **Checks if the holder is a sucker** -- if so, returns 0% cash out tax and grants mint permission. This early return means suckers can always bridge tokens without interference, even if the project's hooks would revert.
|
|
14
|
-
- **Composes the 721 hook and custom data hook** for payments -- the 721 hook is called first to get its specs (including split fund amounts), then the custom
|
|
15
|
-
- **
|
|
14
|
+
- **Composes the 721 hook and custom data hook** for payments -- the 721 hook is called first (via `tiered721HookOf`) to get its specs (including split fund amounts), then the custom hook from `_extraDataHookOf` (if `useDataHookForPay: true`) is called with a reduced amount context (payment minus split amount) so it only considers the available funds. The deployer adjusts the returned weight proportionally for splits, ensuring the terminal only mints tokens for the amount that actually enters the project treasury.
|
|
15
|
+
- **Checks hooks for cash outs** -- the 721 hook is checked first (if `useDataHookForCashOut: true`), then the custom hook. The first with the flag set handles the cash out. If the 721 hook has `useDataHookForCashOut: true` and reverts (e.g., for fungible-only cashouts), that revert propagates. Set `useDataHookForCashOut: false` on the 721 metadata to skip it and let the custom hook handle cashouts instead.
|
|
16
|
+
- **Returns default values** if neither hook has the relevant flag set.
|
|
16
17
|
|
|
17
18
|
This wrapping is invisible to the project and its users. The project's hooks (buyback hook, 721 hook, etc.) work exactly as configured, and can be composed together.
|
|
18
19
|
|
|
@@ -42,20 +43,18 @@ sequenceDiagram
|
|
|
42
43
|
participant Terminal
|
|
43
44
|
participant Deployer as JBOmnichainDeployer
|
|
44
45
|
participant Registry as JBSuckerRegistry
|
|
45
|
-
participant Hook as
|
|
46
|
+
participant Hook as 721 / Custom Hook
|
|
46
47
|
|
|
47
48
|
Terminal->>Deployer: beforeCashOutRecordedWith(context)
|
|
48
49
|
Deployer->>Registry: isSuckerOf(projectId, holder)?
|
|
49
50
|
alt Holder is a sucker
|
|
50
51
|
Deployer-->>Terminal: 0% tax (early return)
|
|
51
|
-
else 721 hook
|
|
52
|
-
Deployer->>721Hook: beforeCashOutRecordedWith(context)
|
|
53
|
-
721Hook-->>Deployer: taxRate, count, supply, specs
|
|
54
|
-
Deployer-->>Terminal: forward 721 hook response
|
|
55
|
-
else Custom data hook exists
|
|
52
|
+
else 721 or custom hook with useDataHookForCashOut=true
|
|
56
53
|
Deployer->>Hook: beforeCashOutRecordedWith(context)
|
|
57
54
|
Hook-->>Deployer: taxRate, count, supply, specs
|
|
58
|
-
Deployer-->>Terminal: forward
|
|
55
|
+
Deployer-->>Terminal: forward hook response
|
|
56
|
+
else Neither hook has useDataHookForCashOut=true
|
|
57
|
+
Deployer-->>Terminal: original values (default)
|
|
59
58
|
end
|
|
60
59
|
```
|
|
61
60
|
|
|
@@ -64,12 +63,12 @@ sequenceDiagram
|
|
|
64
63
|
The `launch721*` and `queue721*` variants deploy a tiered ERC-721 hook alongside the project. The deployer:
|
|
65
64
|
|
|
66
65
|
1. Deploys the 721 hook via `HOOK_DEPLOYER`
|
|
67
|
-
2. Stores the 721 hook in `
|
|
66
|
+
2. Stores the 721 hook per-ruleset in `_tiered721HookOf[projectId][rulesetId]` with its `useDataHookForCashOut` flag
|
|
68
67
|
3. Converts 721-specific ruleset configs (`JBPayDataHookRulesetConfig`) to standard configs, enforcing `useDataHookForPay = true` and `allowSetCustomToken = false`
|
|
69
|
-
4. Stores the optional custom
|
|
68
|
+
4. Stores the optional custom hook (e.g., buyback hook) separately in `_extraDataHookOf[projectId][rulesetId]` with its own per-hook flags
|
|
70
69
|
5. Transfers hook ownership to the project via `JBOwnable.transferOwnershipToProject()`
|
|
71
70
|
|
|
72
|
-
This
|
|
71
|
+
This means a project can have both a 721 hook (for NFT minting on payments) and a custom data hook (for buyback, custom weight logic, etc.) running simultaneously. During payments, both hooks' specifications are merged. During cash outs, the 721 hook is checked first (if `useDataHookForCashOut: true`), then the custom hook.
|
|
73
72
|
|
|
74
73
|
### Deterministic Cross-Chain Addresses
|
|
75
74
|
|
|
@@ -100,9 +99,10 @@ The `queueRulesetsOf` and `queue721RulesetsOf` functions guard against predictio
|
|
|
100
99
|
|
|
101
100
|
| Type | Description |
|
|
102
101
|
|------|-------------|
|
|
103
|
-
| `JBDeployerHookConfig` | Per-
|
|
102
|
+
| `JBDeployerHookConfig` | Per-hook config with `dataHook`, `useDataHookForPay`, and `useDataHookForCashOut` flags. Stored as a single value per `(projectId, rulesetId)` in `_extraDataHookOf` for the custom data hook. |
|
|
103
|
+
| `JBTiered721HookConfig` | Per-ruleset 721 hook config with `hook` (the `IJB721TiersHook`) and `useDataHookForCashOut` flag. Stored per `(projectId, rulesetId)` in `_tiered721HookOf`. |
|
|
104
104
|
| `JBSuckerDeploymentConfig` | Wraps an array of `JBSuckerDeployerConfig` with a `bytes32` salt for deterministic cross-chain addresses. |
|
|
105
|
-
| `IJBOmnichainDeployer` | Interface for all deployer entry points and the `
|
|
105
|
+
| `IJBOmnichainDeployer` | Interface for all deployer entry points and the `extraDataHookOf` view. |
|
|
106
106
|
|
|
107
107
|
## Install
|
|
108
108
|
|
|
@@ -137,7 +137,7 @@ Add to `remappings.txt`:
|
|
|
137
137
|
# foundry.toml
|
|
138
138
|
[profile.default]
|
|
139
139
|
solc = '0.8.26'
|
|
140
|
-
evm_version = '
|
|
140
|
+
evm_version = 'cancun'
|
|
141
141
|
optimizer_runs = 100000
|
|
142
142
|
|
|
143
143
|
[fuzz]
|
|
@@ -148,19 +148,23 @@ runs = 4096
|
|
|
148
148
|
|
|
149
149
|
```
|
|
150
150
|
src/
|
|
151
|
-
JBOmnichainDeployer.sol # Main contract (
|
|
151
|
+
JBOmnichainDeployer.sol # Main contract (~893 lines)
|
|
152
152
|
interfaces/
|
|
153
153
|
IJBOmnichainDeployer.sol # Public interface
|
|
154
154
|
structs/
|
|
155
|
-
JBDeployerHookConfig.sol #
|
|
155
|
+
JBDeployerHookConfig.sol # Custom hook config (dataHook + flags)
|
|
156
|
+
JBTiered721HookConfig.sol # Per-ruleset 721 hook config
|
|
156
157
|
JBSuckerDeploymentConfig.sol # Sucker deployment params
|
|
157
158
|
test/
|
|
158
159
|
JBOmnichainDeployer.t.sol # Unit tests
|
|
159
160
|
JBOmnichainDeployerGuard.t.sol # Ruleset ID prediction tests
|
|
160
161
|
OmnichainDeployerAttacks.t.sol # Adversarial security tests
|
|
161
|
-
|
|
162
|
+
OmnichainDeployerEdgeCases.t.sol # Edge case tests (weight, cashout, mint)
|
|
163
|
+
OmnichainDeployerReentrancy.t.sol # Reentrancy tests
|
|
164
|
+
Tiered721HookComposition.t.sol # 721 hook + custom hook composition tests
|
|
165
|
+
fork/ # Fork tests against mainnet
|
|
162
166
|
regression/
|
|
163
|
-
|
|
167
|
+
HookOwnershipTransfer.t.sol # Hook ownership transfer regression
|
|
164
168
|
script/
|
|
165
169
|
Deploy.s.sol # Sphinx deployment script
|
|
166
170
|
helpers/
|
|
@@ -180,7 +184,7 @@ Note: `launchProjectFor` and `launch721ProjectFor` require no permissions -- any
|
|
|
180
184
|
|
|
181
185
|
## Risks
|
|
182
186
|
|
|
183
|
-
- **Ruleset ID mismatch**: If `_setup()` predictions are wrong (e.g., due to same-block queuing from another source), the stored hook configs will be keyed to the wrong rulesets. The `queueRulesetsOf` guard prevents this, but `launchProjectFor` relies on `PROJECTS.count()` being accurate at call time.
|
|
184
|
-
- **Reverting real hook**: If
|
|
187
|
+
- **Ruleset ID mismatch**: If `_setup()` / `_setup721()` predictions are wrong (e.g., due to same-block queuing from another source), the stored hook configs will be keyed to the wrong rulesets. The `queueRulesetsOf` guard prevents this, but `launchProjectFor` relies on `PROJECTS.count()` being accurate at call time.
|
|
188
|
+
- **Reverting real hook**: If any stored hook reverts on `beforePayRecordedWith`, payments are blocked. If the 721 hook has `useDataHookForCashOut: true`, its revert for fungible cashouts propagates. Suckers are immune to this for cash outs (early return), but not for payments.
|
|
185
189
|
- **Hook forwarding is view-only**: The deployer's data hook functions are `view`, so any real hook that requires state changes in `beforePayRecordedWith` or `beforeCashOutRecordedWith` will fail.
|
|
186
190
|
- **Meta-transaction trust**: ERC2771 `_msgSender()` is used for salt hashing. A compromised trusted forwarder could impersonate senders and create suckers at unexpected addresses.
|
package/RISKS.md
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
| Risk | Description | Mitigation |
|
|
14
14
|
|------|-------------|------------|
|
|
15
15
|
| Sucker privilege abuse | Any registered sucker gets 0% cashout tax | Sucker registration requires DEPLOY_SUCKERS permission |
|
|
16
|
-
| Data hook centralization | Deployer is the data hook for all omnichain projects | Simple pass-through logic minimizes attack surface |
|
|
16
|
+
| Data hook centralization | Deployer is the data hook for all omnichain projects | Simple pass-through logic minimizes attack surface. The 721 hook (in `_tiered721HookOf`) and custom hook (in `_extraDataHookOf`) each have their own `useDataHookForCashOut` flag — set to `false` on the 721 metadata to skip it for fungible cashouts. Suckers always get the early return regardless of hook configuration. |
|
|
17
17
|
| Controller mismatch | Reverts if provided controller doesn't match project's actual controller | Explicit validation via `JBOmnichainDeployer_ControllerMismatch` |
|
|
18
18
|
| Invalid self-hook | Reverts if someone tries to set deployer as hook for deployer itself | `JBOmnichainDeployer_InvalidHook` check |
|
|
19
19
|
| Ownership transfer | Project ownership transferred during deployment | Ownership returned to caller after setup |
|
package/SKILLS.md
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## Purpose
|
|
4
4
|
|
|
5
|
-
Single-transaction deployment of Juicebox projects with cross-chain suckers and optional 721 tiers hooks. Wraps the project's data
|
|
5
|
+
Single-transaction deployment of Juicebox projects with cross-chain suckers and optional 721 tiers hooks. Wraps the project's data hooks to give suckers tax-free cash outs and mint permission without interfering with custom hooks. Stores the 721 hook per-ruleset in `_tiered721HookOf` and the optional custom hook per-ruleset in `_extraDataHookOf`, each with their own `useDataHookForCashOut` flag. Supports composing a 721 hook alongside a custom data hook (e.g., buyback hook) — both run on every payment.
|
|
6
6
|
|
|
7
7
|
## Contracts
|
|
8
8
|
|
|
9
9
|
| Contract | Role |
|
|
10
10
|
|----------|------|
|
|
11
|
-
| `JBOmnichainDeployer` | Deploys projects/rulesets/suckers, wraps data hooks for sucker tax exemption. Implements `IJBRulesetDataHook`, `IERC721Receiver`, `ERC2771Context`, `JBPermissioned`. |
|
|
11
|
+
| `JBOmnichainDeployer` | Deploys projects/rulesets/suckers, wraps data hooks for sucker tax exemption. Stores 721 hook per-ruleset in `_tiered721HookOf` and custom hook per-ruleset in `_extraDataHookOf`. Implements `IJBRulesetDataHook`, `IERC721Receiver`, `ERC2771Context`, `JBPermissioned`. |
|
|
12
12
|
|
|
13
13
|
## Key Functions
|
|
14
14
|
|
|
@@ -17,27 +17,27 @@ Single-transaction deployment of Juicebox projects with cross-chain suckers and
|
|
|
17
17
|
| Function | What it does |
|
|
18
18
|
|----------|-------------|
|
|
19
19
|
| `launchProjectFor(owner, projectUri, rulesetConfigs, terminalConfigs, memo, suckerConfig, controller)` | Creates a new project with rulesets, terminals, and suckers in one tx. Temporarily holds the project NFT. Returns `(projectId, suckers)`. |
|
|
20
|
-
| `launch721ProjectFor(owner, deployTiersHookConfig, launchProjectConfig, suckerConfig, controller,
|
|
20
|
+
| `launch721ProjectFor(owner, deployTiersHookConfig, launchProjectConfig, suckerConfig, controller, dataHookConfig, salt)` | Same as above but also deploys a 721 tiers hook. Pass a `JBDeployerHookConfig` with a custom data hook (e.g., buyback hook) to compose alongside the 721 hook, or `dataHook: address(0)` for none. Each hook gets its own `useDataHookForPay`/`useDataHookForCashOut` flags. Returns `(projectId, hook, suckers)`. |
|
|
21
21
|
| `launchRulesetsFor(projectId, rulesetConfigs, terminalConfigs, memo, controller)` | Launches new rulesets + terminals for an existing project. Requires `QUEUE_RULESETS` + `SET_TERMINALS`. |
|
|
22
|
-
| `launch721RulesetsFor(projectId, deployTiersHookConfig, launchRulesetsConfig, controller,
|
|
22
|
+
| `launch721RulesetsFor(projectId, deployTiersHookConfig, launchRulesetsConfig, controller, dataHookConfig, salt)` | Launches rulesets with a new 721 tiers hook + optional custom data hook config. Requires `QUEUE_RULESETS` + `SET_TERMINALS`. |
|
|
23
23
|
| `queueRulesetsOf(projectId, rulesetConfigs, memo, controller)` | Queues future rulesets. Requires `QUEUE_RULESETS`. Reverts if rulesets were already queued in the same block. |
|
|
24
|
-
| `queue721RulesetsOf(projectId, deployTiersHookConfig, queueRulesetsConfig, controller,
|
|
24
|
+
| `queue721RulesetsOf(projectId, deployTiersHookConfig, queueRulesetsConfig, controller, dataHookConfig, salt)` | Queues rulesets with a new 721 tiers hook + optional custom data hook config. Same same-block guard. |
|
|
25
25
|
| `deploySuckersFor(projectId, suckerConfig)` | Deploys new suckers for an existing project. Requires `DEPLOY_SUCKERS`. |
|
|
26
26
|
|
|
27
27
|
### Data Hook (IJBRulesetDataHook)
|
|
28
28
|
|
|
29
29
|
| Function | What it does |
|
|
30
30
|
|----------|-------------|
|
|
31
|
-
| `beforePayRecordedWith(context)` | Calls the 721 hook first for its specs (including split amounts), then calls the custom
|
|
32
|
-
| `beforeCashOutRecordedWith(context)` | If holder is a sucker: returns 0% tax immediately.
|
|
33
|
-
| `hasMintPermissionFor(projectId, ruleset, addr)` | Returns `true` for registered suckers, OR if the custom
|
|
31
|
+
| `beforePayRecordedWith(context)` | Calls the 721 hook first (via `_tiered721HookOf`) for its specs (including split amounts), then calls the custom hook from `_extraDataHookOf` (if `useDataHookForPay: true`) with a reduced amount context (payment minus split amount) for weight + specs. Adjusts the returned weight proportionally so the terminal only mints tokens for the amount entering the project (`weight = mulDiv(weight, amount - splitAmount, amount)`). Merges both (721 hook specs first, then custom hook specs). |
|
|
32
|
+
| `beforeCashOutRecordedWith(context)` | If holder is a sucker: returns 0% tax immediately. Checks 721 hook first (if `useDataHookForCashOut: true`), then custom hook from `_extraDataHookOf`. The first with the flag set handles it. If the 721 hook has the flag set and reverts (e.g., fungible cashout), the revert propagates. If neither has the flag set, returns original values. |
|
|
33
|
+
| `hasMintPermissionFor(projectId, ruleset, addr)` | Returns `true` for registered suckers, OR if the custom hook in `_extraDataHookOf` grants permission. Returns `false` only if it doesn't grant it. |
|
|
34
34
|
|
|
35
35
|
### Views
|
|
36
36
|
|
|
37
37
|
| Function | What it does |
|
|
38
38
|
|----------|-------------|
|
|
39
|
-
| `
|
|
40
|
-
| `tiered721HookOf(projectId)` | Returns the
|
|
39
|
+
| `extraDataHookOf(projectId, rulesetId)` | Returns the stored `JBDeployerHookConfig` for a given project and ruleset. Contains the custom data hook (e.g., buyback hook) with its per-hook flags. Returns empty struct if none configured. |
|
|
40
|
+
| `tiered721HookOf(projectId, rulesetId)` | Returns the 721 tiers hook and its `useDataHookForCashOut` flag for a given project and ruleset. Returns `(address(0), false)` if no 721 hook was deployed. |
|
|
41
41
|
| `supportsInterface(interfaceId)` | Returns `true` for `IJBOmnichainDeployer`, `IJBRulesetDataHook`, `IERC721Receiver`, `IERC165`. |
|
|
42
42
|
| `onERC721Received(...)` | Accepts project NFTs from `PROJECTS` only. Reverts for any other NFT contract. |
|
|
43
43
|
|
|
@@ -56,7 +56,8 @@ Single-transaction deployment of Juicebox projects with cross-chain suckers and
|
|
|
56
56
|
|
|
57
57
|
| Struct | Key Fields | Used In |
|
|
58
58
|
|--------|------------|---------|
|
|
59
|
-
| `JBDeployerHookConfig` | `
|
|
59
|
+
| `JBDeployerHookConfig` | `IJBRulesetDataHook dataHook`, `bool useDataHookForPay`, `bool useDataHookForCashOut` | `_extraDataHookOf` mapping keyed by `(projectId, rulesetId)` → single custom hook config. |
|
|
60
|
+
| `JBTiered721HookConfig` | `IJB721TiersHook hook`, `bool useDataHookForCashOut` | `_tiered721HookOf` mapping keyed by `(projectId, rulesetId)` → per-ruleset 721 hook config. |
|
|
60
61
|
| `JBSuckerDeploymentConfig` | `JBSuckerDeployerConfig[] deployerConfigurations`, `bytes32 salt` | All launch and deploy functions |
|
|
61
62
|
|
|
62
63
|
## Permission IDs
|
|
@@ -72,7 +73,7 @@ Single-transaction deployment of Juicebox projects with cross-chain suckers and
|
|
|
72
73
|
|
|
73
74
|
| Error | When |
|
|
74
75
|
|-------|------|
|
|
75
|
-
| `JBOmnichainDeployer_InvalidHook` | `_setup()`
|
|
76
|
+
| `JBOmnichainDeployer_InvalidHook` | `_setup()` or `_setup721()` detects the hook is `address(this)` -- prevents infinite forwarding loops |
|
|
76
77
|
| `JBOmnichainDeployer_UnexpectedNFTReceived` | `onERC721Received` called by a contract other than `PROJECTS` |
|
|
77
78
|
| `JBOmnichainDeployer_RulesetIdsUnpredictable` | `queueRulesetsOf`/`queue721RulesetsOf` called when `latestRulesetIdOf(projectId) >= block.timestamp` -- ruleset ID prediction would fail |
|
|
78
79
|
| `JBOmnichainDeployer_ProjectIdMismatch` | `launchProjectFor`/`launch721ProjectFor` -- the project ID returned by the controller does not match the predicted `PROJECTS.count() + 1` |
|
|
@@ -82,25 +83,25 @@ Single-transaction deployment of Juicebox projects with cross-chain suckers and
|
|
|
82
83
|
|
|
83
84
|
1. `launchProjectFor` and `launch721ProjectFor` require **no permissions** -- anyone can launch a project to any owner address.
|
|
84
85
|
2. `queueRulesetsOf` and `queue721RulesetsOf` **revert if called in the same block** as a previous ruleset queue (whether via deployer or directly). The `launch*` functions don't have this guard because they predict IDs from `PROJECTS.count()`, which is always 0 for a new project.
|
|
85
|
-
3. Ruleset IDs in `
|
|
86
|
+
3. Ruleset IDs in `_extraDataHookOf` are keyed by `block.timestamp + i`. If the controller assigns different IDs than predicted, the stored hook configs will be orphaned and the deployer will behave as if no hooks were set (returning default values).
|
|
86
87
|
4. Sucker deployment salts are hashed with `_msgSender()`: `keccak256(abi.encode(salt, _msgSender()))`. Cross-chain deterministic addresses require using the **same sender** on each chain. For `launch721ProjectFor`, the 721 hook salt uses `keccak256(abi.encode(_msgSender(), salt))` (reversed order).
|
|
87
88
|
5. `salt = bytes32(0)` **skips sucker deployment entirely**. Use a nonzero salt to deploy suckers.
|
|
88
|
-
6. The deployer **always forces `useDataHookForCashOut = true`**
|
|
89
|
-
7. Suckers get an **early return** in `beforeCashOutRecordedWith` -- they bypass
|
|
90
|
-
8. If no
|
|
89
|
+
6. The deployer **always forces `useDataHookForCashOut = true`** at the protocol level so it can intercept cash outs for sucker tax exemption. However, the 721 hook's `useDataHookForCashOut` flag (stored in `_tiered721HookOf`) and the custom hook's flag (stored in `_extraDataHookOf`) each control whether that hook processes cash outs. Set `useDataHookForCashOut: false` on the 721 metadata to skip it for fungible cashouts (it reverts with `JB721Hook_UnexpectedTokenCashedOut` otherwise).
|
|
90
|
+
7. Suckers get an **early return** in `beforeCashOutRecordedWith` -- they bypass all stored hooks entirely. This means suckers can cash out even if any hook would revert.
|
|
91
|
+
8. If no custom hook is stored or it doesn't grant permission, `hasMintPermissionFor` returns `false` for non-suckers. Only the custom hook in `_extraDataHookOf` is checked — the 721 hook is not consulted.
|
|
91
92
|
9. 721 ruleset config conversion enforces `useDataHookForPay = true` and `allowSetCustomToken = false`. These cannot be overridden.
|
|
92
93
|
10. Hook ownership is transferred to the **project** (not the owner) via `JBOwnable.transferOwnershipToProject(projectId)`. The project owner controls the hook through project ownership.
|
|
93
94
|
11. The deployer holds the project NFT temporarily during launch. If the controller's `launchProjectFor` reverts, the entire transaction reverts -- no stuck NFTs.
|
|
94
95
|
12. The constructor grants `MAP_SUCKER_TOKEN` permission to `SUCKER_REGISTRY` with `projectId=0`, meaning the registry can map tokens for **any project** deployed through this deployer.
|
|
95
96
|
13. All data hook functions (`beforePayRecordedWith`, `beforeCashOutRecordedWith`, `hasMintPermissionFor`) are `view`. If the project's real hook needs to modify state in these functions, it will fail.
|
|
96
|
-
14. Setting a
|
|
97
|
+
14. Setting a hook's `dataHook` to `address(this)` (the deployer itself) reverts with `JBOmnichainDeployer_InvalidHook` in both `_setup()` and `_setup721()`. This prevents infinite forwarding loops.
|
|
97
98
|
15. `onERC721Received` only accepts NFTs from the `PROJECTS` contract. Sending any other ERC-721 to the deployer will revert.
|
|
98
99
|
16. ERC2771 meta-transaction support allows gasless deployments via a trusted forwarder. Salt hashing uses `_msgSender()` (not `msg.sender`), so forwarder-relayed transactions use the original sender's address for deterministic sucker addresses.
|
|
99
100
|
17. **Prefer `launch721ProjectFor` over `launchProjectFor` even with empty tiers.** Using `launch721ProjectFor` with an empty tiers array wires up the 721 hook from the start, so the project owner can add and sell NFTs later without needing to reconfigure the data hook in a new ruleset. `launchProjectFor` skips hook deployment entirely.
|
|
100
|
-
18. The 721 hook is stored
|
|
101
|
-
19. For payments, `beforePayRecordedWith` calls the 721 hook first to get its specs (including split fund amounts and tier metadata), then calls the custom
|
|
102
|
-
20. For cash outs, the 721 hook
|
|
103
|
-
21. The `launch721*` and `queue721*` functions
|
|
101
|
+
18. The 721 hook is stored per-ruleset in `_tiered721HookOf[projectId][rulesetId]` with its `useDataHookForCashOut` flag. The custom data hook (if any) is stored separately in `_extraDataHookOf[projectId][rulesetId]`. They are never in the same array.
|
|
102
|
+
19. For payments, `beforePayRecordedWith` calls the 721 hook first (via `_tiered721HookOf`) to get its specs (including split fund amounts and tier metadata), then calls the custom hook from `_extraDataHookOf` (if `useDataHookForPay: true`) with a reduced amount context (payment minus split amount) so the buyback hook only considers the available amount. The deployer then adjusts the weight proportionally for splits (`weight = mulDiv(weight, amount - splitAmount, amount)`). The 721 hook's specs come first in the merged result.
|
|
103
|
+
20. For cash outs, `beforeCashOutRecordedWith` checks the 721 hook first (from `_tiered721HookOf`, if `useDataHookForCashOut: true`), then the custom hook (from `_extraDataHookOf`). If the 721 hook has the flag set and reverts (e.g., `JB721Hook_UnexpectedTokenCashedOut` for fungible cashouts), the revert propagates. Set `useDataHookForCashOut: false` on the 721 metadata to skip it and let the custom hook handle cashouts.
|
|
104
|
+
21. The `launch721*` and `queue721*` functions accept a `dataHookConfig` parameter (type `JBDeployerHookConfig`) for the custom data hook to compose alongside the 721 hook. Each hook gets its own `useDataHookForPay`/`useDataHookForCashOut` flags. Pass `dataHook: address(0)` for no custom hook.
|
|
104
105
|
|
|
105
106
|
## Example Integration
|
|
106
107
|
|
|
@@ -149,7 +150,11 @@ address[] memory newSuckers = omnichainDeployer.deploySuckersFor({
|
|
|
149
150
|
deployTiersHookConfig: tiersHookConfig,
|
|
150
151
|
queueRulesetsConfig: queueConfig,
|
|
151
152
|
controller: controller,
|
|
152
|
-
|
|
153
|
+
dataHookConfig: JBDeployerHookConfig({
|
|
154
|
+
dataHook: IJBRulesetDataHook(address(buybackHook)),
|
|
155
|
+
useDataHookForPay: true,
|
|
156
|
+
useDataHookForCashOut: false
|
|
157
|
+
}),
|
|
153
158
|
salt: bytes32("my-hook-salt")
|
|
154
159
|
});
|
|
155
160
|
```
|
package/STYLE_GUIDE.md
CHANGED
|
@@ -314,14 +314,11 @@ Standard config across all repos:
|
|
|
314
314
|
```toml
|
|
315
315
|
[profile.default]
|
|
316
316
|
solc = '0.8.26'
|
|
317
|
-
evm_version = '
|
|
317
|
+
evm_version = 'cancun'
|
|
318
318
|
optimizer_runs = 200
|
|
319
319
|
libs = ["node_modules", "lib"]
|
|
320
320
|
fs_permissions = [{ access = "read-write", path = "./"}]
|
|
321
321
|
|
|
322
|
-
[profile.ci_sizes]
|
|
323
|
-
optimizer_runs = 200
|
|
324
|
-
|
|
325
322
|
[fuzz]
|
|
326
323
|
runs = 4096
|
|
327
324
|
|
|
@@ -336,12 +333,14 @@ multiline_func_header = "all"
|
|
|
336
333
|
wrap_comments = true
|
|
337
334
|
```
|
|
338
335
|
|
|
339
|
-
**
|
|
340
|
-
- `
|
|
341
|
-
- `
|
|
342
|
-
- `optimizer = false` only for deploy-all-v6 (stack-too-deep with optimization)
|
|
336
|
+
**Optional sections (add only when needed):**
|
|
337
|
+
- `[rpc_endpoints]` — repos with fork tests. Maps named endpoints to env vars (e.g. `ethereum = "${RPC_ETHEREUM_MAINNET}"`).
|
|
338
|
+
- `[profile.ci_sizes]` — only when CI needs different optimizer settings than defaults for the size check step (e.g. `optimizer_runs = 200` when the default profile uses a lower value).
|
|
343
339
|
|
|
344
|
-
**
|
|
340
|
+
**Common variations:**
|
|
341
|
+
- `via_ir = true` when hitting stack-too-deep
|
|
342
|
+
- `optimizer = false` when optimization causes stack-too-deep
|
|
343
|
+
- `optimizer_runs` reduced when deep struct nesting causes stack-too-deep at 200 runs
|
|
345
344
|
|
|
346
345
|
### CI Workflows
|
|
347
346
|
|
|
@@ -374,7 +373,7 @@ jobs:
|
|
|
374
373
|
env:
|
|
375
374
|
RPC_ETHEREUM_MAINNET: ${{ secrets.RPC_ETHEREUM_MAINNET }}
|
|
376
375
|
- name: Check contract sizes
|
|
377
|
-
run:
|
|
376
|
+
run: forge build --sizes --skip "*/test/**" --skip "*/script/**" --skip SphinxUtils
|
|
378
377
|
```
|
|
379
378
|
|
|
380
379
|
**lint.yml:**
|
|
@@ -396,11 +395,60 @@ jobs:
|
|
|
396
395
|
run: forge fmt --check
|
|
397
396
|
```
|
|
398
397
|
|
|
398
|
+
**slither.yml** (repos with `src/` contracts only):
|
|
399
|
+
```yaml
|
|
400
|
+
name: slither
|
|
401
|
+
on:
|
|
402
|
+
pull_request:
|
|
403
|
+
branches:
|
|
404
|
+
- main
|
|
405
|
+
push:
|
|
406
|
+
branches:
|
|
407
|
+
- main
|
|
408
|
+
jobs:
|
|
409
|
+
analyze:
|
|
410
|
+
runs-on: ubuntu-latest
|
|
411
|
+
steps:
|
|
412
|
+
- uses: actions/checkout@v4
|
|
413
|
+
with:
|
|
414
|
+
submodules: recursive
|
|
415
|
+
- uses: actions/setup-node@v4
|
|
416
|
+
with:
|
|
417
|
+
node-version: latest
|
|
418
|
+
- name: Install npm dependencies
|
|
419
|
+
run: npm install --omit=dev
|
|
420
|
+
- name: Install Foundry
|
|
421
|
+
uses: foundry-rs/foundry-toolchain@v1
|
|
422
|
+
- name: Run slither
|
|
423
|
+
uses: crytic/slither-action@v0.3.1
|
|
424
|
+
with:
|
|
425
|
+
slither-config: slither-ci.config.json
|
|
426
|
+
fail-on: medium
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
**slither-ci.config.json:**
|
|
430
|
+
```json
|
|
431
|
+
{
|
|
432
|
+
"detectors_to_exclude": "timestamp,uninitialized-local,naming-convention,solc-version,shadowing-local",
|
|
433
|
+
"exclude_informational": true,
|
|
434
|
+
"exclude_low": false,
|
|
435
|
+
"exclude_medium": false,
|
|
436
|
+
"exclude_high": false,
|
|
437
|
+
"disable_color": false,
|
|
438
|
+
"filter_paths": "(mocks/|test/|node_modules/|lib/)",
|
|
439
|
+
"legacy_ast": false
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**Variations:**
|
|
444
|
+
- Deployer-only repos (no `src/`, only `script/`) skip slither entirely — the action's internal `forge build` skips `test/` and `script/` by default, leaving nothing to compile.
|
|
445
|
+
- Use inline `// slither-disable-next-line <detector>` to suppress known false positives rather than adding to `detectors_to_exclude` in the config. The comment must be on the line immediately before the flagged expression.
|
|
446
|
+
|
|
399
447
|
### package.json
|
|
400
448
|
|
|
401
449
|
```json
|
|
402
450
|
{
|
|
403
|
-
"name": "@bananapus/
|
|
451
|
+
"name": "@bananapus/package-name-v6",
|
|
404
452
|
"version": "x.x.x",
|
|
405
453
|
"license": "MIT",
|
|
406
454
|
"repository": { "type": "git", "url": "git+https://github.com/Org/repo.git" },
|
|
@@ -420,13 +468,62 @@ jobs:
|
|
|
420
468
|
|
|
421
469
|
### remappings.txt
|
|
422
470
|
|
|
423
|
-
Every repo has a `remappings.txt
|
|
471
|
+
Every repo has a `remappings.txt` as the **single source of truth** for import remappings. Never add remappings to `foundry.toml`.
|
|
472
|
+
|
|
473
|
+
**Principle:** Import paths in Solidity source must match npm package names exactly. With `libs = ["node_modules", "lib"]`, Foundry auto-resolves `@scope/package/path/File.sol` → `node_modules/@scope/package/path/File.sol`. No remapping needed for packages installed as real directories.
|
|
474
|
+
|
|
475
|
+
**Note:** Auto-resolution does **not** work for symlinked packages (e.g. npm workspace links). Workspace repos like `deploy-all-v6` and `nana-cli-v6` need explicit `@scope/package/=node_modules/@scope/package/` remappings for each symlinked dependency.
|
|
476
|
+
|
|
477
|
+
**Minimal content** (most repos):
|
|
478
|
+
|
|
479
|
+
```
|
|
480
|
+
forge-std/=lib/forge-std/src/
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
Only add extra remappings for:
|
|
484
|
+
- **`forge-std`** — always needed (git submodule with `src/` subdirectory)
|
|
485
|
+
- **Repo-specific `lib/` submodules** that have no npm package (e.g., `hookmate/=lib/hookmate/src/`)
|
|
486
|
+
- **Symlinked npm packages** — need explicit `@scope/package/=node_modules/@scope/package/` entries
|
|
487
|
+
- **Nested transitive deps** — e.g., `@chainlink/contracts-ccip/` nested inside `@bananapus/suckers-v6/node_modules/`
|
|
488
|
+
|
|
489
|
+
**Never add remappings for:**
|
|
490
|
+
- npm packages that match their import path and are installed as real directories — they auto-resolve
|
|
491
|
+
- Short-form aliases (e.g., `@bananapus/core/` → `@bananapus/core-v6/src/`) — fix the import instead
|
|
492
|
+
- Packages available via npm that are also git submodules — remove the submodule, use npm
|
|
493
|
+
|
|
494
|
+
**Import path convention:**
|
|
495
|
+
|
|
496
|
+
| Package | Import path | Resolves to |
|
|
497
|
+
|---------|------------|-------------|
|
|
498
|
+
| `@bananapus/core-v6` | `@bananapus/core-v6/src/libraries/JBConstants.sol` | `node_modules/@bananapus/core-v6/src/...` |
|
|
499
|
+
| `@openzeppelin/contracts` | `@openzeppelin/contracts/token/ERC20/IERC20.sol` | `node_modules/@openzeppelin/contracts/...` |
|
|
500
|
+
| `@uniswap/v4-core` | `@uniswap/v4-core/src/interfaces/IPoolManager.sol` | `node_modules/@uniswap/v4-core/src/...` |
|
|
501
|
+
|
|
502
|
+
### Linting
|
|
503
|
+
|
|
504
|
+
Solar (Foundry's built-in linter) runs automatically during `forge build`. It scans all `.sol` files in `libs` directories, including `node_modules`.
|
|
424
505
|
|
|
506
|
+
**All test helpers must use relative imports** (e.g. `../../src/structs/JBRuleset.sol`), not bare `src/` imports. This ensures solar can resolve paths when the helper is consumed via npm in downstream repos.
|
|
507
|
+
|
|
508
|
+
### Fork Tests
|
|
509
|
+
|
|
510
|
+
Fork tests use named RPC endpoints defined in `[rpc_endpoints]` of `foundry.toml`. No skip guards — fork tests should hard-fail if the RPC endpoint is unavailable, making CI failures explicit.
|
|
511
|
+
|
|
512
|
+
```solidity
|
|
513
|
+
function setUp() public {
|
|
514
|
+
vm.createSelectFork("ethereum");
|
|
515
|
+
// ... setup code
|
|
516
|
+
}
|
|
425
517
|
```
|
|
426
|
-
|
|
518
|
+
|
|
519
|
+
The endpoint name (e.g. `"ethereum"`) maps to an env var via `foundry.toml`:
|
|
520
|
+
|
|
521
|
+
```toml
|
|
522
|
+
[rpc_endpoints]
|
|
523
|
+
ethereum = "${RPC_ETHEREUM_MAINNET}"
|
|
427
524
|
```
|
|
428
525
|
|
|
429
|
-
|
|
526
|
+
For multi-chain fork tests, add all needed endpoints.
|
|
430
527
|
|
|
431
528
|
### Formatting
|
|
432
529
|
|
|
@@ -437,15 +534,6 @@ Run `forge fmt` before committing. The `[fmt]` config in `foundry.toml` enforces
|
|
|
437
534
|
|
|
438
535
|
CI checks formatting via `forge fmt --check`.
|
|
439
536
|
|
|
440
|
-
### CI Secrets
|
|
441
|
-
|
|
442
|
-
| Secret | Purpose |
|
|
443
|
-
|--------|--------|
|
|
444
|
-
| `NPM_TOKEN` | npm publish access (used by `publish.yml`) |
|
|
445
|
-
| `RPC_ETHEREUM_MAINNET` | Ethereum mainnet RPC URL for fork tests (used by `test.yml`) |
|
|
446
|
-
|
|
447
|
-
Fork tests require `RPC_ETHEREUM_MAINNET` — they fail if it's missing.
|
|
448
|
-
|
|
449
537
|
### Branching
|
|
450
538
|
|
|
451
539
|
- `main` is the primary branch
|
|
@@ -463,4 +551,8 @@ Fork tests require `RPC_ETHEREUM_MAINNET` — they fail if it's missing.
|
|
|
463
551
|
|
|
464
552
|
### Contract Size Checks
|
|
465
553
|
|
|
466
|
-
CI runs `
|
|
554
|
+
CI runs `forge build --sizes` to catch contracts approaching the 24KB limit. When the repo's default `optimizer_runs` differs from what you want for size checking, use `FOUNDRY_PROFILE=ci_sizes forge build --sizes` with a `[profile.ci_sizes]` section in `foundry.toml`.
|
|
555
|
+
|
|
556
|
+
## Repo-Specific Deviations
|
|
557
|
+
|
|
558
|
+
None. This repo follows the standard configuration exactly.
|
package/foundry.toml
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bananapus/omnichain-deployers-v6",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
"artifacts": "source ./.env && npx sphinx artifacts --org-id 'ea165b21-7cdc-4d7b-be59-ecdd4c26bee4' --project-name 'nana-omnichain-deployers-v6'"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@bananapus/721-hook-v6": "^0.0.
|
|
20
|
+
"@bananapus/721-hook-v6": "^0.0.14",
|
|
21
21
|
"@bananapus/buyback-hook-v6": "^0.0.10",
|
|
22
|
-
"@bananapus/core-v6": "^0.0.
|
|
22
|
+
"@bananapus/core-v6": "^0.0.15",
|
|
23
23
|
"@bananapus/ownable-v6": "^0.0.7",
|
|
24
|
-
"@bananapus/permission-ids-v6": "^0.0.
|
|
25
|
-
"@bananapus/suckers-v6": "^0.0.
|
|
24
|
+
"@bananapus/permission-ids-v6": "^0.0.7",
|
|
25
|
+
"@bananapus/suckers-v6": "^0.0.9",
|
|
26
26
|
"@openzeppelin/contracts": "^5.6.1",
|
|
27
27
|
"@uniswap/v4-core": "^1.0.2"
|
|
28
28
|
},
|
package/remappings.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
forge-std/=lib/forge-std/src/
|
package/script/Deploy.s.sol
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
pragma solidity ^0.8.26;
|
|
3
3
|
|
|
4
|
-
import "@sphinx-labs/contracts/SphinxPlugin.sol";
|
|
4
|
+
import "@sphinx-labs/contracts/contracts/foundry/SphinxPlugin.sol";
|
|
5
5
|
import {Script, stdJson, VmSafe} from "forge-std/Script.sol";
|
|
6
6
|
|
|
7
7
|
import "@bananapus/core-v6/script/helpers/CoreDeploymentLib.sol";
|
|
@@ -3,7 +3,7 @@ pragma solidity 0.8.26;
|
|
|
3
3
|
|
|
4
4
|
import {stdJson} from "forge-std/Script.sol";
|
|
5
5
|
import {Vm} from "forge-std/Vm.sol";
|
|
6
|
-
import {SphinxConstants, NetworkInfo} from "@sphinx-labs/contracts/SphinxConstants.sol";
|
|
6
|
+
import {SphinxConstants, NetworkInfo} from "@sphinx-labs/contracts/contracts/foundry/SphinxConstants.sol";
|
|
7
7
|
|
|
8
8
|
import {JBOmnichainDeployer} from "src/JBOmnichainDeployer.sol";
|
|
9
9
|
|