@bananapus/core-v6 0.0.37 → 0.0.39

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 (324) hide show
  1. package/foundry.lock +1 -7
  2. package/foundry.toml +1 -1
  3. package/package.json +19 -7
  4. package/src/JBChainlinkV3PriceFeed.sol +4 -1
  5. package/src/JBChainlinkV3SequencerPriceFeed.sol +4 -2
  6. package/src/JBController.sol +71 -44
  7. package/src/JBDeadline.sol +4 -4
  8. package/src/JBDirectory.sol +34 -32
  9. package/src/JBERC20.sol +5 -4
  10. package/src/JBFeelessAddresses.sol +6 -3
  11. package/src/JBFundAccessLimits.sol +25 -21
  12. package/src/JBMultiTerminal.sol +121 -84
  13. package/src/JBPermissions.sol +34 -37
  14. package/src/JBPrices.sol +23 -18
  15. package/src/JBProjects.sol +6 -3
  16. package/src/JBRulesets.sol +44 -41
  17. package/src/JBSplits.sol +18 -16
  18. package/src/JBTerminalStore.sol +32 -25
  19. package/src/JBTokens.sol +36 -26
  20. package/src/abstract/JBControlled.sol +3 -1
  21. package/src/abstract/JBPermissioned.sol +3 -1
  22. package/src/enums/JBApprovalStatus.sol +7 -1
  23. package/src/interfaces/IJBController.sol +7 -3
  24. package/src/interfaces/IJBDirectory.sol +3 -1
  25. package/src/interfaces/IJBMultiTerminal.sol +3 -2
  26. package/src/interfaces/IJBPermissions.sol +2 -1
  27. package/src/interfaces/IJBPrices.sol +3 -1
  28. package/src/interfaces/IJBRulesets.sol +2 -1
  29. package/src/interfaces/IJBSplits.sol +2 -1
  30. package/src/interfaces/IJBTerminal.sol +3 -1
  31. package/src/interfaces/IJBTerminalStore.sol +3 -1
  32. package/src/interfaces/IJBTokens.sol +2 -1
  33. package/src/libraries/JBCashOuts.sol +6 -1
  34. package/src/libraries/JBConstants.sol +12 -3
  35. package/src/libraries/JBCurrencyIds.sol +2 -0
  36. package/src/libraries/JBFees.sol +52 -10
  37. package/src/libraries/JBFixedPointNumber.sol +2 -0
  38. package/src/libraries/JBPayoutSplitGroupLib.sol +7 -4
  39. package/src/libraries/JBRulesetMetadataResolver.sol +4 -0
  40. package/src/libraries/JBSplitGroupIds.sol +2 -1
  41. package/src/libraries/JBSurplus.sol +3 -1
  42. package/src/periphery/JBMatchingPriceFeed.sol +3 -1
  43. package/src/structs/JBAccountingContext.sol +7 -4
  44. package/src/structs/JBFundAccessLimitGroup.sol +10 -17
  45. package/src/structs/JBRuleset.sol +18 -26
  46. package/src/structs/JBRulesetConfig.sol +13 -25
  47. package/src/structs/JBRulesetMetadata.sol +25 -32
  48. package/test/mock/MockMaliciousBeneficiary.sol +15 -15
  49. package/ADMINISTRATION.md +0 -103
  50. package/ARCHITECTURE.md +0 -133
  51. package/AUDIT_INSTRUCTIONS.md +0 -139
  52. package/RISKS.md +0 -215
  53. package/SKILLS.md +0 -55
  54. package/STYLE_GUIDE.md +0 -610
  55. package/USER_JOURNEYS.md +0 -215
  56. package/script/Deploy.s.sol +0 -124
  57. package/script/DeployPeriphery.s.sol +0 -354
  58. package/slither-ci.config.json +0 -10
  59. package/test/AuditFixes.t.sol +0 -808
  60. package/test/ComprehensiveInvariant.t.sol +0 -306
  61. package/test/CoreExploitTests.t.sol +0 -2741
  62. package/test/EconomicSimulation.t.sol +0 -348
  63. package/test/EntryPointPermutations.t.sol +0 -684
  64. package/test/FlashLoanAttacks.t.sol +0 -797
  65. package/test/PermissionEscalation.t.sol +0 -711
  66. package/test/PermissionsInvariant.t.sol +0 -403
  67. package/test/RulesetTransitions.t.sol +0 -713
  68. package/test/SplitLoopTests.t.sol +0 -752
  69. package/test/TestAccessToFunds.sol +0 -2683
  70. package/test/TestAuditResponseDesignProofs.sol +0 -434
  71. package/test/TestCashOut.sol +0 -198
  72. package/test/TestCashOutCountFor.sol +0 -271
  73. package/test/TestCashOutHooks.sol +0 -351
  74. package/test/TestCashOutTimingEdge.sol +0 -241
  75. package/test/TestDataHookFuzzing.sol +0 -524
  76. package/test/TestDurationUnderflow.sol +0 -233
  77. package/test/TestFeeFreeCashOutBypass.sol +0 -949
  78. package/test/TestFeeProcessingFailure.sol +0 -218
  79. package/test/TestFees.sol +0 -619
  80. package/test/TestForwardedTokenConsumption.sol +0 -425
  81. package/test/TestInterfaceSupport.sol +0 -81
  82. package/test/TestJBERC20Inheritance.sol +0 -103
  83. package/test/TestL2SequencerPriceFeed.sol +0 -292
  84. package/test/TestLaunchProject.sol +0 -188
  85. package/test/TestMetaTx.sol +0 -217
  86. package/test/TestMetadataOffsetOverflow.sol +0 -179
  87. package/test/TestMetadataParserLib.sol +0 -471
  88. package/test/TestMigrationHeldFees.sol +0 -255
  89. package/test/TestMintTokensOf.sol +0 -185
  90. package/test/TestMultiTerminalSurplus.sol +0 -348
  91. package/test/TestMultiTokenSurplus.sol +0 -202
  92. package/test/TestMultipleAccessLimits.sol +0 -664
  93. package/test/TestPayBurnRedeemFlow.sol +0 -195
  94. package/test/TestPayHooks.sol +0 -209
  95. package/test/TestPermissions.sol +0 -324
  96. package/test/TestPermissionsEdge.sol +0 -290
  97. package/test/TestPermit2DataHook.t.sol +0 -360
  98. package/test/TestPermit2Terminal.sol +0 -372
  99. package/test/TestRulesetQueueing.sol +0 -1025
  100. package/test/TestRulesetQueuingStress.sol +0 -806
  101. package/test/TestRulesetWeightCaching.sol +0 -178
  102. package/test/TestSplits.sol +0 -391
  103. package/test/TestTerminalMigration.sol +0 -274
  104. package/test/TestTerminalPreviewParity.sol +0 -208
  105. package/test/TestTokenFlow.sol +0 -191
  106. package/test/TestWeightCacheStaleAfterRejection.sol +0 -303
  107. package/test/WeirdTokenTests.t.sol +0 -817
  108. package/test/audit/CashOutReenterPay.t.sol +0 -501
  109. package/test/audit/CodexHeldFeeRounding.t.sol +0 -159
  110. package/test/audit/CodexMigrationFeeFailure.t.sol +0 -163
  111. package/test/audit/CrossTerminalSurplusSpoof.t.sol +0 -140
  112. package/test/audit/CycledSurplusAllowanceReset.t.sol +0 -184
  113. package/test/audit/FeeFreeSurplusLifecycle.t.sol +0 -399
  114. package/test/audit/FeeFreeSurplusStale.t.sol +0 -248
  115. package/test/audit/USDTVoidReturnCompat.t.sol +0 -525
  116. package/test/fork/TestChainlinkPriceFeedFork.sol +0 -254
  117. package/test/fork/TestSequencerPriceFeedFork.sol +0 -168
  118. package/test/fork/TestTerminalPreviewParityFork.sol +0 -108
  119. package/test/formal/BondingCurveProperties.t.sol +0 -420
  120. package/test/formal/FeeProperties.t.sol +0 -252
  121. package/test/invariants/Phase3DeepInvariant.t.sol +0 -412
  122. package/test/invariants/RulesetsInvariant.t.sol +0 -125
  123. package/test/invariants/TerminalStoreInvariant.t.sol +0 -227
  124. package/test/invariants/TokensInvariant.t.sol +0 -195
  125. package/test/invariants/handlers/ComprehensiveHandler.sol +0 -303
  126. package/test/invariants/handlers/EconomicHandler.sol +0 -377
  127. package/test/invariants/handlers/Phase3Handler.sol +0 -443
  128. package/test/invariants/handlers/RulesetsHandler.sol +0 -115
  129. package/test/invariants/handlers/TerminalStoreHandler.sol +0 -151
  130. package/test/invariants/handlers/TokensHandler.sol +0 -126
  131. package/test/regression/HoldFeesCashOutReserved.t.sol +0 -415
  132. package/test/regression/WeightCacheBoundary.t.sol +0 -291
  133. package/test/trees/JBController/burnTokensOf.tree +0 -9
  134. package/test/trees/JBController/claimTokensFor.tree +0 -5
  135. package/test/trees/JBController/deployERC20For.tree +0 -5
  136. package/test/trees/JBController/getRulesetOf.tree +0 -5
  137. package/test/trees/JBController/launchProjectFor.tree +0 -12
  138. package/test/trees/JBController/launchRulesetsFor.tree +0 -8
  139. package/test/trees/JBController/migrateController.tree +0 -12
  140. package/test/trees/JBController/mintTokensOf.tree +0 -12
  141. package/test/trees/JBController/payReservedTokenToTerminal.tree +0 -8
  142. package/test/trees/JBController/receiveMigrationFrom.tree +0 -4
  143. package/test/trees/JBController/sendReservedTokensToSplitsOf.tree +0 -12
  144. package/test/trees/JBController/setMetadataOf.tree +0 -5
  145. package/test/trees/JBController/setSplitGroupsOf.tree +0 -5
  146. package/test/trees/JBController/setTokenFor.tree +0 -5
  147. package/test/trees/JBController/transferCreditsFrom.tree +0 -8
  148. package/test/trees/JBDirectory/primaryTerminalOf.tree +0 -8
  149. package/test/trees/JBDirectory/setControllerOf.tree +0 -11
  150. package/test/trees/JBDirectory/setPrimaryTerminalOf.tree +0 -15
  151. package/test/trees/JBDirectory/setTerminalsOf.tree +0 -11
  152. package/test/trees/JBERC20/initialize.tree +0 -7
  153. package/test/trees/JBERC20/name.tree +0 -5
  154. package/test/trees/JBERC20/nonces.tree +0 -5
  155. package/test/trees/JBERC20/symbol.tree +0 -5
  156. package/test/trees/JBFeelessAddresses/setFeelessAddress.tree +0 -5
  157. package/test/trees/JBFeelessAddresses/supportsInterface.tree +0 -5
  158. package/test/trees/JBFundAccessLimits/payoutLimitOf.tree +0 -5
  159. package/test/trees/JBFundAccessLimits/payoutLimitsOf.tree +0 -8
  160. package/test/trees/JBFundAccessLimits/setFundAccessLimitsFor.tree +0 -18
  161. package/test/trees/JBFundAccessLimits/surplusAllowanceOf.tree +0 -5
  162. package/test/trees/JBFundAccessLimits/surplusAllowancesOf.tree +0 -8
  163. package/test/trees/JBMetadataResolver/getDataFor.tree +0 -8
  164. package/test/trees/JBMultiTerminal/accountingContextsOf.tree +0 -5
  165. package/test/trees/JBMultiTerminal/addAccountingContextsFor.tree +0 -10
  166. package/test/trees/JBMultiTerminal/addToBalanceOf.tree +0 -23
  167. package/test/trees/JBMultiTerminal/cashOutTokensOf.tree +0 -23
  168. package/test/trees/JBMultiTerminal/executePayout.tree +0 -32
  169. package/test/trees/JBMultiTerminal/executeProcessFee.tree +0 -14
  170. package/test/trees/JBMultiTerminal/migrateBalanceOf.tree +0 -12
  171. package/test/trees/JBMultiTerminal/pay.tree +0 -23
  172. package/test/trees/JBMultiTerminal/processHeldFeesOf.tree +0 -8
  173. package/test/trees/JBMultiTerminal/sendPayoutsOf.tree +0 -34
  174. package/test/trees/JBMultiTerminal/useAllowanceOf.tree +0 -16
  175. package/test/trees/JBPermissions/hasPermission.tree +0 -8
  176. package/test/trees/JBPermissions/hasPermissions.tree +0 -8
  177. package/test/trees/JBPermissions/setPermissionsFor.tree +0 -5
  178. package/test/trees/JBPrices/addPriceFeedFor.tree +0 -14
  179. package/test/trees/JBPrices/pricePerUnitOf.tree +0 -11
  180. package/test/trees/JBProjects/createFor.tree +0 -11
  181. package/test/trees/JBProjects/setTokenUriResolver.tree +0 -5
  182. package/test/trees/JBProjects/supportsInterface.tree +0 -9
  183. package/test/trees/JBProjects/tokenURI.tree +0 -5
  184. package/test/trees/JBRulesets/currentApprovalStatusForLatestRulesetOf.tree +0 -8
  185. package/test/trees/JBRulesets/currentOf.tree +0 -12
  186. package/test/trees/JBRulesets/getRulesetOf.tree +0 -5
  187. package/test/trees/JBRulesets/latestQueuedRulesetOf.tree +0 -10
  188. package/test/trees/JBRulesets/rulesetsOf.tree +0 -11
  189. package/test/trees/JBRulesets/upcomingRulesetOf.tree +0 -20
  190. package/test/trees/JBRulesets/updateRulesetWeightCache.tree +0 -5
  191. package/test/trees/JBSplits/setSplitGroupsOf.tree +0 -17
  192. package/test/trees/JBSplits/splitsOf.tree +0 -5
  193. package/test/trees/JBTerminalStore/currentReclaimableSurplusOf.tree +0 -16
  194. package/test/trees/JBTerminalStore/currentSurplusOf.tree +0 -25
  195. package/test/trees/JBTerminalStore/currentTotalSurplusOf.tree +0 -5
  196. package/test/trees/JBTerminalStore/recordCashOutsFor.tree +0 -16
  197. package/test/trees/JBTerminalStore/recordPaymentFrom.tree +0 -14
  198. package/test/trees/JBTerminalStore/recordPayoutFor.tree +0 -10
  199. package/test/trees/JBTerminalStore/recordTerminalMigration.tree +0 -5
  200. package/test/trees/JBTerminalStore/recordUsedAllowanceOf.tree +0 -10
  201. package/test/trees/JBTokens/burnFrom.tree +0 -10
  202. package/test/trees/JBTokens/claimTokensFor.tree +0 -10
  203. package/test/trees/JBTokens/deployERC20For.tree +0 -12
  204. package/test/trees/JBTokens/mintFor.tree +0 -10
  205. package/test/trees/JBTokens/setTokenFor.tree +0 -11
  206. package/test/trees/JBTokens/totalBalanceOf.tree +0 -5
  207. package/test/trees/JBTokens/totalSupplyOf.tree +0 -5
  208. package/test/trees/JBTokens/transferCreditsFrom.tree +0 -8
  209. package/test/trees/mintTokensOf.tree +0 -12
  210. package/test/units/static/JBChainlinkV3PriceFeed/TestPriceFeed.sol +0 -223
  211. package/test/units/static/JBController/JBControllerSetup.sol +0 -50
  212. package/test/units/static/JBController/TestBurnTokensOf.sol +0 -114
  213. package/test/units/static/JBController/TestClaimTokensFor.sol +0 -63
  214. package/test/units/static/JBController/TestDeployErc20For.sol +0 -86
  215. package/test/units/static/JBController/TestLaunchProjectFor.sol +0 -302
  216. package/test/units/static/JBController/TestLaunchRulesetsFor.sol +0 -342
  217. package/test/units/static/JBController/TestMigrateController.sol +0 -157
  218. package/test/units/static/JBController/TestMintTokensOfUnits.sol +0 -111
  219. package/test/units/static/JBController/TestOmnichainRulesetOperator.sol +0 -324
  220. package/test/units/static/JBController/TestPayReservedTokenToTerminal.sol +0 -74
  221. package/test/units/static/JBController/TestPreviewMintOf.sol +0 -117
  222. package/test/units/static/JBController/TestReceiveMigrationFrom.sol +0 -99
  223. package/test/units/static/JBController/TestRulesetViews.sol +0 -225
  224. package/test/units/static/JBController/TestSendReservedTokensToSplitsOf.sol +0 -615
  225. package/test/units/static/JBController/TestSetSplitGroupsOf.sol +0 -68
  226. package/test/units/static/JBController/TestSetTokenFor.sol +0 -239
  227. package/test/units/static/JBController/TestSetUriOf.sol +0 -57
  228. package/test/units/static/JBController/TestTransferCreditsFrom.sol +0 -169
  229. package/test/units/static/JBDeadline/TestDeadlineFuzz.sol +0 -211
  230. package/test/units/static/JBDirectory/JBDirectorySetup.sol +0 -26
  231. package/test/units/static/JBDirectory/TestPrimaryTerminalOf.sol +0 -126
  232. package/test/units/static/JBDirectory/TestSetControllerOf.sol +0 -183
  233. package/test/units/static/JBDirectory/TestSetControllerOfMigrationOrder.sol +0 -104
  234. package/test/units/static/JBDirectory/TestSetPrimaryTerminalOf.sol +0 -179
  235. package/test/units/static/JBDirectory/TestSetTerminalsOf.sol +0 -137
  236. package/test/units/static/JBERC20/JBERC20Setup.sol +0 -34
  237. package/test/units/static/JBERC20/SigUtils.sol +0 -36
  238. package/test/units/static/JBERC20/TestInitialize.sol +0 -60
  239. package/test/units/static/JBERC20/TestName.sol +0 -30
  240. package/test/units/static/JBERC20/TestNonces.sol +0 -62
  241. package/test/units/static/JBERC20/TestSymbol.sol +0 -31
  242. package/test/units/static/JBFeelessAdresses/JBFeelessSetup.sol +0 -22
  243. package/test/units/static/JBFeelessAdresses/TestInterfaces.sol +0 -30
  244. package/test/units/static/JBFeelessAdresses/TestSetFeelessAddress.sol +0 -35
  245. package/test/units/static/JBFees/TestFeesFuzz.sol +0 -79
  246. package/test/units/static/JBFixedPointNumber/TestAdjustDecimals.sol +0 -16
  247. package/test/units/static/JBFixedPointNumber/TestAdjustDecimalsFuzz.sol +0 -71
  248. package/test/units/static/JBFundAccessLimits/JBFundAccessSetup.sol +0 -24
  249. package/test/units/static/JBFundAccessLimits/TestFundAccessLimitsEdge.sol +0 -163
  250. package/test/units/static/JBFundAccessLimits/TestPayoutLimitOf.sol +0 -59
  251. package/test/units/static/JBFundAccessLimits/TestPayoutLimitsOf.sol +0 -101
  252. package/test/units/static/JBFundAccessLimits/TestSetFundAccessLimitsFor.sol +0 -189
  253. package/test/units/static/JBFundAccessLimits/TestSurplusAllowanceOf.sol +0 -64
  254. package/test/units/static/JBFundAccessLimits/TestSurplusAllowancesOf.sol +0 -102
  255. package/test/units/static/JBMetadataResolver/TestGetDataFor.sol +0 -90
  256. package/test/units/static/JBMetadataResolver/TestMetadataResolverEdgeCases.sol +0 -247
  257. package/test/units/static/JBMetadataResolver/TestMetadataResolverFuzz.sol +0 -229
  258. package/test/units/static/JBMultiTerminal/JBMultiTerminalSetup.sol +0 -50
  259. package/test/units/static/JBMultiTerminal/TestAccountingContextsOf.sol +0 -72
  260. package/test/units/static/JBMultiTerminal/TestAddAccountingContextsFor.sol +0 -289
  261. package/test/units/static/JBMultiTerminal/TestAddToBalanceOf.sol +0 -474
  262. package/test/units/static/JBMultiTerminal/TestCashOutTokensOf.sol +0 -624
  263. package/test/units/static/JBMultiTerminal/TestExecutePayout.sol +0 -578
  264. package/test/units/static/JBMultiTerminal/TestExecuteProcessFee.sol +0 -202
  265. package/test/units/static/JBMultiTerminal/TestMigrateBalanceOf.sol +0 -222
  266. package/test/units/static/JBMultiTerminal/TestPay.sol +0 -604
  267. package/test/units/static/JBMultiTerminal/TestPreviewCashOutFrom.sol +0 -117
  268. package/test/units/static/JBMultiTerminal/TestPreviewPayFor.sol +0 -114
  269. package/test/units/static/JBMultiTerminal/TestProcessHeldFeesOf.sol +0 -228
  270. package/test/units/static/JBMultiTerminal/TestSelfPayRevert.sol +0 -55
  271. package/test/units/static/JBMultiTerminal/TestSendPayoutsOf.sol +0 -257
  272. package/test/units/static/JBMultiTerminal/TestUseAllowanceOf.sol +0 -611
  273. package/test/units/static/JBPermissions/JBPermissionsSetup.sol +0 -20
  274. package/test/units/static/JBPermissions/TestHasPermission.sol +0 -50
  275. package/test/units/static/JBPermissions/TestHasPermissions.sol +0 -93
  276. package/test/units/static/JBPermissions/TestSetPermissionsFor.sol +0 -64
  277. package/test/units/static/JBPrices/JBPricesSetup.sol +0 -32
  278. package/test/units/static/JBPrices/TestAddPriceFeedFor.sol +0 -107
  279. package/test/units/static/JBPrices/TestPricePerUnitOf.sol +0 -132
  280. package/test/units/static/JBPrices/TestPrices.sol +0 -265
  281. package/test/units/static/JBProjects/JBProjectsSetup.sol +0 -22
  282. package/test/units/static/JBProjects/TestCreateFor.sol +0 -71
  283. package/test/units/static/JBProjects/TestInitialProject.sol +0 -21
  284. package/test/units/static/JBProjects/TestInterfaces.sol +0 -26
  285. package/test/units/static/JBProjects/TestSetResolver.sol +0 -37
  286. package/test/units/static/JBProjects/TestTokenUri.sol +0 -40
  287. package/test/units/static/JBRulesetMetadataResolver/TestSetCashOutTaxRateTo.sol +0 -108
  288. package/test/units/static/JBRulesets/JBRulesetsSetup.sol +0 -24
  289. package/test/units/static/JBRulesets/TestCurrentApprovalStatusForLatestRulesetOf.sol +0 -265
  290. package/test/units/static/JBRulesets/TestCurrentOf.sol +0 -242
  291. package/test/units/static/JBRulesets/TestGetRulesetOf.sol +0 -100
  292. package/test/units/static/JBRulesets/TestLatestQueuedRulesetOf.sol +0 -260
  293. package/test/units/static/JBRulesets/TestRulesets.sol +0 -632
  294. package/test/units/static/JBRulesets/TestRulesetsOf.sol +0 -37
  295. package/test/units/static/JBRulesets/TestUpcomingRulesetOf.sol +0 -522
  296. package/test/units/static/JBRulesets/TestUpdateRulesetWeightCache.sol +0 -96
  297. package/test/units/static/JBSplits/JBSplitsSetup.sol +0 -26
  298. package/test/units/static/JBSplits/TestSelfManagedSplitGroups.sol +0 -552
  299. package/test/units/static/JBSplits/TestSetSplitGroupsOf.sol +0 -377
  300. package/test/units/static/JBSplits/TestSplitsLockedEdge.sol +0 -267
  301. package/test/units/static/JBSplits/TestSplitsOf.sol +0 -24
  302. package/test/units/static/JBSplits/TestSplitsPacking.sol +0 -36
  303. package/test/units/static/JBSurplus/TestSurplusFuzz.sol +0 -160
  304. package/test/units/static/JBTerminalStore/JBTerminalStoreSetup.sol +0 -45
  305. package/test/units/static/JBTerminalStore/TestCurrentReclaimableSurplusOf.sol +0 -536
  306. package/test/units/static/JBTerminalStore/TestCurrentSurplusOf.sol +0 -463
  307. package/test/units/static/JBTerminalStore/TestCurrentTotalSurplusOf.sol +0 -135
  308. package/test/units/static/JBTerminalStore/TestPreviewCashOutFrom.sol +0 -476
  309. package/test/units/static/JBTerminalStore/TestPreviewPayFrom.sol +0 -494
  310. package/test/units/static/JBTerminalStore/TestRecordCashOutsFor.sol +0 -652
  311. package/test/units/static/JBTerminalStore/TestRecordPaymentFrom.sol +0 -744
  312. package/test/units/static/JBTerminalStore/TestRecordPayoutFor.sol +0 -289
  313. package/test/units/static/JBTerminalStore/TestRecordTerminalMigration.sol +0 -138
  314. package/test/units/static/JBTerminalStore/TestRecordUsedAllowanceOf.sol +0 -415
  315. package/test/units/static/JBTerminalStore/TestUint224Overflow.sol +0 -219
  316. package/test/units/static/JBTokens/JBTokensSetup.sol +0 -32
  317. package/test/units/static/JBTokens/TestBurnFrom.sol +0 -107
  318. package/test/units/static/JBTokens/TestClaimTokensFor.sol +0 -110
  319. package/test/units/static/JBTokens/TestDeployERC20ForUnits.sol +0 -92
  320. package/test/units/static/JBTokens/TestMintFor.sol +0 -100
  321. package/test/units/static/JBTokens/TestSetTokenFor.sol +0 -98
  322. package/test/units/static/JBTokens/TestTotalBalanceOf.sol +0 -65
  323. package/test/units/static/JBTokens/TestTotalSupplyOf.sol +0 -56
  324. package/test/units/static/JBTokens/TestTransferCreditsFrom.sol +0 -56
