@ballkidz/defifa 0.0.4 → 0.0.6

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`, `build_info = true`, `extra_output = ['storageLayout']`. Lower invariant runs (256/depth 50). 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
@@ -336,9 +319,6 @@ optimizer_runs = 200
336
319
  libs = ["node_modules", "lib"]
337
320
  fs_permissions = [{ access = "read-write", path = "./"}]
338
321
 
339
- [profile.ci_sizes]
340
- optimizer_runs = 200
341
-
342
322
  [fuzz]
343
323
  runs = 4096
344
324
 
@@ -353,18 +333,14 @@ multiline_func_header = "all"
353
333
  wrap_comments = true
354
334
  ```
355
335
 
356
- **Variations:**
357
- - `evm_version = 'cancun'` for repos using transient storage (buyback-hook, router-terminal, univ4-router)
358
- - `via_ir = true` for repos hitting stack-too-deep (buyback-hook, banny-retail, univ4-lp-split-hook, deploy-all)
359
- - `optimizer = false` only for deploy-all-v6 (stack-too-deep with optimization)
360
-
361
- **This repo uses:**
362
- - `via-ir = true` (note: hyphen not underscore in this repo's foundry.toml)
363
- - `build_info = true`, `extra_output = ['storageLayout']`
364
- - `[rpc_endpoints]` for ethereum, optimism, arbitrum, base, and their testnets
365
- - `[invariant]` with `runs = 256`, `depth = 50` (lower than standard)
366
- - No `[fuzz]` section
367
- - `[lint]` section with `lint_on_build = false`
336
+ **Optional sections (add only when needed):**
337
+ - `[rpc_endpoints]` repos with fork tests. Maps named endpoints to env vars (e.g. `ethereum = "${RPC_ETHEREUM_MAINNET}"`).
338
+ - `[profile.ci_sizes]` only when CI needs different optimizer settings than defaults for the size check step (e.g. `optimizer_runs = 200` when the default profile uses a lower value).
339
+
340
+ **Common variations:**
341
+ - `via_ir = true` when hitting stack-too-deep
342
+ - `optimizer = false` when optimization causes stack-too-deep
343
+ - `optimizer_runs` reduced when deep struct nesting causes stack-too-deep at 200 runs
368
344
 
369
345
  ### CI Workflows
370
346
 
@@ -397,7 +373,7 @@ jobs:
397
373
  env:
398
374
  RPC_ETHEREUM_MAINNET: ${{ secrets.RPC_ETHEREUM_MAINNET }}
399
375
  - name: Check contract sizes
400
- run: FOUNDRY_PROFILE=ci_sizes forge build --sizes --skip "*/test/**" --skip "*/script/**" --skip SphinxUtils
376
+ run: forge build --sizes --skip "*/test/**" --skip "*/script/**" --skip SphinxUtils
401
377
  ```
402
378
 
403
379
  **lint.yml:**
@@ -419,11 +395,60 @@ jobs:
419
395
  run: forge fmt --check
420
396
  ```
421
397
 
398
+ **slither.yml** (repos with `src/` contracts only):
399
+ ```yaml
400
+ name: slither
401
+ on:
402
+ pull_request:
403
+ branches:
404
+ - main
405
+ push:
406
+ branches:
407
+ - main
408
+ jobs:
409
+ analyze:
410
+ runs-on: ubuntu-latest
411
+ steps:
412
+ - uses: actions/checkout@v4
413
+ with:
414
+ submodules: recursive
415
+ - uses: actions/setup-node@v4
416
+ with:
417
+ node-version: latest
418
+ - name: Install npm dependencies
419
+ run: npm install --omit=dev
420
+ - name: Install Foundry
421
+ uses: foundry-rs/foundry-toolchain@v1
422
+ - name: Run slither
423
+ uses: crytic/slither-action@v0.3.1
424
+ with:
425
+ slither-config: slither-ci.config.json
426
+ fail-on: medium
427
+ ```
428
+
429
+ **slither-ci.config.json:**
430
+ ```json
431
+ {
432
+ "detectors_to_exclude": "timestamp,uninitialized-local,naming-convention,solc-version,shadowing-local",
433
+ "exclude_informational": true,
434
+ "exclude_low": false,
435
+ "exclude_medium": false,
436
+ "exclude_high": false,
437
+ "disable_color": false,
438
+ "filter_paths": "(mocks/|test/|node_modules/|lib/)",
439
+ "legacy_ast": false
440
+ }
441
+ ```
442
+
443
+ **Variations:**
444
+ - Deployer-only repos (no `src/`, only `script/`) skip slither entirely — the action's internal `forge build` skips `test/` and `script/` by default, leaving nothing to compile.
445
+ - Use inline `// slither-disable-next-line <detector>` to suppress known false positives rather than adding to `detectors_to_exclude` in the config. The comment must be on the line immediately before the flagged expression.
446
+
422
447
  ### package.json
423
448
 
424
449
  ```json
425
450
  {
426
- "name": "@ballkidz/defifa",
451
+ "name": "@bananapus/package-name-v6",
427
452
  "version": "x.x.x",
428
453
  "license": "MIT",
429
454
  "repository": { "type": "git", "url": "git+https://github.com/Org/repo.git" },
@@ -443,13 +468,62 @@ jobs:
443
468
 
444
469
  ### remappings.txt
445
470
 
446
- Every repo has a `remappings.txt`. Minimal content:
471
+ Every repo has a `remappings.txt` as the **single source of truth** for import remappings. Never add remappings to `foundry.toml`.
472
+
473
+ **Principle:** Import paths in Solidity source must match npm package names exactly. With `libs = ["node_modules", "lib"]`, Foundry auto-resolves `@scope/package/path/File.sol` → `node_modules/@scope/package/path/File.sol`. No remapping needed for packages installed as real directories.
474
+
475
+ **Note:** Auto-resolution does **not** work for symlinked packages (e.g. npm workspace links). Workspace repos like `deploy-all-v6` and `nana-cli-v6` need explicit `@scope/package/=node_modules/@scope/package/` remappings for each symlinked dependency.
476
+
477
+ **Minimal content** (most repos):
447
478
 
448
479
  ```
449
- @sphinx-labs/contracts/=lib/sphinx/packages/contracts/contracts/foundry
480
+ forge-std/=lib/forge-std/src/
450
481
  ```
451
482
 
452
- Additional mappings as needed for repo-specific dependencies.
483
+ Only add extra remappings for:
484
+ - **`forge-std`** — always needed (git submodule with `src/` subdirectory)
485
+ - **Repo-specific `lib/` submodules** that have no npm package (e.g., `hookmate/=lib/hookmate/src/`)
486
+ - **Symlinked npm packages** — need explicit `@scope/package/=node_modules/@scope/package/` entries
487
+ - **Nested transitive deps** — e.g., `@chainlink/contracts-ccip/` nested inside `@bananapus/suckers-v6/node_modules/`
488
+
489
+ **Never add remappings for:**
490
+ - npm packages that match their import path and are installed as real directories — they auto-resolve
491
+ - Short-form aliases (e.g., `@bananapus/core/` → `@bananapus/core-v6/src/`) — fix the import instead
492
+ - Packages available via npm that are also git submodules — remove the submodule, use npm
493
+
494
+ **Import path convention:**
495
+
496
+ | Package | Import path | Resolves to |
497
+ |---------|------------|-------------|
498
+ | `@bananapus/core-v6` | `@bananapus/core-v6/src/libraries/JBConstants.sol` | `node_modules/@bananapus/core-v6/src/...` |
499
+ | `@openzeppelin/contracts` | `@openzeppelin/contracts/token/ERC20/IERC20.sol` | `node_modules/@openzeppelin/contracts/...` |
500
+ | `@uniswap/v4-core` | `@uniswap/v4-core/src/interfaces/IPoolManager.sol` | `node_modules/@uniswap/v4-core/src/...` |
501
+
502
+ ### Linting
503
+
504
+ Solar (Foundry's built-in linter) runs automatically during `forge build`. It scans all `.sol` files in `libs` directories, including `node_modules`.
505
+
506
+ **All test helpers must use relative imports** (e.g. `../../src/structs/JBRuleset.sol`), not bare `src/` imports. This ensures solar can resolve paths when the helper is consumed via npm in downstream repos.
507
+
508
+ ### Fork Tests
509
+
510
+ Fork tests use named RPC endpoints defined in `[rpc_endpoints]` of `foundry.toml`. No skip guards — fork tests should hard-fail if the RPC endpoint is unavailable, making CI failures explicit.
511
+
512
+ ```solidity
513
+ function setUp() public {
514
+ vm.createSelectFork("ethereum");
515
+ // ... setup code
516
+ }
517
+ ```
518
+
519
+ The endpoint name (e.g. `"ethereum"`) maps to an env var via `foundry.toml`:
520
+
521
+ ```toml
522
+ [rpc_endpoints]
523
+ ethereum = "${RPC_ETHEREUM_MAINNET}"
524
+ ```
525
+
526
+ For multi-chain fork tests, add all needed endpoints.
453
527
 
454
528
  ### Formatting
455
529
 
@@ -460,15 +534,6 @@ Run `forge fmt` before committing. The `[fmt]` config in `foundry.toml` enforces
460
534
 
461
535
  CI checks formatting via `forge fmt --check`.
462
536
 
463
- ### CI Secrets
464
-
465
- | Secret | Purpose |
466
- |--------|--------|
467
- | `NPM_TOKEN` | npm publish access (used by `publish.yml`) |
468
- | `RPC_ETHEREUM_MAINNET` | Ethereum mainnet RPC URL for fork tests (used by `test.yml`) |
469
-
470
- Fork tests require `RPC_ETHEREUM_MAINNET` — they fail if it's missing.
471
-
472
537
  ### Branching
473
538
 
474
539
  - `main` is the primary branch
@@ -486,4 +551,8 @@ Fork tests require `RPC_ETHEREUM_MAINNET` — they fail if it's missing.
486
551
 
487
552
  ### Contract Size Checks
488
553
 
489
- 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.
554
+ CI runs `forge build --sizes` to catch contracts approaching the 24KB limit. When the repo's default `optimizer_runs` differs from what you want for size checking, use `FOUNDRY_PROFILE=ci_sizes forge build --sizes` with a `[profile.ci_sizes]` section in `foundry.toml`.
555
+
556
+ ## Repo-Specific Deviations
557
+
558
+ None. This repo follows the standard configuration exactly.
package/foundry.toml CHANGED
@@ -6,18 +6,8 @@ optimizer_runs = 200
6
6
  libs = ["node_modules", "lib"]
7
7
  fs_permissions = [{ access = "read-write", path = "./"}]
8
8
 
9
- [profile.ci_sizes]
10
- optimizer_runs = 200
11
-
12
9
  [rpc_endpoints]
13
10
  ethereum = "${RPC_ETHEREUM_MAINNET}"
14
- optimism = "${RPC_OPTIMISM_MAINNET}"
15
- arbitrum = "${RPC_ARBITRUM_MAINNET}"
16
- base = "${RPC_BASE_MAINNET}"
17
- arbitrum_sepolia = "${RPC_ARBITRUM_SEPOLIA}"
18
- ethereum_sepolia = "${RPC_ETHEREUM_SEPOLIA}"
19
- optimism_sepolia = "${RPC_OPTIMISM_SEPOLIA}"
20
- base_sepolia = "${RPC_BASE_SEPOLIA}"
21
11
 
22
12
  [fuzz]
23
13
  runs = 4096
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ballkidz/defifa",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "license": "MIT",
5
5
  "engines": {
6
6
  "node": ">=20.0.0"
@@ -13,11 +13,11 @@
13
13
  "url": "https://github.com/BallKidz/defifa-collection-deployer"
14
14
  },
15
15
  "dependencies": {
16
- "@bananapus/721-hook-v6": "^0.0.9",
17
- "@bananapus/address-registry-v6": "^0.0.4",
18
- "@bananapus/core-v6": "^0.0.10",
19
- "@bananapus/permission-ids-v6": "^0.0.5",
20
- "@openzeppelin/contracts": "5.2.0",
16
+ "@bananapus/721-hook-v6": "^0.0.14",
17
+ "@bananapus/address-registry-v6": "^0.0.8",
18
+ "@bananapus/core-v6": "^0.0.15",
19
+ "@bananapus/permission-ids-v6": "^0.0.8",
20
+ "@openzeppelin/contracts": "^5.6.1",
21
21
  "@prb/math": "^4.1.1",
22
22
  "scripty.sol": "^2.1.1"
23
23
  },
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 {
@@ -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;
@@ -411,8 +411,8 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
411
411
  }
412
412
 
413
413
  // Make sure the provided gameplay timestamps are sequential and that there is a mint duration.
414
- // slither-disable-next-line incorrect-equality
415
414
  if (
415
+ // slither-disable-next-line incorrect-equality
416
416
  launchProjectData.mintPeriodDuration == 0
417
417
  || launchProjectData.start
418
418
  < block.timestamp + launchProjectData.refundPeriodDuration + launchProjectData.mintPeriodDuration
@@ -532,6 +532,7 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
532
532
  /// @notice Mint reserved tokens within the tier for the provided value.
533
533
  /// @param tierId The ID of the tier to mint within.
534
534
  /// @param count The number of reserved tokens to mint.
535
+ // slither-disable-next-line reentrancy-no-eth
535
536
  function mintReservesFor(uint256 tierId, uint256 count) public override {
536
537
  // Minting reserves must not be paused.
537
538
  if (JB721TiersRulesetMetadataResolver.mintPendingReservesPaused(
@@ -2,7 +2,6 @@
2
2
  pragma solidity 0.8.26;
3
3
 
4
4
  import {DefifaLaunchProjectData} from "../structs/DefifaLaunchProjectData.sol";
5
- import {DefifaOpsData} from "../structs/DefifaOpsData.sol";
6
5
  import {IDefifaHook} from "./IDefifaHook.sol";
7
6
  import {IDefifaGovernor} from "./IDefifaGovernor.sol";
8
7
 
@@ -3,7 +3,6 @@ pragma solidity 0.8.26;
3
3
 
4
4
  import {DefifaScorecardState} from "../enums/DefifaScorecardState.sol";
5
5
  import {DefifaTierCashOutWeight} from "../structs/DefifaTierCashOutWeight.sol";
6
- import {IDefifaHook} from "./IDefifaHook.sol";
7
6
  import {IJBController} from "@bananapus/core-v6/src/interfaces/IJBController.sol";
8
7
 
9
8
  /// @notice Manages the ratification of Defifa scorecards through attestation-based governance.
@@ -2,8 +2,6 @@
2
2
  pragma solidity 0.8.26;
3
3
 
4
4
  import {ITypeface} from "lib/typeface/contracts/interfaces/ITypeface.sol";
5
- import {IDefifaHook} from "./IDefifaHook.sol";
6
- import {IDefifaGamePhaseReporter} from "./IDefifaGamePhaseReporter.sol";
7
5
 
8
6
  interface IDefifaTokenUriResolver {
9
7
  function typeface() external view returns (ITypeface);
@@ -2,9 +2,7 @@
2
2
  pragma solidity 0.8.26;
3
3
 
4
4
  import {DefifaTierParams} from "./DefifaTierParams.sol";
5
- import {DefifaOpsData} from "./DefifaOpsData.sol";
6
5
 
7
- import {JBLaunchProjectConfig} from "@bananapus/721-hook-v6/src/structs/JBLaunchProjectConfig.sol";
8
6
  import {JBAccountingContext} from "@bananapus/core-v6/src/structs/JBAccountingContext.sol";
9
7
  import {IJB721TiersHookStore} from "@bananapus/721-hook-v6/src/interfaces/IJB721TiersHookStore.sol";
10
8
  import {IJB721TokenUriResolver} from "@bananapus/721-hook-v6/src/interfaces/IJB721TokenUriResolver.sol";
@@ -463,7 +463,7 @@ contract DefifaFeeAccountingTest is JBTest, TestBaseWorkflow {
463
463
  /// @notice Mint 1 NFT per tier, set delegation, return array of user addresses.
464
464
  function _mintAllTiers(
465
465
  DefifaHook _nft,
466
- DefifaGovernor _governor,
466
+ DefifaGovernor,
467
467
  uint256 projectId,
468
468
  uint8 nTiers
469
469
  )
@@ -499,7 +499,7 @@ contract DefifaFeeAccountingTest is JBTest, TestBaseWorkflow {
499
499
  address[] memory users,
500
500
  DefifaHook _nft,
501
501
  DefifaGovernor _governor,
502
- uint256 projectId,
502
+ uint256,
503
503
  uint8 nTiers
504
504
  )
505
505
  internal
@@ -541,7 +541,7 @@ contract DefifaFeeAccountingTest is JBTest, TestBaseWorkflow {
541
541
  return (_tierId * 1_000_000_000) + _tokenNumber;
542
542
  }
543
543
 
544
- function _buildPayMetadata(bytes memory metadata) internal returns (bytes memory) {
544
+ function _buildPayMetadata(bytes memory metadata) internal view returns (bytes memory) {
545
545
  bytes[] memory data = new bytes[](1);
546
546
  data[0] = metadata;
547
547
  bytes4[] memory ids = new bytes4[](1);
@@ -549,7 +549,7 @@ contract DefifaFeeAccountingTest is JBTest, TestBaseWorkflow {
549
549
  return metadataHelper().createMetadata(ids, data);
550
550
  }
551
551
 
552
- function _buildCashOutMetadata(bytes memory metadata) internal returns (bytes memory) {
552
+ function _buildCashOutMetadata(bytes memory metadata) internal view returns (bytes memory) {
553
553
  bytes[] memory data = new bytes[](1);
554
554
  data[0] = metadata;
555
555
  bytes4[] memory ids = new bytes4[](1);
@@ -444,8 +444,8 @@ contract DefifaGovernorTest is JBTest, TestBaseWorkflow {
444
444
  }
445
445
 
446
446
  function testSetCashOutRatesAndRedeem_multipleTiers(uint8 nTiers, uint8[] calldata distribution) public {
447
- vm.assume(nTiers > 10 && nTiers < 100);
448
- vm.assume(distribution.length < nTiers);
447
+ nTiers = uint8(bound(uint256(nTiers), 11, 99));
448
+ vm.assume(distribution.length > 0 && distribution.length < nTiers);
449
449
 
450
450
  uint256 _sumDistribution;
451
451
  for (uint256 i = 0; i < distribution.length; i++) {
@@ -631,7 +631,6 @@ contract DefifaGovernorTest is JBTest, TestBaseWorkflow {
631
631
  JB721Tier memory _tier = _hook.store().tierOf(address(_hook), 1, false);
632
632
  uint256 _cost = _tier.price;
633
633
 
634
- address _delegateUser = address(bytes20(keccak256("_delegateUser")));
635
634
  address _refundUser = address(bytes20(keccak256("refund_user")));
636
635
  // The user should have no balance
637
636
  assertEq(_hook.balanceOf(_refundUser), 0);
@@ -931,8 +930,6 @@ contract DefifaGovernorTest is JBTest, TestBaseWorkflow {
931
930
  _durationUntilProjectLaunch > 2 && _mintPeriodDuration > 1 && _inBetweenMintAndFifa > 1 && _fifaDuration > 1
932
931
  );
933
932
  uint48 _launchProjectAt = uint48(block.timestamp) + _durationUntilProjectLaunch;
934
- uint48 _end =
935
- _launchProjectAt + uint48(_mintPeriodDuration) + uint48(_inBetweenMintAndFifa) + uint48(_fifaDuration);
936
933
  DefifaTierParams[] memory tierParams = new DefifaTierParams[](1);
937
934
  tierParams[0] = DefifaTierParams({
938
935
  reservedRate: 1001,
@@ -988,12 +985,10 @@ contract DefifaGovernorTest is JBTest, TestBaseWorkflow {
988
985
 
989
986
  function testWhenScorecardIsSubmittedWithUnmintedTier() public {
990
987
  uint8 nTiers = 10;
991
- address[] memory _users = new address[](nTiers);
992
988
  DefifaLaunchProjectData memory defifaData = getBasicDefifaLaunchData(nTiers);
993
- (uint256 _projectId, DefifaHook _nft, DefifaGovernor _governor) = createDefifaProject(defifaData);
989
+ (,, DefifaGovernor _governor) = createDefifaProject(defifaData);
994
990
  // Phase 1: Mint
995
991
  vm.warp(defifaData.start - defifaData.mintPeriodDuration - defifaData.refundPeriodDuration);
996
- //deployer.queueNextPhaseOf(_projectId);
997
992
 
998
993
  // Warp to scoring phase (past start time)
999
994
  vm.warp(defifaData.start + 1);
@@ -1007,7 +1002,7 @@ contract DefifaGovernorTest is JBTest, TestBaseWorkflow {
1007
1002
 
1008
1003
  vm.expectRevert(abi.encodeWithSignature("DefifaGovernor_UnownedProposedCashoutValue()"));
1009
1004
  // Forward time so proposals can be created
1010
- uint256 _proposalId = _governor.submitScorecardFor(_gameId, scorecards);
1005
+ _governor.submitScorecardFor(_gameId, scorecards);
1011
1006
  }
1012
1007
 
1013
1008
  // function testWhenPhaseIsAlreadyQueued() public {
@@ -1256,7 +1251,6 @@ contract DefifaGovernorTest is JBTest, TestBaseWorkflow {
1256
1251
  assertEq(_refundUser.balance, 0);
1257
1252
  // The user should have have a token
1258
1253
  assertEq(_hook.balanceOf(_refundUser), 1);
1259
- uint256 _numberBurned = _hook.store().numberOfBurnedFor(address(_hook), _tierId);
1260
1254
  // Craft the metadata: redeem the tokenId
1261
1255
  bytes memory cashOutMetadata;
1262
1256
  {
@@ -1305,7 +1299,7 @@ contract DefifaGovernorTest is JBTest, TestBaseWorkflow {
1305
1299
  return (_tierId * 1_000_000_000) + _tokenNumber;
1306
1300
  }
1307
1301
 
1308
- function _buildPayMetadata(bytes memory metadata) internal returns (bytes memory) {
1302
+ function _buildPayMetadata(bytes memory metadata) internal view returns (bytes memory) {
1309
1303
  // Build the metadata using the tiers to mint and the overspending flag.
1310
1304
  bytes[] memory data = new bytes[](1);
1311
1305
  data[0] = metadata;
@@ -1318,7 +1312,7 @@ contract DefifaGovernorTest is JBTest, TestBaseWorkflow {
1318
1312
  return metadataHelper().createMetadata(ids, data);
1319
1313
  }
1320
1314
 
1321
- function _buildCashOutMetadata(bytes memory metadata) internal returns (bytes memory) {
1315
+ function _buildCashOutMetadata(bytes memory metadata) internal view returns (bytes memory) {
1322
1316
  // Build the metadata using the tiers to mint and the overspending flag.
1323
1317
  bytes[] memory data = new bytes[](1);
1324
1318
  data[0] = metadata;
@@ -30,18 +30,18 @@ import {DefifaTierParams} from "../src/structs/DefifaTierParams.sol";
30
30
  import {DefifaTierCashOutWeight} from "../src/structs/DefifaTierCashOutWeight.sol";
31
31
 
32
32
  /// @dev Helper to read block.timestamp via an external call, bypassing the via-ir optimizer's timestamp caching.
33
- contract TimestampReaderAudit {
33
+ contract TimestampReaderRegressions {
34
34
  function timestamp() external view returns (uint256) {
35
35
  return block.timestamp;
36
36
  }
37
37
  }
38
38
 
39
- /// @title DefifaHook_AuditFindings
39
+ /// @title DefifaHookRegressions
40
40
  /// @notice Regression tests for audit findings in DefifaHook.
41
- contract DefifaHook_AuditFindings is JBTest, TestBaseWorkflow {
41
+ contract DefifaHookRegressions is JBTest, TestBaseWorkflow {
42
42
  using JBRulesetMetadataResolver for JBRuleset;
43
43
 
44
- TimestampReaderAudit private _tsReader = new TimestampReaderAudit();
44
+ TimestampReaderRegressions private _tsReader = new TimestampReaderRegressions();
45
45
 
46
46
  address _protocolFeeProjectTokenAccount;
47
47
  address _defifaProjectTokenAccount;
@@ -364,7 +364,7 @@ contract DefifaHook_AuditFindings is JBTest, TestBaseWorkflow {
364
364
  return (_tierId * 1_000_000_000) + _tokenNumber;
365
365
  }
366
366
 
367
- function _buildPayMetadata(bytes memory metadata) internal returns (bytes memory) {
367
+ function _buildPayMetadata(bytes memory metadata) internal view returns (bytes memory) {
368
368
  bytes[] memory data = new bytes[](1);
369
369
  data[0] = metadata;
370
370
  bytes4[] memory ids = new bytes4[](1);
@@ -892,7 +892,7 @@ contract DefifaNoContestTest is JBTest, TestBaseWorkflow {
892
892
  });
893
893
  }
894
894
 
895
- function _cashOutMeta(uint256 tid, uint256 tnum) internal returns (bytes memory) {
895
+ function _cashOutMeta(uint256 tid, uint256 tnum) internal view returns (bytes memory) {
896
896
  uint256[] memory cid = new uint256[](1);
897
897
  cid[0] = (tid * 1_000_000_000) + tnum;
898
898
  bytes[] memory data = new bytes[](1);
@@ -678,7 +678,7 @@ contract DefifaSecurityTest is JBTest, TestBaseWorkflow {
678
678
  });
679
679
  }
680
680
 
681
- function _cashOutMeta(uint256 tid, uint256 tnum) internal returns (bytes memory) {
681
+ function _cashOutMeta(uint256 tid, uint256 tnum) internal view returns (bytes memory) {
682
682
  uint256[] memory cid = new uint256[](1);
683
683
  cid[0] = (tid * 1_000_000_000) + tnum;
684
684
  bytes[] memory data = new bytes[](1);