@bananapus/core-v6 0.0.59 → 0.0.60

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/package.json CHANGED
@@ -1,19 +1,16 @@
1
1
  {
2
2
  "name": "@bananapus/core-v6",
3
- "version": "0.0.59",
3
+ "version": "0.0.60",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/Bananapus/nana-core-v6"
8
8
  },
9
9
  "files": [
10
- "CHANGELOG.md",
11
- "foundry.lock",
12
10
  "foundry.toml",
13
11
  "references/",
14
12
  "remappings.txt",
15
- "script/helpers/",
16
- "sphinx.lock",
13
+ "script/",
17
14
  "src/",
18
15
  "test/helpers/",
19
16
  "test/mock/"
@@ -0,0 +1,121 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity 0.8.28;
3
+
4
+ import {Sphinx} from "@sphinx-labs/contracts/contracts/foundry/SphinxPlugin.sol";
5
+ import {Script} from "forge-std/Script.sol";
6
+
7
+ import {IPermit2} from "@uniswap/permit2/src/interfaces/IPermit2.sol";
8
+
9
+ import {ERC2771Forwarder} from "@openzeppelin/contracts/metatx/ERC2771Forwarder.sol";
10
+
11
+ import {JBDirectory} from "../src/JBDirectory.sol";
12
+ import {JBERC20} from "../src/JBERC20.sol";
13
+ import {JBFeelessAddresses} from "../src/JBFeelessAddresses.sol";
14
+ import {JBFundAccessLimits} from "../src/JBFundAccessLimits.sol";
15
+ import {JBMultiTerminal} from "../src/JBMultiTerminal.sol";
16
+ import {JBPermissions} from "../src/JBPermissions.sol";
17
+ import {JBPrices} from "../src/JBPrices.sol";
18
+ import {JBProjects} from "../src/JBProjects.sol";
19
+ import {JBRulesets} from "../src/JBRulesets.sol";
20
+ import {JBSplits} from "../src/JBSplits.sol";
21
+ import {JBTerminalStore} from "../src/JBTerminalStore.sol";
22
+ import {JBTokens} from "../src/JBTokens.sol";
23
+
24
+ contract Deploy is Script, Sphinx {
25
+ /// @notice The universal PERMIT2 address.
26
+ IPermit2 private constant _PERMIT2 = IPermit2(0x000000000022D473030F116dDEE9F6B43aC78BA3);
27
+
28
+ /// @notice The address that is allowed to forward calls to the terminal and controller on a users behalf.
29
+ string private constant _TRUSTED_FORWARDER_NAME = "Juicebox";
30
+ address private trustedForwarder;
31
+
32
+ /// @notice The address that will manage the few privileged functions of the protocol.
33
+ address private manager;
34
+
35
+ /// @notice The address that will own the fee-project.
36
+ /// @dev Core deployment transfers project `#1` to this owner, but does not fully activate fee collection on its
37
+ /// own. Production fee collection only starts once the fee project's controller, terminals, and accounting
38
+ /// contexts are configured by follow-up deployment steps.
39
+ address private feeProjectOwner;
40
+
41
+ /// @notice The nonce that gets used across all chains to sync deployment addresses and allow for new deployments of
42
+ /// the same bytecode.
43
+ uint256 private constant _CORE_DEPLOYMENT_NONCE = 6;
44
+
45
+ function configureSphinx() public override {
46
+ sphinxConfig.projectName = "nana-core-v6";
47
+ sphinxConfig.mainnets = ["ethereum", "optimism", "base", "arbitrum"];
48
+ sphinxConfig.testnets = ["ethereum_sepolia", "optimism_sepolia", "base_sepolia", "arbitrum_sepolia"];
49
+ }
50
+
51
+ /// @notice Deploys the protocol.
52
+ function run() public sphinx {
53
+ // Set the manager, this can be changed and won't affect deployment addresses.
54
+ manager = safeAddress();
55
+ // Set the owner of the fee project to be the project multisig. This does not by itself make fee collection
56
+ // live; project `#1` still needs its follow-up controller/terminal/accounting-context configuration.
57
+ feeProjectOwner = safeAddress();
58
+
59
+ // Deploy the protocol.
60
+ deploy();
61
+ }
62
+
63
+ function deploy() public sphinx {
64
+ trustedForwarder =
65
+ address(new ERC2771Forwarder{salt: keccak256(abi.encode(_CORE_DEPLOYMENT_NONCE))}(_TRUSTED_FORWARDER_NAME));
66
+
67
+ JBPermissions permissions =
68
+ new JBPermissions{salt: keccak256(abi.encode(_CORE_DEPLOYMENT_NONCE))}(trustedForwarder);
69
+ JBProjects projects = new JBProjects{salt: keccak256(abi.encode(_CORE_DEPLOYMENT_NONCE))}({
70
+ owner: safeAddress(), feeProjectOwner: safeAddress(), trustedForwarder: trustedForwarder
71
+ });
72
+ JBDirectory directory = new JBDirectory{salt: keccak256(abi.encode(_CORE_DEPLOYMENT_NONCE))}({
73
+ permissions: permissions, projects: projects, owner: safeAddress()
74
+ });
75
+ JBSplits splits = new JBSplits{salt: keccak256(abi.encode(_CORE_DEPLOYMENT_NONCE))}(directory);
76
+ JBRulesets rulesets = new JBRulesets{salt: keccak256(abi.encode(_CORE_DEPLOYMENT_NONCE))}(directory);
77
+ JBPrices prices = new JBPrices{salt: keccak256(abi.encode(_CORE_DEPLOYMENT_NONCE))}({
78
+ directory: directory,
79
+ permissions: permissions,
80
+ projects: projects,
81
+ owner: safeAddress(),
82
+ trustedForwarder: trustedForwarder
83
+ });
84
+ JBTokens tokens = new JBTokens{salt: keccak256(abi.encode(_CORE_DEPLOYMENT_NONCE))}({
85
+ directory: directory,
86
+ token: new JBERC20{salt: keccak256(abi.encode(_CORE_DEPLOYMENT_NONCE))}(permissions, projects)
87
+ });
88
+
89
+ new JBFundAccessLimits{salt: keccak256(abi.encode(_CORE_DEPLOYMENT_NONCE))}(directory);
90
+
91
+ JBFeelessAddresses feeless =
92
+ new JBFeelessAddresses{salt: keccak256(abi.encode(_CORE_DEPLOYMENT_NONCE))}(safeAddress());
93
+
94
+ new JBMultiTerminal{salt: keccak256(abi.encode(_CORE_DEPLOYMENT_NONCE))}({
95
+ permissions: permissions,
96
+ projects: projects,
97
+ splits: splits,
98
+ store: new JBTerminalStore{salt: keccak256(abi.encode(_CORE_DEPLOYMENT_NONCE))}({
99
+ directory: directory, rulesets: rulesets, prices: prices
100
+ }),
101
+ tokens: tokens,
102
+ feelessAddresses: feeless,
103
+ permit2: _PERMIT2,
104
+ trustedForwarder: trustedForwarder
105
+ });
106
+
107
+ // If the manager is not the deployer we transfer all ownership to it.
108
+ if (manager != safeAddress() && manager != address(0)) {
109
+ directory.transferOwnership(manager);
110
+ feeless.transferOwnership(manager);
111
+ prices.transferOwnership(manager);
112
+ projects.transferOwnership(manager);
113
+ }
114
+
115
+ // Transfer ownership to the fee project owner. Follow-up deployment steps must still finish configuring
116
+ // project `#1` before protocol fees are collected instead of being forgiven back to payer projects.
117
+ if (feeProjectOwner != safeAddress() && feeProjectOwner != address(0)) {
118
+ projects.safeTransferFrom({from: safeAddress(), to: feeProjectOwner, tokenId: 1});
119
+ }
120
+ }
121
+ }
@@ -0,0 +1,346 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity 0.8.28;
3
+
4
+ import {Sphinx} from "@sphinx-labs/contracts/contracts/foundry/SphinxPlugin.sol";
5
+ import {Script} from "forge-std/Script.sol";
6
+ import {CoreDeployment, CoreDeploymentLib} from "./helpers/CoreDeploymentLib.sol";
7
+
8
+ import {AggregatorV2V3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV2V3Interface.sol";
9
+
10
+ import {JBChainlinkV3PriceFeed, AggregatorV3Interface} from "../src/JBChainlinkV3PriceFeed.sol";
11
+ import {JBChainlinkV3SequencerPriceFeed} from "../src/JBChainlinkV3SequencerPriceFeed.sol";
12
+ import {JBController} from "../src/JBController.sol";
13
+ import {IJBPriceFeed} from "../src/interfaces/IJBPriceFeed.sol";
14
+ import {JBConstants} from "../src/libraries/JBConstants.sol";
15
+ import {JBCurrencyIds} from "../src/libraries/JBCurrencyIds.sol";
16
+ import {JBDeadline1Day} from "../src/periphery/JBDeadline1Day.sol";
17
+ import {JBDeadline3Days} from "../src/periphery/JBDeadline3Days.sol";
18
+ import {JBDeadline3Hours} from "../src/periphery/JBDeadline3Hours.sol";
19
+ import {JBDeadline7Days} from "../src/periphery/JBDeadline7Days.sol";
20
+ import {JBMatchingPriceFeed} from "../src/periphery/JBMatchingPriceFeed.sol";
21
+
22
+ contract DeployPeriphery is Script, Sphinx {
23
+ /// @notice tracks the deployment of the core contracts for the chain we are deploying to.
24
+ CoreDeployment core;
25
+ address private trustedForwarder;
26
+ bytes32 private constant _DEADLINES_SALT = keccak256("_JBDeadlinesV6_");
27
+ bytes32 private constant _USD_NATIVE_FEED_SALT = keccak256("USD_FEEDV6");
28
+
29
+ /// @notice The nonce that gets used across all chains to sync deployment addresses and allow for new deployments of
30
+ /// the same bytecode.
31
+ uint256 private constant _CORE_DEPLOYMENT_NONCE = 6;
32
+
33
+ /// @notice The address of the omnichain ruleset operator contract (e.g. JBOmnichainDeployer).
34
+ /// @dev TRUST ASSUMPTION: This address is granted implicit permission to launch rulesets, set terminals, and queue
35
+ /// rulesets on any project via the JBController (bypassing normal JBPermissions checks). A compromised or
36
+ /// incorrect operator address could manipulate any project's rulesets across chains.
37
+ /// @dev This address should correspond to the deterministic CREATE2 deployment of the omnichain deployer contract
38
+ /// from the nana-omnichain-deployers-v6 repository. This script only enforces that the address is nonzero, so
39
+ /// operators must verify it matches the intended deployment on every target chain before running this script.
40
+ address private constant _OMNICHAIN_RULESET_OPERATOR = address(0x8f5DED85c40b50d223269C1F922A056E72101590);
41
+
42
+ function configureSphinx() public override {
43
+ sphinxConfig.projectName = "nana-core-v6";
44
+ sphinxConfig.mainnets = ["ethereum", "optimism", "base", "arbitrum"];
45
+ sphinxConfig.testnets = ["ethereum_sepolia", "optimism_sepolia", "base_sepolia", "arbitrum_sepolia"];
46
+ }
47
+
48
+ /// @notice Deploys the protocol.
49
+ function run() public {
50
+ // Get the deployment addresses for the nana CORE for this chain.
51
+ // We want to do this outside of the `sphinx` modifier.
52
+ core = CoreDeploymentLib.getDeployment(vm.envOr("NANA_CORE_DEPLOYMENT_PATH", string("deployments/")));
53
+
54
+ // We use the same trusted forwarder as the core deployment.
55
+ trustedForwarder = core.permissions.trustedForwarder();
56
+
57
+ // Deploy the protocol.
58
+ deploy();
59
+ }
60
+
61
+ function deploy() public sphinx {
62
+ // Validate the omnichain ruleset operator is set. See TRUST ASSUMPTION above. This is intentionally a
63
+ // nonzero-only check; correctness of the configured operator is verified out of band.
64
+ require(_OMNICHAIN_RULESET_OPERATOR != address(0), "Omnichain ruleset operator not set");
65
+
66
+ // Deploy the ETH/USD price feed.
67
+ IJBPriceFeed feed;
68
+
69
+ IJBPriceFeed matchingPriceFeed;
70
+ matchingPriceFeed = new JBMatchingPriceFeed();
71
+
72
+ // Same as the chainlink example grace period.
73
+ uint256 l2GracePeriod = 3600 seconds;
74
+
75
+ // NOTE: Feeds come from this url `https://data.chain.link/feeds/ethereum/mainnet/eth-usd`.
76
+ // Sequencer feeds come from this url `https://docs.chain.link/data-feeds/l2-sequencer-feeds`.
77
+
78
+ // Perform the deploy for L1(s).
79
+ if (block.chainid == 1) {
80
+ feed = new JBChainlinkV3PriceFeed{salt: _USD_NATIVE_FEED_SALT}({
81
+ feed: AggregatorV3Interface(address(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419)),
82
+ threshold: 3600 seconds
83
+ });
84
+ } else if (block.chainid == 11_155_111) {
85
+ feed = new JBChainlinkV3PriceFeed{salt: _USD_NATIVE_FEED_SALT}({
86
+ feed: AggregatorV3Interface(address(0x694AA1769357215DE4FAC081bf1f309aDC325306)),
87
+ threshold: 3600 seconds
88
+ });
89
+ } else {
90
+ // Perform the deploy for L2s
91
+ AggregatorV3Interface source;
92
+
93
+ // Optimism
94
+ if (block.chainid == 10) {
95
+ source = AggregatorV3Interface(0x13e3Ee699D1909E989722E753853AE30b17e08c5);
96
+ feed = new JBChainlinkV3SequencerPriceFeed{salt: _USD_NATIVE_FEED_SALT}({
97
+ feed: source,
98
+ threshold: 3600 seconds,
99
+ sequencerFeed: AggregatorV2V3Interface(0x371EAD81c9102C9BF4874A9075FFFf170F2Ee389),
100
+ gracePeriod: l2GracePeriod
101
+ });
102
+ }
103
+ // Optimism Sepolia
104
+ else if (block.chainid == 11_155_420) {
105
+ source = AggregatorV3Interface(address(0x61Ec26aA57019C486B10502285c5A3D4A4750AD7));
106
+ feed = new JBChainlinkV3PriceFeed{salt: _USD_NATIVE_FEED_SALT}({feed: source, threshold: 3600 seconds});
107
+ }
108
+ // Base
109
+ else if (block.chainid == 8453) {
110
+ source = AggregatorV3Interface(0x71041dddad3595F9CEd3DcCFBe3D1F4b0a16Bb70);
111
+ feed = new JBChainlinkV3SequencerPriceFeed{salt: _USD_NATIVE_FEED_SALT}({
112
+ feed: source,
113
+ threshold: 3600 seconds,
114
+ sequencerFeed: AggregatorV2V3Interface(0xBCF85224fc0756B9Fa45aA7892530B47e10b6433),
115
+ gracePeriod: l2GracePeriod
116
+ });
117
+ }
118
+ // Base Sepolia
119
+ else if (block.chainid == 84_532) {
120
+ source = AggregatorV3Interface(address(0x4aDC67696bA383F43DD60A9e78F2C97Fbbfc7cb1));
121
+ feed = new JBChainlinkV3PriceFeed{salt: _USD_NATIVE_FEED_SALT}({feed: source, threshold: 3600 seconds});
122
+ }
123
+ // Arbitrum
124
+ else if (block.chainid == 42_161) {
125
+ source = AggregatorV3Interface(0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612);
126
+ feed = new JBChainlinkV3SequencerPriceFeed{salt: _USD_NATIVE_FEED_SALT}({
127
+ feed: source,
128
+ threshold: 3600 seconds,
129
+ sequencerFeed: AggregatorV2V3Interface(0xFdB631F5EE196F0ed6FAa767959853A9F217697D),
130
+ gracePeriod: l2GracePeriod
131
+ });
132
+ }
133
+ // Arbitrum Sepolia
134
+ else if (block.chainid == 421_614) {
135
+ source = AggregatorV3Interface(address(0xd30e2101a97dcbAeBCBC04F14C3f624E67A35165));
136
+ feed = new JBChainlinkV3PriceFeed{salt: _USD_NATIVE_FEED_SALT}({feed: source, threshold: 3600 seconds});
137
+ } else {
138
+ revert("Unsupported chain");
139
+ }
140
+ }
141
+ require(address(feed) != address(0), "Invalid price feed");
142
+
143
+ try core.prices
144
+ .addPriceFeedFor({
145
+ projectId: 0,
146
+ pricingCurrency: JBCurrencyIds.USD,
147
+ unitCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
148
+ feed: feed
149
+ }) {}
150
+ catch {}
151
+ // `addPriceFeedFor` can revert if this feed was already registered. Still require the feed to exist so a
152
+ // different failure mode can't silently skip this required deployment step.
153
+ require(
154
+ address(
155
+ core.prices
156
+ .priceFeedFor({
157
+ projectId: 0,
158
+ pricingCurrency: JBCurrencyIds.USD,
159
+ unitCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN))
160
+ })
161
+ ) != address(0),
162
+ "Missing USD/native price feed"
163
+ );
164
+
165
+ // WARN: We are using the same price feed as the native token for the USD price feed. Which is only valid on
166
+ // chains where Ether is the native asset. We *NEED* to update this when we deploy to a non-ether chain!
167
+ try core.prices
168
+ .addPriceFeedFor({
169
+ projectId: 0, pricingCurrency: JBCurrencyIds.USD, unitCurrency: JBCurrencyIds.ETH, feed: feed
170
+ }) {}
171
+ catch {}
172
+ // `addPriceFeedFor` can revert if this feed was already registered. Still require the feed to exist so a
173
+ // different failure mode can't silently skip this required deployment step.
174
+ require(
175
+ address(
176
+ core.prices
177
+ .priceFeedFor({projectId: 0, pricingCurrency: JBCurrencyIds.USD, unitCurrency: JBCurrencyIds.ETH})
178
+ ) != address(0),
179
+ "Missing USD/ETH price feed"
180
+ );
181
+
182
+ // If the native asset for this chain is ether, then the conversion from native asset to ether is 1:1.
183
+ // NOTE: We need to refactor this the moment we add a chain where its native token is *NOT* ether.
184
+ // As otherwise prices for the `NATIVE_TOKEN` will be incorrect!
185
+ try core.prices
186
+ .addPriceFeedFor({
187
+ projectId: 0,
188
+ pricingCurrency: JBCurrencyIds.ETH,
189
+ unitCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
190
+ feed: matchingPriceFeed
191
+ }) {}
192
+ catch {}
193
+ // `addPriceFeedFor` can revert if this feed was already registered. Still require the feed to exist so a
194
+ // different failure mode can't silently skip this required deployment step.
195
+ require(
196
+ address(
197
+ core.prices
198
+ .priceFeedFor({
199
+ projectId: 0,
200
+ pricingCurrency: JBCurrencyIds.ETH,
201
+ unitCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN))
202
+ })
203
+ ) != address(0),
204
+ "Missing ETH/native price feed"
205
+ );
206
+
207
+ // Deploy the USDC/USD price feed.
208
+ _deployUSDCFeed(l2GracePeriod);
209
+
210
+ // Deploy the JBDeadlines
211
+ if (!_isDeployed({salt: _DEADLINES_SALT, creationCode: type(JBDeadline3Hours).creationCode, arguments: ""})) {
212
+ new JBDeadline3Hours{salt: _DEADLINES_SALT}();
213
+ }
214
+
215
+ if (!_isDeployed({salt: _DEADLINES_SALT, creationCode: type(JBDeadline1Day).creationCode, arguments: ""})) {
216
+ new JBDeadline1Day{salt: _DEADLINES_SALT}();
217
+ }
218
+
219
+ if (!_isDeployed({salt: _DEADLINES_SALT, creationCode: type(JBDeadline3Days).creationCode, arguments: ""})) {
220
+ new JBDeadline3Days{salt: _DEADLINES_SALT}();
221
+ }
222
+
223
+ if (!_isDeployed({salt: _DEADLINES_SALT, creationCode: type(JBDeadline7Days).creationCode, arguments: ""})) {
224
+ new JBDeadline7Days{salt: _DEADLINES_SALT}();
225
+ }
226
+
227
+ core.directory
228
+ .setIsAllowedToSetFirstController({
229
+ addr: address(
230
+ new JBController{salt: keccak256(abi.encode(_CORE_DEPLOYMENT_NONCE))}({
231
+ directory: core.directory,
232
+ fundAccessLimits: core.fundAccess,
233
+ prices: core.prices,
234
+ permissions: core.permissions,
235
+ projects: core.projects,
236
+ rulesets: core.rulesets,
237
+ splits: core.splits,
238
+ tokens: core.tokens,
239
+ omnichainRulesetOperator: _OMNICHAIN_RULESET_OPERATOR,
240
+ trustedForwarder: trustedForwarder
241
+ })
242
+ ),
243
+ flag: true
244
+ });
245
+ }
246
+
247
+ // forge-lint: disable-next-line(mixed-case-function, mixed-case-variable)
248
+ function _deployUSDCFeed(uint256 l2GracePeriod) internal {
249
+ IJBPriceFeed usdcFeed;
250
+ address usdc;
251
+
252
+ if (block.chainid == 1) {
253
+ usdc = address(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48);
254
+ usdcFeed = new JBChainlinkV3PriceFeed({
255
+ feed: AggregatorV3Interface(address(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6)),
256
+ threshold: 86_400 seconds
257
+ });
258
+ } else if (block.chainid == 11_155_111) {
259
+ usdc = address(0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238);
260
+ usdcFeed = new JBChainlinkV3PriceFeed({
261
+ feed: AggregatorV3Interface(address(0xA2F78ab2355fe2f984D808B5CeE7FD0A93D5270E)),
262
+ threshold: 86_400 seconds
263
+ });
264
+ } else if (block.chainid == 10) {
265
+ usdc = address(0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85);
266
+ usdcFeed = new JBChainlinkV3SequencerPriceFeed({
267
+ feed: AggregatorV3Interface(0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3),
268
+ threshold: 86_400 seconds,
269
+ sequencerFeed: AggregatorV2V3Interface(0x371EAD81c9102C9BF4874A9075FFFf170F2Ee389),
270
+ gracePeriod: l2GracePeriod
271
+ });
272
+ } else if (block.chainid == 11_155_420) {
273
+ usdc = address(0x5fd84259d66Cd46123540766Be93DFE6D43130D7);
274
+ usdcFeed = new JBChainlinkV3PriceFeed({
275
+ feed: AggregatorV3Interface(address(0x6e44e50E3cc14DD16e01C590DC1d7020cb36eD4C)),
276
+ threshold: 86_400 seconds
277
+ });
278
+ } else if (block.chainid == 8453) {
279
+ usdc = address(0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913);
280
+ usdcFeed = new JBChainlinkV3SequencerPriceFeed({
281
+ feed: AggregatorV3Interface(0x7e860098F58bBFC8648a4311b374B1D669a2bc6B),
282
+ threshold: 86_400 seconds,
283
+ sequencerFeed: AggregatorV2V3Interface(0xBCF85224fc0756B9Fa45aA7892530B47e10b6433),
284
+ gracePeriod: l2GracePeriod
285
+ });
286
+ } else if (block.chainid == 84_532) {
287
+ usdc = address(0x036CbD53842c5426634e7929541eC2318f3dCF7e);
288
+ usdcFeed = new JBChainlinkV3PriceFeed({
289
+ feed: AggregatorV3Interface(address(0xd30e2101a97dcbAeBCBC04F14C3f624E67A35165)),
290
+ threshold: 86_400 seconds
291
+ });
292
+ } else if (block.chainid == 42_161) {
293
+ usdc = address(0xaf88d065e77c8cC2239327C5EDb3A432268e5831);
294
+ usdcFeed = new JBChainlinkV3SequencerPriceFeed({
295
+ feed: AggregatorV3Interface(0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3),
296
+ threshold: 86_400 seconds,
297
+ sequencerFeed: AggregatorV2V3Interface(0xFdB631F5EE196F0ed6FAa767959853A9F217697D),
298
+ gracePeriod: l2GracePeriod
299
+ });
300
+ } else if (block.chainid == 421_614) {
301
+ usdc = address(0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d);
302
+ usdcFeed = new JBChainlinkV3PriceFeed({
303
+ feed: AggregatorV3Interface(address(0x0153002d20B96532C639313c2d54c3dA09109309)),
304
+ threshold: 86_400 seconds
305
+ });
306
+ } else {
307
+ revert("Unsupported chain for USDC feed");
308
+ }
309
+
310
+ require(usdc.code.length > 0, "Invalid USDC address");
311
+ require(address(usdcFeed) != address(0), "Invalid USDC price feed");
312
+
313
+ // forge-lint: disable-next-line(unsafe-typecast)
314
+ uint32 usdcCurrencyId = uint32(uint160(usdc));
315
+
316
+ try core.prices
317
+ .addPriceFeedFor({
318
+ projectId: 0, pricingCurrency: JBCurrencyIds.USD, unitCurrency: usdcCurrencyId, feed: usdcFeed
319
+ }) {}
320
+ catch {}
321
+ // `addPriceFeedFor` can revert if this feed was already registered. Still require the feed to exist so a
322
+ // different failure mode can't silently skip this required deployment step.
323
+ require(
324
+ address(
325
+ core.prices
326
+ .priceFeedFor({projectId: 0, pricingCurrency: JBCurrencyIds.USD, unitCurrency: usdcCurrencyId})
327
+ ) != address(0),
328
+ "Missing USD/USDC price feed"
329
+ );
330
+ }
331
+
332
+ /// @dev This helper predicts addresses using the Arachnid CREATE2 deployer, but actual deployments go through
333
+ /// Sphinx (which uses a different deployer). As a result, this guard will never detect Sphinx-deployed contracts
334
+ /// and is only effective for contracts deployed via the Arachnid deployer directly.
335
+ function _isDeployed(bytes32 salt, bytes memory creationCode, bytes memory arguments) internal view returns (bool) {
336
+ address _deployedTo = vm.computeCreate2Address({
337
+ salt: salt,
338
+ initCodeHash: keccak256(abi.encodePacked(creationCode, arguments)),
339
+ // Arachnid/deterministic-deployment-proxy address.
340
+ deployer: address(0x4e59b44847b379578588920cA78FbF26c0B4956C)
341
+ });
342
+
343
+ // Return if code is already present at this address.
344
+ return address(_deployedTo).code.length != 0;
345
+ }
346
+ }
package/CHANGELOG.md DELETED
@@ -1,73 +0,0 @@
1
- # Changelog
2
-
3
- ## Scope
4
-
5
- This file describes the verified change from `nana-core-v5` to the current `nana-core-v6` repo.
6
-
7
- ## Current v6 surface
8
-
9
- - `JBController`
10
- - `JBMultiTerminal`
11
- - `JBTerminalStore`
12
- - `JBRulesets`
13
- - `JBTokens`
14
- - the shared core interfaces, structs, and libraries under `src/`
15
-
16
- ## Summary
17
-
18
- - v6 adds explicit preview APIs for pay and cash-out flows. Integrations can simulate more of the terminal path directly from the core contracts.
19
- - Token metadata is more editable than in v5. The controller now exposes a dedicated token-metadata update path.
20
- - Approval-hook handling is safer. The v6 codebase and tests are built around preventing a bad approval hook from freezing project behavior.
21
- - Fee accounting is tighter than in v5, especially around fee-free surplus behavior and cross-flow bookkeeping.
22
- - The repo carries much broader test coverage than the v5 tree, including dedicated review, invariant, fork, and formal-style suites.
23
- - The implementation baseline moved from the v5 `0.8.23` world to `0.8.28`.
24
-
25
- ## Verified deltas
26
-
27
- - `IJBTerminal.previewPayFor(...)` is new.
28
- - `IJBCashOutTerminal.previewCashOutFrom(...)` and `IJBTerminalStore.previewCashOutFrom(...)` are new preview surfaces.
29
- - `IJBController.setTokenMetadataOf(uint256,string,string)` is new.
30
- - `IJBController.addPriceFeed(...)` became `addPriceFeedFor(...)`.
31
- - `IJBTerminal.currentSurplusOf(...)` now takes `address[] calldata tokens` instead of the old accounting-context array input.
32
- - The interface surface adds explicit hook-spec return types to preview flows, which changes what off-chain callers can and should decode.
33
-
34
- ## Breaking ABI changes
35
-
36
- - `IJBController.addPriceFeed(...)` was renamed to `addPriceFeedFor(...)`.
37
- - `IJBController.setTokenMetadataOf(...)` is new and sits on the core controller surface.
38
- - `IJBController.previewMintOf(...)` is new.
39
- - `IJBTerminal.previewPayFor(...)` is new.
40
- - `IJBCashOutTerminal.previewCashOutFrom(...)` is new.
41
- - `IJBTerminalStore.previewPayFrom(...)` and `previewCashOutFrom(...)` are new.
42
- - `IJBTerminal.currentSurplusOf(...)` changed parameter shape.
43
-
44
- ## Indexer impact
45
-
46
- - `SplitHookReverted` is a new controller event.
47
- - Preview functions do not emit events, but they change what frontends and simulation services can derive without sending transactions.
48
- - If your indexer inferred token metadata immutability from v5, that assumption is no longer safe once `setTokenMetadataOf(...)` is in use.
49
-
50
- ## Migration notes
51
-
52
- - Rebuild against the v6 interfaces. This repo is too central for hand-maintained ABI diffs to be trustworthy.
53
- - Review any integration that assumed old ruleset-cache behavior, old preview availability, or old token-metadata immutability.
54
- - If your system relied on subtle fee-free cash-out behavior from v5, re-validate it against the v6 accounting model.
55
-
56
- ## ABI appendix
57
-
58
- - Added functions
59
- - `IJBTerminal.previewPayFor(...)`
60
- - `IJBCashOutTerminal.previewCashOutFrom(...)`
61
- - `IJBTerminalStore.previewPayFrom(...)`
62
- - `IJBTerminalStore.previewCashOutFrom(...)`
63
- - `IJBController.previewMintOf(...)`
64
- - `IJBController.setTokenMetadataOf(...)`
65
- - Renamed functions
66
- - `IJBController.addPriceFeed(...)` -> `addPriceFeedFor(...)`
67
- - Changed function shapes
68
- - `IJBTerminal.currentSurplusOf(...)`
69
- - Added events
70
- - `SplitHookReverted`
71
- - Added migration-sensitive capabilities
72
- - mutable token metadata
73
- - preview-oriented hook-spec decoding
package/foundry.lock DELETED
@@ -1,5 +0,0 @@
1
- {
2
- "lib/forge-std": {
3
- "rev": "726a6ee5fc8427a0013d6f624e486c9130c0e336"
4
- }
5
- }
package/sphinx.lock DELETED
@@ -1,507 +0,0 @@
1
- {
2
- "warning": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
3
- "format": "sphinx-lock-1.0.0",
4
- "orgId": "ea165b21-7cdc-4d7b-be59-ecdd4c26bee4",
5
- "projects": {
6
- "nana-address-registry-v5": {
7
- "projectId": "cc6ec42f-5bb5-451a-a66a-928fd3231d2f",
8
- "projectName": "nana-address-registry-v5",
9
- "defaultSafe": {
10
- "safeName": "nana-core-v5",
11
- "owners": [
12
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
13
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
14
- "0xCa81360a91504500674E926b1b301165b2CA9807",
15
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651"
16
- ],
17
- "threshold": "2",
18
- "saltNonce": "0"
19
- }
20
- },
21
- "nana-721-hook-v5": {
22
- "projectId": "b29a3b81-3722-40ad-b831-66472be6d6a8",
23
- "projectName": "nana-721-hook-v5",
24
- "defaultSafe": {
25
- "safeName": "nana-core-v5",
26
- "owners": [
27
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
28
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
29
- "0xCa81360a91504500674E926b1b301165b2CA9807",
30
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651"
31
- ],
32
- "threshold": "2",
33
- "saltNonce": "0"
34
- }
35
- },
36
- "revnet-core-v5": {
37
- "projectId": "cf581f7f-8bab-4773-b1bf-6389b6891056",
38
- "projectName": "revnet-core-v5",
39
- "defaultSafe": {
40
- "safeName": "revnet",
41
- "owners": [
42
- "0x14293560A2dde4fFA136A647b7a2f927b0774AB6",
43
- "0x1bb1e3F6818FeB7c1F1674e6E7D6c30BA2725643",
44
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
45
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
46
- "0xCa81360a91504500674E926b1b301165b2CA9807",
47
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651",
48
- "0xf33CFe55655B0190eAF5aC2749F954c64E06d887"
49
- ],
50
- "threshold": "3",
51
- "saltNonce": "0"
52
- }
53
- },
54
- "croptop-core": {
55
- "projectId": "0c213583-47a4-4212-a7cb-b2c0cfdcdac4",
56
- "projectName": "croptop-core",
57
- "defaultSafe": {
58
- "safeName": "croptop",
59
- "owners": [
60
- "0x14293560A2dde4fFA136A647b7a2f927b0774AB6",
61
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
62
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
63
- "0x8d3CC5b1a5268Ff0C119c5c03252EB8c1bFEBbB2",
64
- "0xCa81360a91504500674E926b1b301165b2CA9807"
65
- ],
66
- "threshold": "2",
67
- "saltNonce": "0"
68
- }
69
- },
70
- "nana-721-hook": {
71
- "projectId": "67cfcad1-d38b-4b4d-b137-a24797c31991",
72
- "projectName": "nana-721-hook",
73
- "defaultSafe": {
74
- "safeName": "nana-core",
75
- "owners": [
76
- "0x1bb1e3F6818FeB7c1F1674e6E7D6c30BA2725643",
77
- "0x34aA3F359A9D614239015126635CE7732c18fDF3",
78
- "0x5a3f5ac3D6f1a0061D3bB91f38606F7103eCdBe8",
79
- "0x5EE9F1cdD9588A3c800441CBd7A38Ffeff40cBc2",
80
- "0x63A2368F4B509438ca90186cb1C15156713D5834",
81
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
82
- "0x721b19e30EF791FF2A67FF4b375E591aAf84136B",
83
- "0x73aEd5a32E898644Acb841C3Ac40663202CfD485",
84
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
85
- "0x8d3CC5b1a5268Ff0C119c5c03252EB8c1bFEBbB2",
86
- "0x99368d83F73b803Caf924956C5EE6E0b8f86Fb3B",
87
- "0xc109636a2b47f8b290cc134dd446Fcd7d7e0cC94",
88
- "0xCa81360a91504500674E926b1b301165b2CA9807",
89
- "0xD78285eef93E13D1F96062265b68099C480121b8",
90
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651",
91
- "0xe7879a2D05dBA966Fcca34EE9C3F99eEe7eDEFd1",
92
- "0xf33CFe55655B0190eAF5aC2749F954c64E06d887"
93
- ],
94
- "threshold": "9",
95
- "saltNonce": "0"
96
- }
97
- },
98
- "nana-suckers": {
99
- "projectId": "1b040a9e-0764-4173-880e-b5ebf312bc44",
100
- "projectName": "nana-suckers",
101
- "defaultSafe": {
102
- "safeName": "nana-core",
103
- "owners": [
104
- "0x1bb1e3F6818FeB7c1F1674e6E7D6c30BA2725643",
105
- "0x34aA3F359A9D614239015126635CE7732c18fDF3",
106
- "0x5a3f5ac3D6f1a0061D3bB91f38606F7103eCdBe8",
107
- "0x5EE9F1cdD9588A3c800441CBd7A38Ffeff40cBc2",
108
- "0x63A2368F4B509438ca90186cb1C15156713D5834",
109
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
110
- "0x721b19e30EF791FF2A67FF4b375E591aAf84136B",
111
- "0x73aEd5a32E898644Acb841C3Ac40663202CfD485",
112
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
113
- "0x8d3CC5b1a5268Ff0C119c5c03252EB8c1bFEBbB2",
114
- "0x99368d83F73b803Caf924956C5EE6E0b8f86Fb3B",
115
- "0xc109636a2b47f8b290cc134dd446Fcd7d7e0cC94",
116
- "0xCa81360a91504500674E926b1b301165b2CA9807",
117
- "0xD78285eef93E13D1F96062265b68099C480121b8",
118
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651",
119
- "0xe7879a2D05dBA966Fcca34EE9C3F99eEe7eDEFd1",
120
- "0xf33CFe55655B0190eAF5aC2749F954c64E06d887"
121
- ],
122
- "threshold": "9",
123
- "saltNonce": "0"
124
- }
125
- },
126
- "nana-project-handles-v5": {
127
- "projectId": "8795935f-e0ba-4b84-9ec2-44315fbdf4d8",
128
- "projectName": "nana-project-handles-v5",
129
- "defaultSafe": {
130
- "safeName": "nana-core-v5",
131
- "owners": [
132
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
133
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
134
- "0xCa81360a91504500674E926b1b301165b2CA9807",
135
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651"
136
- ],
137
- "threshold": "2",
138
- "saltNonce": "0"
139
- }
140
- },
141
- "nana-core": {
142
- "projectId": "290d6007-345d-4bcc-af08-5e5a26ca2dc5",
143
- "projectName": "nana-core",
144
- "defaultSafe": {
145
- "safeName": "nana-core",
146
- "owners": [
147
- "0x1bb1e3F6818FeB7c1F1674e6E7D6c30BA2725643",
148
- "0x34aA3F359A9D614239015126635CE7732c18fDF3",
149
- "0x5a3f5ac3D6f1a0061D3bB91f38606F7103eCdBe8",
150
- "0x5EE9F1cdD9588A3c800441CBd7A38Ffeff40cBc2",
151
- "0x63A2368F4B509438ca90186cb1C15156713D5834",
152
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
153
- "0x721b19e30EF791FF2A67FF4b375E591aAf84136B",
154
- "0x73aEd5a32E898644Acb841C3Ac40663202CfD485",
155
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
156
- "0x8d3CC5b1a5268Ff0C119c5c03252EB8c1bFEBbB2",
157
- "0x99368d83F73b803Caf924956C5EE6E0b8f86Fb3B",
158
- "0xc109636a2b47f8b290cc134dd446Fcd7d7e0cC94",
159
- "0xCa81360a91504500674E926b1b301165b2CA9807",
160
- "0xD78285eef93E13D1F96062265b68099C480121b8",
161
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651",
162
- "0xe7879a2D05dBA966Fcca34EE9C3F99eEe7eDEFd1",
163
- "0xf33CFe55655B0190eAF5aC2749F954c64E06d887"
164
- ],
165
- "threshold": "9",
166
- "saltNonce": "0"
167
- }
168
- },
169
- "revnet-core": {
170
- "projectId": "ff72a6d2-9324-49ef-a415-57e253550e9e",
171
- "projectName": "revnet-core",
172
- "defaultSafe": {
173
- "safeName": "revnet",
174
- "owners": [
175
- "0x14293560A2dde4fFA136A647b7a2f927b0774AB6",
176
- "0x1bb1e3F6818FeB7c1F1674e6E7D6c30BA2725643",
177
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
178
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
179
- "0xCa81360a91504500674E926b1b301165b2CA9807",
180
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651",
181
- "0xf33CFe55655B0190eAF5aC2749F954c64E06d887"
182
- ],
183
- "threshold": "3",
184
- "saltNonce": "0"
185
- }
186
- },
187
- "nana-core-v5": {
188
- "projectId": "43d1f453-3129-4383-a056-d1da4f3b1ee8",
189
- "projectName": "nana-core-v5",
190
- "defaultSafe": {
191
- "safeName": "nana-core-v5",
192
- "owners": [
193
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
194
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
195
- "0xCa81360a91504500674E926b1b301165b2CA9807",
196
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651"
197
- ],
198
- "threshold": "2",
199
- "saltNonce": "0"
200
- }
201
- },
202
- "croptop-core-v5": {
203
- "projectId": "c98d4514-1c9c-4ae5-a31f-8bf705c01fb1",
204
- "projectName": "croptop-core-v5",
205
- "defaultSafe": {
206
- "safeName": "croptop",
207
- "owners": [
208
- "0x14293560A2dde4fFA136A647b7a2f927b0774AB6",
209
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
210
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
211
- "0x8d3CC5b1a5268Ff0C119c5c03252EB8c1bFEBbB2",
212
- "0xCa81360a91504500674E926b1b301165b2CA9807"
213
- ],
214
- "threshold": "2",
215
- "saltNonce": "0"
216
- }
217
- },
218
- "nana-omnichain-deployers-v5": {
219
- "projectId": "85f08b91-0786-425c-a5bc-4e31a2fbedaa",
220
- "projectName": "nana-omnichain-deployers-v5",
221
- "defaultSafe": {
222
- "safeName": "nana-core-v5",
223
- "owners": [
224
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
225
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
226
- "0xCa81360a91504500674E926b1b301165b2CA9807",
227
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651"
228
- ],
229
- "threshold": "2",
230
- "saltNonce": "0"
231
- }
232
- },
233
- "nana-suckers-v5": {
234
- "projectId": "55b45d45-a209-4197-83e1-aa096e19ddbc",
235
- "projectName": "nana-suckers-v5",
236
- "defaultSafe": {
237
- "safeName": "nana-core-v5",
238
- "owners": [
239
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
240
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
241
- "0xCa81360a91504500674E926b1b301165b2CA9807",
242
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651"
243
- ],
244
- "threshold": "2",
245
- "saltNonce": "0"
246
- }
247
- },
248
- "nana-omnichain-deployers": {
249
- "projectId": "4c8b18a7-99c8-431a-b575-e6817503fbd2",
250
- "projectName": "nana-omnichain-deployers",
251
- "defaultSafe": {
252
- "safeName": "nana-core-small",
253
- "owners": [
254
- "0x1bb1e3F6818FeB7c1F1674e6E7D6c30BA2725643",
255
- "0x34aA3F359A9D614239015126635CE7732c18fDF3",
256
- "0x5a3f5ac3D6f1a0061D3bB91f38606F7103eCdBe8",
257
- "0x5EE9F1cdD9588A3c800441CBd7A38Ffeff40cBc2",
258
- "0x63A2368F4B509438ca90186cb1C15156713D5834",
259
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
260
- "0x721b19e30EF791FF2A67FF4b375E591aAf84136B",
261
- "0x73aEd5a32E898644Acb841C3Ac40663202CfD485",
262
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
263
- "0x8d3CC5b1a5268Ff0C119c5c03252EB8c1bFEBbB2",
264
- "0x99368d83F73b803Caf924956C5EE6E0b8f86Fb3B",
265
- "0xc109636a2b47f8b290cc134dd446Fcd7d7e0cC94",
266
- "0xCa81360a91504500674E926b1b301165b2CA9807",
267
- "0xD78285eef93E13D1F96062265b68099C480121b8",
268
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651",
269
- "0xe7879a2D05dBA966Fcca34EE9C3F99eEe7eDEFd1",
270
- "0xf33CFe55655B0190eAF5aC2749F954c64E06d887"
271
- ],
272
- "threshold": "5",
273
- "saltNonce": "0"
274
- }
275
- },
276
- "banny-core": {
277
- "projectId": "26678812-e6ca-443d-a5e0-7b62fcdd455f",
278
- "projectName": "banny-core",
279
- "defaultSafe": {
280
- "safeName": "banny-core",
281
- "owners": [
282
- "0x14293560A2dde4fFA136A647b7a2f927b0774AB6",
283
- "0x63A2368F4B509438ca90186cb1C15156713D5834",
284
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
285
- "0xCa81360a91504500674E926b1b301165b2CA9807",
286
- "0xe7879a2D05dBA966Fcca34EE9C3F99eEe7eDEFd1"
287
- ],
288
- "threshold": "2",
289
- "saltNonce": "0"
290
- }
291
- },
292
- "banny-core-v5": {
293
- "projectId": "47a1f9c8-f418-4907-8402-bfc456ada246",
294
- "projectName": "banny-core-v5",
295
- "defaultSafe": {
296
- "safeName": "banny-core",
297
- "owners": [
298
- "0x14293560A2dde4fFA136A647b7a2f927b0774AB6",
299
- "0x63A2368F4B509438ca90186cb1C15156713D5834",
300
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
301
- "0xCa81360a91504500674E926b1b301165b2CA9807",
302
- "0xe7879a2D05dBA966Fcca34EE9C3F99eEe7eDEFd1"
303
- ],
304
- "threshold": "2",
305
- "saltNonce": "0"
306
- }
307
- },
308
- "nana-periphery": {
309
- "projectId": "0de1ae41-0a43-4bc3-8eec-208718afaa51",
310
- "projectName": "nana-periphery",
311
- "defaultSafe": {
312
- "safeName": "nana-core",
313
- "owners": [
314
- "0x1bb1e3F6818FeB7c1F1674e6E7D6c30BA2725643",
315
- "0x34aA3F359A9D614239015126635CE7732c18fDF3",
316
- "0x5a3f5ac3D6f1a0061D3bB91f38606F7103eCdBe8",
317
- "0x5EE9F1cdD9588A3c800441CBd7A38Ffeff40cBc2",
318
- "0x63A2368F4B509438ca90186cb1C15156713D5834",
319
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
320
- "0x721b19e30EF791FF2A67FF4b375E591aAf84136B",
321
- "0x73aEd5a32E898644Acb841C3Ac40663202CfD485",
322
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
323
- "0x8d3CC5b1a5268Ff0C119c5c03252EB8c1bFEBbB2",
324
- "0x99368d83F73b803Caf924956C5EE6E0b8f86Fb3B",
325
- "0xc109636a2b47f8b290cc134dd446Fcd7d7e0cC94",
326
- "0xCa81360a91504500674E926b1b301165b2CA9807",
327
- "0xD78285eef93E13D1F96062265b68099C480121b8",
328
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651",
329
- "0xe7879a2D05dBA966Fcca34EE9C3F99eEe7eDEFd1",
330
- "0xf33CFe55655B0190eAF5aC2749F954c64E06d887"
331
- ],
332
- "threshold": "9",
333
- "saltNonce": "0"
334
- }
335
- },
336
- "nana-fee-project": {
337
- "projectId": "8420d3da-9977-4908-be04-d600a090744d",
338
- "projectName": "nana-fee-project",
339
- "defaultSafe": {
340
- "safeName": "nana-core",
341
- "owners": [
342
- "0x1bb1e3F6818FeB7c1F1674e6E7D6c30BA2725643",
343
- "0x34aA3F359A9D614239015126635CE7732c18fDF3",
344
- "0x5a3f5ac3D6f1a0061D3bB91f38606F7103eCdBe8",
345
- "0x5EE9F1cdD9588A3c800441CBd7A38Ffeff40cBc2",
346
- "0x63A2368F4B509438ca90186cb1C15156713D5834",
347
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
348
- "0x721b19e30EF791FF2A67FF4b375E591aAf84136B",
349
- "0x73aEd5a32E898644Acb841C3Ac40663202CfD485",
350
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
351
- "0x8d3CC5b1a5268Ff0C119c5c03252EB8c1bFEBbB2",
352
- "0x99368d83F73b803Caf924956C5EE6E0b8f86Fb3B",
353
- "0xc109636a2b47f8b290cc134dd446Fcd7d7e0cC94",
354
- "0xCa81360a91504500674E926b1b301165b2CA9807",
355
- "0xD78285eef93E13D1F96062265b68099C480121b8",
356
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651",
357
- "0xe7879a2D05dBA966Fcca34EE9C3F99eEe7eDEFd1",
358
- "0xf33CFe55655B0190eAF5aC2749F954c64E06d887"
359
- ],
360
- "threshold": "9",
361
- "saltNonce": "0"
362
- }
363
- },
364
- "nana-buyback-hook": {
365
- "projectId": "f348713c-83c9-4a85-9b34-acce562d5593",
366
- "projectName": "nana-buyback-hook",
367
- "defaultSafe": {
368
- "safeName": "nana-core-small",
369
- "owners": [
370
- "0x1bb1e3F6818FeB7c1F1674e6E7D6c30BA2725643",
371
- "0x34aA3F359A9D614239015126635CE7732c18fDF3",
372
- "0x5a3f5ac3D6f1a0061D3bB91f38606F7103eCdBe8",
373
- "0x5EE9F1cdD9588A3c800441CBd7A38Ffeff40cBc2",
374
- "0x63A2368F4B509438ca90186cb1C15156713D5834",
375
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
376
- "0x721b19e30EF791FF2A67FF4b375E591aAf84136B",
377
- "0x73aEd5a32E898644Acb841C3Ac40663202CfD485",
378
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
379
- "0x8d3CC5b1a5268Ff0C119c5c03252EB8c1bFEBbB2",
380
- "0x99368d83F73b803Caf924956C5EE6E0b8f86Fb3B",
381
- "0xc109636a2b47f8b290cc134dd446Fcd7d7e0cC94",
382
- "0xCa81360a91504500674E926b1b301165b2CA9807",
383
- "0xD78285eef93E13D1F96062265b68099C480121b8",
384
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651",
385
- "0xe7879a2D05dBA966Fcca34EE9C3F99eEe7eDEFd1",
386
- "0xf33CFe55655B0190eAF5aC2749F954c64E06d887"
387
- ],
388
- "threshold": "5",
389
- "saltNonce": "0"
390
- }
391
- },
392
- "nana-address-registry": {
393
- "projectId": "b1c7e214-2927-4042-a3c9-d5751940ce28",
394
- "projectName": "nana-address-registry",
395
- "defaultSafe": {
396
- "safeName": "nana-core",
397
- "owners": [
398
- "0x1bb1e3F6818FeB7c1F1674e6E7D6c30BA2725643",
399
- "0x34aA3F359A9D614239015126635CE7732c18fDF3",
400
- "0x5a3f5ac3D6f1a0061D3bB91f38606F7103eCdBe8",
401
- "0x5EE9F1cdD9588A3c800441CBd7A38Ffeff40cBc2",
402
- "0x63A2368F4B509438ca90186cb1C15156713D5834",
403
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
404
- "0x721b19e30EF791FF2A67FF4b375E591aAf84136B",
405
- "0x73aEd5a32E898644Acb841C3Ac40663202CfD485",
406
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
407
- "0x8d3CC5b1a5268Ff0C119c5c03252EB8c1bFEBbB2",
408
- "0x99368d83F73b803Caf924956C5EE6E0b8f86Fb3B",
409
- "0xc109636a2b47f8b290cc134dd446Fcd7d7e0cC94",
410
- "0xCa81360a91504500674E926b1b301165b2CA9807",
411
- "0xD78285eef93E13D1F96062265b68099C480121b8",
412
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651",
413
- "0xe7879a2D05dBA966Fcca34EE9C3F99eEe7eDEFd1",
414
- "0xf33CFe55655B0190eAF5aC2749F954c64E06d887"
415
- ],
416
- "threshold": "9",
417
- "saltNonce": "0"
418
- }
419
- },
420
- "nana-swap-terminal-v5": {
421
- "projectId": "b476ccb3-4857-4d11-87cf-9b5cb3ac27c2",
422
- "projectName": "nana-swap-terminal-v5",
423
- "defaultSafe": {
424
- "safeName": "nana-core-v5",
425
- "owners": [
426
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
427
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
428
- "0xCa81360a91504500674E926b1b301165b2CA9807",
429
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651"
430
- ],
431
- "threshold": "2",
432
- "saltNonce": "0"
433
- }
434
- },
435
- "nana-project-handles": {
436
- "projectId": "67c86da0-a089-4b0f-a04d-4dffda844ff9",
437
- "projectName": "nana-project-handles",
438
- "defaultSafe": {
439
- "safeName": "nana-core-small",
440
- "owners": [
441
- "0x1bb1e3F6818FeB7c1F1674e6E7D6c30BA2725643",
442
- "0x34aA3F359A9D614239015126635CE7732c18fDF3",
443
- "0x5a3f5ac3D6f1a0061D3bB91f38606F7103eCdBe8",
444
- "0x5EE9F1cdD9588A3c800441CBd7A38Ffeff40cBc2",
445
- "0x63A2368F4B509438ca90186cb1C15156713D5834",
446
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
447
- "0x721b19e30EF791FF2A67FF4b375E591aAf84136B",
448
- "0x73aEd5a32E898644Acb841C3Ac40663202CfD485",
449
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
450
- "0x8d3CC5b1a5268Ff0C119c5c03252EB8c1bFEBbB2",
451
- "0x99368d83F73b803Caf924956C5EE6E0b8f86Fb3B",
452
- "0xc109636a2b47f8b290cc134dd446Fcd7d7e0cC94",
453
- "0xCa81360a91504500674E926b1b301165b2CA9807",
454
- "0xD78285eef93E13D1F96062265b68099C480121b8",
455
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651",
456
- "0xe7879a2D05dBA966Fcca34EE9C3F99eEe7eDEFd1",
457
- "0xf33CFe55655B0190eAF5aC2749F954c64E06d887"
458
- ],
459
- "threshold": "5",
460
- "saltNonce": "0"
461
- }
462
- },
463
- "nana-swap-terminal": {
464
- "projectId": "a804c33d-fd0c-4dea-930b-ab72fec9f557",
465
- "projectName": "nana-swap-terminal",
466
- "defaultSafe": {
467
- "safeName": "nana-core-small",
468
- "owners": [
469
- "0x1bb1e3F6818FeB7c1F1674e6E7D6c30BA2725643",
470
- "0x34aA3F359A9D614239015126635CE7732c18fDF3",
471
- "0x5a3f5ac3D6f1a0061D3bB91f38606F7103eCdBe8",
472
- "0x5EE9F1cdD9588A3c800441CBd7A38Ffeff40cBc2",
473
- "0x63A2368F4B509438ca90186cb1C15156713D5834",
474
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
475
- "0x721b19e30EF791FF2A67FF4b375E591aAf84136B",
476
- "0x73aEd5a32E898644Acb841C3Ac40663202CfD485",
477
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
478
- "0x8d3CC5b1a5268Ff0C119c5c03252EB8c1bFEBbB2",
479
- "0x99368d83F73b803Caf924956C5EE6E0b8f86Fb3B",
480
- "0xc109636a2b47f8b290cc134dd446Fcd7d7e0cC94",
481
- "0xCa81360a91504500674E926b1b301165b2CA9807",
482
- "0xD78285eef93E13D1F96062265b68099C480121b8",
483
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651",
484
- "0xe7879a2D05dBA966Fcca34EE9C3F99eEe7eDEFd1",
485
- "0xf33CFe55655B0190eAF5aC2749F954c64E06d887"
486
- ],
487
- "threshold": "5",
488
- "saltNonce": "0"
489
- }
490
- },
491
- "nana-buyback-hook-v5": {
492
- "projectId": "cf0b6f77-d870-4ccf-bbdc-6b22dceb11b6",
493
- "projectName": "nana-buyback-hook-v5",
494
- "defaultSafe": {
495
- "safeName": "nana-core-v5",
496
- "owners": [
497
- "0x6849310926127F819d48894DeA667f3ECD18a07c",
498
- "0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD",
499
- "0xCa81360a91504500674E926b1b301165b2CA9807",
500
- "0xDc6Dd6Bc601448541A4862a91De1B86291839651"
501
- ],
502
- "threshold": "2",
503
- "saltNonce": "0"
504
- }
505
- }
506
- }
507
- }