@ballkidz/defifa 0.0.12 → 0.0.14

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.
Files changed (44) hide show
  1. package/ADMINISTRATION.md +3 -3
  2. package/ARCHITECTURE.md +3 -2
  3. package/AUDIT_INSTRUCTIONS.md +5 -5
  4. package/CHANGE_LOG.md +62 -5
  5. package/CRYPTO_ECON.md +506 -271
  6. package/CRYPTO_ECON.pdf +0 -0
  7. package/CRYPTO_ECON.tex +438 -241
  8. package/RISKS.md +13 -1
  9. package/SKILLS.md +5 -3
  10. package/USER_JOURNEYS.md +4 -3
  11. package/package.json +6 -6
  12. package/src/DefifaDeployer.sol +128 -130
  13. package/src/DefifaGovernor.sol +304 -83
  14. package/src/DefifaHook.sol +184 -171
  15. package/src/enums/DefifaScorecardState.sol +1 -0
  16. package/src/interfaces/IDefifaGovernor.sol +42 -2
  17. package/src/libraries/DefifaHookLib.sol +69 -62
  18. package/src/structs/DefifaAttestations.sol +3 -3
  19. package/src/structs/DefifaLaunchProjectData.sol +1 -0
  20. package/src/structs/DefifaScorecard.sol +2 -0
  21. package/test/BWAFunctionComparison.t.sol +1320 -0
  22. package/test/DefifaAdversarialQuorum.t.sol +52 -37
  23. package/test/DefifaAuditLowGuards.t.sol +9 -5
  24. package/test/DefifaFeeAccounting.t.sol +2 -1
  25. package/test/DefifaGovernanceHardening.t.sol +1315 -0
  26. package/test/DefifaGovernor.t.sol +8 -4
  27. package/test/DefifaHookRegressions.t.sol +2 -1
  28. package/test/DefifaMintCostInvariant.t.sol +2 -1
  29. package/test/DefifaNoContest.t.sol +3 -2
  30. package/test/DefifaSecurity.t.sol +55 -47
  31. package/test/DefifaUSDC.t.sol +3 -2
  32. package/test/Fork.t.sol +37 -32
  33. package/test/TestAuditGaps.sol +6 -4
  34. package/test/TestQALastMile.t.sol +6 -3
  35. package/test/audit/{CodexAttestationDoubleCount.t.sol → AttestationDoubleCount.t.sol} +3 -2
  36. package/test/audit/FixPendingReserveDilution.t.sol +366 -0
  37. package/test/audit/PendingReserveDilution.t.sol +298 -0
  38. package/test/audit/PendingReserveQuorumGrief.t.sol +355 -0
  39. package/test/audit/PendingReserveSnapshotBypass.t.sol +279 -0
  40. package/test/regression/AttestationDelegateBeneficiary.t.sol +2 -1
  41. package/test/regression/FulfillmentBlocksRatification.t.sol +2 -1
  42. package/test/regression/GracePeriodBypass.t.sol +2 -1
  43. package/test/SVG.t.sol +0 -164
  44. package/test/deployScript.t.sol +0 -144
@@ -161,10 +161,10 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
161
161
  /// @return The first owner of the token.
