@bananapus/core-v6 0.0.1

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 (436) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +112 -0
  3. package/SKILLS.md +151 -0
  4. package/docs/book.css +13 -0
  5. package/docs/book.toml +12 -0
  6. package/docs/solidity.min.js +74 -0
  7. package/docs/src/README.md +703 -0
  8. package/docs/src/SUMMARY.md +94 -0
  9. package/docs/src/src/JBChainlinkV3PriceFeed.sol/contract.JBChainlinkV3PriceFeed.md +83 -0
  10. package/docs/src/src/JBChainlinkV3SequencerPriceFeed.sol/contract.JBChainlinkV3SequencerPriceFeed.md +88 -0
  11. package/docs/src/src/JBController.sol/contract.JBController.md +1121 -0
  12. package/docs/src/src/JBDeadline.sol/contract.JBDeadline.md +84 -0
  13. package/docs/src/src/JBDirectory.sol/contract.JBDirectory.md +294 -0
  14. package/docs/src/src/JBERC20.sol/contract.JBERC20.md +190 -0
  15. package/docs/src/src/JBFeelessAddresses.sol/contract.JBFeelessAddresses.md +80 -0
  16. package/docs/src/src/JBFundAccessLimits.sol/contract.JBFundAccessLimits.md +253 -0
  17. package/docs/src/src/JBMultiTerminal.sol/contract.JBMultiTerminal.md +1472 -0
  18. package/docs/src/src/JBPermissions.sol/contract.JBPermissions.md +199 -0
  19. package/docs/src/src/JBPrices.sol/contract.JBPrices.md +154 -0
  20. package/docs/src/src/JBProjects.sol/contract.JBProjects.md +131 -0
  21. package/docs/src/src/JBRulesets.sol/contract.JBRulesets.md +677 -0
  22. package/docs/src/src/JBSplits.sol/contract.JBSplits.md +237 -0
  23. package/docs/src/src/JBTerminalStore.sol/contract.JBTerminalStore.md +591 -0
  24. package/docs/src/src/JBTokens.sol/contract.JBTokens.md +353 -0
  25. package/docs/src/src/README.md +25 -0
  26. package/docs/src/src/abstract/JBControlled.sol/abstract.JBControlled.md +64 -0
  27. package/docs/src/src/abstract/JBPermissioned.sol/abstract.JBPermissioned.md +84 -0
  28. package/docs/src/src/abstract/README.md +5 -0
  29. package/docs/src/src/enums/JBApprovalStatus.sol/enum.JBApprovalStatus.md +17 -0
  30. package/docs/src/src/enums/README.md +4 -0
  31. package/docs/src/src/interfaces/IJBCashOutHook.sol/interface.IJBCashOutHook.md +29 -0
  32. package/docs/src/src/interfaces/IJBCashOutTerminal.sol/interface.IJBCashOutTerminal.md +57 -0
  33. package/docs/src/src/interfaces/IJBControlled.sol/interface.IJBControlled.md +12 -0
  34. package/docs/src/src/interfaces/IJBController.sol/interface.IJBController.md +334 -0
  35. package/docs/src/src/interfaces/IJBDirectory.sol/interface.IJBDirectory.md +108 -0
  36. package/docs/src/src/interfaces/IJBDirectoryAccessControl.sol/interface.IJBDirectoryAccessControl.md +19 -0
  37. package/docs/src/src/interfaces/IJBFeeTerminal.sol/interface.IJBFeeTerminal.md +91 -0
  38. package/docs/src/src/interfaces/IJBFeelessAddresses.sol/interface.IJBFeelessAddresses.md +26 -0
  39. package/docs/src/src/interfaces/IJBFundAccessLimits.sol/interface.IJBFundAccessLimits.md +88 -0
  40. package/docs/src/src/interfaces/IJBMigratable.sol/interface.IJBMigratable.md +29 -0
  41. package/docs/src/src/interfaces/IJBMultiTerminal.sol/interface.IJBMultiTerminal.md +50 -0
  42. package/docs/src/src/interfaces/IJBPayHook.sol/interface.IJBPayHook.md +28 -0
  43. package/docs/src/src/interfaces/IJBPayoutTerminal.sol/interface.IJBPayoutTerminal.md +105 -0
  44. package/docs/src/src/interfaces/IJBPermissioned.sol/interface.IJBPermissioned.md +12 -0
  45. package/docs/src/src/interfaces/IJBPermissions.sol/interface.IJBPermissions.md +74 -0
  46. package/docs/src/src/interfaces/IJBPermitTerminal.sol/interface.IJBPermitTerminal.md +15 -0
  47. package/docs/src/src/interfaces/IJBPriceFeed.sol/interface.IJBPriceFeed.md +12 -0
  48. package/docs/src/src/interfaces/IJBPrices.sol/interface.IJBPrices.md +74 -0
  49. package/docs/src/src/interfaces/IJBProjectUriRegistry.sol/interface.IJBProjectUriRegistry.md +19 -0
  50. package/docs/src/src/interfaces/IJBProjects.sol/interface.IJBProjects.md +49 -0
  51. package/docs/src/src/interfaces/IJBRulesetApprovalHook.sol/interface.IJBRulesetApprovalHook.md +35 -0
  52. package/docs/src/src/interfaces/IJBRulesetDataHook.sol/interface.IJBRulesetDataHook.md +97 -0
  53. package/docs/src/src/interfaces/IJBRulesets.sol/interface.IJBRulesets.md +165 -0
  54. package/docs/src/src/interfaces/IJBSplitHook.sol/interface.IJBSplitHook.md +31 -0
  55. package/docs/src/src/interfaces/IJBSplits.sol/interface.IJBSplits.md +35 -0
  56. package/docs/src/src/interfaces/IJBTerminal.sol/interface.IJBTerminal.md +141 -0
  57. package/docs/src/src/interfaces/IJBTerminalStore.sol/interface.IJBTerminalStore.md +198 -0
  58. package/docs/src/src/interfaces/IJBToken.sol/interface.IJBToken.md +54 -0
  59. package/docs/src/src/interfaces/IJBTokenUriResolver.sol/interface.IJBTokenUriResolver.md +12 -0
  60. package/docs/src/src/interfaces/IJBTokens.sol/interface.IJBTokens.md +151 -0
  61. package/docs/src/src/interfaces/README.md +33 -0
  62. package/docs/src/src/libraries/JBCashOuts.sol/library.JBCashOuts.md +40 -0
  63. package/docs/src/src/libraries/JBConstants.sol/library.JBConstants.md +52 -0
  64. package/docs/src/src/libraries/JBCurrencyIds.sol/library.JBCurrencyIds.md +19 -0
  65. package/docs/src/src/libraries/JBFees.sol/library.JBFees.md +52 -0
  66. package/docs/src/src/libraries/JBFixedPointNumber.sol/library.JBFixedPointNumber.md +12 -0
  67. package/docs/src/src/libraries/JBMetadataResolver.sol/library.JBMetadataResolver.md +242 -0
  68. package/docs/src/src/libraries/JBRulesetMetadataResolver.sol/library.JBRulesetMetadataResolver.md +180 -0
  69. package/docs/src/src/libraries/JBSplitGroupIds.sol/library.JBSplitGroupIds.md +14 -0
  70. package/docs/src/src/libraries/JBSurplus.sol/library.JBSurplus.md +44 -0
  71. package/docs/src/src/libraries/README.md +12 -0
  72. package/docs/src/src/periphery/JBDeadline1Day.sol/contract.JBDeadline1Day.md +15 -0
  73. package/docs/src/src/periphery/JBDeadline3Days.sol/contract.JBDeadline3Days.md +15 -0
  74. package/docs/src/src/periphery/JBDeadline3Hours.sol/contract.JBDeadline3Hours.md +15 -0
  75. package/docs/src/src/periphery/JBDeadline7Days.sol/contract.JBDeadline7Days.md +15 -0
  76. package/docs/src/src/periphery/JBMatchingPriceFeed.sol/contract.JBMatchingPriceFeed.md +22 -0
  77. package/docs/src/src/periphery/README.md +8 -0
  78. package/docs/src/src/structs/JBAccountingContext.sol/struct.JBAccountingContext.md +20 -0
  79. package/docs/src/src/structs/JBAfterCashOutRecordedContext.sol/struct.JBAfterCashOutRecordedContext.md +43 -0
  80. package/docs/src/src/structs/JBAfterPayRecordedContext.sol/struct.JBAfterPayRecordedContext.md +42 -0
  81. package/docs/src/src/structs/JBBeforeCashOutRecordedContext.sol/struct.JBBeforeCashOutRecordedContext.md +45 -0
  82. package/docs/src/src/structs/JBBeforePayRecordedContext.sol/struct.JBBeforePayRecordedContext.md +41 -0
  83. package/docs/src/src/structs/JBCashOutHookSpecification.sol/struct.JBCashOutHookSpecification.md +22 -0
  84. package/docs/src/src/structs/JBCurrencyAmount.sol/struct.JBCurrencyAmount.md +17 -0
  85. package/docs/src/src/structs/JBFee.sol/struct.JBFee.md +20 -0
  86. package/docs/src/src/structs/JBFundAccessLimitGroup.sol/struct.JBFundAccessLimitGroup.md +39 -0
  87. package/docs/src/src/structs/JBPayHookSpecification.sol/struct.JBPayHookSpecification.md +22 -0
  88. package/docs/src/src/structs/JBPermissionsData.sol/struct.JBPermissionsData.md +21 -0
  89. package/docs/src/src/structs/JBRuleset.sol/struct.JBRuleset.md +55 -0
  90. package/docs/src/src/structs/JBRulesetConfig.sol/struct.JBRulesetConfig.md +51 -0
  91. package/docs/src/src/structs/JBRulesetMetadata.sol/struct.JBRulesetMetadata.md +79 -0
  92. package/docs/src/src/structs/JBRulesetWeightCache.sol/struct.JBRulesetWeightCache.md +16 -0
  93. package/docs/src/src/structs/JBRulesetWithMetadata.sol/struct.JBRulesetWithMetadata.md +16 -0
  94. package/docs/src/src/structs/JBSingleAllowance.sol/struct.JBSingleAllowance.md +26 -0
  95. package/docs/src/src/structs/JBSplit.sol/struct.JBSplit.md +49 -0
  96. package/docs/src/src/structs/JBSplitGroup.sol/struct.JBSplitGroup.md +17 -0
  97. package/docs/src/src/structs/JBSplitHookContext.sol/struct.JBSplitHookContext.md +29 -0
  98. package/docs/src/src/structs/JBTerminalConfig.sol/struct.JBTerminalConfig.md +16 -0
  99. package/docs/src/src/structs/JBTokenAmount.sol/struct.JBTokenAmount.md +23 -0
  100. package/docs/src/src/structs/README.md +25 -0
  101. package/foundry.lock +11 -0
  102. package/foundry.toml +41 -0
  103. package/package.json +38 -0
  104. package/remappings.txt +1 -0
  105. package/script/Deploy.s.sol +111 -0
  106. package/script/DeployPeriphery.s.sol +287 -0
  107. package/script/helpers/CoreDeploymentLib.sol +121 -0
  108. package/slither-ci.config.json +10 -0
  109. package/sphinx.lock +507 -0
  110. package/src/JBChainlinkV3PriceFeed.sol +77 -0
  111. package/src/JBChainlinkV3SequencerPriceFeed.sol +75 -0
  112. package/src/JBController.sol +1186 -0
  113. package/src/JBDeadline.sol +73 -0
  114. package/src/JBDirectory.sol +343 -0
  115. package/src/JBERC20.sol +131 -0
  116. package/src/JBFeelessAddresses.sol +54 -0
  117. package/src/JBFundAccessLimits.sol +308 -0
  118. package/src/JBMultiTerminal.sol +2024 -0
  119. package/src/JBPermissions.sol +252 -0
  120. package/src/JBPrices.sol +227 -0
  121. package/src/JBProjects.sol +126 -0
  122. package/src/JBRulesets.sol +1093 -0
  123. package/src/JBSplits.sol +324 -0
  124. package/src/JBTerminalStore.sol +908 -0
  125. package/src/JBTokens.sol +376 -0
  126. package/src/abstract/JBControlled.sol +48 -0
  127. package/src/abstract/JBPermissioned.sol +77 -0
  128. package/src/enums/JBApprovalStatus.sol +12 -0
  129. package/src/interfaces/IJBCashOutHook.sol +15 -0
  130. package/src/interfaces/IJBCashOutTerminal.sol +51 -0
  131. package/src/interfaces/IJBControlled.sol +10 -0
  132. package/src/interfaces/IJBController.sol +280 -0
  133. package/src/interfaces/IJBDirectory.sol +69 -0
  134. package/src/interfaces/IJBDirectoryAccessControl.sol +15 -0
  135. package/src/interfaces/IJBFeeTerminal.sol +61 -0
  136. package/src/interfaces/IJBFeelessAddresses.sol +17 -0
  137. package/src/interfaces/IJBFundAccessLimits.sol +94 -0
  138. package/src/interfaces/IJBMigratable.sol +24 -0
  139. package/src/interfaces/IJBMultiTerminal.sol +36 -0
  140. package/src/interfaces/IJBPayHook.sol +14 -0
  141. package/src/interfaces/IJBPayoutTerminal.sol +92 -0
  142. package/src/interfaces/IJBPermissioned.sol +10 -0
  143. package/src/interfaces/IJBPermissions.sol +71 -0
  144. package/src/interfaces/IJBPermitTerminal.sol +14 -0
  145. package/src/interfaces/IJBPriceFeed.sol +10 -0
  146. package/src/interfaces/IJBPrices.sol +65 -0
  147. package/src/interfaces/IJBProjectUriRegistry.sol +15 -0
  148. package/src/interfaces/IJBProjects.sol +27 -0
  149. package/src/interfaces/IJBRulesetApprovalHook.sol +21 -0
  150. package/src/interfaces/IJBRulesetDataHook.sol +56 -0
  151. package/src/interfaces/IJBRulesets.sol +151 -0
  152. package/src/interfaces/IJBSplitHook.sol +16 -0
  153. package/src/interfaces/IJBSplits.sol +28 -0
  154. package/src/interfaces/IJBTerminal.sol +120 -0
  155. package/src/interfaces/IJBTerminalStore.sol +225 -0
  156. package/src/interfaces/IJBToken.sol +39 -0
  157. package/src/interfaces/IJBTokenUriResolver.sol +10 -0
  158. package/src/interfaces/IJBTokens.sol +113 -0
  159. package/src/libraries/JBCashOuts.sol +120 -0
  160. package/src/libraries/JBConstants.sol +14 -0
  161. package/src/libraries/JBCurrencyIds.sol +7 -0
  162. package/src/libraries/JBFees.sol +28 -0
  163. package/src/libraries/JBFixedPointNumber.sol +12 -0
  164. package/src/libraries/JBMetadataResolver.sol +306 -0
  165. package/src/libraries/JBRulesetMetadataResolver.sol +160 -0
  166. package/src/libraries/JBSplitGroupIds.sol +7 -0
  167. package/src/libraries/JBSurplus.sol +40 -0
  168. package/src/periphery/JBDeadline1Day.sol +8 -0
  169. package/src/periphery/JBDeadline3Days.sol +8 -0
  170. package/src/periphery/JBDeadline3Hours.sol +8 -0
  171. package/src/periphery/JBDeadline7Days.sol +8 -0
  172. package/src/periphery/JBMatchingPriceFeed.sol +13 -0
  173. package/src/structs/JBAccountingContext.sol +12 -0
  174. package/src/structs/JBAfterCashOutRecordedContext.sol +30 -0
  175. package/src/structs/JBAfterPayRecordedContext.sol +29 -0
  176. package/src/structs/JBBeforeCashOutRecordedContext.sol +31 -0
  177. package/src/structs/JBBeforePayRecordedContext.sol +28 -0
  178. package/src/structs/JBCashOutHookSpecification.sol +15 -0
  179. package/src/structs/JBCurrencyAmount.sol +10 -0
  180. package/src/structs/JBFee.sol +12 -0
  181. package/src/structs/JBFundAccessLimitGroup.sol +28 -0
  182. package/src/structs/JBPayHookSpecification.sol +15 -0
  183. package/src/structs/JBPermissionsData.sol +13 -0
  184. package/src/structs/JBRuleset.sol +42 -0
  185. package/src/structs/JBRulesetConfig.sol +43 -0
  186. package/src/structs/JBRulesetMetadata.sol +56 -0
  187. package/src/structs/JBRulesetWeightCache.sol +9 -0
  188. package/src/structs/JBRulesetWithMetadata.sol +12 -0
  189. package/src/structs/JBSingleAllowance.sol +16 -0
  190. package/src/structs/JBSplit.sol +37 -0
  191. package/src/structs/JBSplitGroup.sol +12 -0
  192. package/src/structs/JBSplitHookContext.sol +20 -0
  193. package/src/structs/JBTerminalConfig.sol +12 -0
  194. package/src/structs/JBTokenAmount.sol +14 -0
  195. package/test/AuditExploits.t.sol +2710 -0
  196. package/test/ComprehensiveInvariant.t.sol +298 -0
  197. package/test/EconomicSimulation.t.sol +340 -0
  198. package/test/EntryPointPermutations.t.sol +671 -0
  199. package/test/FlashLoanAttacks.t.sol +792 -0
  200. package/test/PermissionEscalation.t.sol +679 -0
  201. package/test/RulesetTransitions.t.sol +699 -0
  202. package/test/SplitLoopTests.t.sol +731 -0
  203. package/test/TestAccessToFunds.sol +2644 -0
  204. package/test/TestCashOut.sol +185 -0
  205. package/test/TestCashOutCountFor.sol +272 -0
  206. package/test/TestCashOutHooks.sol +317 -0
  207. package/test/TestCashOutTimingEdge.sol +229 -0
  208. package/test/TestDurationUnderflow.sol +220 -0
  209. package/test/TestFeeProcessingFailure.sol +208 -0
  210. package/test/TestFees.sol +604 -0
  211. package/test/TestInterfaceSupport.sol +62 -0
  212. package/test/TestJBERC20Inheritance.sol +91 -0
  213. package/test/TestLaunchProject.sol +176 -0
  214. package/test/TestMetaTx.sol +203 -0
  215. package/test/TestMetadataParserLib.sol +438 -0
  216. package/test/TestMigrationHeldFees.sol +249 -0
  217. package/test/TestMintTokensOf.sol +172 -0
  218. package/test/TestMultiTokenSurplus.sol +206 -0
  219. package/test/TestMultipleAccessLimits.sol +642 -0
  220. package/test/TestPayBurnRedeemFlow.sol +180 -0
  221. package/test/TestPayHooks.sol +190 -0
  222. package/test/TestPermissions.sol +305 -0
  223. package/test/TestPermissionsEdge.sol +286 -0
  224. package/test/TestPermit2Terminal.sol +339 -0
  225. package/test/TestRulesetQueueing.sol +1001 -0
  226. package/test/TestRulesetQueuingStress.sol +778 -0
  227. package/test/TestRulesetWeightCaching.sol +177 -0
  228. package/test/TestSplits.sol +369 -0
  229. package/test/TestTerminalMigration.sol +167 -0
  230. package/test/TestTokenFlow.sol +174 -0
  231. package/test/WeirdTokenTests.t.sol +764 -0
  232. package/test/formal/BondingCurveProperties.t.sol +411 -0
  233. package/test/formal/FeeProperties.t.sol +246 -0
  234. package/test/helpers/JBTest.sol +129 -0
  235. package/test/helpers/MetadataResolverHelper.sol +116 -0
  236. package/test/helpers/TestBaseWorkflow.sol +317 -0
  237. package/test/invariants/Phase3DeepInvariant.t.sol +404 -0
  238. package/test/invariants/RulesetsInvariant.t.sol +115 -0
  239. package/test/invariants/TerminalStoreInvariant.t.sol +220 -0
  240. package/test/invariants/TokensInvariant.t.sol +184 -0
  241. package/test/invariants/handlers/ComprehensiveHandler.sol +285 -0
  242. package/test/invariants/handlers/EconomicHandler.sol +347 -0
  243. package/test/invariants/handlers/Phase3Handler.sol +414 -0
  244. package/test/invariants/handlers/RulesetsHandler.sol +111 -0
  245. package/test/invariants/handlers/TerminalStoreHandler.sol +146 -0
  246. package/test/invariants/handlers/TokensHandler.sol +127 -0
  247. package/test/mock/ERC2771ForwarderMock.sol +37 -0
  248. package/test/mock/MockERC20.sol +18 -0
  249. package/test/mock/MockMaliciousBeneficiary.sol +67 -0
  250. package/test/mock/MockMaliciousSplitHook.sol +42 -0
  251. package/test/mock/MockPriceFeed.sol +20 -0
  252. package/test/trees/JBController/burnTokensOf.tree +9 -0
  253. package/test/trees/JBController/claimTokensFor.tree +5 -0
  254. package/test/trees/JBController/deployERC20For.tree +5 -0
  255. package/test/trees/JBController/getRulesetOf.tree +5 -0
  256. package/test/trees/JBController/launchProjectFor.tree +12 -0
  257. package/test/trees/JBController/launchRulesetsFor.tree +8 -0
  258. package/test/trees/JBController/migrateController.tree +12 -0
  259. package/test/trees/JBController/mintTokensOf.tree +12 -0
  260. package/test/trees/JBController/payReservedTokenToTerminal.tree +8 -0
  261. package/test/trees/JBController/receiveMigrationFrom.tree +4 -0
  262. package/test/trees/JBController/sendReservedTokensToSplitsOf.tree +12 -0
  263. package/test/trees/JBController/setMetadataOf.tree +5 -0
  264. package/test/trees/JBController/setSplitGroupsOf.tree +5 -0
  265. package/test/trees/JBController/setTokenFor.tree +5 -0
  266. package/test/trees/JBController/transferCreditsFrom.tree +8 -0
  267. package/test/trees/JBDirectory/primaryTerminalOf.tree +8 -0
  268. package/test/trees/JBDirectory/setControllerOf.tree +11 -0
  269. package/test/trees/JBDirectory/setPrimaryTerminalOf.tree +15 -0
  270. package/test/trees/JBDirectory/setTerminalsOf.tree +11 -0
  271. package/test/trees/JBERC20/initialize.tree +7 -0
  272. package/test/trees/JBERC20/name.tree +5 -0
  273. package/test/trees/JBERC20/nonces.tree +5 -0
  274. package/test/trees/JBERC20/symbol.tree +5 -0
  275. package/test/trees/JBFeelessAddresses/setFeelessAddress.tree +5 -0
  276. package/test/trees/JBFeelessAddresses/supportsInterface.tree +5 -0
  277. package/test/trees/JBFundAccessLimits/payoutLimitOf.tree +5 -0
  278. package/test/trees/JBFundAccessLimits/payoutLimitsOf.tree +8 -0
  279. package/test/trees/JBFundAccessLimits/setFundAccessLimitsFor.tree +18 -0
  280. package/test/trees/JBFundAccessLimits/surplusAllowanceOf.tree +5 -0
  281. package/test/trees/JBFundAccessLimits/surplusAllowancesOf.tree +8 -0
  282. package/test/trees/JBMetadataResolver/getDataFor.tree +8 -0
  283. package/test/trees/JBMultiTerminal/accountingContextsOf.tree +5 -0
  284. package/test/trees/JBMultiTerminal/addAccountingContextsFor.tree +10 -0
  285. package/test/trees/JBMultiTerminal/addToBalanceOf.tree +23 -0
  286. package/test/trees/JBMultiTerminal/cashOutTokensOf.tree +23 -0
  287. package/test/trees/JBMultiTerminal/executePayout.tree +32 -0
  288. package/test/trees/JBMultiTerminal/executeProcessFee.tree +14 -0
  289. package/test/trees/JBMultiTerminal/migrateBalanceOf.tree +12 -0
  290. package/test/trees/JBMultiTerminal/pay.tree +23 -0
  291. package/test/trees/JBMultiTerminal/processHeldFeesOf.tree +8 -0
  292. package/test/trees/JBMultiTerminal/sendPayoutsOf.tree +34 -0
  293. package/test/trees/JBMultiTerminal/useAllowanceOf.tree +16 -0
  294. package/test/trees/JBPermissions/hasPermission.tree +8 -0
  295. package/test/trees/JBPermissions/hasPermissions.tree +8 -0
  296. package/test/trees/JBPermissions/setPermissionsFor.tree +5 -0
  297. package/test/trees/JBPrices/addPriceFeedFor.tree +14 -0
  298. package/test/trees/JBPrices/pricePerUnitOf.tree +11 -0
  299. package/test/trees/JBProjects/createFor.tree +11 -0
  300. package/test/trees/JBProjects/setTokenUriResolver.tree +5 -0
  301. package/test/trees/JBProjects/supportsInterface.tree +9 -0
  302. package/test/trees/JBProjects/tokenURI.tree +5 -0
  303. package/test/trees/JBRulesets/currentApprovalStatusForLatestRulesetOf.tree +8 -0
  304. package/test/trees/JBRulesets/currentOf.tree +12 -0
  305. package/test/trees/JBRulesets/getRulesetOf.tree +5 -0
  306. package/test/trees/JBRulesets/latestQueuedRulesetOf.tree +10 -0
  307. package/test/trees/JBRulesets/rulesetsOf.tree +11 -0
  308. package/test/trees/JBRulesets/upcomingRulesetOf.tree +20 -0
  309. package/test/trees/JBRulesets/updateRulesetWeightCache.tree +5 -0
  310. package/test/trees/JBSplits/setSplitGroupsOf.tree +17 -0
  311. package/test/trees/JBSplits/splitsOf.tree +5 -0
  312. package/test/trees/JBTerminalStore/currentReclaimableSurplusOf.tree +16 -0
  313. package/test/trees/JBTerminalStore/currentSurplusOf.tree +25 -0
  314. package/test/trees/JBTerminalStore/currentTotalSurplusOf.tree +5 -0
  315. package/test/trees/JBTerminalStore/recordCashOutsFor.tree +16 -0
  316. package/test/trees/JBTerminalStore/recordPaymentFrom.tree +14 -0
  317. package/test/trees/JBTerminalStore/recordPayoutFor.tree +10 -0
  318. package/test/trees/JBTerminalStore/recordTerminalMigration.tree +5 -0
  319. package/test/trees/JBTerminalStore/recordUsedAllowanceOf.tree +10 -0
  320. package/test/trees/JBTokens/burnFrom.tree +10 -0
  321. package/test/trees/JBTokens/claimTokensFor.tree +10 -0
  322. package/test/trees/JBTokens/deployERC20For.tree +12 -0
  323. package/test/trees/JBTokens/mintFor.tree +10 -0
  324. package/test/trees/JBTokens/setTokenFor.tree +11 -0
  325. package/test/trees/JBTokens/totalBalanceOf.tree +5 -0
  326. package/test/trees/JBTokens/totalSupplyOf.tree +5 -0
  327. package/test/trees/JBTokens/transferCreditsFrom.tree +8 -0
  328. package/test/trees/mintTokensOf.tree +12 -0
  329. package/test/units/static/JBChainlinkV3PriceFeed/TestPriceFeed.sol +220 -0
  330. package/test/units/static/JBController/JBControllerSetup.sol +40 -0
  331. package/test/units/static/JBController/TestBurnTokensOf.sol +107 -0
  332. package/test/units/static/JBController/TestClaimTokensFor.sol +60 -0
  333. package/test/units/static/JBController/TestDeployErc20For.sol +80 -0
  334. package/test/units/static/JBController/TestLaunchProjectFor.sol +282 -0
  335. package/test/units/static/JBController/TestLaunchRulesetsFor.sol +322 -0
  336. package/test/units/static/JBController/TestMigrateController.sol +148 -0
  337. package/test/units/static/JBController/TestMintTokensOfUnits.sol +102 -0
  338. package/test/units/static/JBController/TestPayReservedTokenToTerminal.sol +71 -0
  339. package/test/units/static/JBController/TestReceiveMigrationFrom.sol +95 -0
  340. package/test/units/static/JBController/TestRulesetViews.sol +219 -0
  341. package/test/units/static/JBController/TestSendReservedTokensToSplitsOf.sol +595 -0
  342. package/test/units/static/JBController/TestSetSplitGroupsOf.sol +63 -0
  343. package/test/units/static/JBController/TestSetTokenFor.sol +227 -0
  344. package/test/units/static/JBController/TestSetUriOf.sol +53 -0
  345. package/test/units/static/JBController/TestTransferCreditsFrom.sol +159 -0
  346. package/test/units/static/JBDeadline/TestDeadlineFuzz.sol +194 -0
  347. package/test/units/static/JBDirectory/JBDirectorySetup.sol +22 -0
  348. package/test/units/static/JBDirectory/TestPrimaryTerminalOf.sol +122 -0
  349. package/test/units/static/JBDirectory/TestSetControllerOf.sol +173 -0
  350. package/test/units/static/JBDirectory/TestSetControllerOfMigrationOrder.sol +98 -0
  351. package/test/units/static/JBDirectory/TestSetPrimaryTerminalOf.sol +169 -0
  352. package/test/units/static/JBDirectory/TestSetTerminalsOf.sol +128 -0
  353. package/test/units/static/JBERC20/JBERC20Setup.sol +20 -0
  354. package/test/units/static/JBERC20/SigUtils.sol +34 -0
  355. package/test/units/static/JBERC20/TestInitialize.sol +54 -0
  356. package/test/units/static/JBERC20/TestName.sol +30 -0
  357. package/test/units/static/JBERC20/TestNonces.sol +59 -0
  358. package/test/units/static/JBERC20/TestSymbol.sol +31 -0
  359. package/test/units/static/JBFeelessAdresses/JBFeelessSetup.sol +20 -0
  360. package/test/units/static/JBFeelessAdresses/TestInterfaces.sol +29 -0
  361. package/test/units/static/JBFeelessAdresses/TestSetFeelessAddress.sol +35 -0
  362. package/test/units/static/JBFees/TestFeesFuzz.sol +78 -0
  363. package/test/units/static/JBFixedPointNumber/TestAdjustDecimals.sol +16 -0
  364. package/test/units/static/JBFixedPointNumber/TestAdjustDecimalsFuzz.sol +71 -0
  365. package/test/units/static/JBFundAccessLimits/JBFundAccessSetup.sol +21 -0
  366. package/test/units/static/JBFundAccessLimits/TestFundAccessLimitsEdge.sol +159 -0
  367. package/test/units/static/JBFundAccessLimits/TestPayoutLimitOf.sol +56 -0
  368. package/test/units/static/JBFundAccessLimits/TestPayoutLimitsOf.sol +94 -0
  369. package/test/units/static/JBFundAccessLimits/TestSetFundAccessLimitsFor.sol +182 -0
  370. package/test/units/static/JBFundAccessLimits/TestSurplusAllowanceOf.sol +61 -0
  371. package/test/units/static/JBFundAccessLimits/TestSurplusAllowancesOf.sol +96 -0
  372. package/test/units/static/JBMetadataResolver/TestGetDataFor.sol +89 -0
  373. package/test/units/static/JBMetadataResolver/TestMetadataResolverFuzz.sol +227 -0
  374. package/test/units/static/JBMetadataResolver/TestMetadataResolverM20M21.sol +245 -0
  375. package/test/units/static/JBMultiTerminal/JBMultiTerminalSetup.sol +39 -0
  376. package/test/units/static/JBMultiTerminal/TestAccountingContextsOf.sol +65 -0
  377. package/test/units/static/JBMultiTerminal/TestAddAccountingContextsFor.sol +313 -0
  378. package/test/units/static/JBMultiTerminal/TestAddToBalanceOf.sol +432 -0
  379. package/test/units/static/JBMultiTerminal/TestCashOutTokensOf.sol +478 -0
  380. package/test/units/static/JBMultiTerminal/TestExecutePayout.sol +577 -0
  381. package/test/units/static/JBMultiTerminal/TestExecuteProcessFee.sol +176 -0
  382. package/test/units/static/JBMultiTerminal/TestMigrateBalanceOf.sol +190 -0
  383. package/test/units/static/JBMultiTerminal/TestPay.sol +514 -0
  384. package/test/units/static/JBMultiTerminal/TestProcessHeldFeesOf.sol +29 -0
  385. package/test/units/static/JBMultiTerminal/TestSendPayoutsOf.sol +243 -0
  386. package/test/units/static/JBMultiTerminal/TestUseAllowanceOf.sol +310 -0
  387. package/test/units/static/JBPermissions/JBPermissionsSetup.sol +18 -0
  388. package/test/units/static/JBPermissions/TestHasPermission.sol +50 -0
  389. package/test/units/static/JBPermissions/TestHasPermissions.sol +93 -0
  390. package/test/units/static/JBPermissions/TestSetPermissionsFor.sol +62 -0
  391. package/test/units/static/JBPrices/JBPricesSetup.sol +26 -0
  392. package/test/units/static/JBPrices/TestAddPriceFeedFor.sol +102 -0
  393. package/test/units/static/JBPrices/TestPricePerUnitOf.sol +129 -0
  394. package/test/units/static/JBPrices/TestPrices.sol +262 -0
  395. package/test/units/static/JBProjects/JBProjectsSetup.sol +20 -0
  396. package/test/units/static/JBProjects/TestCreateFor.sol +69 -0
  397. package/test/units/static/JBProjects/TestInitialProject.sol +19 -0
  398. package/test/units/static/JBProjects/TestInterfaces.sol +27 -0
  399. package/test/units/static/JBProjects/TestSetResolver.sol +36 -0
  400. package/test/units/static/JBProjects/TestTokenUri.sol +38 -0
  401. package/test/units/static/JBRulesetMetadataResolver/TestSetCashOutTaxRateTo.sol +99 -0
  402. package/test/units/static/JBRulesets/JBRulesetsSetup.sol +21 -0
  403. package/test/units/static/JBRulesets/TestCurrentApprovalStatusForLatestRulesetOf.sol +257 -0
  404. package/test/units/static/JBRulesets/TestCurrentOf.sol +231 -0
  405. package/test/units/static/JBRulesets/TestGetRulesetOf.sol +94 -0
  406. package/test/units/static/JBRulesets/TestLatestQueuedRulesetOf.sol +252 -0
  407. package/test/units/static/JBRulesets/TestRulesets.sol +617 -0
  408. package/test/units/static/JBRulesets/TestRulesetsOf.sol +37 -0
  409. package/test/units/static/JBRulesets/TestUpcomingRulesetOf.sol +526 -0
  410. package/test/units/static/JBRulesets/TestUpdateRulesetWeightCache.sol +91 -0
  411. package/test/units/static/JBSplits/JBSplitsSetup.sol +23 -0
  412. package/test/units/static/JBSplits/TestSelfManagedSplitGroups.sol +502 -0
  413. package/test/units/static/JBSplits/TestSetSplitGroupsOf.sol +370 -0
  414. package/test/units/static/JBSplits/TestSplitsLockedEdge.sol +262 -0
  415. package/test/units/static/JBSplits/TestSplitsOf.sol +24 -0
  416. package/test/units/static/JBSplits/TestSplitsPacking.sol +33 -0
  417. package/test/units/static/JBSurplus/TestSurplusFuzz.sol +125 -0
  418. package/test/units/static/JBTerminalStore/JBTerminalStoreSetup.sol +23 -0
  419. package/test/units/static/JBTerminalStore/TestCurrentReclaimableSurplusOf.sol +434 -0
  420. package/test/units/static/JBTerminalStore/TestCurrentSurplusOf.sol +428 -0
  421. package/test/units/static/JBTerminalStore/TestCurrentTotalSurplusOf.sol +65 -0
  422. package/test/units/static/JBTerminalStore/TestRecordCashOutsFor.sol +479 -0
  423. package/test/units/static/JBTerminalStore/TestRecordPaymentFrom.sol +508 -0
  424. package/test/units/static/JBTerminalStore/TestRecordPayoutFor.sol +257 -0
  425. package/test/units/static/JBTerminalStore/TestRecordTerminalMigration.sol +131 -0
  426. package/test/units/static/JBTerminalStore/TestRecordUsedAllowanceOf.sol +390 -0
  427. package/test/units/static/JBTerminalStore/TestUint224Overflow.sol +187 -0
  428. package/test/units/static/JBTokens/JBTokensSetup.sol +23 -0
  429. package/test/units/static/JBTokens/TestBurnFrom.sol +104 -0
  430. package/test/units/static/JBTokens/TestClaimTokensFor.sol +107 -0
  431. package/test/units/static/JBTokens/TestDeployERC20ForUnits.sol +89 -0
  432. package/test/units/static/JBTokens/TestMintFor.sol +97 -0
  433. package/test/units/static/JBTokens/TestSetTokenFor.sol +95 -0
  434. package/test/units/static/JBTokens/TestTotalBalanceOf.sol +65 -0
  435. package/test/units/static/JBTokens/TestTotalSupplyOf.sol +56 -0
  436. package/test/units/static/JBTokens/TestTransferCreditsFrom.sol +54 -0
