@bananapus/core-v6 0.0.16 → 0.0.18

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 (140) hide show
  1. package/ADMINISTRATION.md +1 -1
  2. package/ARCHITECTURE.md +2 -1
  3. package/AUDIT_INSTRUCTIONS.md +342 -0
  4. package/CHANGE_LOG.md +400 -0
  5. package/README.md +4 -4
  6. package/RISKS.md +171 -50
  7. package/SKILLS.md +9 -6
  8. package/USER_JOURNEYS.md +622 -0
  9. package/package.json +2 -2
  10. package/script/DeployPeriphery.s.sol +7 -1
  11. package/src/JBController.sol +5 -0
  12. package/src/JBDeadline.sol +3 -0
  13. package/src/JBDirectory.sol +2 -1
  14. package/src/JBMultiTerminal.sol +50 -9
  15. package/src/JBPermissions.sol +2 -0
  16. package/src/JBPrices.sol +8 -2
  17. package/src/JBRulesets.sol +3 -0
  18. package/src/JBSplits.sol +9 -5
  19. package/src/JBTerminalStore.sol +54 -47
  20. package/src/JBTokens.sol +3 -0
  21. package/src/interfaces/IJBTerminalStore.sol +3 -0
  22. package/src/libraries/JBFees.sol +2 -0
  23. package/src/libraries/JBMetadataResolver.sol +17 -4
  24. package/src/structs/JBBeforeCashOutRecordedContext.sol +4 -0
  25. package/test/TestAuditResponseDesignProofs.sol +434 -0
  26. package/test/TestDataHookFuzzing.sol +520 -0
  27. package/test/TestFeeFreeCashOutBypass.sol +617 -0
  28. package/test/TestL2SequencerPriceFeed.sol +292 -0
  29. package/test/TestMetadataOffsetOverflow.sol +179 -0
  30. package/test/TestMultiTerminalSurplus.sol +348 -0
  31. package/test/TestPermit2DataHook.t.sol +360 -0
  32. package/test/TestRulesetQueueing.sol +1 -2
  33. package/test/TestRulesetWeightCaching.sol +122 -124
  34. package/test/WeirdTokenTests.t.sol +37 -0
  35. package/test/regression/HoldFeesCashOutReserved.t.sol +415 -0
  36. package/test/regression/WeightCacheBoundary.t.sol +291 -0
  37. package/test/units/static/JBMultiTerminal/TestAddToBalanceOf.sol +2 -2
  38. package/test/units/static/JBMultiTerminal/TestCashOutTokensOf.sol +18 -17
  39. package/test/units/static/JBMultiTerminal/TestPay.sol +6 -4
  40. package/test/units/static/JBMultiTerminal/TestProcessHeldFeesOf.sol +206 -18
  41. package/test/units/static/JBMultiTerminal/TestUseAllowanceOf.sol +280 -0
  42. package/test/units/static/JBSplits/TestSelfManagedSplitGroups.sol +55 -12
  43. package/test/units/static/JBTerminalStore/TestRecordCashOutsFor.sol +72 -0
  44. package/docs/book.css +0 -13
  45. package/docs/book.toml +0 -12
  46. package/docs/solidity.min.js +0 -74
  47. package/docs/src/README.md +0 -703
  48. package/docs/src/SUMMARY.md +0 -94
  49. package/docs/src/src/JBChainlinkV3PriceFeed.sol/contract.JBChainlinkV3PriceFeed.md +0 -83
  50. package/docs/src/src/JBChainlinkV3SequencerPriceFeed.sol/contract.JBChainlinkV3SequencerPriceFeed.md +0 -88
  51. package/docs/src/src/JBController.sol/contract.JBController.md +0 -1121
  52. package/docs/src/src/JBDeadline.sol/contract.JBDeadline.md +0 -84
  53. package/docs/src/src/JBDirectory.sol/contract.JBDirectory.md +0 -294
  54. package/docs/src/src/JBERC20.sol/contract.JBERC20.md +0 -190
  55. package/docs/src/src/JBFeelessAddresses.sol/contract.JBFeelessAddresses.md +0 -80
  56. package/docs/src/src/JBFundAccessLimits.sol/contract.JBFundAccessLimits.md +0 -253
  57. package/docs/src/src/JBMultiTerminal.sol/contract.JBMultiTerminal.md +0 -1472
  58. package/docs/src/src/JBPermissions.sol/contract.JBPermissions.md +0 -199
  59. package/docs/src/src/JBPrices.sol/contract.JBPrices.md +0 -154
  60. package/docs/src/src/JBProjects.sol/contract.JBProjects.md +0 -131
  61. package/docs/src/src/JBRulesets.sol/contract.JBRulesets.md +0 -677
  62. package/docs/src/src/JBSplits.sol/contract.JBSplits.md +0 -237
  63. package/docs/src/src/JBTerminalStore.sol/contract.JBTerminalStore.md +0 -591
  64. package/docs/src/src/JBTokens.sol/contract.JBTokens.md +0 -353
  65. package/docs/src/src/README.md +0 -25
  66. package/docs/src/src/abstract/JBControlled.sol/abstract.JBControlled.md +0 -64
  67. package/docs/src/src/abstract/JBPermissioned.sol/abstract.JBPermissioned.md +0 -84
  68. package/docs/src/src/abstract/README.md +0 -5
  69. package/docs/src/src/enums/JBApprovalStatus.sol/enum.JBApprovalStatus.md +0 -17
  70. package/docs/src/src/enums/README.md +0 -4
  71. package/docs/src/src/interfaces/IJBCashOutHook.sol/interface.IJBCashOutHook.md +0 -29
  72. package/docs/src/src/interfaces/IJBCashOutTerminal.sol/interface.IJBCashOutTerminal.md +0 -57
  73. package/docs/src/src/interfaces/IJBControlled.sol/interface.IJBControlled.md +0 -12
  74. package/docs/src/src/interfaces/IJBController.sol/interface.IJBController.md +0 -334
  75. package/docs/src/src/interfaces/IJBDirectory.sol/interface.IJBDirectory.md +0 -108
  76. package/docs/src/src/interfaces/IJBDirectoryAccessControl.sol/interface.IJBDirectoryAccessControl.md +0 -19
  77. package/docs/src/src/interfaces/IJBFeeTerminal.sol/interface.IJBFeeTerminal.md +0 -91
  78. package/docs/src/src/interfaces/IJBFeelessAddresses.sol/interface.IJBFeelessAddresses.md +0 -26
  79. package/docs/src/src/interfaces/IJBFundAccessLimits.sol/interface.IJBFundAccessLimits.md +0 -88
  80. package/docs/src/src/interfaces/IJBMigratable.sol/interface.IJBMigratable.md +0 -29
  81. package/docs/src/src/interfaces/IJBMultiTerminal.sol/interface.IJBMultiTerminal.md +0 -50
  82. package/docs/src/src/interfaces/IJBPayHook.sol/interface.IJBPayHook.md +0 -28
  83. package/docs/src/src/interfaces/IJBPayoutTerminal.sol/interface.IJBPayoutTerminal.md +0 -105
  84. package/docs/src/src/interfaces/IJBPermissioned.sol/interface.IJBPermissioned.md +0 -12
  85. package/docs/src/src/interfaces/IJBPermissions.sol/interface.IJBPermissions.md +0 -74
  86. package/docs/src/src/interfaces/IJBPermitTerminal.sol/interface.IJBPermitTerminal.md +0 -15
  87. package/docs/src/src/interfaces/IJBPriceFeed.sol/interface.IJBPriceFeed.md +0 -12
  88. package/docs/src/src/interfaces/IJBPrices.sol/interface.IJBPrices.md +0 -74
  89. package/docs/src/src/interfaces/IJBProjectUriRegistry.sol/interface.IJBProjectUriRegistry.md +0 -19
  90. package/docs/src/src/interfaces/IJBProjects.sol/interface.IJBProjects.md +0 -49
  91. package/docs/src/src/interfaces/IJBRulesetApprovalHook.sol/interface.IJBRulesetApprovalHook.md +0 -35
  92. package/docs/src/src/interfaces/IJBRulesetDataHook.sol/interface.IJBRulesetDataHook.md +0 -97
  93. package/docs/src/src/interfaces/IJBRulesets.sol/interface.IJBRulesets.md +0 -165
  94. package/docs/src/src/interfaces/IJBSplitHook.sol/interface.IJBSplitHook.md +0 -31
  95. package/docs/src/src/interfaces/IJBSplits.sol/interface.IJBSplits.md +0 -35
  96. package/docs/src/src/interfaces/IJBTerminal.sol/interface.IJBTerminal.md +0 -141
  97. package/docs/src/src/interfaces/IJBTerminalStore.sol/interface.IJBTerminalStore.md +0 -198
  98. package/docs/src/src/interfaces/IJBToken.sol/interface.IJBToken.md +0 -54
  99. package/docs/src/src/interfaces/IJBTokenUriResolver.sol/interface.IJBTokenUriResolver.md +0 -12
  100. package/docs/src/src/interfaces/IJBTokens.sol/interface.IJBTokens.md +0 -151
  101. package/docs/src/src/interfaces/README.md +0 -33
  102. package/docs/src/src/libraries/JBCashOuts.sol/library.JBCashOuts.md +0 -40
  103. package/docs/src/src/libraries/JBConstants.sol/library.JBConstants.md +0 -52
  104. package/docs/src/src/libraries/JBCurrencyIds.sol/library.JBCurrencyIds.md +0 -19
  105. package/docs/src/src/libraries/JBFees.sol/library.JBFees.md +0 -52
  106. package/docs/src/src/libraries/JBFixedPointNumber.sol/library.JBFixedPointNumber.md +0 -12
  107. package/docs/src/src/libraries/JBMetadataResolver.sol/library.JBMetadataResolver.md +0 -242
  108. package/docs/src/src/libraries/JBRulesetMetadataResolver.sol/library.JBRulesetMetadataResolver.md +0 -180
  109. package/docs/src/src/libraries/JBSplitGroupIds.sol/library.JBSplitGroupIds.md +0 -14
  110. package/docs/src/src/libraries/JBSurplus.sol/library.JBSurplus.md +0 -44
  111. package/docs/src/src/libraries/README.md +0 -12
  112. package/docs/src/src/periphery/JBDeadline1Day.sol/contract.JBDeadline1Day.md +0 -15
  113. package/docs/src/src/periphery/JBDeadline3Days.sol/contract.JBDeadline3Days.md +0 -15
  114. package/docs/src/src/periphery/JBDeadline3Hours.sol/contract.JBDeadline3Hours.md +0 -15
  115. package/docs/src/src/periphery/JBDeadline7Days.sol/contract.JBDeadline7Days.md +0 -15
  116. package/docs/src/src/periphery/JBMatchingPriceFeed.sol/contract.JBMatchingPriceFeed.md +0 -22
  117. package/docs/src/src/periphery/README.md +0 -8
  118. package/docs/src/src/structs/JBAccountingContext.sol/struct.JBAccountingContext.md +0 -20
  119. package/docs/src/src/structs/JBAfterCashOutRecordedContext.sol/struct.JBAfterCashOutRecordedContext.md +0 -43
  120. package/docs/src/src/structs/JBAfterPayRecordedContext.sol/struct.JBAfterPayRecordedContext.md +0 -42
  121. package/docs/src/src/structs/JBBeforeCashOutRecordedContext.sol/struct.JBBeforeCashOutRecordedContext.md +0 -45
  122. package/docs/src/src/structs/JBBeforePayRecordedContext.sol/struct.JBBeforePayRecordedContext.md +0 -41
  123. package/docs/src/src/structs/JBCashOutHookSpecification.sol/struct.JBCashOutHookSpecification.md +0 -22
  124. package/docs/src/src/structs/JBCurrencyAmount.sol/struct.JBCurrencyAmount.md +0 -17
  125. package/docs/src/src/structs/JBFee.sol/struct.JBFee.md +0 -20
  126. package/docs/src/src/structs/JBFundAccessLimitGroup.sol/struct.JBFundAccessLimitGroup.md +0 -39
  127. package/docs/src/src/structs/JBPayHookSpecification.sol/struct.JBPayHookSpecification.md +0 -22
  128. package/docs/src/src/structs/JBPermissionsData.sol/struct.JBPermissionsData.md +0 -21
  129. package/docs/src/src/structs/JBRuleset.sol/struct.JBRuleset.md +0 -55
  130. package/docs/src/src/structs/JBRulesetConfig.sol/struct.JBRulesetConfig.md +0 -51
  131. package/docs/src/src/structs/JBRulesetMetadata.sol/struct.JBRulesetMetadata.md +0 -79
  132. package/docs/src/src/structs/JBRulesetWeightCache.sol/struct.JBRulesetWeightCache.md +0 -16
  133. package/docs/src/src/structs/JBRulesetWithMetadata.sol/struct.JBRulesetWithMetadata.md +0 -16
  134. package/docs/src/src/structs/JBSingleAllowance.sol/struct.JBSingleAllowance.md +0 -26
  135. package/docs/src/src/structs/JBSplit.sol/struct.JBSplit.md +0 -49
  136. package/docs/src/src/structs/JBSplitGroup.sol/struct.JBSplitGroup.md +0 -17
  137. package/docs/src/src/structs/JBSplitHookContext.sol/struct.JBSplitHookContext.md +0 -29
  138. package/docs/src/src/structs/JBTerminalConfig.sol/struct.JBTerminalConfig.md +0 -16
  139. package/docs/src/src/structs/JBTokenAmount.sol/struct.JBTokenAmount.md +0 -23
  140. package/docs/src/src/structs/README.md +0 -25
