@ballkidz/defifa 0.0.29 → 0.0.30

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/ARCHITECTURE.md CHANGED
@@ -115,7 +115,7 @@ The hook's completion math is intentionally phase-sensitive:
115
115
  - fulfillment and ratification coupling:
116
116
  `test/regression/FulfillmentBlocksRatification.t.sol`
117
117
  - pending reserve effects on completion fairness:
118
- `test/audit/PendingReserveSnapshotBypass.t.sol`
118
+ `test/regression/PendingReserveSnapshotBypass.t.sol`
119
119
 
120
120
  ## Source Map
121
121
 
@@ -128,4 +128,4 @@ The hook's completion math is intentionally phase-sensitive:
128
128
  - `test/DefifaHookRegressions.t.sol`
129
129
  - `test/DefifaFeeAccounting.t.sol`
130
130
  - `test/regression/FulfillmentBlocksRatification.t.sol`
131
- - `test/audit/PendingReserveSnapshotBypass.t.sol`
131
+ - `test/regression/PendingReserveSnapshotBypass.t.sol`
package/CHANGELOG.md CHANGED
@@ -17,10 +17,10 @@ This file instead describes the current v6 repo at a high level and the broad mi
17
17
  ## Summary
18
18
 
19
19
  - The repo is now built directly on the v6 Juicebox stack, including the v6 core and 721-hook packages.
20
- - The v6 surface is split across dedicated deployer, hook, governor, project-owner, and token-uri contracts, with dedicated regression and audit test coverage around governance, fee accounting, attestations, and lifecycle edge cases.
20
+ - The v6 surface is split across dedicated deployer, hook, governor, project-owner, and token-uri contracts, with dedicated regression and review test coverage around governance, fee accounting, attestations, and lifecycle edge cases.
21
21
  - Solidity and tooling were upgraded to the v6 baseline around `0.8.28`.
22
22
 
23
- ## Local audit remediations
23
+ ## Local review remediations
24
24
 
25
25
  - Reserve-minted NFTs are now excluded from refund calculations during MINT, REFUND, and NO_CONTEST phases. A public `isReserveMint` mapping tracks which tokens were created via tier reserve frequency rather than paid for. `beforeCashOutRecordedWith` subtracts their tier price from `cumulativeMintPrice`, preventing reserve beneficiaries from withdrawing funds they never contributed.
26
26
 
package/CRYPTO_ECON.md CHANGED
@@ -1187,4 +1187,4 @@ Defifa implements a rigorous approach to prediction gaming through the compositi
1187
1187
 
1188
1188
  The elegance of Defifa resides in its architectural composability: prediction games with arbitrary outcomes, arbitrary tier structures, and arbitrary payout distributions emerge from the same set of twelve parameters (Eq. 1), executed deterministically by immutable smart contracts with a single, time-bounded governance input. From a 4-team presidential election to a 32-team World Cup, the same protocol handles it all — and the safety mechanisms ensure that every game resolves, one way or another.
1189
1189
 
1190
- The most significant finding is the Uniform Participation Theorem: **a game with uniform tier supply is provably impervious to profitable governance attacks regardless of attacker capital.** This transforms game design from an art into an engineering discipline — the designer's job is to choose events and tier structures that naturally produce uniform participation, and the cryptoeconomics handle the rest.
1190
+ The most significant result is the Uniform Participation Theorem: **a game with uniform tier supply is provably impervious to profitable governance attacks regardless of attacker capital.** This transforms game design from an art into an engineering discipline — the designer's job is to choose events and tier structures that naturally produce uniform participation, and the cryptoeconomics handle the rest.
package/README.md CHANGED
@@ -117,7 +117,7 @@ src/
117
117
  libraries/
118
118
  structs/
119
119
  test/
120
- governance, fee-accounting, no-contest, adversarial, regression, fork, and audit coverage
120
+ governance, fee-accounting, no-contest, adversarial, regression, fork, and review coverage
121
121
  script/