162
162
  function firstOwnerOf(uint256 tokenId) external view override returns (address) {
163
163
  // Get a reference to the first owner.
164
- address _storedFirstOwner = _firstOwnerOf[tokenId];
164
+ address storedFirstOwner = _firstOwnerOf[tokenId];
165
165
 
166
166
  // If the stored first owner is set, return it.
167
- if (_storedFirstOwner != address(0)) return _storedFirstOwner;
167
+ if (storedFirstOwner != address(0)) return storedFirstOwner;
168
168
 
169
169
  // Otherwise, the first owner must be the current owner.
170
170
  return _owners[tokenId];
@@ -275,23 +275,22 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
275
275
  if (metadataExists) decodedTokenIds = abi.decode(metadata, (uint256[]));
276
276
 
277
277
  // Get the current game phase.
278
- DefifaGamePhase _gamePhase = gamePhaseReporter.currentGamePhaseOf(context.projectId);
278
+ DefifaGamePhase gamePhase = gamePhaseReporter.currentGamePhaseOf(context.projectId);
279
279
 
280
280
  // Calculate the amount paid to mint the tokens that are being burned.
281
- uint256 _cumulativeMintPrice = DefifaHookLib.computeCumulativeMintPrice({
281
+ uint256 cumulativeMintPrice = DefifaHookLib.computeCumulativeMintPrice({
282
282
  tokenIds: decodedTokenIds, hookStore: store, hook: address(this)
283
283
  });
284
284
 
285
285
  // Use this contract as the only cash out hook.
286
286
  hookSpecifications = new JBCashOutHookSpecification[](1);
287
- hookSpecifications[0] = JBCashOutHookSpecification({
288
- hook: this, noop: false, amount: 0, metadata: abi.encode(_cumulativeMintPrice)
289
- });
287
+ hookSpecifications[0] =
288
+ JBCashOutHookSpecification({hook: this, noop: false, amount: 0, metadata: abi.encode(cumulativeMintPrice)});
290
289
 
291
290
  // Compute the cash out count based on the game phase.
292
291
  cashOutCount = DefifaHookLib.computeCashOutCount({
293
- gamePhase: _gamePhase,
294
- cumulativeMintPrice: _cumulativeMintPrice,
292
+ gamePhase: gamePhase,
293
+ cumulativeMintPrice: cumulativeMintPrice,
295
294
  surplusValue: context.surplus.value,
296
295
  totalAmountRedeemed: amountRedeemed,
297
296
  cumulativeCashOutWeight: cashOutWeightOf(decodedTokenIds)
@@ -516,15 +515,15 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
516
515
  _store.recordAddTiers(_tiers);
517
516
 
518
517
  // Keep a reference to the number of tier names.
519
- uint256 _numberOfTierNames = _tierNames.length;
518
+ uint256 numberOfTierNames = _tierNames.length;
520
519
 
521
520
  // Set the name for each tier.
522
- for (uint256 _i; _i < _numberOfTierNames;) {
521
+ for (uint256 i; i < numberOfTierNames;) {
523
522
  // Set the tier name.
524
- _tierNameOf[_i + 1] = _tierNames[_i];
523
+ _tierNameOf[i + 1] = _tierNames[i];
525
524
 
526
525
  unchecked {
527
- ++_i;
526
+ ++i;
528
527
  }
529
528
  }
530
529
 
@@ -543,57 +542,54 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
543
542
  )) revert DefifaHook_ReservedTokenMintingPaused();
544
543
 
545
544
  // Keep a reference to the reserved token beneficiary.
546
- address _reservedTokenBeneficiary = store.reserveBeneficiaryOf({hook: address(this), tierId: tierId});
545
+ address reservedTokenBeneficiary = store.reserveBeneficiaryOf({hook: address(this), tierId: tierId});
547
546
 
548
547
  // Get a reference to the old delegate.
549
- address _oldDelegate = _tierDelegation[_reservedTokenBeneficiary][tierId];
548
+ address oldDelegate = _tierDelegation[reservedTokenBeneficiary][tierId];
550
549
 
551
550
  // Set the delegate as the beneficiary if the beneficiary hasn't already set a delegate.
552
- if (_oldDelegate == address(0)) {
551
+ if (oldDelegate == address(0)) {
553
552
  _delegateTier({
554
- _account: _reservedTokenBeneficiary,
555
- _delegatee: defaultAttestationDelegate != address(0)
553
+ account: reservedTokenBeneficiary,
554
+ delegatee: defaultAttestationDelegate != address(0)
556
555
  ? defaultAttestationDelegate
557
- : _reservedTokenBeneficiary,
558
- _tierId: tierId
556
+ : reservedTokenBeneficiary,
557
+ tierId: tierId
559
558
  });
560
559
  }
561
560
 
562
561
  // Record the minted reserves for the tier.
563
- uint256[] memory _tokenIds = store.recordMintReservesFor({tierId: tierId, count: count});
562
+ uint256[] memory tokenIds = store.recordMintReservesFor({tierId: tierId, count: count});
564
563
 
565
564
  // Keep a reference to the token ID being iterated on.
566
- uint256 _tokenId;
565
+ uint256 tokenId;
567
566
 
568
567
  // Fetch the tier details (needed for votingUnits below).
569
- JB721Tier memory _tier = store.tierOf({hook: address(this), id: tierId, includeResolvedUri: false});
568
+ JB721Tier memory tier = store.tierOf({hook: address(this), id: tierId, includeResolvedUri: false});
570
569
 
571
570
  // Increment _totalMintCost so reserved recipients can claim their share of fee tokens ($DEFIFA/$NANA).
572
571
  // Note: reserved mints dilute existing fee token claimants because they increase the total mint cost
573
572
  // denominator without contributing new funds to the fee token balances. This is the intended design —
574
573
  // reserved recipients receive a proportional claim on fee tokens as if they had paid to mint.
575
- _totalMintCost += _tier.price * count;
574
+ _totalMintCost += tier.price * count;
576
575
 
577
- for (uint256 _i; _i < count;) {
576
+ for (uint256 i; i < count;) {
578
577
  // Set the token ID.
579
- _tokenId = _tokenIds[_i];
578
+ tokenId = tokenIds[i];
580
579
 
581
580
  // Mint the token.
582
- _mint({to: _reservedTokenBeneficiary, tokenId: _tokenId});
581
+ _mint({to: reservedTokenBeneficiary, tokenId: tokenId});
583
582
 
584
- emit MintReservedToken(_tokenId, tierId, _reservedTokenBeneficiary, msg.sender);
583
+ emit MintReservedToken(tokenId, tierId, reservedTokenBeneficiary, msg.sender);
585
584
 
586
585
  unchecked {
587
- ++_i;
586
+ ++i;
588
587
  }
589
588
  }
590
589
 
591
590
  // Transfer the attestation units to the delegate.
592
591
  _transferTierAttestationUnits({
593
- _from: address(0),
594
- _to: _reservedTokenBeneficiary,
595
- _tierId: tierId,
596
- _amount: _tier.votingUnits * _tokenIds.length
592
+ from: address(0), to: reservedTokenBeneficiary, tierId: tierId, amount: tier.votingUnits * tokenIds.length
597
593
  });
598
594
  }
599
595
 
@@ -630,52 +626,56 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
630
626
  }
631
627
 
632
628
  // Decode the CashOut metadata.
633
- (uint256[] memory _decodedTokenIds) = abi.decode(metadata, (uint256[]));
629
+ (uint256[] memory decodedTokenIds) = abi.decode(metadata, (uint256[]));
634
630
 
635
631
  // Get a reference to the number of token IDs being checked.
636
- uint256 _numberOfTokenIds = _decodedTokenIds.length;
632
+ uint256 numberOfTokenIds = decodedTokenIds.length;
637
633
 
638
634
  // Keep a reference to the token ID being iterated on.
639
- uint256 _tokenId;
635
+ uint256 tokenId;
640
636
 
641
637
  // Keep track of whether the cashOut is happening during the complete phase.
642
- bool _isComplete = gamePhaseReporter.currentGamePhaseOf(PROJECT_ID) == DefifaGamePhase.COMPLETE;
638
+ bool isComplete = gamePhaseReporter.currentGamePhaseOf(PROJECT_ID) == DefifaGamePhase.COMPLETE;
643
639
 
644
640
  // Iterate through all tokens, burning them if the owner is correct.
645
- for (uint256 _i; _i < _numberOfTokenIds; _i++) {
641
+ for (uint256 i; i < numberOfTokenIds; i++) {
646
642
  // Set the token's ID.
647
- _tokenId = _decodedTokenIds[_i];
643
+ tokenId = decodedTokenIds[i];
648
644
 
649
645
  // Make sure the token's owner is correct.
650
- address _tokenOwner = _ownerOf(_tokenId);
651
- if (_tokenOwner != context.holder) {
652
- revert DefifaHook_Unauthorized(_tokenId, _tokenOwner, context.holder);
646
+ address tokenOwner = _ownerOf(tokenId);
647
+ if (tokenOwner != context.holder) {
648
+ revert DefifaHook_Unauthorized(tokenId, tokenOwner, context.holder);
653
649
  }
654
650
 
655
651
  // Burn the token.
656
- _burn(_tokenId);
652
+ _burn(tokenId);
657
653
 
658
- if (_isComplete) {
654
+ if (isComplete) {
659
655
  unchecked {
660
- ++tokensRedeemedFrom[store.tierIdOfToken(_tokenId)];
656
+ ++tokensRedeemedFrom[store.tierIdOfToken(tokenId)];
661
657
  }
662
658
  }
663
659
  }
664
660
 
665
661
  // Call the hook.
666
- _didBurn(_decodedTokenIds);
662
+ _didBurn(decodedTokenIds);
667
663
 
668
664
  // Decode the metadata passed by the hook.
669
- (uint256 _cumulativeMintPrice) = abi.decode(context.hookMetadata, (uint256));
665
+ (uint256 cumulativeMintPrice) = abi.decode(context.hookMetadata, (uint256));
670
666
 
671
667
  // Increment the amount redeemed if this is the complete phase.
672
- bool _beneficiaryReceivedTokens;
673
- if (_isComplete) {
668
+ bool beneficiaryReceivedTokens;
669
+ if (isComplete) {
674
670
  amountRedeemed += context.reclaimedAmount.value;
675
671
 
676
672
  // Claim the $DEFIFA and $NANA tokens for the user.
677
- _beneficiaryReceivedTokens = _claimTokensFor({
678
- _beneficiary: context.holder, shareToBeneficiary: _cumulativeMintPrice, outOfTotal: _totalMintCost
673
+ // Include pending reserve mint cost in the denominator so that unminted reserves
674
+ // are accounted for, preventing paid holders from claiming a disproportionate share.
675
+ beneficiaryReceivedTokens = _claimTokensFor({
676
+ beneficiary: context.holder,
677
+ shareToBeneficiary: cumulativeMintPrice,
678
+ outOfTotal: _totalMintCost + _pendingReserveMintCost()
679
679
  });
680
680
  }
681
681
 
@@ -683,27 +683,27 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
683
683
  // Tokens in 0-weight tiers (losing teams) cannot burn to reclaim fees if no fee tokens were
684
684
  // distributed. This is correct behavior — 0-weight means the tier has no claim on the pot. Burning would
685
685
  // return 0 value regardless.
686
- if (context.reclaimedAmount.value == 0 && !_beneficiaryReceivedTokens) revert DefifaHook_NothingToClaim();
686
+ if (context.reclaimedAmount.value == 0 && !beneficiaryReceivedTokens) revert DefifaHook_NothingToClaim();
687
687
 
688
688
  // Decrement the paid mint cost by the cumulative mint price of the tokens being burned.
689
- _totalMintCost -= _cumulativeMintPrice;
689
+ _totalMintCost -= cumulativeMintPrice;
690
690
  }
691
691
 
692
692
  /// @notice Mint reserved tokens within the tier for the provided value.
693
693
  /// @param mintReservesForTiersData Contains information about how many reserved tokens to mint for each tier.
694
694
  function mintReservesFor(JB721TiersMintReservesConfig[] calldata mintReservesForTiersData) external override {
695
695
  // Keep a reference to the number of tiers there are to mint reserves for.
696
- uint256 _numberOfTiers = mintReservesForTiersData.length;
696
+ uint256 numberOfTiers = mintReservesForTiersData.length;
697
697
 
698
- for (uint256 _i; _i < _numberOfTiers;) {
698
+ for (uint256 i; i < numberOfTiers;) {
699
699
  // Get a reference to the data being iterated on.
700
- JB721TiersMintReservesConfig memory _data = mintReservesForTiersData[_i];
700
+ JB721TiersMintReservesConfig memory data = mintReservesForTiersData[i];
701
701
 
702
702
  // Mint for the tier.
703
- mintReservesFor(_data.tierId, _data.count);
703
+ mintReservesFor(data.tierId, data.count);
704
704
 
705
705
  unchecked {
706
- ++_i;
706
+ ++i;
707
707
  }
708
708
  }
709
709
  }
@@ -713,10 +713,10 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
713
713
  /// @param tierWeights The tier weights to set.
714
714
  function setTierCashOutWeightsTo(DefifaTierCashOutWeight[] memory tierWeights) external override onlyOwner {
715
715
  // Get a reference to the game phase.
716
- DefifaGamePhase _gamePhase = gamePhaseReporter.currentGamePhaseOf(PROJECT_ID);
716
+ DefifaGamePhase gamePhase = gamePhaseReporter.currentGamePhaseOf(PROJECT_ID);
717
717
 
718
718
  // Make sure the game has ended.
719
- if (_gamePhase != DefifaGamePhase.SCORING) {
719
+ if (gamePhase != DefifaGamePhase.SCORING) {
720
720
  revert DefifaHook_GameIsntScoringYet();
721
721
  }
722
722
 
@@ -745,7 +745,7 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
745
745
  revert DefifaHook_DelegateChangesUnavailableInThisPhase();
746
746
  }
747
747
 
748
- _delegateTier({_account: msg.sender, _delegatee: delegatee, _tierId: tierId});
748
+ _delegateTier({account: msg.sender, delegatee: delegatee, tierId: tierId});
749
749
  }
750
750
 
751
751
  /// @notice Delegate attestations.
@@ -757,22 +757,22 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
757
757
  }
758
758
 
759
759
  // Keep a reference to the number of tier delegates.
760
- uint256 _numberOfTierDelegates = delegations.length;
760
+ uint256 numberOfTierDelegates = delegations.length;
761
761
 
762
762
  // Keep a reference to the data being iterated on.
763
- DefifaDelegation memory _data;
763
+ DefifaDelegation memory data;
764
764
 
765
- for (uint256 _i; _i < _numberOfTierDelegates;) {
765
+ for (uint256 i; i < numberOfTierDelegates;) {
766
766
  // Reference the data being iterated on.
767
- _data = delegations[_i];
767
+ data = delegations[i];
768
768
 
769
769
  // Make sure a delegate is specified.
770
- if (_data.delegatee == address(0)) revert DefifaHook_DelegateAddressZero();
770
+ if (data.delegatee == address(0)) revert DefifaHook_DelegateAddressZero();
771
771
 
772
- _delegateTier({_account: msg.sender, _delegatee: _data.delegatee, _tierId: _data.tierId});
772
+ _delegateTier({account: msg.sender, delegatee: data.delegatee, tierId: data.tierId});
773
773
 
774
774
  unchecked {
775
- ++_i;
775
+ ++i;
776
776
  }
777
777
  }
778
778
  }
@@ -781,13 +781,35 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
781
781
  // ------------------------ internal functions ----------------------- //
782
782
  //*********************************************************************//
783
783
 
784
+ /// @notice Computes the total mint cost of all pending (unminted) reserve NFTs across all tiers.
785
+ /// @dev Used to include pending reserves in the fee token claim denominator so that paid holders
786
+ /// cannot claim a disproportionate share before reserves are minted.
787
+ /// @return cost The total mint cost of pending reserves.
788
+ function _pendingReserveMintCost() internal view returns (uint256 cost) {
789
+ IJB721TiersHookStore _store = store;
790
+ address hook = address(this);
791
+ uint256 numberOfTiers = _store.maxTierIdOf(hook);
792
+
793
+ for (uint256 i; i < numberOfTiers;) {
794
+ uint256 tierId = i + 1;
795
+ uint256 pendingReserves = _store.numberOfPendingReservesFor({hook: hook, tierId: tierId});
796
+ if (pendingReserves != 0) {
797
+ JB721Tier memory tier = _store.tierOf({hook: hook, id: tierId, includeResolvedUri: false});
798
+ cost += pendingReserves * tier.price;
799
+ }
800
+ unchecked {
801
+ ++i;
802
+ }
803
+ }
804
+ }
805
+
784
806
  /// @notice Claims the defifa and base protocol tokens for a beneficiary.
785
- /// @param _beneficiary The address to claim tokens for.
807
+ /// @param beneficiary The address to claim tokens for.
786
808
  /// @param shareToBeneficiary The share relative to the `outOfTotal` to send the user.
787
809
  /// @param outOfTotal The total share that the `shareToBeneficiary` is relative to.
788
810
  /// @return beneficiaryReceivedTokens A flag indicating if the beneficiary received any tokens.
789
811
  function _claimTokensFor(
790
- address _beneficiary,
812
+ address beneficiary,
791
813
  uint256 shareToBeneficiary,
792
814
  uint256 outOfTotal
793
815
  )
@@ -795,7 +817,7 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
795
817
  returns (bool beneficiaryReceivedTokens)
796
818
  {
797
819
  return DefifaHookLib.claimTokensFor({
798
- beneficiary: _beneficiary,
820
+ beneficiary: beneficiary,
799
821
  shareToBeneficiary: shareToBeneficiary,
800
822
  outOfTotal: outOfTotal,
801
823
  defifaToken: DEFIFA_TOKEN,
@@ -804,130 +826,130 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
804
826
  }
805
827
 
806
828
  /// @notice Delegate all attestation units for the specified tier.
807
- /// @param _account The account delegating tier attestation units.
808
- /// @param _delegatee The account to delegate tier attestation units to.
809
- /// @param _tierId The ID of the tier for which attestation units are being transferred.
810
- function _delegateTier(address _account, address _delegatee, uint256 _tierId) internal virtual {
829
+ /// @param account The account delegating tier attestation units.
830
+ /// @param delegatee The account to delegate tier attestation units to.
831
+ /// @param tierId The ID of the tier for which attestation units are being transferred.
832
+ function _delegateTier(address account, address delegatee, uint256 tierId) internal virtual {
811
833
  // Get the current delegatee
812
- address _oldDelegate = _tierDelegation[_account][_tierId];
834
+ address oldDelegate = _tierDelegation[account][tierId];
813
835
 
814
836
  // Store the new delegatee
815
- _tierDelegation[_account][_tierId] = _delegatee;
837
+ _tierDelegation[account][tierId] = delegatee;
816
838
 
817
- emit DelegateChanged(_account, _oldDelegate, _delegatee);
839
+ emit DelegateChanged(account, oldDelegate, delegatee);
818
840
 
819
841
  // Move the attestations.
820
842
  _moveTierDelegateAttestations({
821
- _from: _oldDelegate,
822
- _to: _delegatee,
823
- _tierId: _tierId,
824
- _amount: _getTierAttestationUnits({_account: _account, _tierId: _tierId})
843
+ from: oldDelegate,
844
+ to: delegatee,
845
+ tierId: tierId,
846
+ amount: _getTierAttestationUnits({account: account, tierId: tierId})
825
847
  });
826
848
  }
827
849
 
828
850
  /// @notice A function that will run when tokens are burned via cashOut.
829
- /// @param _tokenIds The IDs of the tokens that were burned.
830
- function _didBurn(uint256[] memory _tokenIds) internal virtual override {
851
+ /// @param tokenIds The IDs of the tokens that were burned.
852
+ function _didBurn(uint256[] memory tokenIds) internal virtual override {
831
853
  // Add to burned counter.
832
- store.recordBurn(_tokenIds);
854
+ store.recordBurn(tokenIds);
833
855
  }
834
856
 
835
857
  /// @notice Gets the amount of attestation units an address has for a particular tier.
836
- /// @param _account The account to get attestation units for.
837
- /// @param _tierId The ID of the tier to get attestation units for.
858
+ /// @param account The account to get attestation units for.
859
+ /// @param tierId The ID of the tier to get attestation units for.
838
860
  /// @return The attestation units.
839
- function _getTierAttestationUnits(address _account, uint256 _tierId) internal view virtual returns (uint256) {
840
- return store.tierVotingUnitsOf({hook: address(this), account: _account, tierId: _tierId});
861
+ function _getTierAttestationUnits(address account, uint256 tierId) internal view virtual returns (uint256) {
862
+ return store.tierVotingUnitsOf({hook: address(this), account: account, tierId: tierId});
841
863
  }
842
864
 
843
865
  /// @notice Mints a token in all provided tiers.
844
- /// @param _amount The amount to base the mints on. All mints' price floors must fit in this amount.
845
- /// @param _mintTierIds An array of tier IDs that are intended to be minted.
846
- /// @param _beneficiary The address to mint for.
866
+ /// @param amount The amount to base the mints on. All mints' price floors must fit in this amount.
867
+ /// @param mintTierIds An array of tier IDs that are intended to be minted.
868
+ /// @param beneficiary The address to mint for.
847
869
  /// @return leftoverAmount The amount leftover after the mint.
848
870
  function _mintAll(
849
- uint256 _amount,
850
- uint16[] memory _mintTierIds,
851
- address _beneficiary
871
+ uint256 amount,
872
+ uint16[] memory mintTierIds,
873
+ address beneficiary
852
874
  )
853
875
  internal
854
876
  returns (uint256 leftoverAmount)
855
877
  {
856
878
  // Keep a reference to the token ID.
857
- uint256[] memory _tokenIds;
879
+ uint256[] memory tokenIds;
858
880
 
859
881
  // Record the mint. The returned token IDs correspond to the tiers passed in.
860
882
  // slither-disable-next-line reentrancy-benign
861
- (_tokenIds, leftoverAmount) = store.recordMint({
862
- amount: _amount,
863
- tierIds: _mintTierIds,
883
+ (tokenIds, leftoverAmount) = store.recordMint({
884
+ amount: amount,
885
+ tierIds: mintTierIds,
864
886
  isOwnerMint: false // Not a manual mint
865
887
  });
866
888
 
867
889
  // Get a reference to the number of mints.
868
- uint256 _mintsLength = _tokenIds.length;
890
+ uint256 mintsLength = tokenIds.length;
869
891
 
870
892
  // Keep a reference to the token ID being iterated on.
871
- uint256 _tokenId;
893
+ uint256 tokenId;
872
894
 
873
895
  // Increment the paid mint cost.
874
- _totalMintCost += _amount;
896
+ _totalMintCost += amount;
875
897
 
876
898
  // Loop through each token ID and mint.
877
- for (uint256 _i; _i < _mintsLength;) {
899
+ for (uint256 i; i < mintsLength;) {
878
900
  // Get a reference to the tier being iterated on.
879
- _tokenId = _tokenIds[_i];
901
+ tokenId = tokenIds[i];
880
902
 
881
903
  // Mint the tokens.
882
- _mint({to: _beneficiary, tokenId: _tokenId});
904
+ _mint({to: beneficiary, tokenId: tokenId});
883
905
 
884
- emit Mint(_tokenId, _mintTierIds[_i], _beneficiary, _amount, msg.sender);
906
+ emit Mint(tokenId, mintTierIds[i], beneficiary, amount, msg.sender);
885
907
 
886
908
  unchecked {
887
- ++_i;
909
+ ++i;
888
910
  }
889
911
  }
890
912
  }
891
913
 
892
914
  /// @notice Moves delegated tier attestations from one delegate to another.
893
- /// @param _from The account to transfer tier attestation units from.
894
- /// @param _to The account to transfer tier attestation units to.
895
- /// @param _tierId The ID of the tier for which attestation units are being transferred.
896
- /// @param _amount The amount of attestation units to delegate.
897
- function _moveTierDelegateAttestations(address _from, address _to, uint256 _tierId, uint256 _amount) internal {
915
+ /// @param from The account to transfer tier attestation units from.
916
+ /// @param to The account to transfer tier attestation units to.
917
+ /// @param tierId The ID of the tier for which attestation units are being transferred.
918
+ /// @param amount The amount of attestation units to delegate.
919
+ function _moveTierDelegateAttestations(address from, address to, uint256 tierId, uint256 amount) internal {
898
920
  // Nothing to do if moving to the same account, or no amount is being moved.
899
- if (_from == _to || _amount == 0) return;
921
+ if (from == to || amount == 0) return;
900
922
 
901
923
  // If not moving from the zero address, update the checkpoints to subtract the amount.
902
- if (_from != address(0)) {
924
+ if (from != address(0)) {
903
925
  // Get the current amount for the sending delegate.
904
- uint208 _current = _delegateTierCheckpoints[_from][_tierId].latest();
926
+ uint208 current = _delegateTierCheckpoints[from][tierId].latest();
905
927
  // Set the new amount for the sending delegate.
906
928
  // uint208 is sufficient for attestation values: each tier's attestation units are bounded by the NFT
907
929
  // supply (max ~999_999_999 per tier * 128 tiers), well within uint208's ~4.1e62 range.
908
930
  // forge-lint: disable-next-line(unsafe-typecast)
909
- (uint256 _oldValue, uint256 _newValue) = _delegateTierCheckpoints[_from][_tierId].push({
931
+ (uint256 oldValue, uint256 newValue) = _delegateTierCheckpoints[from][tierId].push({
910
932
  // forge-lint: disable-next-line(unsafe-typecast)
911
933
  key: uint48(block.timestamp),
912
934
  // forge-lint: disable-next-line(unsafe-typecast)
913
- value: _current - uint208(_amount)
935
+ value: current - uint208(amount)
914
936
  });
915
- emit TierDelegateAttestationsChanged(_from, _tierId, _oldValue, _newValue, msg.sender);
937
+ emit TierDelegateAttestationsChanged(from, tierId, oldValue, newValue, msg.sender);
916
938
  }
917
939
 
918
940
  // If not moving to the zero address, update the checkpoints to add the amount.
919
- if (_to != address(0)) {
941
+ if (to != address(0)) {
920
942
  // Get the current amount for the receiving delegate.
921
- uint208 _current = _delegateTierCheckpoints[_to][_tierId].latest();
943
+ uint208 current = _delegateTierCheckpoints[to][tierId].latest();
922
944
  // Set the new amount for the receiving delegate.
923
945
  // forge-lint: disable-next-line(unsafe-typecast)
924
- (uint256 _oldValue, uint256 _newValue) = _delegateTierCheckpoints[_to][_tierId].push({
946
+ (uint256 oldValue, uint256 newValue) = _delegateTierCheckpoints[to][tierId].push({
925
947
  // forge-lint: disable-next-line(unsafe-typecast)
926
948
  key: uint48(block.timestamp),
927
949
  // forge-lint: disable-next-line(unsafe-typecast)
928
- value: _current + uint208(_amount)
950
+ value: current + uint208(amount)
929
951
  });
930
- emit TierDelegateAttestationsChanged(_to, _tierId, _oldValue, _newValue, msg.sender);
952
+ emit TierDelegateAttestationsChanged(to, tierId, oldValue, newValue, msg.sender);
931
953
  }
932
954
  }
933
955
 
@@ -945,92 +967,83 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
945
967
  if (!found) revert DefifaHook_NothingToMint();
946
968
 
947
969
  // Decode the metadata.
948
- (address _attestationDelegate, uint16[] memory _tierIdsToMint) = abi.decode(metadata, (address, uint16[]));
970
+ (address attestationDelegate, uint16[] memory tierIdsToMint) = abi.decode(metadata, (address, uint16[]));
949
971
 
950
972
  // Set the beneficiary as the attestation delegate by default.
951
- if (_attestationDelegate == address(0)) {
952
- _attestationDelegate =
973
+ if (attestationDelegate == address(0)) {
974
+ attestationDelegate =
953
975
  defaultAttestationDelegate != address(0) ? defaultAttestationDelegate : context.beneficiary;
954
976
  }
955
977
 
956
978
  // Make sure something is being minted.
957
- if (_tierIdsToMint.length == 0) revert DefifaHook_NothingToMint();
979
+ if (tierIdsToMint.length == 0) revert DefifaHook_NothingToMint();
958
980
 
959
981
  // Compute attestation units per unique tier (validates ascending order, reverts on bad order).
960
- (uint256[] memory _tierIds, uint256[] memory _attestationAmounts, uint256 _uniqueTierCount) = DefifaHookLib.computeAttestationUnits({
961
- tierIdsToMint: _tierIdsToMint, hookStore: store, hook: address(this)
962
- });
982
+ (uint256[] memory tierIds, uint256[] memory attestationAmounts, uint256 uniqueTierCount) =
983
+ DefifaHookLib.computeAttestationUnits({tierIdsToMint: tierIdsToMint, hookStore: store, hook: address(this)});
963
984
 
964
985
  // Apply attestation units for each unique tier.
965
- for (uint256 _i; _i < _uniqueTierCount;) {
966
- uint256 _tierId = _tierIds[_i];
986
+ for (uint256 i; i < uniqueTierCount;) {
987
+ uint256 tierId = tierIds[i];
967
988
 
968
989
  // Get a reference to the old delegate.
969
- address _oldDelegate = _tierDelegation[context.beneficiary][_tierId];
990
+ address oldDelegate = _tierDelegation[context.beneficiary][tierId];
970
991
 
971
992
  // If there's either a new delegate or old delegate, set delegation and transfer units.
972
- if (_attestationDelegate != address(0) || _oldDelegate != address(0)) {
993
+ if (attestationDelegate != address(0) || oldDelegate != address(0)) {
973
994
  // Switch delegates if needed.
974
- if (_attestationDelegate != address(0) && _attestationDelegate != _oldDelegate) {
975
- _delegateTier({_account: context.beneficiary, _delegatee: _attestationDelegate, _tierId: _tierId});
995
+ if (attestationDelegate != address(0) && attestationDelegate != oldDelegate) {
996
+ _delegateTier({account: context.beneficiary, delegatee: attestationDelegate, tierId: tierId});
976
997
  }
977
998
 
978
999
  // Transfer the attestation units.
979
1000
  _transferTierAttestationUnits({
980
- _from: address(0), _to: context.beneficiary, _tierId: _tierId, _amount: _attestationAmounts[_i]
1001
+ from: address(0), to: context.beneficiary, tierId: tierId, amount: attestationAmounts[i]
981
1002
  });
982
1003
  }
983
1004
 
984
1005
  unchecked {
985
- ++_i;
1006
+ ++i;
986
1007
  }
987
1008
  }
988
1009
 
989
1010
  // Mint tiers if they were specified.
990
- uint256 _leftoverAmount =
991
- _mintAll({_amount: context.amount.value, _mintTierIds: _tierIdsToMint, _beneficiary: context.beneficiary});
1011
+ uint256 leftoverAmount =
1012
+ _mintAll({amount: context.amount.value, mintTierIds: tierIdsToMint, beneficiary: context.beneficiary});
992
1013
 
993
1014
  // Make sure the buyer isn't overspending.
994
- if (_leftoverAmount != 0) revert DefifaHook_Overspending();
1015
+ if (leftoverAmount != 0) revert DefifaHook_Overspending();
995
1016
  }
996
1017
 
997
- /// @notice Transfers, mints, or burns tier attestation units. To register a mint, `_from` should be zero. To
998
- /// register a burn, `_to` should be zero. Total supply of attestation units will be adjusted with mints and burns.
999
- /// @param _from The account to transfer tier attestation units from.
1000
- /// @param _to The account to transfer tier attestation units to.
1001
- /// @param _tierId The ID of the tier for which attestation units are being transferred.
1002
- /// @param _amount The amount of attestation units to delegate.
1003
- function _transferTierAttestationUnits(
1004
- address _from,
1005
- address _to,
1006
- uint256 _tierId,
1007
- uint256 _amount
1008
- )
1009
- internal
1010
- virtual
1011
- {
1012
- if (_from == address(0) || _to == address(0)) {
1018
+ /// @notice Transfers, mints, or burns tier attestation units. To register a mint, `from` should be zero. To
1019
+ /// register a burn, `to` should be zero. Total supply of attestation units will be adjusted with mints and burns.
1020
+ /// @param from The account to transfer tier attestation units from.
1021
+ /// @param to The account to transfer tier attestation units to.
1022
+ /// @param tierId The ID of the tier for which attestation units are being transferred.
1023
+ /// @param amount The amount of attestation units to delegate.
1024
+ function _transferTierAttestationUnits(address from, address to, uint256 tierId, uint256 amount) internal virtual {
1025
+ if (from == address(0) || to == address(0)) {
1013
1026
  // Get the current total for the tier.
1014
- uint208 _current = _totalTierCheckpoints[_tierId].latest();
1027
+ uint208 current = _totalTierCheckpoints[tierId].latest();
1015
1028
 
1016
1029
  // If minting, add to the total tier checkpoints.
1017
- if (_from == address(0)) {
1030
+ if (from == address(0)) {
1018
1031
  // Casting to uint208/uint48 is safe because attestation unit amounts are bounded by NFT supply counts.
1019
1032
  // forge-lint: disable-next-line(unsafe-typecast)
1020
- uint208 newValue = _current + uint208(_amount);
1033
+ uint208 newValue = current + uint208(amount);
1021
1034
  // forge-lint: disable-next-line(unsafe-typecast)
1022
1035
  // slither-disable-next-line unused-return
1023
- _totalTierCheckpoints[_tierId].push({key: uint48(block.timestamp), value: newValue});
1036
+ _totalTierCheckpoints[tierId].push({key: uint48(block.timestamp), value: newValue});
1024
1037
  }
1025
1038
 
1026
1039
  // If burning, subtract from the total tier checkpoints.
1027
- if (_to == address(0)) {
1040
+ if (to == address(0)) {
1028
1041
  // Casting to uint208/uint48 is safe because attestation unit amounts are bounded by NFT supply counts.
1029
1042
  // forge-lint: disable-next-line(unsafe-typecast)
1030
- uint208 newValue = _current - uint208(_amount);
1043
+ uint208 newValue = current - uint208(amount);
1031
1044
  // forge-lint: disable-next-line(unsafe-typecast)
1032
1045
  // slither-disable-next-line unused-return
1033
- _totalTierCheckpoints[_tierId].push({key: uint48(block.timestamp), value: newValue});
1046
+ _totalTierCheckpoints[tierId].push({key: uint48(block.timestamp), value: newValue});
1034
1047
  }
1035
1048
  }
1036
1049
 
@@ -1040,16 +1053,16 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
1040
1053
  // to Carol, Carol's attestation units auto-delegate to Carol (not Bob). However, Alice's delegation
1041
1054
  // to Bob persists — if Alice later receives another token, her units still go to Bob. This matches
1042
1055
  // ERC5805Votes behavior where delegation is an account-level setting, not a token-level one.
1043
- address _toDelegate = _tierDelegation[_to][_tierId];
1044
- if (_toDelegate == address(0) && _to != address(0)) {
1045
- _toDelegate = _to;
1046
- _tierDelegation[_to][_tierId] = _to;
1047
- emit DelegateChanged(_to, address(0), _to);
1056
+ address toDelegate = _tierDelegation[to][tierId];
1057
+ if (toDelegate == address(0) && to != address(0)) {
1058
+ toDelegate = to;
1059
+ _tierDelegation[to][tierId] = to;
1060
+ emit DelegateChanged(to, address(0), to);
1048
1061
  }
1049
1062
 
1050
1063
  // Move delegated attestations.
1051
1064
  _moveTierDelegateAttestations({
1052
- _from: _tierDelegation[_from][_tierId], _to: _toDelegate, _tierId: _tierId, _amount: _amount
1065
+ from: _tierDelegation[from][tierId], to: toDelegate, tierId: tierId, amount: amount
1053
1066
  });
1054
1067
  }
1055
1068
 
@@ -1093,6 +1106,6 @@ contract DefifaHook is JB721Hook, Ownable, IDefifaHook {
1093
1106
  if (from == address(0)) return from;
1094
1107
 
1095
1108
  // Transfer the attestation units.
1096
- _transferTierAttestationUnits({_from: from, _to: to, _tierId: tier.id, _amount: tier.votingUnits});
1109
+ _transferTierAttestationUnits({from: from, to: to, tierId: tier.id, amount: tier.votingUnits});
1097
1110
  }
1098
1111
  }