@@ -0,0 +1,604 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.6;
3
+
4
+ import /* {*} from */ "./helpers/TestBaseWorkflow.sol";
5
+
6
+ // Projects can be launched.
7
+ contract TestFees_Local is TestBaseWorkflow {
8
+ IJBController private _controller;
9
+ JBRulesetMetadata private _metadata;
10
+ JBRulesetMetadata private _feeProjectMetadata;
11
+ IJBMultiTerminal private _terminal;
12
+ IJBMultiTerminal private _terminal2;
13
+ IJBRulesets private _rulesets;
14
+
15
+ uint224 _nativePayAmount;
16
+ uint224 _nativeDistLimit;
17
+
18
+ uint256 private _projectId;
19
+ address private _projectOwner;
20
+ address private _beneficiary;
21
+
22
+ function setUp() public override {
23
+ super.setUp();
24
+
25
+ _projectOwner = multisig();
26
+ _beneficiary = beneficiary();
27
+ _terminal = jbMultiTerminal();
28
+ _terminal2 = jbMultiTerminal2();
29
+ _controller = jbController();
30
+ _rulesets = jbRulesets();
31
+ _nativePayAmount = 2 ether;
32
+ _nativeDistLimit = 1 ether;
33
+
34
+ _metadata = JBRulesetMetadata({
35
+ reservedPercent: 0,
36
+ cashOutTaxRate: 0,
37
+ baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
38
+ pausePay: false,
39
+ pauseCreditTransfers: false,
40
+ allowOwnerMinting: false,
41
+ allowSetCustomToken: false,
42
+ allowTerminalMigration: true,
43
+ allowSetTerminals: false,
44
+ ownerMustSendPayouts: false,
45
+ allowSetController: false,
46
+ allowAddAccountingContext: true,
47
+ allowAddPriceFeed: false,
48
+ holdFees: true,
49
+ useTotalSurplusForCashOuts: false,
50
+ useDataHookForPay: false,
51
+ useDataHookForCashOut: false,
52
+ dataHook: address(0),
53
+ metadata: 0
54
+ });
55
+
56
+ _feeProjectMetadata = JBRulesetMetadata({
57
+ reservedPercent: 0,
58
+ cashOutTaxRate: 0,
59
+ baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
60
+ pausePay: false,
61
+ pauseCreditTransfers: false,
62
+ allowOwnerMinting: false,
63
+ allowSetCustomToken: false,
64
+ allowTerminalMigration: true,
65
+ allowSetTerminals: false,
66
+ ownerMustSendPayouts: false,
67
+ allowSetController: false,
68
+ allowAddAccountingContext: true,
69
+ allowAddPriceFeed: false,
70
+ holdFees: true,
71
+ useTotalSurplusForCashOuts: false,
72
+ useDataHookForPay: false,
73
+ useDataHookForCashOut: false,
74
+ dataHook: address(0),
75
+ metadata: 0
76
+ });
77
+
78
+ // Package up the limits for the given terminal.
79
+ JBFundAccessLimitGroup[] memory _fundAccessLimitGroupProjectOne = new JBFundAccessLimitGroup[](1);
80
+ {
81
+ // Specify a payout limit.
82
+ JBCurrencyAmount[] memory _payoutLimits = new JBCurrencyAmount[](1);
83
+ _payoutLimits[0] = JBCurrencyAmount({amount: 2 ether, currency: uint32(uint160(JBConstants.NATIVE_TOKEN))});
84
+
85
+ // Specify a surplus allowance.
86
+ JBCurrencyAmount[] memory _surplusAllowances = new JBCurrencyAmount[](1);
87
+ _surplusAllowances[0] = JBCurrencyAmount({amount: 0, currency: uint32(uint160(JBConstants.NATIVE_TOKEN))});
88
+
89
+ _fundAccessLimitGroupProjectOne[0] = JBFundAccessLimitGroup({
90
+ terminal: address(_terminal),
91
+ token: JBConstants.NATIVE_TOKEN,
92
+ payoutLimits: _payoutLimits,
93
+ surplusAllowances: _surplusAllowances
94
+ });
95
+ }
96
+
97
+ JBFundAccessLimitGroup[] memory _fundAccessLimitGroupProjectTwo = new JBFundAccessLimitGroup[](1);
98
+ {
99
+ // Specify a payout limit.
100
+ JBCurrencyAmount[] memory _payoutLimits = new JBCurrencyAmount[](1);
101
+ _payoutLimits[0] =
102
+ JBCurrencyAmount({amount: _nativeDistLimit, currency: uint32(uint160(JBConstants.NATIVE_TOKEN))});
103
+
104
+ // Specify a surplus allowance.
105
+ JBCurrencyAmount[] memory _surplusAllowances = new JBCurrencyAmount[](1);
106
+ _surplusAllowances[0] =
107
+ JBCurrencyAmount({amount: _nativeDistLimit, currency: uint32(uint160(JBConstants.NATIVE_TOKEN))});
108
+
109
+ _fundAccessLimitGroupProjectTwo[0] = JBFundAccessLimitGroup({
110
+ terminal: address(_terminal),
111
+ token: JBConstants.NATIVE_TOKEN,
112
+ payoutLimits: _payoutLimits,
113
+ surplusAllowances: _surplusAllowances
114
+ });
115
+ }
116
+
117
+ // Package up ruleset configuration.
118
+ JBRulesetConfig[] memory _feeProjectRuleset = new JBRulesetConfig[](1);
119
+ _feeProjectRuleset[0].mustStartAtOrAfter = 0;
120
+ _feeProjectRuleset[0].duration = 0;
121
+ _feeProjectRuleset[0].weight = 0;
122
+ _feeProjectRuleset[0].weightCutPercent = 0;
123
+ _feeProjectRuleset[0].approvalHook = IJBRulesetApprovalHook(address(0));
124
+ _feeProjectRuleset[0].metadata = _feeProjectMetadata;
125
+ _feeProjectRuleset[0].splitGroups = new JBSplitGroup[](0);
126
+ _feeProjectRuleset[0].fundAccessLimitGroups = _fundAccessLimitGroupProjectOne;
127
+
128
+ // Package up ruleset configuration.
129
+ JBRulesetConfig[] memory _rulesetConfig = new JBRulesetConfig[](1);
130
+ _rulesetConfig[0].mustStartAtOrAfter = 0;
131
+ _rulesetConfig[0].duration = 0;
132
+ _rulesetConfig[0].weight = 0;
133
+ _rulesetConfig[0].weightCutPercent = 0;
134
+ _rulesetConfig[0].approvalHook = IJBRulesetApprovalHook(address(0));
135
+ _rulesetConfig[0].metadata = _metadata;
136
+ _rulesetConfig[0].splitGroups = new JBSplitGroup[](0);
137
+ _rulesetConfig[0].fundAccessLimitGroups = _fundAccessLimitGroupProjectTwo;
138
+
139
+ JBTerminalConfig[] memory _terminalConfigurations = new JBTerminalConfig[](2);
140
+
141
+ JBAccountingContext[] memory _tokensToAccept = new JBAccountingContext[](1);
142
+ _tokensToAccept[0] = JBAccountingContext({
143
+ token: JBConstants.NATIVE_TOKEN, decimals: 18, currency: uint32(uint160(JBConstants.NATIVE_TOKEN))
144
+ });
145
+
146
+ _terminalConfigurations[0] =
147
+ JBTerminalConfig({terminal: _terminal, accountingContextsToAccept: _tokensToAccept});
148
+ _terminalConfigurations[1] =
149
+ JBTerminalConfig({terminal: _terminal2, accountingContextsToAccept: _tokensToAccept});
150
+
151
+ // Dummy project that receive fees.
152
+ _controller.launchProjectFor({
153
+ owner: _projectOwner,
154
+ projectUri: "myIPFSHash",
155
+ rulesetConfigurations: _feeProjectRuleset,
156
+ terminalConfigurations: _terminalConfigurations,
157
+ memo: ""
158
+ });
159
+
160
+ _projectId = _controller.launchProjectFor({
161
+ owner: _projectOwner,
162
+ projectUri: "myIPFSHash",
163
+ rulesetConfigurations: _rulesetConfig,
164
+ terminalConfigurations: _terminalConfigurations,
165
+ memo: ""
166
+ });
167
+ }
168
+
169
+ function testHeldFeeIsProcessedOnMigrate() public {
170
+ // Setup: Pay so we have balance to use
171
+ _terminal.pay{value: _nativePayAmount}({
172
+ projectId: _projectId,
173
+ amount: _nativePayAmount,
174
+ token: JBConstants.NATIVE_TOKEN,
175
+ beneficiary: _beneficiary,
176
+ minReturnedTokens: 0,
177
+ memo: "",
178
+ metadata: new bytes(0)
179
+ });
180
+
181
+ // Setup: use allowance so we incur a fee
182
+ vm.startPrank(_projectOwner);
183
+ _terminal.useAllowanceOf({
184
+ projectId: _projectId,
185
+ amount: _nativeDistLimit,
186
+ currency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
187
+ token: JBConstants.NATIVE_TOKEN,
188
+ minTokensPaidOut: 0,
189
+ beneficiary: payable(_projectOwner),
190
+ feeBeneficiary: payable(_projectOwner),
191
+ memo: "MEMO"
192
+ });
193
+
194
+ // Calculate the fee from the allowance use.
195
+ uint256 _feeAmount = _nativeDistLimit * _terminal.FEE() / JBConstants.MAX_FEE;
196
+
197
+ uint256 _afterFee = _nativeDistLimit - _feeAmount;
198
+
199
+ // Check: Owner balance is accurate (dist - fee) and fee is in the terminal (held but not processed)
200
+ assertEq(_projectOwner.balance, _afterFee);
201
+ assertEq(address(_terminal).balance, _nativeDistLimit + _feeAmount);
202
+
203
+ // Send: Migration to terminal2
204
+ _terminal.migrateBalanceOf(_projectId, JBConstants.NATIVE_TOKEN, _terminal2);
205
+
206
+ // Check: Held Fee is processed and feeAmount remains in terminal
207
+ assertEq(address(_terminal).balance, _feeAmount);
208
+
209
+ vm.stopPrank();
210
+ }
211
+
212
+ function testHeldFeeRepaymentWithMigration() public {
213
+ // Setup: Pay so we have balance to use
214
+ _terminal.pay{value: _nativePayAmount}({
215
+ projectId: _projectId,
216
+ amount: _nativePayAmount,
217
+ token: JBConstants.NATIVE_TOKEN,
218
+ beneficiary: _beneficiary,
219
+ minReturnedTokens: 0,
220
+ memo: "",
221
+ metadata: new bytes(0)
222
+ });
223
+
224
+ // Setup: use allowance so we incur a fee
225
+ vm.startPrank(_projectOwner);
226
+ _terminal.useAllowanceOf({
227
+ projectId: _projectId,
228
+ amount: _nativeDistLimit,
229
+ currency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
230
+ token: JBConstants.NATIVE_TOKEN,
231
+ minTokensPaidOut: 0,
232
+ beneficiary: payable(_projectOwner),
233
+ feeBeneficiary: payable(_projectOwner),
234
+ memo: "MEMO"
235
+ });
236
+
237
+ // Calculate the fee from the allowance use.
238
+ uint256 _feeAmount = _nativeDistLimit * _terminal.FEE() / JBConstants.MAX_FEE;
239
+
240
+ uint256 _afterFee = _nativeDistLimit - _feeAmount;
241
+
242
+ // Check: Owner balance is accurate (dist - fee) and fee is in the terminal (held but not processed)
243
+ assertEq(_projectOwner.balance, _afterFee);
244
+ assertEq(address(_terminal).balance, _nativeDistLimit + _feeAmount);
245
+
246
+ vm.startPrank(_projectOwner);
247
+ // Setup: addToBalance to reset our held fees
248
+ _terminal.addToBalanceOf{value: _nativeDistLimit - _feeAmount}(
249
+ _projectId, JBConstants.NATIVE_TOKEN, _nativeDistLimit - _feeAmount, true, "forge test", ""
250
+ );
251
+
252
+ // Send: Migration to terminal2
253
+ _terminal.migrateBalanceOf(_projectId, JBConstants.NATIVE_TOKEN, _terminal2);
254
+
255
+ // Check: Held fee has been repaid, no balance remains.
256
+ assertEq(address(_terminal).balance, 0);
257
+
258
+ vm.stopPrank();
259
+ }
260
+
261
+ function testHeldFeeUnlockAndProcess() public {
262
+ // Setup: Pay so we have balance to use
263
+ _terminal.pay{value: _nativePayAmount}({
264
+ projectId: _projectId,
265
+ amount: _nativePayAmount,
266
+ token: JBConstants.NATIVE_TOKEN,
267
+ beneficiary: _beneficiary,
268
+ minReturnedTokens: 0,
269
+ memo: "",
270
+ metadata: new bytes(0)
271
+ });
272
+
273
+ // Setup: use allowance so we incur a fee
274
+ vm.startPrank(_projectOwner);
275
+ _terminal.useAllowanceOf({
276
+ projectId: _projectId,
277
+ amount: _nativeDistLimit,
278
+ currency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
279
+ token: JBConstants.NATIVE_TOKEN,
280
+ minTokensPaidOut: 0,
281
+ beneficiary: payable(_projectOwner),
282
+ feeBeneficiary: payable(_projectOwner),
283
+ memo: "MEMO"
284
+ });
285
+
286
+ // Calculate the fee from the allowance use.
287
+ uint256 _feeAmount = _nativeDistLimit * _terminal.FEE() / JBConstants.MAX_FEE;
288
+
289
+ uint256 _afterFee = _nativeDistLimit - _feeAmount;
290
+
291
+ // Check: Owner balance is accurate (dist - fee) and fee is in the terminal (held but not processed)
292
+ assertEq(_projectOwner.balance, _afterFee);
293
+ assertEq(address(_terminal).balance, _nativeDistLimit + _feeAmount);
294
+
295
+ // Setup: fast-forward to when fees can be processed
296
+ vm.warp(block.timestamp + 2_419_200);
297
+
298
+ // Send: Process the fees
299
+ _terminal.processHeldFeesOf(_projectId, JBConstants.NATIVE_TOKEN, 100);
300
+
301
+ // Check: Reflected in terminal
302
+ JBFee[] memory _emptyFee = _terminal.heldFeesOf(_projectId, JBConstants.NATIVE_TOKEN, 100);
303
+ assertEq(_emptyFee.length, 0);
304
+ }
305
+
306
+ function testDoubleHeldFeeUnlockAndProcess() public {
307
+ // Setup: Pay so we have balance to use.
308
+ _terminal.pay{value: _nativePayAmount}({
309
+ projectId: _projectId,
310
+ amount: _nativePayAmount,
311
+ token: JBConstants.NATIVE_TOKEN,
312
+ beneficiary: _beneficiary,
313
+ minReturnedTokens: 0,
314
+ memo: "",
315
+ metadata: new bytes(0)
316
+ });
317
+
318
+ // Half the dist limit to be able to use allowance twice.
319
+ uint256 _halfDistLimit = _nativeDistLimit / 2;
320
+
321
+ // Setup: use allowance so we incur a fee
322
+ vm.startPrank(_projectOwner);
323
+ _terminal.useAllowanceOf({
324
+ projectId: _projectId,
325
+ amount: _halfDistLimit,
326
+ currency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
327
+ token: JBConstants.NATIVE_TOKEN,
328
+ minTokensPaidOut: 0,
329
+ beneficiary: payable(_projectOwner),
330
+ feeBeneficiary: payable(_projectOwner),
331
+ memo: "MEMO"
332
+ });
333
+ // Setup: use allowance so we incur a fee
334
+ vm.startPrank(_projectOwner);
335
+ _terminal.useAllowanceOf({
336
+ projectId: _projectId,
337
+ amount: _halfDistLimit,
338
+ currency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
339
+ token: JBConstants.NATIVE_TOKEN,
340
+ minTokensPaidOut: 0,
341
+ beneficiary: payable(_projectOwner),
342
+ feeBeneficiary: payable(_projectOwner),
343
+ memo: "MEMO"
344
+ });
345
+
346
+ // Calculate the fee from the allowance use.
347
+ uint256 _feeAmount = _halfDistLimit * _terminal.FEE() / JBConstants.MAX_FEE;
348
+
349
+ uint256 _afterFee = (_halfDistLimit - _feeAmount) * 2;
350
+
351
+ // Check: Owner balance is accurate (dist - fee) and fee is in the terminal (held but not processed)
352
+ assertEq(_projectOwner.balance, _afterFee);
353
+ assertEq(address(_terminal).balance, _nativeDistLimit + (_feeAmount * 2));
354
+
355
+ // Setup: fast-forward to when fees can be processed
356
+ vm.warp(block.timestamp + 2_419_200);
357
+
358
+ // Send: Process the fees
359
+ _terminal.processHeldFeesOf(_projectId, JBConstants.NATIVE_TOKEN, 2);
360
+
361
+ // Check: Reflected in terminal
362
+ JBFee[] memory _emptyFee = _terminal.heldFeesOf(_projectId, JBConstants.NATIVE_TOKEN, 100);
363
+ assertEq(_emptyFee.length, 0);
364
+ }
365
+
366
+ function testDoubleSequentialHeldFeeUnlockAndProcess() public {
367
+ // Setup: Pay so we have balance to use.
368
+ _terminal.pay{value: _nativePayAmount}({
369
+ projectId: _projectId,
370
+ amount: _nativePayAmount,
371
+ token: JBConstants.NATIVE_TOKEN,
372
+ beneficiary: _beneficiary,
373
+ minReturnedTokens: 0,
374
+ memo: "",
375
+ metadata: new bytes(0)
376
+ });
377
+
378
+ // Half the dist limit to be able to use allowance twice.
379
+ uint256 _halfDistLimit = _nativeDistLimit / 2;
380
+
381
+ // Setup: use allowance so we incur a fee
382
+ vm.startPrank(_projectOwner);
383
+ _terminal.useAllowanceOf({
384
+ projectId: _projectId,
385
+ amount: _halfDistLimit,
386
+ currency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
387
+ token: JBConstants.NATIVE_TOKEN,
388
+ minTokensPaidOut: 0,
389
+ beneficiary: payable(_projectOwner),
390
+ feeBeneficiary: payable(_projectOwner),
391
+ memo: "MEMO"
392
+ });
393
+ // Setup: use allowance so we incur a fee
394
+ vm.startPrank(_projectOwner);
395
+ _terminal.useAllowanceOf({
396
+ projectId: _projectId,
397
+ amount: _halfDistLimit,
398
+ currency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
399
+ token: JBConstants.NATIVE_TOKEN,
400
+ minTokensPaidOut: 0,
401
+ beneficiary: payable(_projectOwner),
402
+ feeBeneficiary: payable(_projectOwner),
403
+ memo: "MEMO"
404
+ });
405
+
406
+ // Calculate the fee from the allowance use.
407
+ uint256 _feeAmount = _halfDistLimit * _terminal.FEE() / JBConstants.MAX_FEE;
408
+
409
+ uint256 _afterFee = (_halfDistLimit - _feeAmount) * 2;
410
+
411
+ // Check: Owner balance is accurate (dist - fee) and fee is in the terminal (held but not processed)
412
+ assertEq(_projectOwner.balance, _afterFee);
413
+ assertEq(address(_terminal).balance, _nativeDistLimit + (_feeAmount * 2));
414
+
415
+ // Setup: fast-forward to when fees can be processed
416
+ vm.warp(block.timestamp + 2_419_200);
417
+
418
+ // Send: Process the fees
419
+ _terminal.processHeldFeesOf(_projectId, JBConstants.NATIVE_TOKEN, 1);
420
+
421
+ // Check: Reflected in terminal
422
+ JBFee[] memory _oneFee = _terminal.heldFeesOf(_projectId, JBConstants.NATIVE_TOKEN, 100);
423
+ assertEq(_oneFee.length, 1);
424
+
425
+ // Send: Process the fees
426
+ _terminal.processHeldFeesOf(_projectId, JBConstants.NATIVE_TOKEN, 1);
427
+
428
+ // Check: Reflected in terminal
429
+ JBFee[] memory _emptyFee = _terminal.heldFeesOf(_projectId, JBConstants.NATIVE_TOKEN, 100);
430
+ assertEq(_emptyFee.length, 0);
431
+ }
432
+
433
+ function testHeldFeeUnlockTooSoon() public {
434
+ // Setup: Pay so we have balance to use
435
+ _terminal.pay{value: _nativePayAmount}({
436
+ projectId: _projectId,
437
+ amount: _nativePayAmount,
438
+ token: JBConstants.NATIVE_TOKEN,
439
+ beneficiary: _beneficiary,
440
+ minReturnedTokens: 0,
441
+ memo: "",
442
+ metadata: new bytes(0)
443
+ });
444
+
445
+ // Setup: use allowance so we incur a fee
446
+ vm.prank(_projectOwner);
447
+ _terminal.useAllowanceOf({
448
+ projectId: _projectId,
449
+ amount: _nativeDistLimit,
450
+ currency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
451
+ token: JBConstants.NATIVE_TOKEN,
452
+ minTokensPaidOut: 0,
453
+ beneficiary: payable(_projectOwner),
454
+ feeBeneficiary: payable(_projectOwner),
455
+ memo: "MEMO"
456
+ });
457
+
458
+ // Calculate the fee from the allowance use.
459
+ uint256 _feeAmount = _nativeDistLimit * _terminal.FEE() / JBConstants.MAX_FEE;
460
+
461
+ uint256 _afterFee = _nativeDistLimit - _feeAmount;
462
+
463
+ // Check: Owner balance is accurate (dist - fee) and fee is in the terminal (held but not processed)
464
+ assertEq(_projectOwner.balance, _afterFee);
465
+ assertEq(address(_terminal).balance, _nativeDistLimit + _feeAmount);
466
+
467
+ // Check: Heldfee unlock timestamp
468
+ JBFee[] memory _checkOgFee = _terminal.heldFeesOf(_projectId, JBConstants.NATIVE_TOKEN, 100);
469
+ assertEq(_checkOgFee[0].unlockTimestamp, block.timestamp + 2_419_200);
470
+
471
+ // Setup: fast-forward to next block where fee shouldn't process (too early)
472
+ vm.warp(block.timestamp + 1);
473
+
474
+ // Send: Fail to process the fees
475
+ _terminal.processHeldFeesOf(_projectId, JBConstants.NATIVE_TOKEN, 100);
476
+
477
+ // Check: Fee persists in terminal
478
+ JBFee[] memory _persistingFee = _terminal.heldFeesOf(_projectId, JBConstants.NATIVE_TOKEN, 100);
479
+
480
+ // Wher go fee..?
481
+ assertEq(_persistingFee.length, 1);
482
+ }
483
+
484
+ function test_AuditFinding4POC() external {
485
+ vm.skip(true);
486
+
487
+ // Setup: Pay the zero project so the terminal has balance of 1 eth from another project.
488
+ _terminal.pay{value: 1 ether}({
489
+ projectId: 1,
490
+ amount: _nativePayAmount,
491
+ token: JBConstants.NATIVE_TOKEN,
492
+ beneficiary: _beneficiary,
493
+ minReturnedTokens: 0,
494
+ memo: "",
495
+ metadata: new bytes(0)
496
+ });
497
+
498
+ // Setup: Pay project 2 so we have balance to use
499
+ _terminal.pay{value: 1 ether}({
500
+ projectId: _projectId,
501
+ amount: _nativePayAmount,
502
+ token: JBConstants.NATIVE_TOKEN,
503
+ beneficiary: _beneficiary,
504
+ minReturnedTokens: 0,
505
+ memo: "",
506
+ metadata: new bytes(0)
507
+ });
508
+
509
+ uint256 prevBalance = _projectOwner.balance;
510
+
511
+ // Ensure we start with zero balance before payout
512
+ assertEq(prevBalance, 0);
513
+
514
+ // Send payout
515
+ // So you don't have to scroll up, _nativeDistAmount = 1 ether.
516
+ _terminal.sendPayoutsOf(
517
+ _projectId,
518
+ JBConstants.NATIVE_TOKEN,
519
+ _nativeDistLimit,
520
+ uint32(uint160(JBConstants.NATIVE_TOKEN)),
521
+ _nativeDistLimit
522
+ );
523
+
524
+ // Ensure the payout was successful
525
+ uint256 _feeAmount =
526
+ _nativeDistLimit - _nativeDistLimit * JBConstants.MAX_FEE / (_terminal.FEE() + JBConstants.MAX_FEE);
527
+ uint256 _afterFee = _nativeDistLimit - _feeAmount;
528
+ assertEq(_projectOwner.balance, _afterFee);
529
+
530
+ // Terminal has accepted 2 pays (totaling 2 eth), payout of nativeDistLimit (1eth) was sent, and fee was taken.
531
+ // So we only have 1 eth and the fee taken left in the terminal.
532
+ assertEq(address(_terminal).balance, _nativeDistLimit + _feeAmount);
533
+
534
+ // Check the fee attributes
535
+ JBFee[] memory _checkOgFee = _terminal.heldFeesOf(_projectId, JBConstants.NATIVE_TOKEN, 100);
536
+
537
+ // Check the unlock timestamp
538
+ assertEq(_checkOgFee[0].unlockTimestamp, block.timestamp + 2_419_200);
539
+
540
+ // Audit Example correctly asserts that the fee amount is 1 ETH
541
+ assertEq(_checkOgFee[0].amount, _nativeDistLimit);
542
+
543
+ // Audit Example correctly asserts that the projects balance in terminal store will be zero.
544
+ uint256 project2BalanceStore =
545
+ jbTerminalStore().balanceOf(address(_terminal), _projectId, JBConstants.NATIVE_TOKEN);
546
+ assertEq(project2BalanceStore, 0);
547
+
548
+ // We continue on with the example, where another project carries a balance (1 eth here).
549
+ uint256 project1BalanceStore = jbTerminalStore().balanceOf(address(_terminal), 1, JBConstants.NATIVE_TOKEN);
550
+ assertEq(project1BalanceStore, 1 ether);
551
+
552
+ // Warp to when we can call processHeldFeesOf.
553
+ vm.warp(_checkOgFee[0].unlockTimestamp);
554
+
555
+ // Accounting should be incorrectly adjusted for the fee project after the process call.
556
+ uint256 feeProjectBalanceBefore = project1BalanceStore;
557
+
558
+ // Process the held fees, which adds 1 ether 'amount' to the fee project.
559
+ _terminal.processHeldFeesOf(_projectId, JBConstants.NATIVE_TOKEN, 100);
560
+
561
+ // Reference the balance now (for the fee project).
562
+ uint256 feeProjectBalanceAfter = jbTerminalStore().balanceOf(address(_terminal), 1, JBConstants.NATIVE_TOKEN);
563
+
564
+ // Fee project now has a balance of 2 eth even though it has only been paid one eth.
565
+ assertEq(feeProjectBalanceAfter, 2 ether);
566
+ assertGt(feeProjectBalanceAfter, feeProjectBalanceBefore);
567
+
568
+ // Pay project 2 again so the terminal holds enough balance for the excess usage via the fee project.
569
+ _terminal.pay{value: 1 ether}({
570
+ projectId: _projectId,
571
+ amount: _nativePayAmount,
572
+ token: JBConstants.NATIVE_TOKEN,
573
+ beneficiary: _beneficiary,
574
+ minReturnedTokens: 0,
575
+ memo: "",
576
+ metadata: new bytes(0)
577
+ });
578
+
579
+ // Reference the owner balance before payout.
580
+ uint256 ownerBalanceBefore = _projectOwner.balance;
581
+
582
+ // Now we see if we can use the 2 ether minus fees via project 1.
583
+ uint256 paidOutFromProjectOne = _terminal.sendPayoutsOf({
584
+ projectId: 1,
585
+ token: JBConstants.NATIVE_TOKEN,
586
+ amount: 2 ether,
587
+ currency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
588
+ minTokensPaidOut: 0
589
+ });
590
+
591
+ // Calculate the fee from the allowance use.
592
+ uint256 _feeAmount2 = paidOutFromProjectOne - paidOutFromProjectOne * JBConstants.MAX_FEE
593
+ / (_terminal.FEE() + JBConstants.MAX_FEE);
594
+
595
+ // The payout happens as described in the example.
596
+ uint256 _afterFee2 = paidOutFromProjectOne - _feeAmount2;
597
+ assertEq(_projectOwner.balance - ownerBalanceBefore, _afterFee2);
598
+
599
+ // Confirm the total terminal balance < the balance of project 2.
600
+ uint256 balanceOfProject2 =
601
+ jbTerminalStore().balanceOf(address(_terminal), _projectId, JBConstants.NATIVE_TOKEN);
602
+ assertLt(address(_terminal).balance, balanceOfProject2);
603
+ }
604
+ }
@@ -0,0 +1,62 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.6;
3
+
4
+ import /* {*} from */ "./helpers/TestBaseWorkflow.sol";
5
+
6
+ /// Contracts are introspective about the interfaces they adhere to.
7
+ contract TestEIP165_Local is TestBaseWorkflow {
8
+ bytes4 private constant _notSupportedInterface = 0xffffffff;
9
+
10
+ function testJBController() public view {
11
+ JBController _controller = jbController();
12
+
13
+ // Should support these interfaces.
14
+ assertTrue(_controller.supportsInterface(type(IERC165).interfaceId));
15
+ assertTrue(_controller.supportsInterface(type(IJBMigratable).interfaceId));
16
+ assertTrue(_controller.supportsInterface(type(IJBPermissioned).interfaceId));
17
+ assertTrue(_controller.supportsInterface(type(IJBController).interfaceId));
18
+
19
+ // Make sure it doesn't always return true.
20
+ assertTrue(!_controller.supportsInterface(_notSupportedInterface));
21
+ }
22
+
23
+ function testJBMultiTerminal() public view {
24
+ JBMultiTerminal _terminal = jbMultiTerminal();
25
+
26
+ // Should support these interfaces.
27
+ assertTrue(_terminal.supportsInterface(type(IJBMultiTerminal).interfaceId));
28
+ assertTrue(_terminal.supportsInterface(type(IJBTerminal).interfaceId));
29
+ assertTrue(_terminal.supportsInterface(type(IJBCashOutTerminal).interfaceId));
30
+ assertTrue(_terminal.supportsInterface(type(IJBPayoutTerminal).interfaceId));
31
+ assertTrue(_terminal.supportsInterface(type(IJBPermitTerminal).interfaceId));
32
+ assertTrue(_terminal.supportsInterface(type(IJBFeeTerminal).interfaceId));
33
+ assertTrue(_terminal.supportsInterface(type(IERC165).interfaceId));
34
+
35
+ // Make sure it doesn't always return true.
36
+ assertTrue(!_terminal.supportsInterface(_notSupportedInterface));
37
+ }
38
+
39
+ function testJBProjects() public view {
40
+ JBProjects _projects = jbProjects();
41
+
42
+ // Should support these interfaces.
43
+ assertTrue(_projects.supportsInterface(type(IERC165).interfaceId));
44
+ assertTrue(_projects.supportsInterface(type(IERC721).interfaceId));
45
+ assertTrue(_projects.supportsInterface(type(IERC721Metadata).interfaceId));
46
+ assertTrue(_projects.supportsInterface(type(IJBProjects).interfaceId));
47
+
48
+ // Make sure it doesn't always return true.
49
+ assertTrue(!_projects.supportsInterface(_notSupportedInterface));
50
+ }
51
+
52
+ function testJBDeadline() public {
53
+ JBDeadline _approvalHook = new JBDeadline(3000);
54
+
55
+ // Should support these interfaces.
56
+ assertTrue(_approvalHook.supportsInterface(type(IERC165).interfaceId));
57
+ assertTrue(_approvalHook.supportsInterface(type(IJBRulesetApprovalHook).interfaceId));
58
+
59
+ // Make sure it doesn't always return true.
60
+ assertTrue(!_approvalHook.supportsInterface(_notSupportedInterface));
61
+ }
62
+ }