122
122
  Deploy.s.sol
123
123
  helpers/
@@ -141,8 +141,8 @@ references/
141
141
  - [`test/DefifaFeeAccounting.t.sol`](./test/DefifaFeeAccounting.t.sol)
142
142
  - [`test/DefifaNoContest.t.sol`](./test/DefifaNoContest.t.sol)
143
143
  - [`test/DefifaAdversarialQuorum.t.sol`](./test/DefifaAdversarialQuorum.t.sol)
144
- - [`test/audit/PendingReserveDilution.t.sol`](./test/audit/PendingReserveDilution.t.sol)
145
- - [`test/audit/AttestationDoubleCount.t.sol`](./test/audit/AttestationDoubleCount.t.sol)
144
+ - [`test/regression/PendingReserveDilution.t.sol`](./test/regression/PendingReserveDilution.t.sol)
145
+ - [`test/regression/AttestationDoubleCount.t.sol`](./test/regression/AttestationDoubleCount.t.sol)
146
146
  - [`test/regression/GracePeriodBypass.t.sol`](./test/regression/GracePeriodBypass.t.sol)
147
147
 
148
148
  ## Deployment Notes
package/RISKS.md CHANGED
@@ -6,7 +6,7 @@ This file focuses on the game-theoretic, governance, and settlement risks in Def
6
6
 
7
7
  - Read `Priority risks` first.
8
8
  - Use the detailed sections below to reason about governor power, live supply assumptions, and downstream hook dependencies.
9
- - Treat `Accepted Behaviors` and `Invariants to Verify` as explicit boundaries for audit scope.
9
+ - Treat `Accepted Behaviors` and `Invariants to Verify` as explicit boundaries for review scope.
10
10
 
11
11
  ## Priority risks
12
12
 
package/SKILLS.md CHANGED
@@ -43,4 +43,4 @@ Defifa is an onchain prediction game system built on Juicebox. This repo package
43
43
  - Defifa-specific cash-out weights and governance thresholds sit on top of `nana-721-hook-v6` and `nana-core-v6`.
44
44
  - When a task mentions NFT rendering or metadata, confirm whether it belongs in [`src/DefifaTokenUriResolver.sol`](./src/DefifaTokenUriResolver.sol).
45
45
  - If you edit phase transitions, check lifecycle, governance, and fee-accounting tests together.
46
- - If ratification, attestation, or quorum behavior changes, re-read the audit and regression tests before trusting a clean happy-path result.
46
+ - If ratification, attestation, or quorum behavior changes, re-read the review and regression tests before trusting a clean happy-path result.
package/STYLE_GUIDE.md CHANGED
@@ -451,57 +451,9 @@ jobs:
451
451
  run: forge fmt --check
