@bananapus/distributor-v6 0.0.18 → 0.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bananapus/distributor-v6",
3
- "version": "0.0.18",
3
+ "version": "0.0.20",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,8 +26,8 @@
26
26
  "deploy:testnets": "source ./.env && npx sphinx propose ./script/Deploy.s.sol --networks testnets"
27
27
  },
28
28
  "dependencies": {
29
- "@bananapus/721-hook-v6": "^0.0.51",
30
- "@bananapus/core-v6": "^0.0.54",
29
+ "@bananapus/721-hook-v6": "^0.0.52",
30
+ "@bananapus/core-v6": "^0.0.55",
31
31
  "@bananapus/permission-ids-v6": "^0.0.25",
32
32
  "@openzeppelin/contracts": "5.6.1",
33
33
  "@prb/math": "4.1.1"
@@ -16,7 +16,9 @@ contract Deploy is Script {
16
16
  uint256 roundDuration = vm.envUint("ROUND_DURATION");
17
17
  uint256 vestingRounds = vm.envUint("VESTING_ROUNDS");
18
18
 
19
- new JB721Distributor(directory, roundDuration, vestingRounds);
19
+ new JB721Distributor({
20
+ directory: directory, initialRoundDuration: roundDuration, initialVestingRounds: vestingRounds
21
+ });
20
22
 
21
23
  vm.stopBroadcast();
22
24
  }
@@ -77,14 +77,14 @@ contract JB721Distributor is JBDistributor, IJB721Distributor {
77
77
  //*********************************************************************//
78
78
 
79
79
  /// @param directory The JB directory used to verify terminal/controller callers.
80
- /// @param roundDuration_ The duration of each round, specified in seconds.
81
- /// @param vestingRounds_ The number of rounds until tokens are fully vested.
80
+ /// @param initialRoundDuration The duration of each round, specified in seconds.
81
+ /// @param initialVestingRounds The number of rounds until tokens are fully vested.
82
82
  constructor(
83
83
  IJBDirectory directory,
84
- uint256 roundDuration_,
85
- uint256 vestingRounds_
84
+ uint256 initialRoundDuration,
85
+ uint256 initialVestingRounds
86
86
  )
87
- JBDistributor(roundDuration_, vestingRounds_)
87
+ JBDistributor(initialRoundDuration, initialVestingRounds)
88
88
  {
89
89
  DIRECTORY = directory;
90
90
  }
@@ -109,7 +109,7 @@ contract JB721Distributor is JBDistributor, IJB721Distributor {
109
109
  function processSplitWith(JBSplitHookContext calldata context) external payable override {
110
110
  // Only terminals and controllers for the project can call this.
111
111
  if (
112
- !DIRECTORY.isTerminalOf(context.projectId, IJBTerminal(msg.sender))
112
+ !DIRECTORY.isTerminalOf({projectId: context.projectId, terminal: IJBTerminal(msg.sender)})
113
113
  && DIRECTORY.controllerOf(context.projectId) != IERC165(msg.sender)
114
114
  ) revert JB721Distributor_Unauthorized({projectId: context.projectId, caller: msg.sender});
115
115
 
@@ -266,7 +266,7 @@ contract JB721Distributor is JBDistributor, IJB721Distributor {
266
266
 
267
267
  // Use the checkpoints module to verify the token's snapshot owner had voting power at the round's snapshot
268
268
  // block. If the token did not exist then, ownerOfAt returns zero above and the token is not eligible.
269
- uint256 pastVotes = IVotes(address(IJB721TiersHook(hook).CHECKPOINTS()))
269
+ uint256 pastVotes = IVotes(address(IJB721TiersHook(hook).checkpoints()))
270
270
  .getPastVotes({account: owner, timepoint: snapshotBlock});
271
271
 
272
272
  // If the owner had no voting power at round start, the token is ineligible.
@@ -278,14 +278,14 @@ contract JB721Distributor is JBDistributor, IJB721Distributor {
278
278
  }
279
279
 
280
280
  /// @notice The total stake at a specific block, using the hook's checkpoints module for historical accuracy.
281
- /// @dev Uses `IVotes.getPastTotalSupply` from the hook's CHECKPOINTS module. This ensures that only NFTs
281
+ /// @dev Uses `IVotes.getPastTotalSupply` from the hook's checkpoints module. This ensures that only NFTs
282
282
  /// that existed (and were delegated) at `blockNumber` are counted, preventing late mints from diluting or
283
283
  /// capturing rewards within the current round.
284
284
  /// @param hook The hook to get the total stake for.
285
285
  /// @param blockNumber The block number to get the total staked amount at.
286
286
  /// @return total The total checkpointed voting units at the given block.
287
287
  function _totalStake(address hook, uint256 blockNumber) internal view override returns (uint256 total) {
288
- IJB721Checkpoints checkpoints = IJB721TiersHook(hook).CHECKPOINTS();
288
+ IJB721Checkpoints checkpoints = IJB721TiersHook(hook).checkpoints();
289
289
  total = IVotes(address(checkpoints)).getPastTotalSupply(blockNumber);
290
290
  }
291
291
 
@@ -311,7 +311,7 @@ contract JB721Distributor is JBDistributor, IJB721Distributor {
311
311
  returns (address owner)
312
312
  {
313
313
  // The 721 hook owns the checkpoint module; the distributor only trusts that module's historical proof.
314
- IJB721Checkpoints checkpoints = IJB721TiersHook(hook).CHECKPOINTS();
314
+ IJB721Checkpoints checkpoints = IJB721TiersHook(hook).checkpoints();
315
315
 
316
316
  // Use staticcall so older hooks without `ownerOfAt` fail closed instead of reverting the whole distribution.
317
317
  (bool success, bytes memory data) =
@@ -382,7 +382,7 @@ contract JB721Distributor is JBDistributor, IJB721Distributor {
382
382
  if (owner == address(0)) return (0, newUniqueCount);
383
383
 
384
384
  // Query the owner's checkpointed voting power at the round's snapshot block.
385
- pastVotes = IVotes(address(IJB721TiersHook(ctx.hook).CHECKPOINTS()))
385
+ pastVotes = IVotes(address(IJB721TiersHook(ctx.hook).checkpoints()))
386
386
  .getPastVotes({account: owner, timepoint: snapshotBlock});
387
387
 
388
388
  // If the snapshot owner had no voting power at round start, the token is ineligible for this round.
@@ -119,13 +119,15 @@ abstract contract JBDistributor is IJBDistributor {
119
119
  // -------------------------- constructor ---------------------------- //
120
120
  //*********************************************************************//
121
121
 
122
- /// @param roundDuration_ The duration of each round, specified in seconds.
123
- /// @param vestingRounds_ The number of rounds until tokens are fully vested.
124
- constructor(uint256 roundDuration_, uint256 vestingRounds_) {
125
- if (roundDuration_ == 0) revert JBDistributor_InvalidRoundDuration({roundDuration: roundDuration_});
122
+ /// @param initialRoundDuration The duration of each round, specified in seconds.
123
+ /// @param initialVestingRounds The number of rounds until tokens are fully vested.
124
+ constructor(uint256 initialRoundDuration, uint256 initialVestingRounds) {
125
+ if (initialRoundDuration == 0) {
126
+ revert JBDistributor_InvalidRoundDuration({roundDuration: initialRoundDuration});
127
+ }
126
128
  startingTimestamp = block.timestamp;
127
- roundDuration = roundDuration_;
128
- vestingRounds = vestingRounds_;
129
+ roundDuration = initialRoundDuration;
130
+ vestingRounds = initialVestingRounds;
129
131
  }
130
132
 
131
133
  //*********************************************************************//
@@ -202,7 +204,7 @@ abstract contract JBDistributor is IJBDistributor {
202
204
  }
203
205
  // Use balance delta to handle fee-on-transfer tokens correctly.
204
206
  uint256 balanceBefore = token.balanceOf(address(this));
205
- token.safeTransferFrom(msg.sender, address(this), amount);
207
+ token.safeTransferFrom({from: msg.sender, to: address(this), value: amount});
206
208
  amount = token.balanceOf(address(this)) - balanceBefore;
207
209
  }
208
210
  _balanceOf[hook][token] += amount;
@@ -283,7 +285,7 @@ abstract contract JBDistributor is IJBDistributor {
283
285
  JBVestingData memory vesting = vestingDataOf[hook][tokenId][token][vestedIndex];
284
286
 
285
287
  // Use `original - alreadyPaid` to include rounding dust in the remaining amount.
286
- tokenAmount += vesting.amount - mulDiv(vesting.amount, vesting.shareClaimed, MAX_SHARE);
288
+ tokenAmount += vesting.amount - mulDiv({x: vesting.amount, y: vesting.shareClaimed, denominator: MAX_SHARE});
287
289
 
288
290
  unchecked {
289
291
  ++vestedIndex;
@@ -329,11 +331,14 @@ abstract contract JBDistributor is IJBDistributor {
329
331
 
330
332
  if (lockedShare == 0 && vesting.shareClaimed < MAX_SHARE) {
331
333
  // Final unlock: compute remaining as `original - alreadyPaid` to include dust.
332
- tokenAmount += vesting.amount - mulDiv(vesting.amount, vesting.shareClaimed, MAX_SHARE);
334
+ tokenAmount += vesting.amount
335
+ - mulDiv({x: vesting.amount, y: vesting.shareClaimed, denominator: MAX_SHARE});
333
336
  } else {
334
337
  uint256 newShareClaimed = MAX_SHARE - lockedShare;
335
338
  if (newShareClaimed > vesting.shareClaimed) {
336
- tokenAmount += mulDiv(vesting.amount, newShareClaimed - vesting.shareClaimed, MAX_SHARE);
339
+ tokenAmount += mulDiv({
340
+ x: vesting.amount, y: newShareClaimed - vesting.shareClaimed, denominator: MAX_SHARE
341
+ });
337
342
  }
338
343
  }
339
344
 
@@ -542,7 +547,7 @@ abstract contract JBDistributor is IJBDistributor {
542
547
  });
543
548
  }
544
549
  } else {
545
- token.safeTransfer(beneficiary, totalTokenAmount);
550
+ token.safeTransfer({to: beneficiary, value: totalTokenAmount});
546
551
  }
547
552
  }
548
553
  // If forfeiture: _balanceOf is NOT decremented so the forfeited tokens
@@ -598,9 +603,12 @@ abstract contract JBDistributor is IJBDistributor {
598
603
  if (lockedShare == 0 && vesting.shareClaimed < MAX_SHARE) {
599
604
  // Final unlock: compute remaining amount as `original - alreadyPaid` to force
600
605
  // rounding dust out so nothing is stranded in the entry.
601
- claimAmount = vesting.amount - mulDiv(vesting.amount, vesting.shareClaimed, MAX_SHARE);
606
+ claimAmount =
607
+ vesting.amount - mulDiv({x: vesting.amount, y: vesting.shareClaimed, denominator: MAX_SHARE});
602
608
  } else if (MAX_SHARE - lockedShare > vesting.shareClaimed) {
603
- claimAmount = mulDiv(vesting.amount, MAX_SHARE - lockedShare - vesting.shareClaimed, MAX_SHARE);
609
+ claimAmount = mulDiv({
610
+ x: vesting.amount, y: MAX_SHARE - lockedShare - vesting.shareClaimed, denominator: MAX_SHARE
611
+ });
604
612
  }
605
613
 
606
614
  if (claimAmount != 0) {
@@ -682,7 +690,9 @@ abstract contract JBDistributor is IJBDistributor {
682
690
  }
683
691
 
684
692
  // Keep a reference to the amount of tokens being claimed.
685
- uint256 tokenAmount = mulDiv(distributable, _tokenStake({hook: hook, tokenId: tokenId}), totalStakeAmount);
693
+ uint256 tokenAmount = mulDiv({
694
+ x: distributable, y: _tokenStake({hook: hook, tokenId: tokenId}), denominator: totalStakeAmount
695
+ });
686
696
 
687
697
  // Skip zero-amount entries to prevent stalling latestVestedIndexOf advancement.
688
698
  if (tokenAmount == 0) {
@@ -49,14 +49,14 @@ contract JBTokenDistributor is JBDistributor, IJBTokenDistributor {
49
49
  //*********************************************************************//
50
50
 
51
51
  /// @param directory The JB directory used to verify terminal/controller callers.
52
- /// @param roundDuration_ The duration of each round, specified in seconds.
53
- /// @param vestingRounds_ The number of rounds until tokens are fully vested.
52
+ /// @param initialRoundDuration The duration of each round, specified in seconds.
53
+ /// @param initialVestingRounds The number of rounds until tokens are fully vested.
54
54
  constructor(
55
55
  IJBDirectory directory,
56
- uint256 roundDuration_,
57
- uint256 vestingRounds_
56
+ uint256 initialRoundDuration,
57
+ uint256 initialVestingRounds
58
58
  )
59
- JBDistributor(roundDuration_, vestingRounds_)
59
+ JBDistributor(initialRoundDuration, initialVestingRounds)
60
60
  {
61
61
  DIRECTORY = directory;
62
62
  }
@@ -79,7 +79,7 @@ contract JBTokenDistributor is JBDistributor, IJBTokenDistributor {
79
79
  function processSplitWith(JBSplitHookContext calldata context) external payable override {
80
80
  // Only terminals and controllers for the project can call this.
81
81
  if (
82
- !DIRECTORY.isTerminalOf(context.projectId, IJBTerminal(msg.sender))
82
+ !DIRECTORY.isTerminalOf({projectId: context.projectId, terminal: IJBTerminal(msg.sender)})
83
83
  && DIRECTORY.controllerOf(context.projectId) != IERC165(msg.sender)
84
84
  ) revert JBTokenDistributor_Unauthorized({projectId: context.projectId, caller: msg.sender});
85
85
 
@@ -160,7 +160,8 @@ contract JBTokenDistributor is JBDistributor, IJBTokenDistributor {
160
160
  if (tokenId >> 160 != 0) revert JBTokenDistributor_InvalidTokenId({tokenId: tokenId});
161
161
  // The high bits were checked above, so this cast recovers the encoded address.
162
162
  // forge-lint: disable-next-line(unsafe-typecast)
163
- tokenStakeAmount = IVotes(hook).getPastVotes(address(uint160(tokenId)), roundSnapshotBlock[currentRound()]);
163
+ address account = address(uint160(tokenId));
164
+ tokenStakeAmount = IVotes(hook).getPastVotes({account: account, timepoint: roundSnapshotBlock[currentRound()]});
164
165
  }
165
166
 
166
167
  /// @notice The total supply of votes at a specific block.