@bananapus/721-hook-v6 0.0.1
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/.gas-snapshot +152 -0
- package/LICENSE +21 -0
- package/README.md +253 -0
- package/SKILLS.md +140 -0
- package/docs/book.css +13 -0
- package/docs/book.toml +12 -0
- package/docs/solidity.min.js +74 -0
- package/docs/src/README.md +253 -0
- package/docs/src/SUMMARY.md +38 -0
- package/docs/src/src/JB721TiersHook.sol/contract.JB721TiersHook.md +645 -0
- package/docs/src/src/JB721TiersHookDeployer.sol/contract.JB721TiersHookDeployer.md +99 -0
- package/docs/src/src/JB721TiersHookProjectDeployer.sol/contract.JB721TiersHookProjectDeployer.md +288 -0
- package/docs/src/src/JB721TiersHookStore.sol/contract.JB721TiersHookStore.md +1096 -0
- package/docs/src/src/README.md +11 -0
- package/docs/src/src/abstract/ERC721.sol/abstract.ERC721.md +430 -0
- package/docs/src/src/abstract/JB721Hook.sol/abstract.JB721Hook.md +309 -0
- package/docs/src/src/abstract/README.md +5 -0
- package/docs/src/src/interfaces/IJB721Hook.sol/interface.IJB721Hook.md +29 -0
- package/docs/src/src/interfaces/IJB721TiersHook.sol/interface.IJB721TiersHook.md +203 -0
- package/docs/src/src/interfaces/IJB721TiersHookDeployer.sol/interface.IJB721TiersHookDeployer.md +25 -0
- package/docs/src/src/interfaces/IJB721TiersHookProjectDeployer.sol/interface.IJB721TiersHookProjectDeployer.md +64 -0
- package/docs/src/src/interfaces/IJB721TiersHookStore.sol/interface.IJB721TiersHookStore.md +265 -0
- package/docs/src/src/interfaces/IJB721TokenUriResolver.sol/interface.IJB721TokenUriResolver.md +12 -0
- package/docs/src/src/interfaces/README.md +9 -0
- package/docs/src/src/libraries/JB721Constants.sol/library.JB721Constants.md +14 -0
- package/docs/src/src/libraries/JB721TiersRulesetMetadataResolver.sol/library.JB721TiersRulesetMetadataResolver.md +68 -0
- package/docs/src/src/libraries/JBBitmap.sol/library.JBBitmap.md +82 -0
- package/docs/src/src/libraries/JBIpfsDecoder.sol/library.JBIpfsDecoder.md +61 -0
- package/docs/src/src/libraries/README.md +7 -0
- package/docs/src/src/structs/JB721InitTiersConfig.sol/struct.JB721InitTiersConfig.md +27 -0
- package/docs/src/src/structs/JB721Tier.sol/struct.JB721Tier.md +59 -0
- package/docs/src/src/structs/JB721TierConfig.sol/struct.JB721TierConfig.md +60 -0
- package/docs/src/src/structs/JB721TiersHookFlags.sol/struct.JB721TiersHookFlags.md +26 -0
- package/docs/src/src/structs/JB721TiersMintReservesConfig.sol/struct.JB721TiersMintReservesConfig.md +16 -0
- package/docs/src/src/structs/JB721TiersRulesetMetadata.sol/struct.JB721TiersRulesetMetadata.md +20 -0
- package/docs/src/src/structs/JB721TiersSetDiscountPercentConfig.sol/struct.JB721TiersSetDiscountPercentConfig.md +16 -0
- package/docs/src/src/structs/JBBitmapWord.sol/struct.JBBitmapWord.md +19 -0
- package/docs/src/src/structs/JBDeploy721TiersHookConfig.sol/struct.JBDeploy721TiersHookConfig.md +34 -0
- package/docs/src/src/structs/JBLaunchProjectConfig.sol/struct.JBLaunchProjectConfig.md +23 -0
- package/docs/src/src/structs/JBLaunchRulesetsConfig.sol/struct.JBLaunchRulesetsConfig.md +22 -0
- package/docs/src/src/structs/JBPayDataHookRulesetConfig.sol/struct.JBPayDataHookRulesetConfig.md +51 -0
- package/docs/src/src/structs/JBPayDataHookRulesetMetadata.sol/struct.JBPayDataHookRulesetMetadata.md +66 -0
- package/docs/src/src/structs/JBQueueRulesetsConfig.sol/struct.JBQueueRulesetsConfig.md +21 -0
- package/docs/src/src/structs/JBStored721Tier.sol/struct.JBStored721Tier.md +42 -0
- package/docs/src/src/structs/README.md +18 -0
- package/foundry.lock +11 -0
- package/foundry.toml +22 -0
- package/package.json +31 -0
- package/remappings.txt +1 -0
- package/script/Deploy.s.sol +140 -0
- package/script/helpers/Hook721DeploymentLib.sol +81 -0
- package/slither-ci.config.json +10 -0
- package/sphinx.lock +476 -0
- package/src/JB721TiersHook.sol +765 -0
- package/src/JB721TiersHookDeployer.sol +114 -0
- package/src/JB721TiersHookProjectDeployer.sol +413 -0
- package/src/JB721TiersHookStore.sol +1195 -0
- package/src/abstract/ERC721.sol +484 -0
- package/src/abstract/JB721Hook.sol +279 -0
- package/src/interfaces/IJB721Hook.sol +21 -0
- package/src/interfaces/IJB721TiersHook.sol +135 -0
- package/src/interfaces/IJB721TiersHookDeployer.sol +22 -0
- package/src/interfaces/IJB721TiersHookProjectDeployer.sol +76 -0
- package/src/interfaces/IJB721TiersHookStore.sol +220 -0
- package/src/interfaces/IJB721TokenUriResolver.sol +10 -0
- package/src/libraries/JB721Constants.sol +7 -0
- package/src/libraries/JB721TiersRulesetMetadataResolver.sol +44 -0
- package/src/libraries/JBBitmap.sol +57 -0
- package/src/libraries/JBIpfsDecoder.sol +95 -0
- package/src/structs/JB721InitTiersConfig.sol +20 -0
- package/src/structs/JB721Tier.sol +39 -0
- package/src/structs/JB721TierConfig.sol +40 -0
- package/src/structs/JB721TiersHookFlags.sol +17 -0
- package/src/structs/JB721TiersMintReservesConfig.sol +9 -0
- package/src/structs/JB721TiersRulesetMetadata.sol +12 -0
- package/src/structs/JB721TiersSetDiscountPercentConfig.sol +9 -0
- package/src/structs/JBBitmapWord.sol +11 -0
- package/src/structs/JBDeploy721TiersHookConfig.sol +25 -0
- package/src/structs/JBLaunchProjectConfig.sol +18 -0
- package/src/structs/JBLaunchRulesetsConfig.sol +17 -0
- package/src/structs/JBPayDataHookRulesetConfig.sol +44 -0
- package/src/structs/JBPayDataHookRulesetMetadata.sol +46 -0
- package/src/structs/JBQueueRulesetsConfig.sol +13 -0
- package/src/structs/JBStored721Tier.sol +24 -0
- package/test/721HookAttacks.t.sol +396 -0
- package/test/E2E/Pay_Mint_Redeem_E2E.t.sol +944 -0
- package/test/invariants/TierLifecycleInvariant.t.sol +187 -0
- package/test/invariants/TieredHookStoreInvariant.t.sol +81 -0
- package/test/invariants/handlers/TierLifecycleHandler.sol +262 -0
- package/test/invariants/handlers/TierStoreHandler.sol +155 -0
- package/test/unit/JB721TiersRulesetMetadataResolver.t.sol +141 -0
- package/test/unit/JBBitmap.t.sol +169 -0
- package/test/unit/JBIpfsDecoder.t.sol +131 -0
- package/test/unit/M6_TierSupplyCheck.t.sol +220 -0
- package/test/unit/adjustTier_Unit.t.sol +1740 -0
- package/test/unit/deployer_Unit.t.sol +103 -0
- package/test/unit/getters_constructor_Unit.t.sol +548 -0
- package/test/unit/mintFor_mintReservesFor_Unit.t.sol +443 -0
- package/test/unit/pay_Unit.t.sol +1537 -0
- package/test/unit/redeem_Unit.t.sol +459 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.23;
|
|
3
|
+
|
|
4
|
+
import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
|
|
5
|
+
import {JBOwnable} from "@bananapus/ownable-v6/src/JBOwnable.sol";
|
|
6
|
+
import {LibClone} from "solady/src/utils/LibClone.sol";
|
|
7
|
+
import {ERC2771Context} from "@openzeppelin/contracts/metatx/ERC2771Context.sol";
|
|
8
|
+
|
|
9
|
+
import {JB721TiersHook} from "./JB721TiersHook.sol";
|
|
10
|
+
import {IJB721TiersHookDeployer} from "./interfaces/IJB721TiersHookDeployer.sol";
|
|
11
|
+
import {IJB721TiersHook} from "./interfaces/IJB721TiersHook.sol";
|
|
12
|
+
import {IJB721TiersHookStore} from "./interfaces/IJB721TiersHookStore.sol";
|
|
13
|
+
import {JBDeploy721TiersHookConfig} from "./structs/JBDeploy721TiersHookConfig.sol";
|
|
14
|
+
|
|
15
|
+
/// @title JB721TiersHookDeployer
|
|
16
|
+
/// @notice Deploys a `JB721TiersHook` for an existing project.
|
|
17
|
+
contract JB721TiersHookDeployer is ERC2771Context, IJB721TiersHookDeployer {
|
|
18
|
+
//*********************************************************************//
|
|
19
|
+
// --------------- public immutable stored properties ---------------- //
|
|
20
|
+
//*********************************************************************//
|
|
21
|
+
|
|
22
|
+
/// @notice A registry which stores references to contracts and their deployers.
|
|
23
|
+
IJBAddressRegistry public immutable ADDRESS_REGISTRY;
|
|
24
|
+
|
|
25
|
+
/// @notice A 721 tiers hook.
|
|
26
|
+
JB721TiersHook public immutable HOOK;
|
|
27
|
+
|
|
28
|
+
/// @notice The contract that stores and manages data for this contract's NFTs.
|
|
29
|
+
IJB721TiersHookStore public immutable STORE;
|
|
30
|
+
|
|
31
|
+
//*********************************************************************//
|
|
32
|
+
// ----------------------- internal properties ----------------------- //
|
|
33
|
+
//*********************************************************************//
|
|
34
|
+
|
|
35
|
+
/// @notice This contract's current nonce, used for the Juicebox address registry.
|
|
36
|
+
uint256 internal _nonce;
|
|
37
|
+
|
|
38
|
+
//*********************************************************************//
|
|
39
|
+
// -------------------------- constructor ---------------------------- //
|
|
40
|
+
//*********************************************************************//
|
|
41
|
+
|
|
42
|
+
/// @param hook Reference copy of a hook.
|
|
43
|
+
/// @param store The contract that stores and manages data for this contract's NFTs.
|
|
44
|
+
/// @param addressRegistry A registry which stores references to contracts and their deployers.
|
|
45
|
+
/// @param trustedForwarder The trusted forwarder for the ERC2771Context.
|
|
46
|
+
constructor(
|
|
47
|
+
JB721TiersHook hook,
|
|
48
|
+
IJB721TiersHookStore store,
|
|
49
|
+
IJBAddressRegistry addressRegistry,
|
|
50
|
+
address trustedForwarder
|
|
51
|
+
)
|
|
52
|
+
ERC2771Context(trustedForwarder)
|
|
53
|
+
{
|
|
54
|
+
HOOK = hook;
|
|
55
|
+
STORE = store;
|
|
56
|
+
ADDRESS_REGISTRY = addressRegistry;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
//*********************************************************************//
|
|
60
|
+
// ---------------------- external transactions ---------------------- //
|
|
61
|
+
//*********************************************************************//
|
|
62
|
+
|
|
63
|
+
/// @notice Deploys a 721 tiers hook for the specified project.
|
|
64
|
+
/// @param projectId The ID of the project to deploy the hook for.
|
|
65
|
+
/// @param deployTiersHookConfig The config to deploy the hook with, which determines its behavior.
|
|
66
|
+
/// @param salt A salt to use for the deterministic deployment.
|
|
67
|
+
/// @return newHook The address of the newly deployed hook.
|
|
68
|
+
function deployHookFor(
|
|
69
|
+
uint256 projectId,
|
|
70
|
+
JBDeploy721TiersHookConfig calldata deployTiersHookConfig,
|
|
71
|
+
bytes32 salt
|
|
72
|
+
)
|
|
73
|
+
external
|
|
74
|
+
override
|
|
75
|
+
returns (IJB721TiersHook newHook)
|
|
76
|
+
{
|
|
77
|
+
// Deploy the governance variant specified by the config.
|
|
78
|
+
newHook = IJB721TiersHook(
|
|
79
|
+
salt == bytes32(0)
|
|
80
|
+
? LibClone.clone(address(HOOK))
|
|
81
|
+
: LibClone.cloneDeterministic({
|
|
82
|
+
value: 0, implementation: address(HOOK), salt: keccak256(abi.encode(_msgSender(), salt))
|
|
83
|
+
})
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
emit HookDeployed({projectId: projectId, hook: newHook, caller: _msgSender()});
|
|
87
|
+
|
|
88
|
+
newHook.initialize({
|
|
89
|
+
projectId: projectId,
|
|
90
|
+
name: deployTiersHookConfig.name,
|
|
91
|
+
symbol: deployTiersHookConfig.symbol,
|
|
92
|
+
baseUri: deployTiersHookConfig.baseUri,
|
|
93
|
+
tokenUriResolver: deployTiersHookConfig.tokenUriResolver,
|
|
94
|
+
contractUri: deployTiersHookConfig.contractUri,
|
|
95
|
+
tiersConfig: deployTiersHookConfig.tiersConfig,
|
|
96
|
+
flags: deployTiersHookConfig.flags
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Transfer the hook's ownership to the address that called this function.
|
|
100
|
+
JBOwnable(address(newHook)).transferOwnership(_msgSender());
|
|
101
|
+
|
|
102
|
+
// Increment the nonce.
|
|
103
|
+
++_nonce;
|
|
104
|
+
|
|
105
|
+
// Add the hook to the address registry. This contract's nonce starts at 1.
|
|
106
|
+
salt == bytes32(0)
|
|
107
|
+
? ADDRESS_REGISTRY.registerAddress({deployer: address(this), nonce: _nonce})
|
|
108
|
+
: ADDRESS_REGISTRY.registerAddress({
|
|
109
|
+
deployer: address(this),
|
|
110
|
+
salt: keccak256(abi.encode(_msgSender(), salt)),
|
|
111
|
+
bytecode: LibClone.initCode(address(HOOK))
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.23;
|
|
3
|
+
|
|
4
|
+
import {JBPermissioned} from "@bananapus/core-v6/src/abstract/JBPermissioned.sol";
|
|
5
|
+
import {IJBController} from "@bananapus/core-v6/src/interfaces/IJBController.sol";
|
|
6
|
+
import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
|
|
7
|
+
import {IJBPermissions} from "@bananapus/core-v6/src/interfaces/IJBPermissions.sol";
|
|
8
|
+
import {IJBProjects} from "@bananapus/core-v6/src/interfaces/IJBProjects.sol";
|
|
9
|
+
import {JBRulesetConfig} from "@bananapus/core-v6/src/structs/JBRulesetConfig.sol";
|
|
10
|
+
import {JBRulesetMetadata} from "@bananapus/core-v6/src/structs/JBRulesetMetadata.sol";
|
|
11
|
+
import {JBOwnable} from "@bananapus/ownable-v6/src/JBOwnable.sol";
|
|
12
|
+
import {JBPermissionIds} from "@bananapus/permission-ids-v6/src/JBPermissionIds.sol";
|
|
13
|
+
import {ERC2771Context} from "@openzeppelin/contracts/metatx/ERC2771Context.sol";
|
|
14
|
+
import {Context} from "@openzeppelin/contracts/utils/Context.sol";
|
|
15
|
+
|
|
16
|
+
import {IJB721TiersHookDeployer} from "./interfaces/IJB721TiersHookDeployer.sol";
|
|
17
|
+
import {IJB721TiersHookProjectDeployer} from "./interfaces/IJB721TiersHookProjectDeployer.sol";
|
|
18
|
+
import {IJB721TiersHook} from "./interfaces/IJB721TiersHook.sol";
|
|
19
|
+
import {JBDeploy721TiersHookConfig} from "./structs/JBDeploy721TiersHookConfig.sol";
|
|
20
|
+
import {JBLaunchRulesetsConfig} from "./structs/JBLaunchRulesetsConfig.sol";
|
|
21
|
+
import {JBQueueRulesetsConfig} from "./structs/JBQueueRulesetsConfig.sol";
|
|
22
|
+
import {JBLaunchProjectConfig} from "./structs/JBLaunchProjectConfig.sol";
|
|
23
|
+
import {JBPayDataHookRulesetConfig} from "./structs/JBPayDataHookRulesetConfig.sol";
|
|
24
|
+
|
|
25
|
+
/// @title JB721TiersHookProjectDeployer
|
|
26
|
+
/// @notice Deploys a project and a 721 tiers hook for it. Can be used to queue rulesets for the project if given
|
|
27
|
+
/// `JBPermissionIds.QUEUE_RULESETS`.
|
|
28
|
+
contract JB721TiersHookProjectDeployer is ERC2771Context, JBPermissioned, IJB721TiersHookProjectDeployer {
|
|
29
|
+
//*********************************************************************//
|
|
30
|
+
// --------------- public immutable stored properties ---------------- //
|
|
31
|
+
//*********************************************************************//
|
|
32
|
+
|
|
33
|
+
/// @notice The directory of terminals and controllers for projects.
|
|
34
|
+
IJBDirectory public immutable override DIRECTORY;
|
|
35
|
+
|
|
36
|
+
/// @notice The 721 tiers hook deployer.
|
|
37
|
+
IJB721TiersHookDeployer public immutable override HOOK_DEPLOYER;
|
|
38
|
+
|
|
39
|
+
//*********************************************************************//
|
|
40
|
+
// -------------------------- constructor ---------------------------- //
|
|
41
|
+
//*********************************************************************//
|
|
42
|
+
|
|
43
|
+
/// @param directory The directory of terminals and controllers for projects.
|
|
44
|
+
/// @param permissions A contract storing permissions.
|
|
45
|
+
/// @param hookDeployer The 721 tiers hook deployer.
|
|
46
|
+
/// @param trustedForwarder The trusted forwarder for the ERC2771Context.
|
|
47
|
+
constructor(
|
|
48
|
+
IJBDirectory directory,
|
|
49
|
+
IJBPermissions permissions,
|
|
50
|
+
IJB721TiersHookDeployer hookDeployer,
|
|
51
|
+
address trustedForwarder
|
|
52
|
+
)
|
|
53
|
+
JBPermissioned(permissions)
|
|
54
|
+
ERC2771Context(trustedForwarder)
|
|
55
|
+
{
|
|
56
|
+
DIRECTORY = directory;
|
|
57
|
+
HOOK_DEPLOYER = hookDeployer;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
//*********************************************************************//
|
|
61
|
+
// ---------------------- external transactions ---------------------- //
|
|
62
|
+
//*********************************************************************//
|
|
63
|
+
|
|
64
|
+
/// @notice Launches a new project with a 721 tiers hook attached.
|
|
65
|
+
/// @param owner The address to set as the owner of the project. The ERC-721 which confers this project's ownership
|
|
66
|
+
/// will be sent to this address.
|
|
67
|
+
/// @param deployTiersHookConfig Configuration which dictates the behavior of the 721 tiers hook which is being
|
|
68
|
+
/// deployed.
|
|
69
|
+
/// @param launchProjectConfig Configuration which dictates the behavior of the project which is being launched.
|
|
70
|
+
/// @param controller The controller that the project's rulesets will be queued with.
|
|
71
|
+
/// @param salt A salt to use for the deterministic deployment.
|
|
72
|
+
/// @return projectId The ID of the newly launched project.
|
|
73
|
+
/// @return hook The 721 tiers hook that was deployed for the project.
|
|
74
|
+
function launchProjectFor(
|
|
75
|
+
address owner,
|
|
76
|
+
JBDeploy721TiersHookConfig calldata deployTiersHookConfig,
|
|
77
|
+
JBLaunchProjectConfig calldata launchProjectConfig,
|
|
78
|
+
IJBController controller,
|
|
79
|
+
bytes32 salt
|
|
80
|
+
)
|
|
81
|
+
external
|
|
82
|
+
override
|
|
83
|
+
returns (uint256 projectId, IJB721TiersHook hook)
|
|
84
|
+
{
|
|
85
|
+
// Get the project's ID, optimistically knowing it will be one greater than the current number of projects.
|
|
86
|
+
projectId = DIRECTORY.PROJECTS().count() + 1;
|
|
87
|
+
|
|
88
|
+
// Deploy the hook.
|
|
89
|
+
hook = HOOK_DEPLOYER.deployHookFor({
|
|
90
|
+
projectId: projectId,
|
|
91
|
+
deployTiersHookConfig: deployTiersHookConfig,
|
|
92
|
+
salt: salt == bytes32(0) ? bytes32(0) : keccak256(abi.encode(_msgSender(), salt))
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Launch the project.
|
|
96
|
+
_launchProjectFor({
|
|
97
|
+
owner: owner, launchProjectConfig: launchProjectConfig, dataHook: hook, controller: controller
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Transfer the hook's ownership to the project.
|
|
101
|
+
JBOwnable(address(hook)).transferOwnershipToProject(projectId);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/// @notice Launches rulesets for a project with an attached 721 tiers hook.
|
|
105
|
+
/// @dev Only a project's owner or an operator with the `QUEUE_RULESETS & SET_TERMINALS` permission can launch its
|
|
106
|
+
/// rulesets.
|
|
107
|
+
/// @param projectId The ID of the project that rulesets are being launched for.
|
|
108
|
+
/// @param deployTiersHookConfig Configuration which dictates the behavior of the 721 tiers hook which is being
|
|
109
|
+
/// deployed.
|
|
110
|
+
/// @param launchRulesetsConfig Configuration which dictates the project's new rulesets.
|
|
111
|
+
/// @param controller The controller that the project's rulesets will be queued with.
|
|
112
|
+
/// @param salt A salt to use for the deterministic deployment.
|
|
113
|
+
/// @return rulesetId The ID of the successfully created ruleset.
|
|
114
|
+
/// @return hook The 721 tiers hook that was deployed for the project.
|
|
115
|
+
function launchRulesetsFor(
|
|
116
|
+
uint256 projectId,
|
|
117
|
+
JBDeploy721TiersHookConfig calldata deployTiersHookConfig,
|
|
118
|
+
JBLaunchRulesetsConfig calldata launchRulesetsConfig,
|
|
119
|
+
IJBController controller,
|
|
120
|
+
bytes32 salt
|
|
121
|
+
)
|
|
122
|
+
external
|
|
123
|
+
override
|
|
124
|
+
returns (uint256 rulesetId, IJB721TiersHook hook)
|
|
125
|
+
{
|
|
126
|
+
// Get the project's projects contract.
|
|
127
|
+
IJBProjects PROJECTS = DIRECTORY.PROJECTS();
|
|
128
|
+
|
|
129
|
+
// Enforce permissions.
|
|
130
|
+
_requirePermissionFrom({
|
|
131
|
+
account: PROJECTS.ownerOf(projectId), projectId: projectId, permissionId: JBPermissionIds.QUEUE_RULESETS
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
_requirePermissionFrom({
|
|
135
|
+
account: PROJECTS.ownerOf(projectId), projectId: projectId, permissionId: JBPermissionIds.SET_TERMINALS
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// Deploy the hook.
|
|
139
|
+
hook = HOOK_DEPLOYER.deployHookFor({
|
|
140
|
+
projectId: projectId,
|
|
141
|
+
deployTiersHookConfig: deployTiersHookConfig,
|
|
142
|
+
salt: salt == bytes32(0) ? bytes32(0) : keccak256(abi.encode(_msgSender(), salt))
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// Transfer the hook's ownership to the project.
|
|
146
|
+
JBOwnable(address(hook)).transferOwnershipToProject(projectId);
|
|
147
|
+
|
|
148
|
+
// Launch the rulesets.
|
|
149
|
+
rulesetId = _launchRulesetsFor({
|
|
150
|
+
projectId: projectId, launchRulesetsConfig: launchRulesetsConfig, dataHook: hook, controller: controller
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/// @notice Queues rulesets for a project with an attached 721 tiers hook.
|
|
155
|
+
/// @dev Only a project's owner or an operator with the `QUEUE_RULESETS` permission can queue its rulesets.
|
|
156
|
+
/// @param projectId The ID of the project that rulesets are being queued for.
|
|
157
|
+
/// @param deployTiersHookConfig Configuration which dictates the behavior of the 721 tiers hook which is being
|
|
158
|
+
/// deployed.
|
|
159
|
+
/// @param queueRulesetsConfig Configuration which dictates the project's newly queued rulesets.
|
|
160
|
+
/// @param controller The controller that the project's rulesets will be queued with.
|
|
161
|
+
/// @param salt A salt to use for the deterministic deployment.
|
|
162
|
+
/// @return rulesetId The ID of the successfully created ruleset.
|
|
163
|
+
/// @return hook The 721 tiers hook that was deployed for the project.
|
|
164
|
+
function queueRulesetsOf(
|
|
165
|
+
uint256 projectId,
|
|
166
|
+
JBDeploy721TiersHookConfig calldata deployTiersHookConfig,
|
|
167
|
+
JBQueueRulesetsConfig calldata queueRulesetsConfig,
|
|
168
|
+
IJBController controller,
|
|
169
|
+
bytes32 salt
|
|
170
|
+
)
|
|
171
|
+
external
|
|
172
|
+
override
|
|
173
|
+
returns (uint256 rulesetId, IJB721TiersHook hook)
|
|
174
|
+
{
|
|
175
|
+
// Enforce permissions.
|
|
176
|
+
_requirePermissionFrom({
|
|
177
|
+
account: DIRECTORY.PROJECTS().ownerOf(projectId),
|
|
178
|
+
projectId: projectId,
|
|
179
|
+
permissionId: JBPermissionIds.QUEUE_RULESETS
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// Deploy the hook.
|
|
183
|
+
hook = HOOK_DEPLOYER.deployHookFor({
|
|
184
|
+
projectId: projectId,
|
|
185
|
+
deployTiersHookConfig: deployTiersHookConfig,
|
|
186
|
+
salt: salt == bytes32(0) ? bytes32(0) : keccak256(abi.encode(_msgSender(), salt))
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// Transfer the hook's ownership to the project.
|
|
190
|
+
JBOwnable(address(hook)).transferOwnershipToProject(projectId);
|
|
191
|
+
|
|
192
|
+
// Queue the rulesets.
|
|
193
|
+
rulesetId = _queueRulesetsOf({
|
|
194
|
+
projectId: projectId, queueRulesetsConfig: queueRulesetsConfig, dataHook: hook, controller: controller
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
//*********************************************************************//
|
|
199
|
+
// ------------------------ internal functions ----------------------- //
|
|
200
|
+
//*********************************************************************//
|
|
201
|
+
|
|
202
|
+
/// @notice Launches a project.
|
|
203
|
+
/// @param owner The address that will own the project.
|
|
204
|
+
/// @param launchProjectConfig Configuration which dictates the behavior of the project which is being launched.
|
|
205
|
+
/// @param dataHook The data hook to use for the project.
|
|
206
|
+
/// @param controller The controller that the project's rulesets will be queued with.
|
|
207
|
+
function _launchProjectFor(
|
|
208
|
+
address owner,
|
|
209
|
+
JBLaunchProjectConfig memory launchProjectConfig,
|
|
210
|
+
IJB721TiersHook dataHook,
|
|
211
|
+
IJBController controller
|
|
212
|
+
)
|
|
213
|
+
internal
|
|
214
|
+
{
|
|
215
|
+
// Initialize an array of ruleset configurations.
|
|
216
|
+
JBRulesetConfig[] memory rulesetConfigurations =
|
|
217
|
+
new JBRulesetConfig[](launchProjectConfig.rulesetConfigurations.length);
|
|
218
|
+
|
|
219
|
+
// Set the data hook to be active for pay transactions for each ruleset configuration.
|
|
220
|
+
for (uint256 i; i < launchProjectConfig.rulesetConfigurations.length; i++) {
|
|
221
|
+
// Set the pay data ruleset config being iterated on.
|
|
222
|
+
JBPayDataHookRulesetConfig memory payDataRulesetConfig = launchProjectConfig.rulesetConfigurations[i];
|
|
223
|
+
|
|
224
|
+
// Add the ruleset config.
|
|
225
|
+
rulesetConfigurations[i] = JBRulesetConfig({
|
|
226
|
+
mustStartAtOrAfter: payDataRulesetConfig.mustStartAtOrAfter,
|
|
227
|
+
duration: payDataRulesetConfig.duration,
|
|
228
|
+
weight: payDataRulesetConfig.weight,
|
|
229
|
+
weightCutPercent: payDataRulesetConfig.weightCutPercent,
|
|
230
|
+
approvalHook: payDataRulesetConfig.approvalHook,
|
|
231
|
+
metadata: JBRulesetMetadata({
|
|
232
|
+
reservedPercent: payDataRulesetConfig.metadata.reservedPercent,
|
|
233
|
+
cashOutTaxRate: payDataRulesetConfig.metadata.cashOutTaxRate,
|
|
234
|
+
baseCurrency: payDataRulesetConfig.metadata.baseCurrency,
|
|
235
|
+
pausePay: payDataRulesetConfig.metadata.pausePay,
|
|
236
|
+
pauseCreditTransfers: payDataRulesetConfig.metadata.pauseCreditTransfers,
|
|
237
|
+
allowOwnerMinting: payDataRulesetConfig.metadata.allowOwnerMinting,
|
|
238
|
+
allowSetCustomToken: false,
|
|
239
|
+
allowTerminalMigration: payDataRulesetConfig.metadata.allowTerminalMigration,
|
|
240
|
+
allowSetTerminals: payDataRulesetConfig.metadata.allowSetTerminals,
|
|
241
|
+
allowSetController: payDataRulesetConfig.metadata.allowSetController,
|
|
242
|
+
allowAddAccountingContext: payDataRulesetConfig.metadata.allowAddAccountingContext,
|
|
243
|
+
allowAddPriceFeed: payDataRulesetConfig.metadata.allowAddPriceFeed,
|
|
244
|
+
ownerMustSendPayouts: payDataRulesetConfig.metadata.ownerMustSendPayouts,
|
|
245
|
+
holdFees: payDataRulesetConfig.metadata.holdFees,
|
|
246
|
+
useTotalSurplusForCashOuts: payDataRulesetConfig.metadata.useTotalSurplusForCashOuts,
|
|
247
|
+
useDataHookForPay: true,
|
|
248
|
+
useDataHookForCashOut: payDataRulesetConfig.metadata.useDataHookForCashOut,
|
|
249
|
+
dataHook: address(dataHook),
|
|
250
|
+
metadata: payDataRulesetConfig.metadata.metadata
|
|
251
|
+
}),
|
|
252
|
+
splitGroups: payDataRulesetConfig.splitGroups,
|
|
253
|
+
fundAccessLimitGroups: payDataRulesetConfig.fundAccessLimitGroups
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Launch the project.
|
|
258
|
+
// slither-disable-next-line unused-return
|
|
259
|
+
controller.launchProjectFor({
|
|
260
|
+
owner: owner,
|
|
261
|
+
projectUri: launchProjectConfig.projectUri,
|
|
262
|
+
rulesetConfigurations: rulesetConfigurations,
|
|
263
|
+
terminalConfigurations: launchProjectConfig.terminalConfigurations,
|
|
264
|
+
memo: launchProjectConfig.memo
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/// @notice Launches rulesets for a project.
|
|
269
|
+
/// @param projectId The ID of the project to launch rulesets for.
|
|
270
|
+
/// @param launchRulesetsConfig Configuration which dictates the behavior of the project's rulesets.
|
|
271
|
+
/// @param dataHook The data hook to use for the project.
|
|
272
|
+
/// @param controller The controller that the project's rulesets will be queued with.
|
|
273
|
+
/// @return rulesetId The ID of the successfully created ruleset.
|
|
274
|
+
function _launchRulesetsFor(
|
|
275
|
+
uint256 projectId,
|
|
276
|
+
JBLaunchRulesetsConfig memory launchRulesetsConfig,
|
|
277
|
+
IJB721TiersHook dataHook,
|
|
278
|
+
IJBController controller
|
|
279
|
+
)
|
|
280
|
+
internal
|
|
281
|
+
returns (uint256)
|
|
282
|
+
{
|
|
283
|
+
// Initialize an array of ruleset configurations.
|
|
284
|
+
JBRulesetConfig[] memory rulesetConfigurations =
|
|
285
|
+
new JBRulesetConfig[](launchRulesetsConfig.rulesetConfigurations.length);
|
|
286
|
+
|
|
287
|
+
// Set the data hook to be active for pay transactions for each ruleset configuration.
|
|
288
|
+
for (uint256 i; i < launchRulesetsConfig.rulesetConfigurations.length; i++) {
|
|
289
|
+
// Set the pay data ruleset config being iterated on.
|
|
290
|
+
JBPayDataHookRulesetConfig memory payDataRulesetConfig = launchRulesetsConfig.rulesetConfigurations[i];
|
|
291
|
+
|
|
292
|
+
// Add the ruleset config.
|
|
293
|
+
rulesetConfigurations[i] = JBRulesetConfig({
|
|
294
|
+
mustStartAtOrAfter: payDataRulesetConfig.mustStartAtOrAfter,
|
|
295
|
+
duration: payDataRulesetConfig.duration,
|
|
296
|
+
weight: payDataRulesetConfig.weight,
|
|
297
|
+
weightCutPercent: payDataRulesetConfig.weightCutPercent,
|
|
298
|
+
approvalHook: payDataRulesetConfig.approvalHook,
|
|
299
|
+
metadata: JBRulesetMetadata({
|
|
300
|
+
reservedPercent: payDataRulesetConfig.metadata.reservedPercent,
|
|
301
|
+
cashOutTaxRate: payDataRulesetConfig.metadata.cashOutTaxRate,
|
|
302
|
+
baseCurrency: payDataRulesetConfig.metadata.baseCurrency,
|
|
303
|
+
pausePay: payDataRulesetConfig.metadata.pausePay,
|
|
304
|
+
pauseCreditTransfers: payDataRulesetConfig.metadata.pauseCreditTransfers,
|
|
305
|
+
allowOwnerMinting: payDataRulesetConfig.metadata.allowOwnerMinting,
|
|
306
|
+
allowSetCustomToken: false,
|
|
307
|
+
allowTerminalMigration: payDataRulesetConfig.metadata.allowTerminalMigration,
|
|
308
|
+
allowSetTerminals: payDataRulesetConfig.metadata.allowSetTerminals,
|
|
309
|
+
allowSetController: payDataRulesetConfig.metadata.allowSetController,
|
|
310
|
+
allowAddAccountingContext: payDataRulesetConfig.metadata.allowAddAccountingContext,
|
|
311
|
+
allowAddPriceFeed: payDataRulesetConfig.metadata.allowAddPriceFeed,
|
|
312
|
+
ownerMustSendPayouts: payDataRulesetConfig.metadata.ownerMustSendPayouts,
|
|
313
|
+
holdFees: payDataRulesetConfig.metadata.holdFees,
|
|
314
|
+
useTotalSurplusForCashOuts: payDataRulesetConfig.metadata.useTotalSurplusForCashOuts,
|
|
315
|
+
useDataHookForPay: true,
|
|
316
|
+
useDataHookForCashOut: payDataRulesetConfig.metadata.useDataHookForCashOut,
|
|
317
|
+
dataHook: address(dataHook),
|
|
318
|
+
metadata: payDataRulesetConfig.metadata.metadata
|
|
319
|
+
}),
|
|
320
|
+
splitGroups: payDataRulesetConfig.splitGroups,
|
|
321
|
+
fundAccessLimitGroups: payDataRulesetConfig.fundAccessLimitGroups
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Launch the rulesets.
|
|
326
|
+
return controller.launchRulesetsFor({
|
|
327
|
+
projectId: projectId,
|
|
328
|
+
rulesetConfigurations: rulesetConfigurations,
|
|
329
|
+
terminalConfigurations: launchRulesetsConfig.terminalConfigurations,
|
|
330
|
+
memo: launchRulesetsConfig.memo
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/// @notice Queues rulesets for a project.
|
|
335
|
+
/// @param projectId The ID of the project to queue rulesets for.
|
|
336
|
+
/// @param queueRulesetsConfig Configuration which dictates the behavior of the project's rulesets.
|
|
337
|
+
/// @param dataHook The data hook to use for the project.
|
|
338
|
+
/// @param controller The controller that the project's rulesets will be queued with.
|
|
339
|
+
/// @return The ID of the successfully created ruleset.
|
|
340
|
+
function _queueRulesetsOf(
|
|
341
|
+
uint256 projectId,
|
|
342
|
+
JBQueueRulesetsConfig memory queueRulesetsConfig,
|
|
343
|
+
IJB721TiersHook dataHook,
|
|
344
|
+
IJBController controller
|
|
345
|
+
)
|
|
346
|
+
internal
|
|
347
|
+
returns (uint256)
|
|
348
|
+
{
|
|
349
|
+
// Initialize an array of ruleset configurations.
|
|
350
|
+
JBRulesetConfig[] memory rulesetConfigurations =
|
|
351
|
+
new JBRulesetConfig[](queueRulesetsConfig.rulesetConfigurations.length);
|
|
352
|
+
|
|
353
|
+
// Set the data hook to be active for pay transactions for each ruleset configuration.
|
|
354
|
+
for (uint256 i; i < queueRulesetsConfig.rulesetConfigurations.length; i++) {
|
|
355
|
+
// Set the pay data ruleset config being iterated on.
|
|
356
|
+
JBPayDataHookRulesetConfig memory payDataRulesetConfig = queueRulesetsConfig.rulesetConfigurations[i];
|
|
357
|
+
|
|
358
|
+
// Add the ruleset config.
|
|
359
|
+
rulesetConfigurations[i] = JBRulesetConfig({
|
|
360
|
+
mustStartAtOrAfter: payDataRulesetConfig.mustStartAtOrAfter,
|
|
361
|
+
duration: payDataRulesetConfig.duration,
|
|
362
|
+
weight: payDataRulesetConfig.weight,
|
|
363
|
+
weightCutPercent: payDataRulesetConfig.weightCutPercent,
|
|
364
|
+
approvalHook: payDataRulesetConfig.approvalHook,
|
|
365
|
+
metadata: JBRulesetMetadata({
|
|
366
|
+
reservedPercent: payDataRulesetConfig.metadata.reservedPercent,
|
|
367
|
+
cashOutTaxRate: payDataRulesetConfig.metadata.cashOutTaxRate,
|
|
368
|
+
baseCurrency: payDataRulesetConfig.metadata.baseCurrency,
|
|
369
|
+
pausePay: payDataRulesetConfig.metadata.pausePay,
|
|
370
|
+
pauseCreditTransfers: payDataRulesetConfig.metadata.pauseCreditTransfers,
|
|
371
|
+
allowOwnerMinting: payDataRulesetConfig.metadata.allowOwnerMinting,
|
|
372
|
+
allowSetCustomToken: false,
|
|
373
|
+
allowTerminalMigration: payDataRulesetConfig.metadata.allowTerminalMigration,
|
|
374
|
+
allowSetTerminals: payDataRulesetConfig.metadata.allowSetTerminals,
|
|
375
|
+
allowSetController: payDataRulesetConfig.metadata.allowSetController,
|
|
376
|
+
allowAddAccountingContext: payDataRulesetConfig.metadata.allowAddAccountingContext,
|
|
377
|
+
allowAddPriceFeed: payDataRulesetConfig.metadata.allowAddPriceFeed,
|
|
378
|
+
ownerMustSendPayouts: payDataRulesetConfig.metadata.ownerMustSendPayouts,
|
|
379
|
+
holdFees: payDataRulesetConfig.metadata.holdFees,
|
|
380
|
+
useTotalSurplusForCashOuts: payDataRulesetConfig.metadata.useTotalSurplusForCashOuts,
|
|
381
|
+
useDataHookForPay: true,
|
|
382
|
+
useDataHookForCashOut: payDataRulesetConfig.metadata.useDataHookForCashOut,
|
|
383
|
+
dataHook: address(dataHook),
|
|
384
|
+
metadata: payDataRulesetConfig.metadata.metadata
|
|
385
|
+
}),
|
|
386
|
+
splitGroups: payDataRulesetConfig.splitGroups,
|
|
387
|
+
fundAccessLimitGroups: payDataRulesetConfig.fundAccessLimitGroups
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Queue the rulesets.
|
|
392
|
+
return controller.queueRulesetsOf({
|
|
393
|
+
projectId: projectId, rulesetConfigurations: rulesetConfigurations, memo: queueRulesetsConfig.memo
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/// @notice The calldata. Preferred to use over `msg.data`.
|
|
398
|
+
/// @return calldata The `msg.data` of this call.
|
|
399
|
+
function _msgData() internal view override(ERC2771Context, Context) returns (bytes calldata) {
|
|
400
|
+
return ERC2771Context._msgData();
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/// @notice The message's sender. Preferred to use over `msg.sender`.
|
|
404
|
+
/// @return sender The address which sent this call.
|
|
405
|
+
function _msgSender() internal view override(ERC2771Context, Context) returns (address sender) {
|
|
406
|
+
return ERC2771Context._msgSender();
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/// @dev ERC-2771 specifies the context as being a single address (20 bytes).
|
|
410
|
+
function _contextSuffixLength() internal view virtual override(ERC2771Context, Context) returns (uint256) {
|
|
411
|
+
return ERC2771Context._contextSuffixLength();
|
|
412
|
+
}
|
|
413
|
+
}
|