452
452
  ```
453
453
 
454
- **slither.yml** (repos with `src/` contracts only):
455
- ```yaml
456
- name: slither
457
- on:
458
- pull_request:
459
- branches:
460
- - main
461
- push:
462
- branches:
463
- - main
464
- jobs:
465
- analyze:
466
- runs-on: ubuntu-latest
467
- steps:
468
- - uses: actions/checkout@v4
469
- with:
470
- submodules: recursive
471
- - uses: actions/setup-node@v4
472
- with:
473
- node-version: 25.9.0
474
- - name: Install npm dependencies
475
- run: npm install --omit=dev
476
- - name: Install Foundry
477
- uses: foundry-rs/foundry-toolchain@v1
478
- - name: Prebuild contracts
479
- run: forge build --deny notes --build-info --skip "*/test/**" --skip "*/script/**"
480
- - name: Run slither
481
- uses: crytic/slither-action@v0.4.1
482
- with:
483
- slither-config: slither-ci.config.json
484
- fail-on: medium
485
- ignore-compile: true
486
- ```
487
-
488
- **slither-ci.config.json:**
489
- ```json
490
- {
491
- "detectors_to_exclude": "timestamp,uninitialized-local,naming-convention,solc-version,shadowing-local",
492
- "exclude_informational": true,
493
- "exclude_low": false,
494
- "exclude_medium": false,
495
- "exclude_high": false,
496
- "disable_color": false,
497
- "filter_paths": "(mocks/|test/|node_modules/|lib/)",
498
- "legacy_ast": false
499
- }
500
- ```
454
+ **Static review workflow** (repos with `src/` contracts only):
501
455
 
502
- **Variations:**
503
- - 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.
504
- - 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.
456
+ Keep repo-local static review automation current with the package's runtime surface. At minimum, CI should run formatting, linting, and build checks with `--deny notes`. Repos that only contain deployment scripts can rely on the shared formatting and lint jobs unless they add runtime contracts.
505
457
 
506
458
  ### package.json
507
459
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ballkidz/defifa",
3
- "version": "0.0.29",
3
+ "version": "0.0.30",
4
4
  "license": "MIT",
5
5
  "engines": {
6
6
  "node": "25.9.0"
@@ -33,7 +33,7 @@
33
33
  "dependencies": {
34
34
  "@bananapus/721-hook-v6": "0.0.43",
35
35
  "@bananapus/address-registry-v6": "0.0.25",
36
- "@bananapus/core-v6": "0.0.39",
36
+ "@bananapus/core-v6": "0.0.44",
37
37
  "@bananapus/permission-ids-v6": "0.0.22",
38
38
  "@openzeppelin/contracts": "5.6.1",
39
39
  "@prb/math": "4.1.1",
@@ -54,18 +54,14 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
54
54
  // --------------------------- custom errors ------------------------- //
55
55
  //*********************************************************************//
56
56
 
57
- error DefifaDeployer_CantFulfillYet();
58
- error DefifaDeployer_GameOver();
59
- error DefifaDeployer_InvalidFeePercent();
60
- error DefifaDeployer_InvalidGameConfiguration();
61
- error DefifaDeployer_IncorrectDecimalAmount();
62
- error DefifaDeployer_InvalidCurrency();
63
- error DefifaDeployer_NotNoContest();
64
- error DefifaDeployer_NoContestAlreadyTriggered();
65
- error DefifaDeployer_TerminalNotFound();
66
- error DefifaDeployer_PhaseAlreadyQueued();
67
- error DefifaDeployer_SplitsDontAddUp();
68
- error DefifaDeployer_UnexpectedTerminalCurrency();
57
+ error DefifaDeployer_CantFulfillYet(uint256 gameId);
58
+ error DefifaDeployer_InvalidGameConfiguration(
59
+ uint256 start, uint256 mintPeriodDuration, uint256 refundPeriodDuration, uint256 tierCount
60
+ );
61
+ error DefifaDeployer_InvalidCurrency(address token, uint256 currency);
62
+ error DefifaDeployer_NotNoContest(uint256 gameId, DefifaGamePhase phase);
63
+ error DefifaDeployer_NoContestAlreadyTriggered(uint256 gameId);
64
+ error DefifaDeployer_SplitsDontAddUp(uint256 totalPercent, uint256 maxPercent);
69
65
 
70
66
  //*********************************************************************//
71
67
  // ----------------------- internal properties ----------------------- //
@@ -182,7 +178,6 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
182
178
  // Get the game's current funding cycle along with its metadata.
183
179
  JBRuleset memory currentRuleset = CONTROLLER.RULESETS().currentOf(gameId);
184
180
  // Get the game's queued funding cycle along with its metadata.
185
- // slither-disable-next-line unused-return
186
181
  (JBRuleset memory queuedRuleset,) = CONTROLLER.RULESETS().latestQueuedOf(gameId);
187
182
 
188
183
  // If the configurations are the same and the game hasn't ended, queueing is still needed.
@@ -294,7 +289,6 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
294
289
  uint256 _baseProtocolProjectId,
295
290
  IJB721TiersHookStore _hookStore
296
291
  ) {
297
- // slither-disable-next-line missing-zero-check
298
292
  HOOK_CODE_ORIGIN = _hookCodeOrigin;
299
293
  TOKEN_URI_RESOLVER = _tokenUriResolver;
300
294
  GOVERNOR = _governor;
@@ -313,19 +307,17 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
313
307
 
314
308
  /// @notice Fulfill split amounts between all splits for a game.
315
309
  /// @param gameId The ID of the game to fulfill splits for.
316
- // slither-disable-next-line reentrancy-benign,reentrancy-no-eth
317
310
  function fulfillCommitmentsOf(uint256 gameId) external virtual override {
318
311
  // Make sure commitments haven't already been fulfilled.
319
312
  if (commitmentsFulfilledFor[gameId]) return;
320
313
  commitmentsFulfilledFor[gameId] = true;
321
314
 
322
315
  // Get the game's current funding cycle along with its metadata.
323
- // slither-disable-next-line unused-return
324
316
  (, JBRulesetMetadata memory metadata) = CONTROLLER.currentRulesetOf(gameId);
325
317
 
326
318
  // Make sure the game's commitments can be fulfilled.
327
319
  if (!IDefifaHook(metadata.dataHook).cashOutWeightIsSet()) {
328
- revert DefifaDeployer_CantFulfillYet();
320
+ revert DefifaDeployer_CantFulfillYet({gameId: gameId});
329
321
  }
330
322
 
331
323
  // Get the game token and the terminal.
@@ -337,10 +329,8 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
337
329
  uint256 pot = terminal.STORE().balanceOf({terminal: address(terminal), projectId: gameId, token: token});
338
330
 
339
331
  // If the pot is empty, queue the final ruleset without attempting payouts.
340
- // slither-disable-next-line incorrect-equality
341
332
  if (pot == 0) {
342
333
  _queueFinalRuleset({gameId: gameId, metadata: metadata});
343
- // slither-disable-next-line reentrancy-events
344
334
  emit FulfilledCommitments({gameId: gameId, pot: 0, caller: msg.sender});
345
335
  return;
346
336
  }
@@ -356,7 +346,6 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
356
346
  // Use the ruleset's baseCurrency — this matches the currency under which payout limits were stored
357
347
  // at launch time, regardless of whether the token is native ETH or an ERC-20.
358
348
  // Wrapped in try-catch so the final ruleset is always queued even if payout fails.
359
- // slither-disable-next-line unused-return,reentrancy-no-eth
360
349
  try terminal.sendPayoutsOf({
361
350
  projectId: gameId, token: token, amount: feeAmount, currency: metadata.baseCurrency, minTokensPaidOut: 0
362
351
  }) {}
@@ -364,21 +353,18 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
364
353
  // Payout failed — fee stays in pot. Reset to 0 so currentGamePotOf
365
354
  // doesn't double-count the fee.
366
355
  fulfilledCommitmentsOf[gameId] = 0;
367
- // slither-disable-next-line reentrancy-events
368
356
  emit CommitmentPayoutFailed({gameId: gameId, amount: feeAmount, reason: reason});
369
357
  }
370
358
 
371
359
  // Queue the final ruleset and emit.
372
360
  _queueFinalRuleset({gameId: gameId, metadata: metadata});
373
361
 
374
- // slither-disable-next-line reentrancy-events
375
362
  emit FulfilledCommitments({gameId: gameId, pot: pot, caller: msg.sender});
376
363
  }
377
364
 
378
365
  /// @notice Launches a new game owned by this contract with a DefifaHook attached.
379
366
  /// @param launchProjectData Data necessary to fulfill the transaction to launch a game.
380
367
  /// @return gameId The ID of the newly configured game.
381
- // slither-disable-next-line reentrancy-benign,reentrancy-no-eth
382
368
  function launchGameWith(DefifaLaunchProjectData memory launchProjectData)
383
369
  external
384
370
  override
@@ -391,7 +377,14 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
391
377
  if (launchProjectData.start == 0) {
392
378
  uint256 start =
393
379
  currentTimestamp + launchProjectData.mintPeriodDuration + launchProjectData.refundPeriodDuration;
394
- if (start > type(uint48).max) revert DefifaDeployer_InvalidGameConfiguration();
380
+ if (start > type(uint48).max) {
381
+ revert DefifaDeployer_InvalidGameConfiguration({
382
+ start: start,
383
+ mintPeriodDuration: launchProjectData.mintPeriodDuration,
384
+ refundPeriodDuration: launchProjectData.refundPeriodDuration,
385
+ tierCount: launchProjectData.tiers.length
386
+ });
387
+ }
395
388
 
396
389
  // Casting to uint48 is safe because `start` was bounded above.
397
390
  // forge-lint: disable-next-line(unsafe-typecast)
@@ -399,7 +392,6 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
399
392
  }
400
393
  // If callers provide a future start with no mint duration, derive a mint window that begins now and ends
401
394
  // before the refund window. This preserves the requested start while keeping minting immediately available.
402
- // slither-disable-next-line incorrect-equality
403
395
  else if (
404
396
  launchProjectData.mintPeriodDuration == 0
405
397
  && launchProjectData.start > currentTimestamp + launchProjectData.refundPeriodDuration
@@ -410,20 +402,34 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
410
402
 
411
403
  // Make sure the provided gameplay timestamps are sequential and that there is a mint duration.
412
404
  if (
413
- // slither-disable-next-line incorrect-equality
414
405
  launchProjectData.mintPeriodDuration == 0
415
406
  || launchProjectData.start
416
407
  < currentTimestamp + launchProjectData.refundPeriodDuration + launchProjectData.mintPeriodDuration
417
- ) revert DefifaDeployer_InvalidGameConfiguration();
408
+ ) {
409
+ revert DefifaDeployer_InvalidGameConfiguration({
410
+ start: launchProjectData.start,
411
+ mintPeriodDuration: launchProjectData.mintPeriodDuration,
412
+ refundPeriodDuration: launchProjectData.refundPeriodDuration,
413
+ tierCount: launchProjectData.tiers.length
414
+ });
415
+ }
418
416
 
419
417
  // The hook and governor hardcode uint256[128] tier-weight tables, so reject games with more than 128 tiers.
420
- if (launchProjectData.tiers.length > 128) revert DefifaDeployer_InvalidGameConfiguration();
418
+ if (launchProjectData.tiers.length > 128) {
419
+ revert DefifaDeployer_InvalidGameConfiguration({
420
+ start: launchProjectData.start,
421
+ mintPeriodDuration: launchProjectData.mintPeriodDuration,
422
+ refundPeriodDuration: launchProjectData.refundPeriodDuration,
423
+ tierCount: launchProjectData.tiers.length
424
+ });
425
+ }
421
426
 
422
427
  // Reject ERC-20 games with a zero currency. A zero baseCurrency would cause payout limit lookups
423
428
  // in fulfillCommitmentsOf to silently fail, skipping all commitment payouts.
424
- // slither-disable-next-line incorrect-equality
425
429
  if (launchProjectData.token.token != JBConstants.NATIVE_TOKEN && launchProjectData.token.currency == 0) {
426
- revert DefifaDeployer_InvalidCurrency();
430
+ revert DefifaDeployer_InvalidCurrency({
431
+ token: launchProjectData.token.token, currency: launchProjectData.token.currency
432
+ });
427
433
  }
428
434
 
429
435
  // If a scorecard timeout is set, it must exceed the full ratification window:
@@ -437,7 +443,14 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
437
443
  if (
438
444
  launchProjectData.scorecardTimeout
439
445
  <= attestationDelay + launchProjectData.attestationGracePeriod + launchProjectData.timelockDuration
440
- ) revert DefifaDeployer_InvalidGameConfiguration();
446
+ ) {
447
+ revert DefifaDeployer_InvalidGameConfiguration({
448
+ start: launchProjectData.start,
449
+ mintPeriodDuration: launchProjectData.mintPeriodDuration,
450
+ refundPeriodDuration: launchProjectData.refundPeriodDuration,
451
+ tierCount: launchProjectData.tiers.length
452
+ });
453
+ }
441
454
  }
442
455
 
443
456
  // Reserve the game ID up front so permissionless project creations cannot invalidate hook deployment.
@@ -542,7 +555,6 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
542
555
  }
543
556
 
544
557
  // Increment the nonce for this deployment.
545
- // slither-disable-next-line reentrancy-benign
546
558
  uint256 currentNonce = ++_nonce;
547
559
 
548
560
  // Clone deterministically using sender and nonce to prevent front-running.
@@ -601,8 +613,9 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
601
613
  bytecode: _cloneCreationCodeFor(address(HOOK_CODE_ORIGIN))
602
614
  });
603
615
 
604
- // slither-disable-next-line reentrancy-events
605
- emit LaunchGame(gameId, hook, GOVERNOR, uriResolver, msg.sender);
616
+ emit LaunchGame({
617
+ gameId: gameId, hook: hook, governor: GOVERNOR, tokenUriResolver: uriResolver, caller: msg.sender
618
+ });
606
619
  }
607
620
 
608
621
  /// @notice Allows this contract to receive 721s.
@@ -617,12 +630,13 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
617
630
  /// @param gameId The ID of the game to trigger no-contest for.
618
631
  function triggerNoContestFor(uint256 gameId) external override {
619
632
  // Make sure the game is currently in NO_CONTEST phase.
620
- if (currentGamePhaseOf(gameId) != DefifaGamePhase.NO_CONTEST) {
621
- revert DefifaDeployer_NotNoContest();
633
+ DefifaGamePhase phase = currentGamePhaseOf(gameId);
634
+ if (phase != DefifaGamePhase.NO_CONTEST) {
635
+ revert DefifaDeployer_NotNoContest({gameId: gameId, phase: phase});
622
636
  }
623
637
 
624
638
  // Make sure no-contest hasn't already been triggered.
625
- if (noContestTriggeredFor[gameId]) revert DefifaDeployer_NoContestAlreadyTriggered();
639
+ if (noContestTriggeredFor[gameId]) revert DefifaDeployer_NoContestAlreadyTriggered({gameId: gameId});
626
640
 
627
641
  // Mark as triggered.
628
642
  // Note: the queued ruleset does not take effect until the current ruleset's cycle ends (or immediately
@@ -632,7 +646,6 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
632
646
  noContestTriggeredFor[gameId] = true;
633
647
 
634
648
  // Get the game's current ruleset metadata for the data hook address.
635
- // slither-disable-next-line unused-return
636
649
  (, JBRulesetMetadata memory metadata) = CONTROLLER.currentRulesetOf(gameId);
637
650
 
638
651
  // Queue a new ruleset without payout limits so surplus = balance, enabling refunds.
@@ -658,7 +671,7 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
658
671
  allowAddPriceFeed: false,
659
672
  ownerMustSendPayouts: true,
660
673
  holdFees: false,
661
- useTotalSurplusForCashOuts: false,
674
+ scopeCashOutsToLocalBalances: true,
662
675
  useDataHookForPay: true,
663
676
  useDataHookForCashOut: true,
664
677
  dataHook: metadata.dataHook,
@@ -673,13 +686,11 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
673
686
  });
674
687
 
675
688
  // Queue the no-contest refund ruleset.
676
- // slither-disable-next-line unused-return
677
689
  CONTROLLER.queueRulesetsOf({
678
690
  projectId: gameId, rulesetConfigurations: rulesetConfigs, memo: "Defifa game: no contest."
679
691
  });
680
692
 
681
- // slither-disable-next-line reentrancy-events
682
- emit QueuedNoContest(gameId, msg.sender);
693
+ emit QueuedNoContest({gameId: gameId, caller: msg.sender});
683
694
  }
684
695
 
685
696
  //*********************************************************************//
@@ -711,10 +722,13 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
711
722
  }
712
723
 
713
724
  // Validate that total fee splits don't exceed 100%.
714
- if (totalAbsolutePercent > JBConstants.SPLITS_TOTAL_PERCENT) revert DefifaDeployer_SplitsDontAddUp();
725
+ if (totalAbsolutePercent > JBConstants.SPLITS_TOTAL_PERCENT) {
726
+ revert DefifaDeployer_SplitsDontAddUp({
727
+ totalPercent: totalAbsolutePercent, maxPercent: JBConstants.SPLITS_TOTAL_PERCENT
728
+ });
729
+ }
715
730
 
716
731
  // Store the total absolute percent for use in fulfillCommitmentsOf.
717
- // slither-disable-next-line reentrancy-benign
718
732
  _commitmentPercentOf[gameId] = totalAbsolutePercent;
719
733
 
720
734
  // Build the splits array: user splits + Defifa + NANA (NANA last to absorb rounding).
@@ -820,7 +834,7 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
820
834
  allowAddPriceFeed: false,
821
835
  ownerMustSendPayouts: false,
822
836
  holdFees: false,
823
- useTotalSurplusForCashOuts: false,
837
+ scopeCashOutsToLocalBalances: true,
824
838
  useDataHookForPay: true,
825
839
  useDataHookForCashOut: true,
826
840
  dataHook: dataHook,
@@ -863,7 +877,7 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
863
877
  allowAddPriceFeed: false,
864
878
  ownerMustSendPayouts: false,
865
879
  holdFees: false,
866
- useTotalSurplusForCashOuts: false,
880
+ scopeCashOutsToLocalBalances: true,
867
881
  useDataHookForPay: true,
868
882
  useDataHookForCashOut: true,
869
883
  dataHook: dataHook,
@@ -923,7 +937,7 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
923
937
  // Set this to true so only the deployer can fulfill the commitments.
924
938
  ownerMustSendPayouts: true,
925
939
  holdFees: false,
926
- useTotalSurplusForCashOuts: false,
940
+ scopeCashOutsToLocalBalances: true,
927
941
  useDataHookForPay: true,
928
942
  useDataHookForCashOut: true,
929
943
  dataHook: dataHook,
@@ -943,7 +957,6 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
943
957
  });
944
958
 
945
959
  // Launch the rulesets for the reserved project and set the project URI in the same controller call.
946
- // slither-disable-next-line unused-return
947
960
  CONTROLLER.launchRulesetsFor({
948
961
  projectId: gameId,
949
962
  projectUri: launchProjectData.projectUri,
@@ -979,7 +992,7 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
979
992
  allowAddPriceFeed: false,
980
993
  ownerMustSendPayouts: false,
981
994
  holdFees: false,
982
- useTotalSurplusForCashOuts: false,
995
+ scopeCashOutsToLocalBalances: true,
983
996
  useDataHookForPay: true,
984
997
  useDataHookForCashOut: true,
985
998
  dataHook: metadata.dataHook,
@@ -994,7 +1007,6 @@ contract DefifaDeployer is IDefifaDeployer, IDefifaGamePhaseReporter, IDefifaGam
994
1007
  fundAccessLimitGroups: new JBFundAccessLimitGroup[](0)
995
1008
  });
996
1009
 
997
- // slither-disable-next-line unused-return
998
1010
  CONTROLLER.queueRulesetsOf({
999
1011
  projectId: gameId, rulesetConfigurations: rulesetConfigs, memo: "Defifa game has finished."
1000
1012
  });