@ballkidz/defifa 0.0.5 → 0.0.7

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/RISKS.md CHANGED
@@ -101,7 +101,7 @@ Deep implementation-level risk analysis with line references, severity ratings,
101
101
 
102
102
  **Severity:** MEDIUM
103
103
  **Status:** BY DESIGN
104
- **Tested:** `DefifaSecurityTest.testM_D6_delegationBlocked`, `DefifaHook_AuditFindings.test_M5_attestationUnitsPreservedOnTransferToUndelegatedRecipient`
104
+ **Tested:** `DefifaSecurityTest.testM_D6_delegationBlocked`, `DefifaHookRegressions.test_M5_attestationUnitsPreservedOnTransferToUndelegatedRecipient`
105
105
 
106
106
  **Description:** `setTierDelegateTo` and `setTierDelegatesTo` only work during MINT phase (DefifaHook lines 730, 740). After MINT, NFT transfers auto-delegate to the recipient (if no delegate set), but holders cannot explicitly re-delegate.
107
107
 
@@ -140,7 +140,7 @@ Deep implementation-level risk analysis with line references, severity ratings,
140
140
 
141
141
  **Severity:** LOW
142
142
  **Status:** MITIGATED
143
- **Tested:** `M36_FulfillmentBlocksRatification.test_ratificationSucceedsWhenFulfillmentReverts`
143
+ **Tested:** `FulfillmentBlocksRatification.test_ratificationSucceedsWhenFulfillmentReverts`
144
144
 
145
145
  **Description:** `ratifyScorecardFrom` wraps `fulfillCommitmentsOf` in a try-catch (DefifaGovernor lines 402-405). If fulfillment fails (e.g., `sendPayoutsOf` reverts), the scorecard is still ratified and `FulfillmentFailed` event is emitted.
146
146
 
@@ -154,7 +154,7 @@ Deep implementation-level risk analysis with line references, severity ratings,
154
154
 
155
155
  **Severity:** LOW
156
156
  **Status:** FIXED (Regression tested)
157
- **Tested:** `M35_GracePeriodBypass.test_gracePeriodExtendsFromAttestationStart`
157
+ **Tested:** `GracePeriodBypass.test_gracePeriodExtendsFromAttestationStart`
158
158
 
159
159
  **Description:** When a scorecard is submitted before `attestationStartTime`, the grace period could previously expire before attestations even begin. Fixed by anchoring `gracePeriodEnds` to `attestationsBegin` rather than submission time.
160
160
 
@@ -245,7 +245,7 @@ Deep implementation-level risk analysis with line references, severity ratings,
245
245
 
246
246
  **Severity:** HIGH (before fix)
247
247
  **Status:** FIXED
248
- **Tested:** `DefifaHook_AuditFindings.test_M5_attestationUnitsPreservedOnTransferToUndelegatedRecipient`, `test_M5_multipleTransfersToUndelegatedRecipientsPreserveUnits`
248
+ **Tested:** `DefifaHookRegressions.test_M5_attestationUnitsPreservedOnTransferToUndelegatedRecipient`, `test_M5_multipleTransfersToUndelegatedRecipientsPreserveUnits`
249
249
 
