@bananapus/omnichain-deployers-v6 0.0.56 → 0.0.58
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/README.md +9 -10
- package/package.json +2 -2
- package/references/operations.md +4 -4
- package/references/runtime.md +4 -4
- package/src/JBOmnichainDeployer.sol +28 -24
- package/src/interfaces/IJBOmnichainDeployer.sol +1 -0
- package/src/structs/JBDeployerHookConfig.sol +3 -3
- package/src/structs/JBOmnichain721Config.sol +4 -4
- package/src/structs/JBSuckerDeploymentConfig.sol +2 -0
- package/src/structs/JBTiered721HookConfig.sol +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
`@bananapus/omnichain-deployers-v6` launches Juicebox projects with cross-chain suckers and a 721 hook already wired in. It is the package you use when the default project shape should be omnichain from day one.
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
## Documentation
|
|
7
6
|
|
|
8
7
|
- [INVARIANTS.md](./INVARIANTS.md) — runtime guarantees enforced by `JBOmnichainDeployer`, per-function caller / effect / invariant inventory, and cross-cutting invariants.
|
|
@@ -29,13 +28,13 @@ The wrapper exists so sucker-triggered flows can be exempted from project-specif
|
|
|
29
28
|
|
|
30
29
|
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.
|
|
31
30
|
|
|
32
|
-
## Key
|
|
31
|
+
## Key contract
|
|
33
32
|
|
|
34
33
|
| Contract | Role |
|
|
35
34
|
| --- | --- |
|
|
36
35
|
| `JBOmnichainDeployer` | Launches projects and rulesets, manages per-ruleset hook composition, and deploys suckers with deterministic salts. |
|
|
37
36
|
|
|
38
|
-
## Mental
|
|
37
|
+
## Mental model
|
|
39
38
|
|
|
40
39
|
This repo owns orchestration plus runtime wrapping:
|
|
41
40
|
|
|
@@ -43,21 +42,21 @@ This repo owns orchestration plus runtime wrapping:
|
|
|
43
42
|
2. remember which hook composition belongs to which ruleset
|
|
44
43
|
3. special-case sucker behavior so bridge flows are not broken by project-specific logic
|
|
45
44
|
|
|
46
|
-
## Read
|
|
45
|
+
## Read these files first
|
|
47
46
|
|
|
48
47
|
1. `src/JBOmnichainDeployer.sol`
|
|
49
48
|
2. `nana-suckers-v6/src/JBSucker.sol`
|
|
50
49
|
3. `nana-721-hook-v6/src/JB721TiersHook.sol`
|
|
51
50
|
4. the extra hook repo, if the deployment composes one
|
|
52
51
|
|
|
53
|
-
## Integration
|
|
52
|
+
## Integration traps
|
|
54
53
|
|
|
55
54
|
- this repo wraps hooks and bridge flows together, so ownership and hook-order assumptions matter as much as deployment salt
|
|
56
55
|
- ruleset ID prediction is a real implementation dependency
|
|
57
56
|
- the deployer can carry forward an existing 721 hook shape, so stale hook assumptions can leak across deployments
|
|
58
57
|
- bridge-safe wrapper behavior is part of the runtime trust model
|
|
59
58
|
|
|
60
|
-
## Where
|
|
59
|
+
## Where state lives
|
|
61
60
|
|
|
62
61
|
- orchestration and wrapper logic: `JBOmnichainDeployer`
|
|
63
62
|
- bridge runtime state: `nana-suckers-v6`
|
|
@@ -83,11 +82,11 @@ Useful scripts:
|
|
|
83
82
|
- `npm run deploy:mainnets`
|
|
84
83
|
- `npm run deploy:testnets`
|
|
85
84
|
|
|
86
|
-
## Deployment
|
|
85
|
+
## Deployment notes
|
|
87
86
|
|
|
88
87
|
This repo assumes the 721 hook, address registry, buyback hook, suckers, ownable, and core packages are already available. Matching salts from the same sender keep sucker addresses deterministic across chains.
|
|
89
88
|
|
|
90
|
-
## Repository
|
|
89
|
+
## Repository layout
|
|
91
90
|
|
|
92
91
|
```text
|
|
93
92
|
src/
|
|
@@ -101,14 +100,14 @@ script/
|
|
|
101
100
|
helpers/
|
|
102
101
|
```
|
|
103
102
|
|
|
104
|
-
## Risks
|
|
103
|
+
## Risks and notes
|
|
105
104
|
|
|
106
105
|
- ruleset ID prediction is part of the implementation strategy
|
|
107
106
|
- hook composition order matters because the 721 hook runs before any extra custom hook
|
|
108
107
|
- default empty-tier 721 config is convenient, but teams should still decide explicitly whether the hook participates in cash-out behavior
|
|
109
108
|
- deterministic salts only help with cross-chain address alignment when sender and configuration match exactly
|
|
110
109
|
|
|
111
|
-
## For AI
|
|
110
|
+
## For AI agents
|
|
112
111
|
|
|
113
112
|
- Describe this repo as an orchestration and wrapper layer, not as the source of sucker or 721 runtime behavior.
|
|
114
113
|
- Start with `JBOmnichainDeployer`, then inspect the sibling repo that owns the behavior being questioned.
|
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.58",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@bananapus/core-v6": "^0.0.78",
|
|
29
29
|
"@bananapus/ownable-v6": "^0.0.34",
|
|
30
30
|
"@bananapus/permission-ids-v6": "^0.0.28",
|
|
31
|
-
"@bananapus/suckers-v6": "^0.0.
|
|
31
|
+
"@bananapus/suckers-v6": "^0.0.69",
|
|
32
32
|
"@openzeppelin/contracts": "5.6.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
package/references/operations.md
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
# Omnichain Deployer Operations
|
|
2
2
|
|
|
3
|
-
## Deployment
|
|
3
|
+
## Deployment surface
|
|
4
4
|
|
|
5
5
|
- [`src/JBOmnichainDeployer.sol`](../src/JBOmnichainDeployer.sol) is the first stop for launch, queue, and sucker-deployment behavior.
|
|
6
6
|
- [`script/Deploy.s.sol`](../script/Deploy.s.sol) is the deployment entry point when the question is about current wiring rather than wrapper semantics.
|
|
7
7
|
- [`src/structs/`](../src/structs/) defines the deploy and queue config types that often drift from memory.
|
|
8
8
|
|
|
9
|
-
## Change
|
|
9
|
+
## Change checklist
|
|
10
10
|
|
|
11
11
|
- If you edit launch or queue behavior, verify ruleset IDs, carry-forward behavior, and stored hook config keys together.
|
|
12
12
|
- If you edit salt handling, confirm deterministic-address assumptions for both suckers and 721 hooks.
|
|
13
13
|
- If you edit wrapper behavior, check both pay and cash-out paths, not only one.
|
|
14
14
|
- If you touch mint-permission logic, confirm whether the permission should come from suckers, the extra hook, or neither.
|
|
15
15
|
|
|
16
|
-
## Common
|
|
16
|
+
## Common failure modes
|
|
17
17
|
|
|
18
18
|
- Wrapper behavior is blamed on the composed hook, but the deployer stored the wrong hook config for the ruleset.
|
|
19
19
|
- A same-block queue assumption breaks predicted ruleset IDs and silently strands stored config.
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
- Deterministic deployment assumptions fail because sender or salt composition changed.
|
|
22
22
|
- Existing-project sucker deployment is treated as a pure `DEPLOY_SUCKERS` flow even though the registry also performs token mapping, so missing `MAP_SUCKER_TOKEN` authority for the registry shows up only when the deploy path reaches `mapTokens`.
|
|
23
23
|
|
|
24
|
-
## Useful
|
|
24
|
+
## Useful proof points
|
|
25
25
|
|
|
26
26
|
- [`test/JBOmnichainDeployer.t.sol`](../test/JBOmnichainDeployer.t.sol) for baseline deploy and queue flows.
|
|
27
27
|
- [`test/TestRegressionGaps.sol`](../test/TestRegressionGaps.sol) for pinned edge cases.
|
package/references/runtime.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Omnichain Deployer Runtime
|
|
2
2
|
|
|
3
|
-
## Contract
|
|
3
|
+
## Contract role
|
|
4
4
|
|
|
5
5
|
- [`src/JBOmnichainDeployer.sol`](../src/JBOmnichainDeployer.sol) launches projects, deploys suckers, installs a 721 hook, wraps extra hooks, and serves as the live ruleset data-hook wrapper for the projects it creates.
|
|
6
6
|
|
|
7
|
-
## Runtime
|
|
7
|
+
## Runtime path
|
|
8
8
|
|
|
9
9
|
1. Project launch or ruleset queue stores the relevant 721 hook and optional extra hook per ruleset.
|
|
10
10
|
2. The deployer installs itself as the data-hook wrapper on the ruleset.
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
4. On cash out, it can short-circuit for suckers, otherwise it forwards into the configured hook stack in order.
|
|
13
13
|
5. Mint permission queries can be granted by suckers or by the configured extra hook.
|
|
14
14
|
|
|
15
|
-
## High-
|
|
15
|
+
## High-risk areas
|
|
16
16
|
|
|
17
17
|
- Ruleset ID prediction: if the predicted ID is wrong, hook config can be stored under the wrong key.
|
|
18
18
|
- Hook composition order: 721 logic runs before any extra hook, which affects both specs and accounting.
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
- Carry-forward logic: queueing rulesets without new tiers intentionally reuses the latest 721 hook.
|
|
21
21
|
- Meta-transaction sender handling: salt derivation uses `_msgSender()`, not raw `msg.sender`.
|
|
22
22
|
|
|
23
|
-
## Tests
|
|
23
|
+
## Tests to trust first
|
|
24
24
|
|
|
25
25
|
- [`test/Tiered721HookComposition.t.sol`](../test/Tiered721HookComposition.t.sol) for hook-composition behavior.
|
|
26
26
|
- [`test/JBOmnichainDeployerGuard.t.sol`](../test/JBOmnichainDeployerGuard.t.sol) and [`test/OmnichainDeployerAttacks.t.sol`](../test/OmnichainDeployerAttacks.t.sol) for safety properties.
|
|
@@ -22,6 +22,7 @@ import {JBOwnable} from "@bananapus/ownable-v6/src/JBOwnable.sol";
|
|
|
22
22
|
import {JBPermissionIds} from "@bananapus/permission-ids-v6/src/JBPermissionIds.sol";
|
|
23
23
|
import {IJBPeerChainAdjustedAccounts} from "@bananapus/suckers-v6/src/interfaces/IJBPeerChainAdjustedAccounts.sol";
|
|
24
24
|
import {IJBSuckerRegistry} from "@bananapus/suckers-v6/src/interfaces/IJBSuckerRegistry.sol";
|
|
25
|
+
import {JBSourceContext} from "@bananapus/suckers-v6/src/structs/JBSourceContext.sol";
|
|
25
26
|
import {ERC2771Context} from "@openzeppelin/contracts/metatx/ERC2771Context.sol";
|
|
26
27
|
import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
|
|
27
28
|
import {Context} from "@openzeppelin/contracts/utils/Context.sol";
|
|
@@ -157,6 +158,7 @@ contract JBOmnichainDeployer is
|
|
|
157
158
|
/// call on both chains for deterministic address matching.
|
|
158
159
|
/// @param projectId The ID of the project to deploy suckers for.
|
|
159
160
|
/// @param suckerDeploymentConfiguration The suckers to set up for the project.
|
|
161
|
+
/// @return suckers The addresses of the deployed suckers.
|
|
160
162
|
function deploySuckersFor(
|
|
161
163
|
uint256 projectId,
|
|
162
164
|
JBSuckerDeploymentConfig calldata suckerDeploymentConfiguration
|
|
@@ -434,7 +436,7 @@ contract JBOmnichainDeployer is
|
|
|
434
436
|
// If the ruleset aggregates cross-chain state, add remote supply and surplus.
|
|
435
437
|
if (!context.scopeCashOutsToLocalBalances) {
|
|
436
438
|
totalSupply += SUCKER_REGISTRY.remoteTotalSupplyOf(context.projectId);
|
|
437
|
-
effectiveSurplusValue += SUCKER_REGISTRY.
|
|
439
|
+
effectiveSurplusValue += SUCKER_REGISTRY.totalRemoteSurplusOf({
|
|
438
440
|
projectId: context.projectId,
|
|
439
441
|
decimals: context.surplus.decimals,
|
|
440
442
|
currency: uint256(context.surplus.currency)
|
|
@@ -682,44 +684,38 @@ contract JBOmnichainDeployer is
|
|
|
682
684
|
}
|
|
683
685
|
|
|
684
686
|
/// @notice Forwards peer-chain adjusted accounts from the stored extra data hook. Suckers call this on the active
|
|
685
|
-
/// data hook (which is this deployer after wrapping) to learn about additional supply
|
|
686
|
-
/// be included in cross-chain snapshots. Without forwarding, the extra hook's peer-chain
|
|
687
|
-
/// masked, causing the bonding curve to use only local values and over-reclaiming on peer
|
|
687
|
+
/// data hook (which is this deployer after wrapping) to learn about additional supply and per-context surplus and
|
|
688
|
+
/// balance that should be included in cross-chain snapshots. Without forwarding, the extra hook's peer-chain
|
|
689
|
+
/// adjustments are silently masked, causing the bonding curve to use only local values and over-reclaiming on peer
|
|
690
|
+
/// chains.
|
|
688
691
|
/// @dev Part of `IJBPeerChainAdjustedAccounts`. Uses staticcall to safely handle extra hooks that do not implement
|
|
689
692
|
/// this interface.
|
|
690
693
|
/// @param projectId The ID of the project to snapshot.
|
|
691
|
-
/// @param decimals The decimals the returned surplus and balance should use.
|
|
692
|
-
/// @param currency The currency the returned surplus and balance should be in terms of.
|
|
693
694
|
/// @return supply The extra supply to include in `sourceTotalSupply`.
|
|
694
|
-
/// @return
|
|
695
|
-
|
|
696
|
-
function peerChainAdjustedAccountsOf(
|
|
697
|
-
uint256 projectId,
|
|
698
|
-
uint256 decimals,
|
|
699
|
-
uint256 currency
|
|
700
|
-
)
|
|
695
|
+
/// @return contexts The extra per-context surplus and balance to include in the snapshot, un-valued.
|
|
696
|
+
function peerChainAdjustedAccountsOf(uint256 projectId)
|
|
701
697
|
external
|
|
702
698
|
view
|
|
703
699
|
override
|
|
704
|
-
returns (uint256 supply,
|
|
700
|
+
returns (uint256 supply, JBSourceContext[] memory contexts)
|
|
705
701
|
{
|
|
706
702
|
// Get the current ruleset from the canonical controller to look up the stored extra hook.
|
|
707
703
|
(JBRuleset memory ruleset,) = CONTROLLER.currentRulesetOf(projectId);
|
|
708
704
|
|
|
709
705
|
// Look up the extra data hook for this project's current ruleset.
|
|
710
706
|
JBDeployerHookConfig memory extraHook = _extraDataHookOf[projectId][ruleset.id];
|
|
711
|
-
if (address(extraHook.dataHook) == address(0)) return (0,
|
|
707
|
+
if (address(extraHook.dataHook) == address(0)) return (0, new JBSourceContext[](0));
|
|
712
708
|
|
|
713
709
|
// Forward via staticcall — the extra hook may or may not implement IJBPeerChainAdjustedAccounts.
|
|
714
710
|
(bool success, bytes memory data) = address(extraHook.dataHook)
|
|
715
|
-
.staticcall(
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
if (!success || data.length < 96) return (0,
|
|
721
|
-
|
|
722
|
-
return abi.decode(data, (uint256,
|
|
711
|
+
.staticcall(abi.encodeCall(IJBPeerChainAdjustedAccounts.peerChainAdjustedAccountsOf, (projectId)));
|
|
712
|
+
|
|
713
|
+
// A well-formed `(uint256, JBSourceContext[])` return is at least three words: the supply, the array offset,
|
|
714
|
+
// and the array length. Anything shorter (an empty return, a hook with no code, or a mismatched ABI) is
|
|
715
|
+
// treated as no contribution rather than letting the decode revert.
|
|
716
|
+
if (!success || data.length < 96) return (0, new JBSourceContext[](0));
|
|
717
|
+
|
|
718
|
+
return abi.decode(data, (uint256, JBSourceContext[]));
|
|
723
719
|
}
|
|
724
720
|
|
|
725
721
|
//*********************************************************************//
|
|
@@ -765,6 +761,9 @@ contract JBOmnichainDeployer is
|
|
|
765
761
|
}
|
|
766
762
|
|
|
767
763
|
/// @notice Internal implementation of `launchProjectFor`.
|
|
764
|
+
/// @return projectId The ID of the newly launched project.
|
|
765
|
+
/// @return hook The 721 tiers hook that was deployed for the project.
|
|
766
|
+
/// @return suckers The addresses of the deployed suckers.
|
|
768
767
|
function _launchProjectFor(
|
|
769
768
|
address owner,
|
|
770
769
|
string calldata projectUri,
|
|
@@ -828,6 +827,8 @@ contract JBOmnichainDeployer is
|
|
|
828
827
|
}
|
|
829
828
|
|
|
830
829
|
/// @notice Internal implementation of `launchRulesetsFor`.
|
|
830
|
+
/// @return rulesetId The ID of the newly launched rulesets.
|
|
831
|
+
/// @return hook The 721 tiers hook that was deployed for the project.
|
|
831
832
|
function _launchRulesetsFor(
|
|
832
833
|
uint256 projectId,
|
|
833
834
|
string calldata projectUri,
|
|
@@ -880,6 +881,8 @@ contract JBOmnichainDeployer is
|
|
|
880
881
|
}
|
|
881
882
|
|
|
882
883
|
/// @notice Internal implementation of `queueRulesetsOf`.
|
|
884
|
+
/// @return rulesetId The ID of the newly queued rulesets.
|
|
885
|
+
/// @return hook The 721 tiers hook (newly deployed or carried forward from the previous ruleset).
|
|
883
886
|
function _queueRulesetsOf(
|
|
884
887
|
uint256 projectId,
|
|
885
888
|
JBOmnichain721Config memory deploy721Config,
|
|
@@ -924,7 +927,8 @@ contract JBOmnichainDeployer is
|
|
|
924
927
|
// (or has no approval hook), its hook config should take precedence.
|
|
925
928
|
// Conservative: only use Approved or Empty status. ApprovalExpected is intentionally
|
|
926
929
|
// excluded because hook selection is irreversible — if the pending ruleset is later rejected
|
|
927
|
-
// by the approval hook,
|
|
930
|
+
// by the approval hook, the deployer would otherwise lock in a hook from a ruleset that never
|
|
931
|
+
// became active.
|
|
928
932
|
(JBRuleset memory latestQueued, JBApprovalStatus approvalStatus) =
|
|
929
933
|
CONTROLLER.RULESETS().latestQueuedOf(projectId);
|
|
930
934
|
if (
|
|
@@ -13,6 +13,7 @@ import {JBSuckerDeploymentConfig} from "../structs/JBSuckerDeploymentConfig.sol"
|
|
|
13
13
|
/// pay/cash-out logic through a data hook wrapper.
|
|
14
14
|
interface IJBOmnichainDeployer {
|
|
15
15
|
/// @notice The controller used for every project launch and ruleset queue.
|
|
16
|
+
/// @return controller The controller used for every project launch and ruleset queue.
|
|
16
17
|
function CONTROLLER() external view returns (IJBController);
|
|
17
18
|
|
|
18
19
|
/// @notice Get the extra data hook for a project and ruleset.
|
|
@@ -5,9 +5,9 @@ import {IJBRulesetDataHook} from "@bananapus/core-v6/src/interfaces/IJBRulesetDa
|
|
|
5
5
|
|
|
6
6
|
/// @notice Configuration for an extra data hook (e.g. a buyback hook) that the omnichain deployer delegates to
|
|
7
7
|
/// alongside the primary 721 hook. Stored per project per ruleset.
|
|
8
|
-
/// @
|
|
9
|
-
/// @
|
|
10
|
-
/// @
|
|
8
|
+
/// @custom:member dataHook The extra data hook contract to delegate to.
|
|
9
|
+
/// @custom:member useDataHookForPay Whether to call this hook's `beforePayRecordedWith` during payments.
|
|
10
|
+
/// @custom:member useDataHookForCashOut Whether to call this hook's `beforeCashOutRecordedWith` during cash outs.
|
|
11
11
|
struct JBDeployerHookConfig {
|
|
12
12
|
IJBRulesetDataHook dataHook;
|
|
13
13
|
bool useDataHookForPay;
|
|
@@ -4,10 +4,10 @@ pragma solidity ^0.8.0;
|
|
|
4
4
|
import {JBDeploy721TiersHookConfig} from "@bananapus/721-hook-v6/src/structs/JBDeploy721TiersHookConfig.sol";
|
|
5
5
|
|
|
6
6
|
/// @notice Configuration for deploying a 721 tiers hook alongside omnichain rulesets.
|
|
7
|
-
/// @
|
|
8
|
-
/// @
|
|
9
|
-
/// @
|
|
10
|
-
/// cross-chain deterministic addresses require the same sender on each chain.
|
|
7
|
+
/// @custom:member deployTiersHookConfig Configuration which dictates the behavior of the 721 tiers hook to deploy.
|
|
8
|
+
/// @custom:member useDataHookForCashOut Whether the 721 hook should handle cash outs (via beforeCashOutRecordedWith).
|
|
9
|
+
/// @custom:member salt A salt to use for the deterministic 721 hook deployment. Combined with `msg.sender` internally,
|
|
10
|
+
/// so cross-chain deterministic addresses require the same sender on each chain.
|
|
11
11
|
struct JBOmnichain721Config {
|
|
12
12
|
JBDeploy721TiersHookConfig deployTiersHookConfig;
|
|
13
13
|
bool useDataHookForCashOut;
|
|
@@ -3,6 +3,8 @@ pragma solidity ^0.8.0;
|
|
|
3
3
|
|
|
4
4
|
import {JBSuckerDeployerConfig} from "@bananapus/suckers-v6/src/structs/JBSuckerDeployerConfig.sol";
|
|
5
5
|
|
|
6
|
+
/// @notice Configuration for deploying a project's suckers in one call: the per-peer deployer configs plus the salt
|
|
7
|
+
/// that seeds deterministic addresses.
|
|
6
8
|
/// @custom:member deployerConfigurations Sucker deployer configs and token mappings for peer chains.
|
|
7
9
|
/// @custom:member salt The salt combined with `_msgSender()` to create deterministic sucker addresses.
|
|
8
10
|
struct JBSuckerDeploymentConfig {
|
|
@@ -4,8 +4,8 @@ pragma solidity ^0.8.0;
|
|
|
4
4
|
import {IJB721TiersHook} from "@bananapus/721-hook-v6/src/interfaces/IJB721TiersHook.sol";
|
|
5
5
|
|
|
6
6
|
/// @notice Stored configuration for a project's tiered 721 hook within a specific ruleset.
|
|
7
|
-
/// @
|
|
8
|
-
/// @
|
|
7
|
+
/// @custom:member hook The tiered 721 hook contract used for NFT minting on payments.
|
|
8
|
+
/// @custom:member useDataHookForCashOut Whether the 721 hook should participate in cash-out tax calculations and NFT
|
|
9
9
|
/// redemptions.
|
|
10
10
|
struct JBTiered721HookConfig {
|
|
11
11
|
IJB721TiersHook hook;
|