@@ -57,9 +57,9 @@ contract TestSelfManagedSplitGroups_Local is JBSplitsSetup {
57
57
  // ──────────────────
58
58
 
59
59
  function test_CallerCanSetSplitsInOwnGroupNamespace() external {
60
- // Any contract can set splits when groupId's lower 160 bits == msg.sender.
60
+ // Self-auth requires non-zero upper 96 bits + lower 160 bits == msg.sender.
61
61
  address caller = makeAddr("hookContract");
62
- uint256 groupId = uint256(uint160(caller));
62
+ uint256 groupId = (1 << 160) | uint256(uint160(caller));
63
63
 
64
64
  JBSplitGroup[] memory groups = _makeSplitGroup(groupId, JBConstants.SPLITS_TOTAL_PERCENT / 2, _bene);
65
65
 
@@ -121,7 +121,7 @@ contract TestSelfManagedSplitGroups_Local is JBSplitsSetup {
121
121
  function test_CallerCanSetMultipleSplitsInOwnGroup() external {
122
122
  // Multiple splits in the same self-managed group.
123
123
  address caller = makeAddr("hookContract");
124
- uint256 groupId = uint256(uint160(caller));
124
+ uint256 groupId = (1 << 160) | uint256(uint160(caller));
125
125
 
126
126
  address payable bene1 = payable(makeAddr("bene1"));
127
127
  address payable bene2 = payable(makeAddr("bene2"));
@@ -158,7 +158,7 @@ contract TestSelfManagedSplitGroups_Local is JBSplitsSetup {
158
158
  function test_CallerCanOverwriteOwnSplits() external {
159
159
  // Caller can overwrite their own splits.
160
160
  address caller = makeAddr("hookContract");
161
- uint256 groupId = uint256(uint160(caller));
161
+ uint256 groupId = (1 << 160) | uint256(uint160(caller));
162
162
 
163
163
  address payable beneOld = payable(makeAddr("beneOld"));
164
164
  address payable beneNew = payable(makeAddr("beneNew"));
@@ -183,7 +183,7 @@ contract TestSelfManagedSplitGroups_Local is JBSplitsSetup {
183
183
  function test_SelfManagedSplitsEmitSetSplitEvent() external {
184
184
  // Setting self-managed splits emits SetSplit with correct caller.
185
185
  address caller = makeAddr("hookContract");
186
- uint256 groupId = uint256(uint160(caller));
186
+ uint256 groupId = (1 << 160) | uint256(uint160(caller));
187
187
 
188
188
  JBSplitGroup[] memory groups = _makeSplitGroup(groupId, JBConstants.SPLITS_TOTAL_PERCENT, _bene);
189
189
 
@@ -197,7 +197,7 @@ contract TestSelfManagedSplitGroups_Local is JBSplitsSetup {
197
197
  function test_SelfManagedSplitsWorkAcrossRulesets() external {
198
198
  // Caller can set splits in the same group but different rulesets.
199
199
  address caller = makeAddr("hookContract");
200
- uint256 groupId = uint256(uint160(caller));
200
+ uint256 groupId = (1 << 160) | uint256(uint160(caller));
201
201
 
202
202
  uint256 rulesetA = 100;
203
203
  uint256 rulesetB = 200;
@@ -227,7 +227,7 @@ contract TestSelfManagedSplitGroups_Local is JBSplitsSetup {
227
227
 
228
228
  function test_SelfManagedSplitsRevertOnZeroPercent() external {
229
229
  address caller = makeAddr("hookContract");
230
- uint256 groupId = uint256(uint160(caller));
230
+ uint256 groupId = (1 << 160) | uint256(uint160(caller));
231
231
 
232
232
  JBSplitGroup[] memory groups = new JBSplitGroup[](1);
233
233
  JBSplit[] memory splits = new JBSplit[](1);
@@ -248,7 +248,7 @@ contract TestSelfManagedSplitGroups_Local is JBSplitsSetup {
248
248
 
249
249
  function test_SelfManagedSplitsRevertOnExcessPercent() external {
250
250
  address caller = makeAddr("hookContract");
251
- uint256 groupId = uint256(uint160(caller));
251
+ uint256 groupId = (1 << 160) | uint256(uint160(caller));
252
252
 
253
253
  JBSplitGroup[] memory groups = new JBSplitGroup[](1);
254
254
  JBSplit[] memory splits = new JBSplit[](2);
@@ -278,7 +278,7 @@ contract TestSelfManagedSplitGroups_Local is JBSplitsSetup {
278
278
  function test_SelfManagedSplitsEnforceLocks() external {
279
279
  // Locked splits in a self-managed group cannot be removed.
280
280
  address caller = makeAddr("hookContract");
281
- uint256 groupId = uint256(uint160(caller));
281
+ uint256 groupId = (1 << 160) | uint256(uint160(caller));
282
282
 
283
283
  // Set a locked split.
284
284
  JBSplitGroup[] memory groups = new JBSplitGroup[](1);
@@ -357,6 +357,46 @@ contract TestSelfManagedSplitGroups_Local is JBSplitsSetup {
357
357
  _splits.setSplitGroupsOf(_projectId, _rulesetId, groups);
358
358
  }
359
359
 
360
+ // ──────────────── Bare-address groupIds require controller auth
361
+ // ───────────────
362
+
363
+ function test_BareAddressGroupIdRequiresControllerEvenForMatchingSender() external {
364
+ // A contract cannot self-auth for groupId == uint256(uint160(self)) (upper 96 bits = 0).
365
+ // This prevents token contracts from hijacking terminal payout splits.
366
+ address caller = makeAddr("maliciousToken");
367
+ uint256 groupId = uint256(uint160(caller)); // bare address, upper bits = 0
368
+
369
+ JBSplitGroup[] memory groups = _makeSplitGroup(groupId, JBConstants.SPLITS_TOTAL_PERCENT, _bene);
370
+
371
+ _mockController(makeAddr("realController"));
372
+
373
+ vm.prank(caller);
374
+ vm.expectRevert(
375
+ abi.encodeWithSelector(
376
+ JBControlled.JBControlled_ControllerUnauthorized.selector, makeAddr("realController")
377
+ )
378
+ );
379
+ _splits.setSplitGroupsOf(_projectId, _rulesetId, groups);
380
+ }
381
+
382
+ function test_BareAddressGroupIdSucceedsWithControllerAuth() external {
383
+ // The controller CAN still set splits for bare-address groupIds (terminal payout groups).
384
+ address controller = makeAddr("controller");
385
+ address token = makeAddr("someToken");
386
+ uint256 groupId = uint256(uint160(token));
387
+
388
+ JBSplitGroup[] memory groups = _makeSplitGroup(groupId, JBConstants.SPLITS_TOTAL_PERCENT, _bene);
389
+
390
+ _mockController(controller);
391
+
392
+ vm.prank(controller);
393
+ _splits.setSplitGroupsOf(_projectId, _rulesetId, groups);
394
+
395
+ JBSplit[] memory result = _splits.splitsOf(_projectId, _rulesetId, groupId);
396
+ assertEq(result.length, 1);
397
+ assertEq(result[0].beneficiary, _bene);
398
+ }
399
+
360
400
  // ───────────────────── Controller can still set any group
361
401
  // ──────────────────
362
402
 
@@ -382,9 +422,10 @@ contract TestSelfManagedSplitGroups_Local is JBSplitsSetup {
382
422
  // ─────────────────────────────
383
423
 
384
424
  function test_MixedSelfManagedAndControllerGroupsInOneCall() external {
385
- // A single setSplitGroupsOf call with one self-managed group and one controller-gated group.
425
+ // A single setSplitGroupsOf call with one self-managed group (non-zero upper bits) and one controller-gated
426
+ // group.
386
427
  address caller = makeAddr("hookContract");
387
- uint256 selfGroupId = uint256(uint160(caller));
428
+ uint256 selfGroupId = (1 << 160) | uint256(uint160(caller));
388
429
  uint256 otherGroupId = 0;
389
430
 
390
431
  // Mock: caller IS the controller.
@@ -427,7 +468,7 @@ contract TestSelfManagedSplitGroups_Local is JBSplitsSetup {
427
468
  function test_MixedCallRevertsIfNonControllerSetsOtherGroup() external {
428
469
  // A call with one self-managed group (ok) and one non-owned group (reverts) in the same call.
429
470
  address caller = makeAddr("hookContract");
430
- uint256 selfGroupId = uint256(uint160(caller));
471
+ uint256 selfGroupId = (1 << 160) | uint256(uint160(caller));
431
472
  uint256 otherGroupId = 0;
432
473
 
433
474
  _mockController(makeAddr("realController"));
@@ -472,6 +513,8 @@ contract TestSelfManagedSplitGroups_Local is JBSplitsSetup {
472
513
  function testFuzz_AnyAddressCanSetOwnNamespace(address caller, uint96 upperBits, uint32 percent) external {
473
514
  vm.assume(caller != address(0));
474
515
  vm.assume(percent > 0 && percent <= JBConstants.SPLITS_TOTAL_PERCENT);
516
+ // Self-auth requires non-zero upper bits.
517
+ vm.assume(upperBits > 0);
475
518
 
476
519
  uint256 groupId = (uint256(upperBits) << 160) | uint256(uint160(caller));
477
520
 
@@ -336,6 +336,7 @@ contract TestRecordCashOutsFor_Local is JBTerminalStoreSetup {
336
336
  cashOutCount: _cashOutCount,
337
337
  accountingContext: _accountingContexts,
338
338
  balanceAccountingContexts: _balanceContexts,
339
+ beneficiaryIsFeeless: false,
339
340
  metadata: ""
340
341
  });
341
342
  }
@@ -369,6 +370,7 @@ contract TestRecordCashOutsFor_Local is JBTerminalStoreSetup {
369
370
  cashOutCount: _cashOutCount,
370
371
  accountingContext: _accountingContexts,
371
372
  balanceAccountingContexts: _balanceContexts,
373
+ beneficiaryIsFeeless: false,
372
374
  metadata: ""
373
375
  });
374
376
 
@@ -420,6 +422,7 @@ contract TestRecordCashOutsFor_Local is JBTerminalStoreSetup {
420
422
  surplus: _reclaimedTokenAmount,
421
423
  useTotalSurplus: true,
422
424
  cashOutTaxRate: 0,
425
+ beneficiaryIsFeeless: false,
423
426
  metadata: ""
424
427
  });
425
428
 
@@ -442,6 +445,7 @@ contract TestRecordCashOutsFor_Local is JBTerminalStoreSetup {
442
445
  cashOutCount: _cashOutCount,
443
446
  accountingContext: _accountingContexts,
444
447
  balanceAccountingContexts: _balanceContexts,
448
+ beneficiaryIsFeeless: false,
445
449
  metadata: ""
446
450
  });
447
451
 
@@ -487,10 +491,78 @@ contract TestRecordCashOutsFor_Local is JBTerminalStoreSetup {
487
491
  cashOutCount: _cashOutCount,
488
492
  accountingContext: _accountingContexts,
489
493
  balanceAccountingContexts: _balanceContexts,
494
+ beneficiaryIsFeeless: false,
490
495
  metadata: ""
491
496
  });
492
497
  }
493
498
 
499
+ function test_GivenBeneficiaryIsFeeless_DataHookReceivesTrue()
500
+ external
501
+ whenCurrentRulesetUseTotalSurplusForCashOutsEqTrueWithHook
502
+ {
503
+ // it will pass beneficiaryIsFeeless=true through to the data hook context
504
+
505
+ // mock JBController totalTokenSupplyWithReservedTokensOf
506
+ mockExpect(
507
+ address(_controller),
508
+ abi.encodeCall(IJBController.totalTokenSupplyWithReservedTokensOf, (_projectId)),
509
+ abi.encode(_totalSupply)
510
+ );
511
+
512
+ // call params
513
+ JBAccountingContext memory _accountingContexts =
514
+ JBAccountingContext({token: address(_token), decimals: 18, currency: _currency});
515
+ JBAccountingContext[] memory _balanceContexts = new JBAccountingContext[](1);
516
+
517
+ _balanceContexts[0] = JBAccountingContext({token: address(_token), decimals: 18, currency: _currency});
518
+
519
+ uint256 _cashOutCount = 1e18;
520
+ uint256 expectedCashOuts = mulDiv(3e18, _cashOutCount, _totalSupply);
521
+
522
+ // Create the expected context — beneficiaryIsFeeless should be true.
523
+ JBBeforeCashOutRecordedContext memory _context = JBBeforeCashOutRecordedContext({
524
+ terminal: address(this),
525
+ holder: address(this),
526
+ projectId: _projectId,
527
+ rulesetId: uint48(block.timestamp),
528
+ cashOutCount: _cashOutCount,
529
+ totalSupply: _totalSupply,
530
+ surplus: JBTokenAmount({
531
+ token: _accountingContexts.token,
532
+ value: 3e18,
533
+ decimals: _accountingContexts.decimals,
534
+ currency: _accountingContexts.currency
535
+ }),
536
+ useTotalSurplus: true,
537
+ cashOutTaxRate: 0,
538
+ beneficiaryIsFeeless: true,
539
+ metadata: ""
540
+ });
541
+
542
+ // return data
543
+ JBCashOutHookSpecification[] memory _spec = new JBCashOutHookSpecification[](1);
544
+ _spec[0] = JBCashOutHookSpecification({hook: _cashOutHook, amount: 0, metadata: ""});
545
+
546
+ // The mock will only match if the context has beneficiaryIsFeeless=true.
547
+ mockExpect(
548
+ address(_dataHook),
549
+ abi.encodeCall(IJBRulesetDataHook.beforeCashOutRecordedWith, (_context)),
550
+ abi.encode(0, 1e18, _totalSupply, _spec)
551
+ );
552
+
553
+ (, uint256 reclaimed,,) = _store.recordCashOutFor({
554
+ holder: address(this),
555
+ projectId: _projectId,
556
+ cashOutCount: _cashOutCount,
557
+ accountingContext: _accountingContexts,
558
+ balanceAccountingContexts: _balanceContexts,
559
+ beneficiaryIsFeeless: true,
560
+ metadata: ""
561
+ });
562
+
563
+ assertEq(expectedCashOuts, reclaimed);
564
+ }
565
+
494
566
  // Probably unnecessary even though it may give us a bit of cov %.. skipping for now
495
567
  /* function test_WhenTheCurrentRulesetUseTotalSurplusForCashOutsEqFalse() external {
496
568
  // it will use the standard surplus calculation
package/docs/book.css DELETED
@@ -1,13 +0,0 @@
1
- table {
2
- margin: 0 auto;
3
- border-collapse: collapse;
4
- width: 100%;
5
- }
6
-
7
- table td:first-child {
8
- width: 15%;
9
- }
10
-
11
- table td:nth-child(2) {
12
- width: 25%;
13
- }
package/docs/book.toml DELETED
@@ -1,12 +0,0 @@
1
- [book]
2
- src = "src"
3
- title = ""
4
-
5
- [output.html]
6
- no-section-label = true
7
- additional-js = ["solidity.min.js"]
8
- additional-css = ["book.css"]
9
- git-repository-url = "https://github.com/Bananapus/nana-core"
10
-
11
- [output.html.fold]
12
- enable = true
@@ -1,74 +0,0 @@
1
- hljs.registerLanguage("solidity",(()=>{"use strict";function e(){try{return!0
2
- }catch(e){return!1}}
3
- var a=/-?(\b0[xX]([a-fA-F0-9]_?)*[a-fA-F0-9]|(\b[1-9](_?\d)*(\.((\d_?)*\d)?)?|\.\d(_?\d)*)([eE][-+]?\d(_?\d)*)?|\b0)(?!\w|\$)/
4
- ;e()&&(a=a.source.replace(/\\b/g,"(?<!\\$)\\b"));var s={className:"number",
5
- begin:a,relevance:0},n={
6
- keyword:"assembly let function if switch case default for leave break continue u256 jump jumpi stop return revert selfdestruct invalid",
7
- built_in:"add sub mul div sdiv mod smod exp not lt gt slt sgt eq iszero and or xor byte shl shr sar addmod mulmod signextend keccak256 pc pop dup1 dup2 dup3 dup4 dup5 dup6 dup7 dup8 dup9 dup10 dup11 dup12 dup13 dup14 dup15 dup16 swap1 swap2 swap3 swap4 swap5 swap6 swap7 swap8 swap9 swap10 swap11 swap12 swap13 swap14 swap15 swap16 mload mstore mstore8 sload sstore msize gas address balance selfbalance caller callvalue calldataload calldatasize calldatacopy codesize codecopy extcodesize extcodecopy returndatasize returndatacopy extcodehash create create2 call callcode delegatecall staticcall log0 log1 log2 log3 log4 chainid origin gasprice basefee blockhash coinbase timestamp number difficulty gaslimit",
8
- literal:"true false"},i={className:"string",
9
- begin:/\bhex'(([0-9a-fA-F]{2}_?)*[0-9a-fA-F]{2})?'/},t={className:"string",
10
- begin:/\bhex"(([0-9a-fA-F]{2}_?)*[0-9a-fA-F]{2})?"/};function r(e){
11
- return e.inherit(e.APOS_STRING_MODE,{begin:/(\bunicode)?'/})}function l(e){
12
- return e.inherit(e.QUOTE_STRING_MODE,{begin:/(\bunicode)?"/})}var o={
13
- SOL_ASSEMBLY_KEYWORDS:n,baseAssembly:e=>{
14
- var a=r(e),o=l(e),c=/[A-Za-z_$][A-Za-z_$0-9.]*/,d=e.inherit(e.TITLE_MODE,{
15
- begin:/[A-Za-z$_][0-9A-Za-z$_]*/,lexemes:c,keywords:n}),u={className:"params",
16
- begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,lexemes:c,keywords:n,
17
- contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,o,s]},_={
18
- className:"operator",begin:/:=|->/};return{keywords:n,lexemes:c,
19
- contains:[a,o,i,t,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,s,_,{
20
- className:"function",lexemes:c,beginKeywords:"function",end:"{",excludeEnd:!0,
21
- contains:[d,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,_]}]}},
22
- solAposStringMode:r,solQuoteStringMode:l,HEX_APOS_STRING_MODE:i,
23
- HEX_QUOTE_STRING_MODE:t,SOL_NUMBER:s,isNegativeLookbehindAvailable:e}
24
- ;const{baseAssembly:c,solAposStringMode:d,solQuoteStringMode:u,HEX_APOS_STRING_MODE:_,HEX_QUOTE_STRING_MODE:m,SOL_NUMBER:b,isNegativeLookbehindAvailable:E}=o
25
- ;return e=>{for(var a=d(e),s=u(e),n=[],i=0;i<32;i++)n[i]=i+1
26
- ;var t=n.map((e=>8*e)),r=[];for(i=0;i<=80;i++)r[i]=i
27
- ;var l=n.map((e=>"bytes"+e)).join(" ")+" ",o=t.map((e=>"uint"+e)).join(" ")+" ",g=t.map((e=>"int"+e)).join(" ")+" ",M=[].concat.apply([],t.map((e=>r.map((a=>e+"x"+a))))),p={
28
- keyword:"var bool string int uint "+g+o+"byte bytes "+l+"fixed ufixed "+M.map((e=>"fixed"+e)).join(" ")+" "+M.map((e=>"ufixed"+e)).join(" ")+" enum struct mapping address new delete if else for while continue break return throw emit try catch revert unchecked _ function modifier event constructor fallback receive error virtual override constant immutable anonymous indexed storage memory calldata external public internal payable pure view private returns import from as using pragma contract interface library is abstract type assembly",
29
- literal:"true false wei gwei szabo finney ether seconds minutes hours days weeks years",
30
- built_in:"self this super selfdestruct suicide now msg block tx abi blockhash gasleft assert require Error Panic sha3 sha256 keccak256 ripemd160 ecrecover addmod mulmod log0 log1 log2 log3 log4"
31
- },O={className:"operator",begin:/[+\-!~*\/%<>&^|=]/
32
- },C=/[A-Za-z_$][A-Za-z_$0-9]*/,N={className:"params",begin:/\(/,end:/\)/,
33
- excludeBegin:!0,excludeEnd:!0,lexemes:C,keywords:p,
34
- contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,s,b,"self"]},f={
35
- begin:/\.\s*/,end:/[^A-Za-z0-9$_\.]/,excludeBegin:!0,excludeEnd:!0,keywords:{
36
- built_in:"gas value selector address length push pop send transfer call callcode delegatecall staticcall balance code codehash wrap unwrap name creationCode runtimeCode interfaceId min max"
37
- },relevance:2},y=e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][0-9A-Za-z$_]*/,
38
- lexemes:C,keywords:p}),w={className:"built_in",
39
- begin:(E()?"(?<!\\$)\\b":"\\b")+"(gas|value|salt)(?=:)"};function x(e,a){return{
40
- begin:(E()?"(?<!\\$)\\b":"\\b")+e+"\\.\\s*",end:/[^A-Za-z0-9$_\.]/,
41
- excludeBegin:!1,excludeEnd:!0,lexemes:C,keywords:{built_in:e+" "+a},
42
- contains:[f],relevance:10}}var h=c(e),v=e.inherit(h,{
43
- contains:h.contains.concat([{begin:/\./,end:/[^A-Za-z0-9$.]/,excludeBegin:!0,
44
- excludeEnd:!0,keywords:{built_in:"slot offset length address selector"},
45
- relevance:2},{begin:/_/,end:/[^A-Za-z0-9$.]/,excludeBegin:!0,excludeEnd:!0,
46
- keywords:{built_in:"slot offset"},relevance:2}])});return{aliases:["sol"],
47
- keywords:p,lexemes:C,
48
- contains:[a,s,_,m,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,b,w,O,{
49
- className:"function",lexemes:C,
50
- beginKeywords:"function modifier event constructor fallback receive error",
51
- end:/[{;]/,excludeEnd:!0,
52
- contains:[y,N,w,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],illegal:/%/
53
- },x("msg","gas value data sender sig"),x("block","blockhash coinbase difficulty gaslimit basefee number timestamp chainid"),x("tx","gasprice origin"),x("abi","decode encode encodePacked encodeWithSelector encodeWithSignature encodeCall"),x("bytes","concat"),f,{
54
- className:"class",lexemes:C,beginKeywords:"contract interface library",end:"{",
55
- excludeEnd:!0,illegal:/[:"\[\]]/,contains:[{beginKeywords:"is",lexemes:C
56
- },y,N,w,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{lexemes:C,
57
- beginKeywords:"struct enum",end:"{",excludeEnd:!0,illegal:/[:"\[\]]/,
58
- contains:[y,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{
59
- beginKeywords:"import",end:";",lexemes:C,keywords:"import from as",
60
- contains:[y,a,s,_,m,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,O]},{
61
- beginKeywords:"using",end:";",lexemes:C,keywords:"using for",
62
- contains:[y,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,O]},{className:"meta",
63
- beginKeywords:"pragma",end:";",lexemes:C,keywords:{
64
- keyword:"pragma solidity experimental abicoder",
65
- built_in:"ABIEncoderV2 SMTChecker v1 v2"},
66
- contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.inherit(a,{
67
- className:"meta-string"}),e.inherit(s,{className:"meta-string"})]},{
68
- beginKeywords:"assembly",end:/\b\B/,
69
- contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.inherit(v,{begin:"{",
70
- end:"}",endsParent:!0,contains:v.contains.concat([e.inherit(v,{begin:"{",
71
- end:"}",contains:v.contains.concat(["self"])})])})]}],illegal:/#/}}})());
72
-
73
- // Ugly hack to reload HLJS
74
- hljs.initHighlightingOnLoad();