250
250
  **Description:** Previously, transferring an NFT to a recipient with no delegate set would lose attestation units (sender's delegate lost units but no one gained them). Fixed by auto-delegating undelegated recipients to themselves in `_transferTierAttestationUnits` (DefifaHook lines 1001-1006).
251
251
 
@@ -314,15 +314,15 @@ Deep implementation-level risk analysis with line references, severity ratings,
314
314
  | RISK-6 Delegation locked | `DefifaSecurity.t.sol` | `testM_D6_delegationBlocked` |
315
315
  | RISK-7 Single governor | (No isolation test) | Design review only |
316
316
  | RISK-8 Clone front-running | (Implicit) | All `launchGameWith` tests |
317
- | RISK-9 Fulfillment failure | `regression/M36_FulfillmentBlocksRatification.t.sol` | `test_ratificationSucceedsWhenFulfillmentReverts` |
318
- | RISK-10 Grace period bypass | `regression/M35_GracePeriodBypass.t.sol` | `test_gracePeriodExtendsFromAttestationStart` |
317
+ | RISK-9 Fulfillment failure | `regression/FulfillmentBlocksRatification.t.sol` | `test_ratificationSucceedsWhenFulfillmentReverts` |
318
+ | RISK-10 Grace period bypass | `regression/GracePeriodBypass.t.sol` | `test_gracePeriodExtendsFromAttestationStart` |
319
319
  | RISK-11 Overweight scorecard | `DefifaSecurity.t.sol` | `testC_D2_rejectsOverweight` |
320
320
  | RISK-12 No-contest trigger | `DefifaNoContest.t.sol` | `testNoContest_cashOutBeforeTrigger_reverts`, `testTriggerNoContest_revertsWhenNotNoContest`, `testTriggerNoContest_revertsWhenAlreadyTriggered` |
321
321
  | RISK-13 `_totalMintCost` | `DefifaMintCostInvariant.t.sol` | `invariant_totalMintCostMatchesExpected`, `invariant_totalMintCostEqualsPriceTimesLiveTokens`, `invariant_tokenCountConsistency` |
322
322
  | RISK-14 Fee accounting | `DefifaFeeAccounting.t.sol` | All 6 tests |
323
323
  | RISK-15 Cash-out reentrancy | (Code review) | State ordering analysis |
324
324
  | RISK-16 Fulfillment reentrancy | (Code review) | Guard analysis |
325
- | RISK-17 Attestation conservation | `DefifaHook_AuditFindings.t.sol` | `test_M5_attestationUnitsPreservedOnTransferToUndelegatedRecipient`, `test_M5_multipleTransfersToUndelegatedRecipientsPreserveUnits` |
325
+ | RISK-17 Attestation conservation | `DefifaHookRegressions.t.sol` | `test_M5_attestationUnitsPreservedOnTransferToUndelegatedRecipient`, `test_M5_multipleTransfersToUndelegatedRecipientsPreserveUnits` |
326
326
  | RISK-18 Fund conservation | `DefifaSecurity.t.sol` | `testFuzz_fundConservation`, `testHighVolume_32tiers`, `testMultiPlayer_winnerTakesAll`, `testRefundIntegrity` |
327
327
  | RISK-19 uint208 overflow | (Bounded analysis) | Arithmetic review |
328
328
  | RISK-20 Timestamp caching | (Test infrastructure) | `TimestampReader` pattern |
package/STYLE_GUIDE.md CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  How we write Solidity and organize repos across the Juicebox V6 ecosystem. `nana-core-v6` is the gold standard — when in doubt, match what it does.
4
4
 
5
- **This repo's deviations:** `via_ir = true` (stack depth). Package scope: `@ballkidz/`.
6
-
7
5
  ## File Organization
8
6
 
9
7
  ```
@@ -19,8 +17,6 @@ src/
19
17
 
20
18
  One contract/interface/struct/enum per file. Name the file after the type it contains.
21
19
 
22
- **Structs, enums, libraries, and interfaces always go in their subdirectories** (`src/structs/`, `src/enums/`, `src/libraries/`, `src/interfaces/`) — never inline in contract files or placed in `src/` root. This keeps type definitions discoverable and import paths consistent across repos.
23
-
24
20
  ## Pragma Versions
25
21
 
26
22
  ```solidity
@@ -108,14 +104,6 @@ contract JBExample is JBPermissioned, IJBExample {
108
104
  // -------------------------- constructor ---------------------------- //
109
105
  //*********************************************************************//
110
106
 
111
- //*********************************************************************//
112
- // ---------------------- receive / fallback ------------------------- //
113
- //*********************************************************************//
114
-
115
- //*********************************************************************//
116
- // --------------------------- modifiers ----------------------------- //
117
- //*********************************************************************//
118
-
119
107
  //*********************************************************************//
120
108
  // ---------------------- external transactions ---------------------- //
121
109
  //*********************************************************************//
@@ -143,28 +131,23 @@ contract JBExample is JBPermissioned, IJBExample {
143
131
  ```
144
132
 
145
133
  **Section order:**
146
- 1. `using` declarations
147
- 2. Custom errors
148
- 3. Public constants
149
- 4. Internal constants
150
- 5. Public immutable stored properties
151
- 6. Internal immutable stored properties
152
- 7. Public stored properties
153
- 8. Internal stored properties
154
- 9. Constructor
155
- 10. `receive` / `fallback`
156
- 11. Modifiers
157
- 12. External transactions
158
- 13. External views
159
- 14. Public transactions
160
- 15. Internal helpers
161
- 16. Internal views
162
- 17. Private helpers
134
+ 1. Custom errors
135
+ 2. Public constants
136
+ 3. Internal constants
137
+ 4. Public immutable stored properties
138
+ 5. Internal immutable stored properties
139
+ 6. Public stored properties
140
+ 7. Internal stored properties
141
+ 8. Constructor
142
+ 9. External transactions
143
+ 10. External views
144
+ 11. Public transactions
145
+ 12. Internal helpers
146
+ 13. Internal views
147
+ 14. Private helpers
163
148
 
164
149
  Functions are alphabetized within each section.
165
150
 
166
- **Events:** Events are declared in interfaces only, never in implementation contracts. Implementations inherit events from their interface and emit them unqualified. This keeps the ABI definition in one place and allows tests to use interface-qualified event expectations (e.g., `emit IJBController.LaunchProject(...)`).
167
-
168
151
  ## Interface Structure
169
152
 
170
153
  ```solidity
@@ -270,9 +253,12 @@ uint256 public constant MAX_RESERVED_PERCENT = 10_000;
270
253
 
271
254
  ## Function Calls
272
255
 
273
- Use named parameters for readability when calling functions with 3+ arguments:
256
+ Use named arguments for all function calls with 2 or more arguments — in both `src/` and `script/`:
274
257
 
275
258
  ```solidity
259
+ // Good — named arguments
260
+ token.mint({account: beneficiary, amount: count});
261
+ _transferOwnership({newOwner: address(0), projectId: 0});
276
262
  PERMISSIONS.hasPermission({
277
263
  operator: sender,
278
264
  account: account,
@@ -281,8 +267,18 @@ PERMISSIONS.hasPermission({
281
267
  includeRoot: true,
282
268
  includeWildcardProjectId: true
283
269
  });
270
+
271
+ // Bad — positional arguments with 2+ args
272
+ token.mint(beneficiary, count);
273
+ _transferOwnership(address(0), 0);
284
274
  ```
285
275
 
276
+ Single-argument calls use positional style: `_burn(amount)`.
277
+
278
+ This also applies to constructor calls, struct literals, and inherited/library calls (e.g., OZ `_mint`, `_safeMint`, `safeTransfer`, `allowance`, `Clones.cloneDeterministic`).
279
+
280
+ Named argument keys must use **camelCase** — never underscores. If a function's parameter names use underscores, rename them to camelCase first.
281
+
286
282
  ## Multiline Signatures
287
283
 
288
284
  ```solidity
@@ -326,7 +322,7 @@ try hook.afterPayRecordedWith(context) {} catch (bytes memory reason) {
326
322
 
327
323
  ### foundry.toml
328
324
 
329
- Standard config for `@bananapus/core-v6`:
325
+ Standard config across all repos:
330
326
 
331
327
  ```toml
332
328
  [profile.default]
@@ -336,9 +332,6 @@ optimizer_runs = 200
336
332
  libs = ["node_modules", "lib"]
337
333
  fs_permissions = [{ access = "read-write", path = "./"}]
338
334
 
339
- [profile.ci_sizes]
340
- optimizer_runs = 200
341
-
342
335
  [fuzz]
343
336
  runs = 4096
344
337
 
@@ -353,7 +346,14 @@ multiline_func_header = "all"
353
346
  wrap_comments = true
354
347
  ```
355
348
 
356
- This is the standard config with no deviations.
349
+ **Optional sections (add only when needed):**
350
+ - `[rpc_endpoints]` — repos with fork tests. Maps named endpoints to env vars (e.g. `ethereum = "${RPC_ETHEREUM_MAINNET}"`).
351
+ - `[profile.ci_sizes]` — only when CI needs different optimizer settings than defaults for the size check step (e.g. `optimizer_runs = 200` when the default profile uses a lower value).
352
+
353
+ **Common variations:**
354
+ - `via_ir = true` when hitting stack-too-deep
355
+ - `optimizer = false` when optimization causes stack-too-deep
356
+ - `optimizer_runs` reduced when deep struct nesting causes stack-too-deep at 200 runs
357
357
 
358
358
  ### CI Workflows
359
359
 
@@ -383,8 +383,10 @@ jobs:
383
383
  uses: foundry-rs/foundry-toolchain@v1
384
384
  - name: Run tests
385
385
  run: forge test --fail-fast --summary --detailed --skip "*/script/**"
386
+ env:
387
+ RPC_ETHEREUM_MAINNET: ${{ secrets.RPC_ETHEREUM_MAINNET }}
386
388
  - name: Check contract sizes
387
- run: FOUNDRY_PROFILE=ci_sizes forge build --sizes --skip "*/test/**" --skip "*/script/**" --skip SphinxUtils
389
+ run: forge build --sizes --skip "*/test/**" --skip "*/script/**" --skip SphinxUtils
388
390
  ```
389
391
 
390
392
  **lint.yml:**
@@ -406,14 +408,63 @@ jobs:
406
408
  run: forge fmt --check
407
409
  ```
408
410
 
411
+ **slither.yml** (repos with `src/` contracts only):
412
+ ```yaml
413
+ name: slither
414
+ on:
415
+ pull_request:
416
+ branches:
417
+ - main
418
+ push:
419
+ branches:
420
+ - main
421
+ jobs:
422
+ analyze:
423
+ runs-on: ubuntu-latest
424
+ steps:
425
+ - uses: actions/checkout@v4
426
+ with:
427
+ submodules: recursive
428
+ - uses: actions/setup-node@v4
429
+ with:
430
+ node-version: latest
431
+ - name: Install npm dependencies
432
+ run: npm install --omit=dev
433
+ - name: Install Foundry
434
+ uses: foundry-rs/foundry-toolchain@v1
435
+ - name: Run slither
436
+ uses: crytic/slither-action@v0.3.1
437
+ with:
438
+ slither-config: slither-ci.config.json
439
+ fail-on: medium
440
+ ```
441
+
442
+ **slither-ci.config.json:**
443
+ ```json
444
+ {
445
+ "detectors_to_exclude": "timestamp,uninitialized-local,naming-convention,solc-version,shadowing-local",
446
+ "exclude_informational": true,
447
+ "exclude_low": false,
448
+ "exclude_medium": false,
449
+ "exclude_high": false,
450
+ "disable_color": false,
451
+ "filter_paths": "(mocks/|test/|node_modules/|lib/)",
452
+ "legacy_ast": false
453
+ }
454
+ ```
455
+
456
+ **Variations:**
457
+ - Deployer-only repos (no `src/`, only `script/`) skip slither entirely — the action's internal `forge build` skips `test/` and `script/` by default, leaving nothing to compile.
458
+ - Use inline `// slither-disable-next-line <detector>` to suppress known false positives rather than adding to `detectors_to_exclude` in the config. The comment must be on the line immediately before the flagged expression.
459
+
409
460
  ### package.json
410
461
 
411
462
  ```json
412
463
  {
413
- "name": "@bananapus/core-v6",
464
+ "name": "@bananapus/package-name-v6",
414
465
  "version": "x.x.x",
415
466
  "license": "MIT",
416
- "repository": { "type": "git", "url": "git+https://github.com/Bananapus/nana-core-v6.git" },
467
+ "repository": { "type": "git", "url": "git+https://github.com/Org/repo.git" },
417
468
  "engines": { "node": ">=20.0.0" },
418
469
  "scripts": {
419
470
  "test": "forge test",
@@ -430,13 +481,62 @@ jobs:
430
481
 
431
482
  ### remappings.txt
432
483
 
433
- Every repo has a `remappings.txt`. Minimal content:
484
+ Every repo has a `remappings.txt` as the **single source of truth** for import remappings. Never add remappings to `foundry.toml`.
485
+
486
+ **Principle:** Import paths in Solidity source must match npm package names exactly. With `libs = ["node_modules", "lib"]`, Foundry auto-resolves `@scope/package/path/File.sol` → `node_modules/@scope/package/path/File.sol`. No remapping needed for packages installed as real directories.
487
+
488
+ **Note:** Auto-resolution does **not** work for symlinked packages (e.g. npm workspace links). Workspace repos like `deploy-all-v6` and `nana-cli-v6` need explicit `@scope/package/=node_modules/@scope/package/` remappings for each symlinked dependency.
489
+
490
+ **Minimal content** (most repos):
491
+
492
+ ```
493
+ forge-std/=lib/forge-std/src/
494
+ ```
495
+
496
+ Only add extra remappings for:
497
+ - **`forge-std`** — always needed (git submodule with `src/` subdirectory)
498
+ - **Repo-specific `lib/` submodules** that have no npm package (e.g., `hookmate/=lib/hookmate/src/`)
499
+ - **Symlinked npm packages** — need explicit `@scope/package/=node_modules/@scope/package/` entries
500
+ - **Nested transitive deps** — e.g., `@chainlink/contracts-ccip/` nested inside `@bananapus/suckers-v6/node_modules/`
434
501
 
502
+ **Never add remappings for:**
503
+ - npm packages that match their import path and are installed as real directories — they auto-resolve
504
+ - Short-form aliases (e.g., `@bananapus/core/` → `@bananapus/core-v6/src/`) — fix the import instead
505
+ - Packages available via npm that are also git submodules — remove the submodule, use npm
506
+
507
+ **Import path convention:**
508
+
509
+ | Package | Import path | Resolves to |
510
+ |---------|------------|-------------|
511
+ | `@bananapus/core-v6` | `@bananapus/core-v6/src/libraries/JBConstants.sol` | `node_modules/@bananapus/core-v6/src/...` |
512
+ | `@openzeppelin/contracts` | `@openzeppelin/contracts/token/ERC20/IERC20.sol` | `node_modules/@openzeppelin/contracts/...` |
513
+ | `@uniswap/v4-core` | `@uniswap/v4-core/src/interfaces/IPoolManager.sol` | `node_modules/@uniswap/v4-core/src/...` |
514
+
515
+ ### Linting
516
+
517
+ Solar (Foundry's built-in linter) runs automatically during `forge build`. It scans all `.sol` files in `libs` directories, including `node_modules`.
518
+
519
+ **All test helpers must use relative imports** (e.g. `../../src/structs/JBRuleset.sol`), not bare `src/` imports. This ensures solar can resolve paths when the helper is consumed via npm in downstream repos.
520
+
521
+ ### Fork Tests
522
+
523
+ Fork tests use named RPC endpoints defined in `[rpc_endpoints]` of `foundry.toml`. No skip guards — fork tests should hard-fail if the RPC endpoint is unavailable, making CI failures explicit.
524
+
525
+ ```solidity
526
+ function setUp() public {
527
+ vm.createSelectFork("ethereum");
528
+ // ... setup code
529
+ }
435
530
  ```
436
- @sphinx-labs/contracts/=lib/sphinx/packages/contracts/contracts/foundry
531
+
532
+ The endpoint name (e.g. `"ethereum"`) maps to an env var via `foundry.toml`:
533
+
534
+ ```toml
535
+ [rpc_endpoints]
536
+ ethereum = "${RPC_ETHEREUM_MAINNET}"
437
537
  ```
438
538
 
439
- Additional mappings as needed for repo-specific dependencies.
539
+ For multi-chain fork tests, add all needed endpoints.
440
540
 
441
541
  ### Formatting
442
542
 
@@ -464,4 +564,8 @@ CI checks formatting via `forge fmt --check`.
464
564
 
465
565
  ### Contract Size Checks
466
566
 
467
- CI runs `FOUNDRY_PROFILE=ci_sizes forge build --sizes` to catch contracts approaching the 24KB limit. The `ci_sizes` profile uses `optimizer_runs = 200` for realistic size measurement even when the default profile has different optimizer settings.
567
+ CI runs `forge build --sizes` to catch contracts approaching the 24KB limit. When the repo's default `optimizer_runs` differs from what you want for size checking, use `FOUNDRY_PROFILE=ci_sizes forge build --sizes` with a `[profile.ci_sizes]` section in `foundry.toml`.
568
+
569
+ ## Repo-Specific Deviations
570
+
571
+ None. This repo follows the standard configuration exactly.
package/foundry.toml CHANGED
@@ -17,9 +17,6 @@ runs = 1024
17
17
  depth = 100
18
18
  fail_on_revert = false
19
19
 
20
- [lint]
21
- lint_on_build = false
22
-
23
20
  [fmt]
24
21
  number_underscore = "thousands"
25
22
  multiline_func_header = "all"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ballkidz/defifa",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "license": "MIT",
5
5
  "engines": {
6
6
  "node": ">=20.0.0"
@@ -13,12 +13,14 @@
13
13
  "url": "https://github.com/BallKidz/defifa-collection-deployer"
14
14
  },
15
15
  "dependencies": {
16
- "@bananapus/721-hook-v6": "^0.0.13",
17
- "@bananapus/address-registry-v6": "^0.0.4",
18
- "@bananapus/core-v6": "^0.0.14",
19
- "@bananapus/permission-ids-v6": "^0.0.5",
20
- "@openzeppelin/contracts": "5.2.0",
16
+ "@bananapus/721-hook-v6": "^0.0.16",
17
+ "@bananapus/address-registry-v6": "^0.0.9",
18
+ "@bananapus/core-v6": "^0.0.16",
19
+ "@bananapus/permission-ids-v6": "^0.0.9",
20
+ "@croptop/core-v6": "^0.0.15",
21
+ "@openzeppelin/contracts": "^5.6.1",
21
22
  "@prb/math": "^4.1.1",
23
+ "@rev-net/core-v6": "^0.0.12",
22
24
  "scripty.sol": "^2.1.1"
23
25
  },
24
26
  "devDependencies": {
package/remappings.txt CHANGED
@@ -1,6 +1 @@
1
- @openzeppelin/=node_modules/@openzeppelin/
2
- @prb/math/=node_modules/@prb/math/
3
- @bananapus/=node_modules/@bananapus/
4
- @sphinx-labs/contracts/=node_modules/@sphinx-labs/contracts/contracts/foundry/
5
1
  forge-std/=lib/forge-std/src/
6
- scripty.sol/=node_modules/scripty.sol/
@@ -9,7 +9,7 @@ import {DefifaDeployer} from "../src/DefifaDeployer.sol";
9
9
  import {DefifaGovernor} from "../src/DefifaGovernor.sol";
10
10
  import {DefifaProjectOwner} from "../src/DefifaProjectOwner.sol";
11
11
  import {DefifaTokenUriResolver} from "../src/DefifaTokenUriResolver.sol";
12
- import {Sphinx} from "@sphinx-labs/contracts/SphinxPlugin.sol";
12
+ import {Sphinx} from "@sphinx-labs/contracts/contracts/foundry/SphinxPlugin.sol";
13
13
 
14
14
  import {CoreDeployment, CoreDeploymentLib} from "@bananapus/core-v6/script/helpers/CoreDeploymentLib.sol";
15
15
  import {
@@ -91,18 +91,20 @@ contract DeployMainnet is Script, Sphinx {
91
91
  }
92
92
 
93
93
  function deploy() public sphinx {
94
- DefifaHook hook = new DefifaHook{salt: _salt}(core.directory, defifaToken, baseProtocolToken);
94
+ DefifaHook hook = new DefifaHook{salt: _salt}({
95
+ _directory: core.directory, _defifaToken: defifaToken, _baseProtocolToken: baseProtocolToken
96
+ });
95
97
  DefifaTokenUriResolver tokenUriResolver = new DefifaTokenUriResolver{salt: _salt}(_typeface);
96
- DefifaGovernor governor = new DefifaGovernor{salt: _salt}(core.controller, safeAddress());
97
- DefifaDeployer deployer = new DefifaDeployer{salt: _salt}(
98
- address(hook),
99
- tokenUriResolver,
100
- governor,
101
- core.controller,
102
- registry.registry,
103
- _defifaProjectId,
104
- _baseProtocolProjectId
105
- );
98
+ DefifaGovernor governor = new DefifaGovernor{salt: _salt}({_controller: core.controller, _owner: safeAddress()});
99
+ DefifaDeployer deployer = new DefifaDeployer{salt: _salt}({
100
+ _hookCodeOrigin: address(hook),
101
+ _tokenUriResolver: tokenUriResolver,
102
+ _governor: governor,
103
+ _controller: core.controller,
104
+ _registry: registry.registry,
105
+ _defifaProjectId: _defifaProjectId,
106
+ _baseProtocolProjectId: _baseProtocolProjectId
107
+ });
106
108
 
107
109
  governor.transferOwnership(address(deployer));
108
110
  }
@@ -9,7 +9,7 @@ import {DefifaDeployer} from "../../src/DefifaDeployer.sol";
9
9
  import {DefifaGovernor} from "../../src/DefifaGovernor.sol";
10
10
  import {DefifaTokenUriResolver} from "../../src/DefifaTokenUriResolver.sol";
11
11
 
12
- import {SphinxConstants, NetworkInfo} from "@sphinx-labs/contracts/SphinxConstants.sol";
12
+ import {SphinxConstants, NetworkInfo} from "@sphinx-labs/contracts/contracts/foundry/SphinxConstants.sol";
13
13
 
14
14
  struct DefifaDeployment {
15
15
  DefifaHook hook;
@@ -34,7 +34,7 @@ library DefifaDeploymentLib {
34
34
 
35
35
  for (uint256 _i; _i < networks.length; _i++) {
36
36
  if (networks[_i].chainId == chainId) {
37
- return getDeployment(path, networks[_i].name);
37
+ return getDeployment({path: path, network_name: networks[_i].name});
38
38
  }
39
39
  }
40
40
 
@@ -49,14 +49,32 @@ library DefifaDeploymentLib {
49
49
  view
50
50
  returns (DefifaDeployment memory deployment)
51
51
  {
52
- deployment.hook = DefifaHook(_getDeploymentAddress(path, PROJECT_NAME, network_name, "DefifaHook"));
52
+ deployment.hook = DefifaHook(
53
+ _getDeploymentAddress({
54
+ path: path, project_name: PROJECT_NAME, network_name: network_name, contractName: "DefifaHook"
55
+ })
56
+ );
53
57
 
54
- deployment.deployer = DefifaDeployer(_getDeploymentAddress(path, PROJECT_NAME, network_name, "DefifaDeployer"));
58
+ deployment.deployer = DefifaDeployer(
59
+ _getDeploymentAddress({
60
+ path: path, project_name: PROJECT_NAME, network_name: network_name, contractName: "DefifaDeployer"
61
+ })
62
+ );
55
63
 
56
- deployment.governor = DefifaGovernor(_getDeploymentAddress(path, PROJECT_NAME, network_name, "DefifaGovernor"));
64
+ deployment.governor = DefifaGovernor(
65
+ _getDeploymentAddress({
66
+ path: path, project_name: PROJECT_NAME, network_name: network_name, contractName: "DefifaGovernor"
67
+ })
68
+ );
57
69
 
58
- deployment.tokenUriResolver =
59
- DefifaTokenUriResolver(_getDeploymentAddress(path, PROJECT_NAME, network_name, "DefifaTokenUriResolver"));
70
+ deployment.tokenUriResolver = DefifaTokenUriResolver(
71
+ _getDeploymentAddress({
72
+ path: path,
73
+ project_name: PROJECT_NAME,
74
+ network_name: network_name,
75
+ contractName: "DefifaTokenUriResolver"
76
+ })
77
+ );
60
78
  }
61
79
 
62
80
  /// @notice Get the address of a contract that was deployed by the Deploy script.
@@ -78,6 +96,6 @@ library DefifaDeploymentLib {
78
96
  {
79
97
  string memory deploymentJson =
80
98
  vm.readFile(string.concat(path, project_name, "/", network_name, "/", contractName, ".json"));
81
- return stdJson.readAddress(deploymentJson, ".address");
99
+ return stdJson.readAddress({json: deploymentJson, key: ".address"});
82
100
  }
83
101
  }
@@ -323,7 +323,8 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
323
323
  if (_pot == 0) revert DefifaDeployer_NothingToFulfill();
324
324
 
325
325
  // Compute the fee amount based on the total absolute split percent stored at game creation.
326
- uint256 _feeAmount = mulDiv(_pot, _commitmentPercentOf[gameId], JBConstants.SPLITS_TOTAL_PERCENT);
326
+ uint256 _feeAmount =
327
+ mulDiv({x: _pot, y: _commitmentPercentOf[gameId], denominator: JBConstants.SPLITS_TOTAL_PERCENT});
327
328
 
328
329
  // Store the actual fee amount for accurate currentGamePotOf reporting.
329
330
  // Use max(feeAmount, 1) to preserve the reentrancy guard when pot is 0.
@@ -523,7 +524,9 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
523
524
  // cloneDeterministic with msg.sender in the salt prevents this since a different
524
525
  // caller produces a different address.
525
526
  DefifaHook _hook = DefifaHook(
526
- Clones.cloneDeterministic(hookCodeOrigin, keccak256(abi.encodePacked(msg.sender, _currentNonce)))
527
+ Clones.cloneDeterministic({
528
+ implementation: hookCodeOrigin, salt: keccak256(abi.encodePacked(msg.sender, _currentNonce))
529
+ })
527
530
  );
528
531
 
529
532
  // Use the default uri resolver if provided, else use the hardcoded generic default.
@@ -857,14 +860,20 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
857
860
  uint256 _normalizedTotal;
858
861
  for (uint256 _i; _i < _numberOfUserSplits; _i++) {
859
862
  _splits[_i] = _initialSplits[_i];
860
- _splits[_i].percent =
861
- uint32(mulDiv(_initialSplits[_i].percent, JBConstants.SPLITS_TOTAL_PERCENT, _totalAbsolutePercent));
863
+ _splits[_i].percent = uint32(
864
+ mulDiv({
865
+ x: _initialSplits[_i].percent,
866
+ y: JBConstants.SPLITS_TOTAL_PERCENT,
867
+ denominator: _totalAbsolutePercent
868
+ })
869
+ );
862
870
  _normalizedTotal += _splits[_i].percent;
863
871
  }
864
872
 
865
873
  // Add Defifa fee split (normalized).
866
- uint256 _defifaNormalized =
867
- mulDiv(_defifaAbsolutePercent, JBConstants.SPLITS_TOTAL_PERCENT, _totalAbsolutePercent);
874
+ uint256 _defifaNormalized = mulDiv({
875
+ x: _defifaAbsolutePercent, y: JBConstants.SPLITS_TOTAL_PERCENT, denominator: _totalAbsolutePercent
876
+ });
868
877
  _splits[_numberOfUserSplits] = JBSplit({
869
878
  preferAddToBalance: false,
870
879
  percent: uint32(_defifaNormalized),
@@ -182,12 +182,12 @@ contract DefifaGovernor is Ownable, IDefifaGovernor {
182
182
  // e.g. holding 3 of 10 tokens → 3/10 * MAX_ATTESTATION_POWER_TIER attestation power from this tier.
183
183
  unchecked {
184
184
  if (_tierAttestationUnitsForAccount != 0) {
185
- attestationPower += mulDiv(
186
- MAX_ATTESTATION_POWER_TIER,
187
- _tierAttestationUnitsForAccount,
188
- IDefifaHook(_metadata.dataHook)
185
+ attestationPower += mulDiv({
186
+ x: MAX_ATTESTATION_POWER_TIER,
187
+ y: _tierAttestationUnitsForAccount,
188
+ denominator: IDefifaHook(_metadata.dataHook)
189
189
  .getPastTierTotalAttestationUnitsOf({tier: _tierId, timestamp: _timestamp})
190
- );
190
+ });
191
191
  }
192
192
  }
193
193
  }