@@ -1,624 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity 0.8.28;
3
-
4
- import {MockERC20} from "../../../mock/MockERC20.sol";
5
- import {JBMultiTerminal} from "../../../../src/JBMultiTerminal.sol";
6
- import {JBPermissioned} from "../../../../src/abstract/JBPermissioned.sol";
7
- import {IJBCashOutHook} from "../../../../src/interfaces/IJBCashOutHook.sol";
8
- import {IJBController} from "../../../../src/interfaces/IJBController.sol";
9
- import {IJBDirectory} from "../../../../src/interfaces/IJBDirectory.sol";
10
- import {IJBFeelessAddresses} from "../../../../src/interfaces/IJBFeelessAddresses.sol";
11
- import {IJBPermissions} from "../../../../src/interfaces/IJBPermissions.sol";
12
- import {IJBRulesetApprovalHook} from "../../../../src/interfaces/IJBRulesetApprovalHook.sol";
13
- import {IJBTerminalStore} from "../../../../src/interfaces/IJBTerminalStore.sol";
14
- import {JBConstants} from "../../../../src/libraries/JBConstants.sol";
15
- import {JBFees} from "../../../../src/libraries/JBFees.sol";
16
- import {JBAccountingContext} from "../../../../src/structs/JBAccountingContext.sol";
17
- import {JBAfterCashOutRecordedContext} from "../../../../src/structs/JBAfterCashOutRecordedContext.sol";
18
- import {JBCashOutHookSpecification} from "../../../../src/structs/JBCashOutHookSpecification.sol";
19
- import {JBRuleset} from "../../../../src/structs/JBRuleset.sol";
20
- import {JBTokenAmount} from "../../../../src/structs/JBTokenAmount.sol";
21
- import {JBPermissionIds} from "@bananapus/permission-ids-v6/src/JBPermissionIds.sol";
22
- import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
23
- import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
24
- import {JBMultiTerminalSetup} from "./JBMultiTerminalSetup.sol";
25
-
26
- contract TestCashOutTokensOf_Local is JBMultiTerminalSetup {
27
- uint64 _projectId = 1;
28
- uint256 _defaultAmount = 1e18;
29
- uint16 _maxCashOutTaxRate = JBConstants.MAX_CASH_OUT_TAX_RATE;
30
- uint16 _halfCashOutTaxRate = JBConstants.MAX_CASH_OUT_TAX_RATE / 2;
31
-
32
- address _holder = makeAddr("holder");
33
- address payable _bene = payable(makeAddr("beneficiary"));
34
- address _mockToken = makeAddr("mockToken");
35
- IJBCashOutHook _mockHook = IJBCashOutHook(makeAddr("cashOutHook"));
36
-
37
- // mock erc20 necessary for balance checks
38
- MockERC20 _mockToken2;
39
-
40
- uint256 _minReclaimed;
41
-
42
- function setUp() public {
43
- super.multiTerminalSetup();
44
-
45
- _mockToken2 = new MockERC20("testToken", "TT");
46
- }
47
-
48
- function _acceptToken(address token, uint8 decimals, uint32 currency) internal {
49
- mockExpect(address(projects), abi.encodeCall(IERC721.ownerOf, (_projectId)), abi.encode(address(0)));
50
- mockExpect(
51
- address(directory), abi.encodeCall(IJBDirectory.controllerOf, (_projectId)), abi.encode(address(this))
52
- );
53
-
54
- // Mock ERC20 transfer for non-contract token addresses (needed for SafeERC20 calls later).
55
- if (token != JBConstants.NATIVE_TOKEN && token.code.length == 0) {
56
- vm.mockCall(token, abi.encodeWithSelector(IERC20.transfer.selector), abi.encode(true));
57
- }
58
-
59
- JBAccountingContext[] memory _tokens = new JBAccountingContext[](1);
60
- _tokens[0] = JBAccountingContext({token: token, decimals: decimals, currency: currency});
61
-
62
- // Mock recordAccountingContextOf in the store (validation now happens there)
63
- mockExpect(
64
- address(store), abi.encodeCall(IJBTerminalStore.recordAccountingContextOf, (_projectId, _tokens)), ""
65
- );
66
-
67
- vm.prank(address(this));
68
- _terminal.addAccountingContextsFor(_projectId, _tokens);
69
-
70
- // Mock accountingContextOf for subsequent reads (not all code paths call it, so use mockCall only)
71
- vm.mockCall(
72
- address(store),
73
- abi.encodeCall(IJBTerminalStore.accountingContextOf, (address(_terminal), _projectId, token)),
74
- abi.encode(_tokens[0])
75
- );
76
- }
77
-
78
- function test_WhenCallerDNHavePermission() external {
79
- // it will revert UNAUTHORIZED
80
-
81
- // mock call to JBPermissions hasPermission
82
- mockExpect(
83
- address(permissions),
84
- abi.encodeCall(
85
- IJBPermissions.hasPermission,
86
- (address(_bene), address(_holder), _projectId, JBPermissionIds.CASH_OUT_TOKENS, true, true)
87
- ),
88
- abi.encode(false)
89
- );
90
-
91
- vm.expectRevert(
92
- abi.encodeWithSelector(
93
- JBPermissioned.JBPermissioned_Unauthorized.selector,
94
- _holder,
95
- _bene,
96
- _projectId,
97
- JBPermissionIds.CASH_OUT_TOKENS
98
- )
99
- );
100
- vm.prank(_bene);
101
- _terminal.cashOutTokensOf(_holder, _projectId, _defaultAmount, _mockToken, _minReclaimed, _bene, "");
102
- }
103
-
104
- modifier whenCallerHasPermission() {
105
- // mock call to JBPermissions hasPermission
106
- mockExpect(
107
- address(permissions),
108
- abi.encodeCall(
109
- IJBPermissions.hasPermission,
110
- (address(_bene), address(_holder), _projectId, JBPermissionIds.CASH_OUT_TOKENS, true, true)
111
- ),
112
- abi.encode(true)
113
- );
114
-
115
- _;
116
- }
117
-
118
- function test_GivenCashOutCountLTMinTokensReclaimed() external whenCallerHasPermission {
119
- // it will revert UNDER_MIN_TOKENS_RECLAIMED
120
-
121
- uint256 reclaimAmount = 1e9;
122
- JBCashOutHookSpecification[] memory hookSpecifications = new JBCashOutHookSpecification[](0);
123
- JBAccountingContext memory mockTokenContext =
124
- // forge-lint: disable-next-line(unsafe-typecast)
125
- JBAccountingContext({token: _mockToken, decimals: 18, currency: uint32(uint160(_mockToken))});
126
- JBAccountingContext[] memory mockBalanceContext = new JBAccountingContext[](1);
127
- mockBalanceContext[0] = mockTokenContext;
128
- JBRuleset memory returnedRuleset = JBRuleset({
129
- cycleNumber: 1,
130
- id: 1,
131
- basedOnId: 0,
132
- start: 0,
133
- duration: 0,
134
- weight: 0,
135
- weightCutPercent: 0,
136
- approvalHook: IJBRulesetApprovalHook(address(0)),
137
- metadata: 0
138
- });
139
-
140
- // mock feeless address check
141
- mockExpect(address(feelessAddresses), abi.encodeCall(IJBFeelessAddresses.isFeeless, (_bene)), abi.encode(true));
142
-
143
- // mock call to JBTerminalStore recordCashOutFor
144
- mockExpect(
145
- address(store),
146
- abi.encodeCall(
147
- IJBTerminalStore.recordCashOutFor,
148
- (_holder, _projectId, _defaultAmount, mockTokenContext.token, true, "")
149
- ),
150
- abi.encode(returnedRuleset, reclaimAmount, _maxCashOutTaxRate, hookSpecifications)
151
- );
152
-
153
- // mock call to find the controller (we'll just use this contracts address for simplicity)
154
- mockExpect(
155
- address(directory), abi.encodeCall(IJBDirectory.controllerOf, (_projectId)), abi.encode(address(this))
156
- );
157
-
158
- // mock controller burn call
159
- mockExpect(
160
- address(this), abi.encodeCall(IJBController.burnTokensOf, (_holder, _projectId, _defaultAmount, "")), ""
161
- );
162
-
163
- // put code at mockToken address to pass OZ Address check
164
- vm.etch(_mockToken, abi.encode(1));
165
- // forge-lint: disable-next-line(unsafe-typecast)
166
- _acceptToken(_mockToken, 18, uint32(uint160(_mockToken)));
167
-
168
- vm.prank(_bene);
169
- _terminal.cashOutTokensOf(_holder, _projectId, _defaultAmount, _mockToken, _minReclaimed, _bene, "");
170
- }
171
-
172
- function test_GivenCashOutCountGtZero() external whenCallerHasPermission {
173
- // it will call directory controller of and burnTokensOf
174
-
175
- uint256 reclaimAmount = 1e9;
176
- JBCashOutHookSpecification[] memory hookSpecifications = new JBCashOutHookSpecification[](0);
177
- JBAccountingContext memory mockTokenContext =
178
- // forge-lint: disable-next-line(unsafe-typecast)
179
- JBAccountingContext({token: _mockToken, decimals: 18, currency: uint32(uint160(_mockToken))});
180
- JBAccountingContext[] memory mockBalanceContext = new JBAccountingContext[](1);
181
- mockBalanceContext[0] = mockTokenContext;
182
- JBRuleset memory returnedRuleset = JBRuleset({
183
- cycleNumber: 1,
184
- id: 1,
185
- basedOnId: 0,
186
- start: 0,
187
- duration: 0,
188
- weight: 0,
189
- weightCutPercent: 0,
190
- approvalHook: IJBRulesetApprovalHook(address(0)),
191
- metadata: 0
192
- });
193
-
194
- // mock feeless address check
195
- mockExpect(address(feelessAddresses), abi.encodeCall(IJBFeelessAddresses.isFeeless, (_bene)), abi.encode(true));
196
-
197
- // mock call to JBTerminalStore recordCashOutFor
198
- mockExpect(
199
- address(store),
200
- abi.encodeCall(
201
- IJBTerminalStore.recordCashOutFor,
202
- (_holder, _projectId, _defaultAmount, mockTokenContext.token, true, "")
203
- ),
204
- abi.encode(returnedRuleset, reclaimAmount, _maxCashOutTaxRate, hookSpecifications)
205
- );
206
-
207
- // mock call to find the controller (we'll just use this contracts address for simplicity)
208
- mockExpect(
209
- address(directory), abi.encodeCall(IJBDirectory.controllerOf, (_projectId)), abi.encode(address(this))
210
- );
211
-
212
- // mock controller burn call
213
- mockExpect(
214
- address(this), abi.encodeCall(IJBController.burnTokensOf, (_holder, _projectId, _defaultAmount, "")), ""
215
- );
216
-
217
- // put code at mockToken address to pass OZ Address check
218
- vm.etch(_mockToken, abi.encode(1));
219
- // forge-lint: disable-next-line(unsafe-typecast)
220
- _acceptToken(_mockToken, 18, uint32(uint160(_mockToken)));
221
-
222
- vm.expectRevert(abi.encodeWithSelector(JBMultiTerminal.JBMultiTerminal_UnderMin.selector, reclaimAmount, 1e18));
223
- vm.prank(_bene);
224
- _terminal.cashOutTokensOf(_holder, _projectId, _defaultAmount, _mockToken, 1e18, _bene, ""); // minReclaimAmount
225
- // = 1e18 but only 1e9 reclaimed
226
- }
227
-
228
- function test_GivenReclaimAmountGtZeroBeneficiaryIsNotFeelessAndCashOutRateDneqMAX_CASH_OUT_RATE()
229
- external
230
- whenCallerHasPermission
231
- {
232
- // it will subtract the fee for the reclaim
233
-
234
- uint256 reclaimAmount = 1e9;
235
- JBCashOutHookSpecification[] memory hookSpecifications = new JBCashOutHookSpecification[](0);
236
- JBAccountingContext memory mockTokenContext =
237
- // forge-lint: disable-next-line(unsafe-typecast)
238
- JBAccountingContext({token: _mockToken, decimals: 18, currency: uint32(uint160(_mockToken))});
239
- JBAccountingContext[] memory mockBalanceContext = new JBAccountingContext[](1);
240
- mockBalanceContext[0] = mockTokenContext;
241
- JBRuleset memory returnedRuleset = JBRuleset({
242
- cycleNumber: 1,
243
- id: 1,
244
- basedOnId: 0,
245
- start: 0,
246
- duration: 0,
247
- weight: 0,
248
- weightCutPercent: 0,
249
- approvalHook: IJBRulesetApprovalHook(address(0)),
250
- metadata: 0
251
- });
252
-
253
- // mock feeless address check
254
- mockExpect(address(feelessAddresses), abi.encodeCall(IJBFeelessAddresses.isFeeless, (_bene)), abi.encode(false));
255
-
256
- // mock call to JBTerminalStore recordCashOutFor
257
- mockExpect(
258
- address(store),
259
- abi.encodeCall(
260
- IJBTerminalStore.recordCashOutFor,
261
- (_holder, _projectId, _defaultAmount, mockTokenContext.token, false, "")
262
- ),
263
- abi.encode(returnedRuleset, reclaimAmount, _halfCashOutTaxRate, hookSpecifications)
264
- );
265
-
266
- // mock call to find the controller (we'll just use this contracts address for simplicity)
267
- mockExpect(
268
- address(directory), abi.encodeCall(IJBDirectory.controllerOf, (_projectId)), abi.encode(address(this))
269
- );
270
-
271
- // mock controller burn call
272
- mockExpect(
273
- address(this), abi.encodeCall(IJBController.burnTokensOf, (_holder, _projectId, _defaultAmount, "")), ""
274
- );
275
-
276
- // put code at mockToken address to pass OZ Address check
277
- vm.etch(_mockToken, abi.encode(1));
278
- // forge-lint: disable-next-line(unsafe-typecast)
279
- _acceptToken(_mockToken, 18, uint32(uint160(_mockToken)));
280
-
281
- // get fee amount
282
- uint256 tax = JBFees.feeAmountFrom(reclaimAmount, 25); // 25 = default fee)
283
- uint256 transferredAmount = reclaimAmount - tax;
284
-
285
- // transfer reclaimed to beneficiary
286
- mockExpect(_mockToken, abi.encodeCall(IERC20.transfer, (_bene, transferredAmount)), abi.encode(true));
287
-
288
- // find the terminal where subtracted fees are sent
289
- mockExpect(
290
- address(directory),
291
- abi.encodeCall(IJBDirectory.primaryTerminalOf, (_projectId, _mockToken)),
292
- abi.encode(address(_terminal))
293
- );
294
-
295
- // executeProcessFee
296
- mockExpect(
297
- address(_terminal),
298
- abi.encodeCall(JBMultiTerminal.executeProcessFee, (_projectId, _mockToken, tax, _bene, _terminal)),
299
- ""
300
- );
301
-
302
- vm.prank(_bene);
303
- _terminal.cashOutTokensOf(_holder, _projectId, _defaultAmount, _mockToken, _minReclaimed, _bene, "");
304
- }
305
-
306
- // covered above / in other units that test transfers
307
- /* function test_GivenTheTokenIsNative() external whenCallerHasPermission {
308
- // it will sendValue
309
- }
310
-
311
- function test_GivenTheTokenIsErc20() external whenCallerHasPermission {
312
- // it will safeTransfer tokens
313
- }
314
-
315
- function test_GivenAmountEligibleForFeesDneqZero() external whenCallerHasPermission {
316
- // it will call directory primaryTerminalOf and process the fee
317
- } */
318
-
319
- modifier whenADataHookIsConfigured() {
320
- _;
321
- }
322
-
323
- /* function test_GivenDataHookReturnsCashOutHookSpecsHookIsFeelessAndTokenIsNative()
324
- external
325
- whenADataHookIsConfigured
326
- whenCallerHasPermission
327
- {
328
- // it will pass the full amount to the hook and emit HookAfterRecordCashOut
329
-
330
-
331
- } */
332
-
333
- function test_GivenDataHookReturnsCashOutHookSpecsHookIsFeelessAndTokenIsErc20()
334
- external
335
- whenADataHookIsConfigured
336
- whenCallerHasPermission
337
- {
338
- // it will forceApprove pass the full amount to the hook and emit HookAfterRecordCashOut
339
-
340
- // mint mocked erc20 tokens to hodler
341
- _mockToken2.mint(address(_terminal), _defaultAmount * 10);
342
- _mockToken2.mint(address(_holder), _defaultAmount * 10);
343
-
344
- // approve those tokens to the terminal
345
- vm.prank(_holder);
346
- _mockToken2.approve(address(_terminal), _defaultAmount);
347
-
348
- uint256 reclaimAmount = 1e9;
349
- JBCashOutHookSpecification[] memory hookSpecifications = new JBCashOutHookSpecification[](1);
350
- hookSpecifications[0] =
351
- JBCashOutHookSpecification({hook: _mockHook, noop: false, amount: _defaultAmount, metadata: ""});
352
- JBAccountingContext memory mockTokenContext = JBAccountingContext({
353
- token: address(_mockToken2), decimals: 18, currency: uint32(uint160(address(_mockToken2)))
354
- });
355
- JBAccountingContext[] memory mockBalanceContext = new JBAccountingContext[](1);
356
- mockBalanceContext[0] = mockTokenContext;
357
- JBRuleset memory returnedRuleset = JBRuleset({
358
- cycleNumber: 1,
359
- id: 1,
360
- basedOnId: 0,
361
- start: 0,
362
- duration: 0,
363
- weight: 0,
364
- weightCutPercent: 0,
365
- approvalHook: IJBRulesetApprovalHook(address(0)),
366
- metadata: 0
367
- });
368
-
369
- mockExpect(address(feelessAddresses), abi.encodeCall(IJBFeelessAddresses.isFeeless, (_bene)), abi.encode(true));
370
-
371
- // mock call to JBTerminalStore recordCashOutFor
372
- mockExpect(
373
- address(store),
374
- abi.encodeCall(
375
- IJBTerminalStore.recordCashOutFor,
376
- (_holder, _projectId, _defaultAmount, mockTokenContext.token, true, "")
377
- ),
378
- abi.encode(returnedRuleset, reclaimAmount, _maxCashOutTaxRate, hookSpecifications)
379
- );
380
-
381
- // mock call to find the controller (we'll just use this contracts address for simplicity)
382
- mockExpect(
383
- address(directory), abi.encodeCall(IJBDirectory.controllerOf, (_projectId)), abi.encode(address(this))
384
- );
385
-
386
- // mock controller burn call
387
- mockExpect(
388
- address(this), abi.encodeCall(IJBController.burnTokensOf, (_holder, _projectId, _defaultAmount, "")), ""
389
- );
390
-
391
- mockExpect(
392
- address(feelessAddresses),
393
- abi.encodeCall(IJBFeelessAddresses.isFeeless, (address(_mockHook))),
394
- abi.encode(true)
395
- );
396
-
397
- JBTokenAmount memory reclaimedAmount = JBTokenAmount({
398
- token: address(_mockToken2),
399
- decimals: 18,
400
- currency: uint32(uint160(address(_mockToken2))),
401
- value: reclaimAmount
402
- });
403
- JBTokenAmount memory forwardedAmount = JBTokenAmount({
404
- token: address(_mockToken2),
405
- decimals: 18,
406
- currency: uint32(uint160(address(_mockToken2))),
407
- value: _defaultAmount
408
- });
409
-
410
- // needed for hook call
411
- JBAfterCashOutRecordedContext memory context = JBAfterCashOutRecordedContext({
412
- holder: _holder,
413
- projectId: _projectId,
414
- rulesetId: returnedRuleset.id,
415
- cashOutCount: _defaultAmount,
416
- reclaimedAmount: reclaimedAmount,
417
- forwardedAmount: forwardedAmount,
418
- cashOutTaxRate: _maxCashOutTaxRate,
419
- beneficiary: _bene,
420
- hookMetadata: "",
421
- cashOutMetadata: ""
422
- });
423
-
424
- mockExpect(address(_mockHook), abi.encodeCall(IJBCashOutHook.afterCashOutRecordedWith, (context)), "");
425
-
426
- // ensure approval is set via forceApprove
427
- vm.expectCall(address(_mockToken2), abi.encodeCall(IERC20.approve, (address(_mockHook), _defaultAmount)));
428
-
429
- // Mock the temporary allowance as fully consumed by the hook so the cleanup guard passes.
430
- vm.mockCall(
431
- address(_mockToken2),
432
- abi.encodeCall(IERC20.allowance, (address(_terminal), address(_mockHook))),
433
- abi.encode(0)
434
- );
435
-
436
- _acceptToken(address(_mockToken2), 18, uint32(uint160(address(_mockToken2))));
437
-
438
- vm.prank(_bene);
439
- _terminal.cashOutTokensOf(_holder, _projectId, _defaultAmount, address(_mockToken2), _minReclaimed, _bene, "");
440
- }
441
-
442
- /* function test_GivenDataHookReturnsCashOutHookSpecsHookIsNotFeelessAndTokenIsNative()
443
- external
444
- whenADataHookIsConfigured
445
- whenCallerHasPermission
446
- {
447
- // it will calculate the fee pass the amount to the hook and emit HookAfterRecordCashOut
448
- } */
449
-
450
- function test_GivenDataHookReturnsCashOutHookSpecsHookIsNotFeelessAndTokenIsErc20()
451
- external
452
- whenADataHookIsConfigured
453
- whenCallerHasPermission
454
- {
455
- // it will forceApprove pass the amount to the hook and emit HookAfterRecordCashOut
456
-
457
- // mint mocked erc20 tokens to hodler
458
- _mockToken2.mint(address(_terminal), _defaultAmount * 10);
459
- _mockToken2.mint(address(_holder), _defaultAmount * 10);
460
-
461
- // approve those tokens to the terminal
462
- vm.prank(_holder);
463
- _mockToken2.approve(address(_terminal), _defaultAmount);
464
-
465
- uint256 reclaimAmount = 1e9;
466
- JBCashOutHookSpecification[] memory hookSpecifications = new JBCashOutHookSpecification[](1);
467
- JBCashOutHookSpecification[] memory paySpecs = new JBCashOutHookSpecification[](0);
468
- hookSpecifications[0] =
469
- JBCashOutHookSpecification({hook: _mockHook, noop: false, amount: _defaultAmount, metadata: ""});
470
- JBAccountingContext memory mockTokenContext = JBAccountingContext({
471
- token: address(_mockToken2), decimals: 18, currency: uint32(uint160(address(_mockToken2)))
472
- });
473
- JBAccountingContext[] memory mockBalanceContext = new JBAccountingContext[](1);
474
- mockBalanceContext[0] = mockTokenContext;
475
- JBRuleset memory returnedRuleset = JBRuleset({
476
- cycleNumber: 1,
477
- id: 1,
478
- basedOnId: 0,
479
- start: 0,
480
- duration: 0,
481
- weight: 0,
482
- weightCutPercent: 0,
483
- approvalHook: IJBRulesetApprovalHook(address(0)),
484
- metadata: 0
485
- });
486
-
487
- mockExpect(address(feelessAddresses), abi.encodeCall(IJBFeelessAddresses.isFeeless, (_bene)), abi.encode(true));
488
-
489
- // mock call to JBTerminalStore recordCashOutFor
490
- mockExpect(
491
- address(store),
492
- abi.encodeCall(
493
- IJBTerminalStore.recordCashOutFor,
494
- (_holder, _projectId, _defaultAmount, mockTokenContext.token, true, "")
495
- ),
496
- abi.encode(returnedRuleset, reclaimAmount, _maxCashOutTaxRate, hookSpecifications)
497
- );
498
-
499
- // mock call to find the controller (we'll just use this contracts address for simplicity)
500
- mockExpect(
501
- address(directory), abi.encodeCall(IJBDirectory.controllerOf, (_projectId)), abi.encode(address(this))
502
- );
503
-
504
- // mock controller burn call
505
- mockExpect(
506
- address(this), abi.encodeCall(IJBController.burnTokensOf, (_holder, _projectId, _defaultAmount, "")), ""
507
- );
508
-
509
- mockExpect(
510
- address(feelessAddresses),
511
- abi.encodeCall(IJBFeelessAddresses.isFeeless, (address(_mockHook))),
512
- abi.encode(false)
513
- );
514
-
515
- uint256 hookTax = JBFees.feeAmountFrom(_defaultAmount, 25);
516
- uint256 passedAfterTax = _defaultAmount - hookTax;
517
-
518
- JBTokenAmount memory reclaimedAmount = JBTokenAmount({
519
- token: address(_mockToken2),
520
- decimals: 18,
521
- currency: uint32(uint160(address(_mockToken2))),
522
- value: reclaimAmount
523
- });
524
- JBTokenAmount memory forwardedAmount = JBTokenAmount({
525
- token: address(_mockToken2),
526
- decimals: 18,
527
- currency: uint32(uint160(address(_mockToken2))),
528
- value: passedAfterTax
529
- });
530
- JBTokenAmount memory feeRepayAmount = JBTokenAmount({
531
- token: address(_mockToken2), decimals: 18, currency: uint32(uint160(address(_mockToken2))), value: hookTax
532
- });
533
-
534
- // needed for hook call
535
- JBAfterCashOutRecordedContext memory context = JBAfterCashOutRecordedContext({
536
- holder: _holder,
537
- projectId: _projectId,
538
- rulesetId: returnedRuleset.id,
539
- cashOutCount: _defaultAmount,
540
- reclaimedAmount: reclaimedAmount,
541
- forwardedAmount: forwardedAmount,
542
- cashOutTaxRate: _maxCashOutTaxRate,
543
- beneficiary: _bene,
544
- hookMetadata: "",
545
- cashOutMetadata: ""
546
- });
547
-
548
- mockExpect(address(_mockHook), abi.encodeCall(IJBCashOutHook.afterCashOutRecordedWith, (context)), "");
549
-
550
- // Mock the temporary allowance as fully consumed by the hook so the cleanup guard passes.
551
- vm.mockCall(
552
- address(_mockToken2),
553
- abi.encodeCall(IERC20.allowance, (address(_terminal), address(_mockHook))),
554
- abi.encode(0)
555
- );
556
-
557
- // primary terminal check
558
- mockExpect(
559
- address(directory),
560
- abi.encodeCall(IJBDirectory.primaryTerminalOf, (_projectId, address(_mockToken2))),
561
- abi.encode(address(_terminal))
562
- );
563
-
564
- // mock call to JBTerminalStore recordPaymentFrom
565
- mockExpect(
566
- address(store),
567
- abi.encodeCall(
568
- IJBTerminalStore.recordPaymentFrom,
569
- (address(_terminal), feeRepayAmount, _projectId, _bene, bytes(abi.encodePacked(uint256(_projectId))))
570
- ),
571
- abi.encode(returnedRuleset, 0, paySpecs)
572
- );
573
-
574
- _acceptToken(address(_mockToken2), 18, uint32(uint160(address(_mockToken2))));
575
-
576
- vm.prank(_bene);
577
- _terminal.cashOutTokensOf(_holder, _projectId, _defaultAmount, address(_mockToken2), _minReclaimed, _bene, "");
578
- }
579
-
580
- function test_GivenTheCashOutHookSpecIsNoop() external whenCallerHasPermission {
581
- uint256 reclaimAmount = 1e9;
582
- JBCashOutHookSpecification[] memory hookSpecifications = new JBCashOutHookSpecification[](1);
583
- hookSpecifications[0] =
584
- JBCashOutHookSpecification({hook: IJBCashOutHook(address(this)), noop: true, amount: 0, metadata: "info"});
585
- JBAccountingContext memory mockTokenContext =
586
- // forge-lint: disable-next-line(unsafe-typecast)
587
- JBAccountingContext({token: _mockToken, decimals: 18, currency: uint32(uint160(_mockToken))});
588
- JBAccountingContext[] memory mockBalanceContext = new JBAccountingContext[](1);
589
- mockBalanceContext[0] = mockTokenContext;
590
- JBRuleset memory returnedRuleset = JBRuleset({
591
- cycleNumber: 1,
592
- id: 1,
593
- basedOnId: 0,
594
- start: 0,
595
- duration: 0,
596
- weight: 0,
597
- weightCutPercent: 0,
598
- approvalHook: IJBRulesetApprovalHook(address(0)),
599
- metadata: 0
600
- });
601
-
602
- mockExpect(address(feelessAddresses), abi.encodeCall(IJBFeelessAddresses.isFeeless, (_bene)), abi.encode(true));
603
- mockExpect(
604
- address(store),
605
- abi.encodeCall(
606
- IJBTerminalStore.recordCashOutFor,
607
- (_holder, _projectId, _defaultAmount, mockTokenContext.token, true, "")
608
- ),
609
- abi.encode(returnedRuleset, reclaimAmount, _maxCashOutTaxRate, hookSpecifications)
610
- );
611
- mockExpect(
612
- address(directory), abi.encodeCall(IJBDirectory.controllerOf, (_projectId)), abi.encode(address(this))
613
- );
614
- mockExpect(
615
- address(this), abi.encodeCall(IJBController.burnTokensOf, (_holder, _projectId, _defaultAmount, "")), ""
616
- );
617
-
618
- // forge-lint: disable-next-line(unsafe-typecast)
619
- _acceptToken(_mockToken, 18, uint32(uint160(_mockToken)));
620
-
621
- vm.prank(_bene);
622
- _terminal.cashOutTokensOf(_holder, _projectId, _defaultAmount, _mockToken, _minReclaimed, _bene, "");
623
- }
624
- }