@rev-net/core-v6 0.0.11 → 0.0.13

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 (81) hide show
  1. package/ADMINISTRATION.md +7 -7
  2. package/ARCHITECTURE.md +11 -11
  3. package/AUDIT_INSTRUCTIONS.md +295 -0
  4. package/CHANGE_LOG.md +316 -0
  5. package/README.md +9 -6
  6. package/RISKS.md +180 -35
  7. package/SKILLS.md +9 -11
  8. package/STYLE_GUIDE.md +14 -1
  9. package/USER_JOURNEYS.md +489 -0
  10. package/package.json +9 -9
  11. package/script/Deploy.s.sol +124 -40
  12. package/script/helpers/RevnetCoreDeploymentLib.sol +19 -6
  13. package/src/REVDeployer.sol +183 -175
  14. package/src/REVLoans.sol +65 -28
  15. package/src/interfaces/IREVDeployer.sol +25 -23
  16. package/src/structs/REV721TiersHookFlags.sol +1 -0
  17. package/src/structs/REVAutoIssuance.sol +1 -0
  18. package/src/structs/REVBaseline721HookConfig.sol +1 -0
  19. package/src/structs/REVConfig.sol +1 -0
  20. package/src/structs/REVCroptopAllowedPost.sol +1 -0
  21. package/src/structs/REVDeploy721TiersHookConfig.sol +13 -14
  22. package/src/structs/REVDescription.sol +1 -0
  23. package/src/structs/REVLoan.sol +1 -0
  24. package/src/structs/REVLoanSource.sol +1 -0
  25. package/src/structs/REVStageConfig.sol +1 -0
  26. package/src/structs/REVSuckerDeploymentConfig.sol +1 -0
  27. package/test/REV.integrations.t.sol +148 -19
  28. package/test/REVAutoIssuanceFuzz.t.sol +31 -6
  29. package/test/REVDeployerRegressions.t.sol +47 -9
  30. package/test/REVInvincibility.t.sol +83 -19
  31. package/test/REVInvincibilityHandler.sol +29 -0
  32. package/test/REVLifecycle.t.sol +36 -6
  33. package/test/REVLoans.invariants.t.sol +64 -10
  34. package/test/REVLoansAttacks.t.sol +54 -9
  35. package/test/REVLoansFeeRecovery.t.sol +61 -15
  36. package/test/REVLoansFindings.t.sol +42 -9
  37. package/test/REVLoansRegressions.t.sol +33 -6
  38. package/test/REVLoansSourceFeeRecovery.t.sol +491 -0
  39. package/test/REVLoansSourced.t.sol +79 -17
  40. package/test/REVLoansUnSourced.t.sol +61 -10
  41. package/test/TestBurnHeldTokens.t.sol +47 -11
  42. package/test/TestCEIPattern.t.sol +37 -6
  43. package/test/TestCashOutCallerValidation.t.sol +41 -8
  44. package/test/TestConversionDocumentation.t.sol +50 -13
  45. package/test/TestCrossCurrencyReclaim.t.sol +584 -0
  46. package/test/TestCrossSourceReallocation.t.sol +37 -6
  47. package/test/TestERC2771MetaTx.t.sol +557 -0
  48. package/test/TestEmptyBuybackSpecs.t.sol +45 -10
  49. package/test/TestFlashLoanSurplus.t.sol +39 -7
  50. package/test/TestHookArrayOOB.t.sol +42 -13
  51. package/test/TestLiquidationBehavior.t.sol +37 -7
  52. package/test/TestLoanSourceRotation.t.sol +525 -0
  53. package/test/TestLongTailEconomics.t.sol +651 -0
  54. package/test/TestLowFindings.t.sol +80 -8
  55. package/test/TestMixedFixes.t.sol +43 -9
  56. package/test/TestPermit2Signatures.t.sol +657 -0
  57. package/test/TestReallocationSandwich.t.sol +384 -0
  58. package/test/TestRevnetRegressions.t.sol +324 -0
  59. package/test/TestSplitWeightAdjustment.t.sol +52 -13
  60. package/test/TestSplitWeightE2E.t.sol +53 -18
  61. package/test/TestSplitWeightFork.t.sol +66 -21
  62. package/test/TestStageTransitionBorrowable.t.sol +38 -6
  63. package/test/TestSwapTerminalPermission.t.sol +37 -7
  64. package/test/TestUint112Overflow.t.sol +39 -6
  65. package/test/TestZeroRepayment.t.sol +37 -6
  66. package/test/fork/ForkTestBase.sol +66 -17
  67. package/test/fork/TestCashOutFork.t.sol +9 -3
  68. package/test/fork/TestLoanBorrowFork.t.sol +1 -0
  69. package/test/fork/TestLoanCrossRulesetFork.t.sol +11 -3
  70. package/test/fork/TestLoanLiquidationFork.t.sol +1 -0
  71. package/test/fork/TestLoanReallocateFork.t.sol +1 -0
  72. package/test/fork/TestLoanRepayFork.t.sol +1 -0
  73. package/test/fork/TestLoanTransferFork.t.sol +133 -0
  74. package/test/fork/TestSplitWeightFork.t.sol +3 -0
  75. package/test/helpers/REVEmpty721Config.sol +46 -0
  76. package/test/mock/MockBuybackDataHook.sol +1 -0
  77. package/test/regression/TestBurnPermissionRequired.t.sol +267 -0
  78. package/test/regression/TestCrossRevnetLiquidation.t.sol +228 -0
  79. package/test/regression/TestCumulativeLoanCounter.t.sol +38 -8
  80. package/test/regression/TestLiquidateGapHandling.t.sol +40 -8
  81. package/test/regression/TestZeroPriceFeed.t.sol +396 -0
@@ -1,22 +1,31 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity 0.8.26;
3
3
 
4
+ // forge-lint: disable-next-line(unaliased-plain-import)
4
5
  import "forge-std/Test.sol";
6
+ // forge-lint: disable-next-line(unaliased-plain-import)
5
7
  import /* {*} from */ "@bananapus/core-v6/test/helpers/TestBaseWorkflow.sol";
6
- import /* {*} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
8
+ // import /* {*} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
9
+ // forge-lint: disable-next-line(unaliased-plain-import)
7
10
  import /* {*} from */ "./../src/REVDeployer.sol";
11
+ // forge-lint: disable-next-line(unaliased-plain-import)
8
12
  import "@croptop/core-v6/src/CTPublisher.sol";
9
13
  import {MockBuybackDataHook} from "./mock/MockBuybackDataHook.sol";
14
+ import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
10
15
 
16
+ // forge-lint: disable-next-line(unaliased-plain-import)
11
17
  import "@bananapus/core-v6/script/helpers/CoreDeploymentLib.sol";
18
+ // forge-lint: disable-next-line(unaliased-plain-import)
12
19
  import "@bananapus/721-hook-v6/script/helpers/Hook721DeploymentLib.sol";
20
+ // forge-lint: disable-next-line(unaliased-plain-import)
13
21
  import "@bananapus/suckers-v6/script/helpers/SuckerDeploymentLib.sol";
22
+ // forge-lint: disable-next-line(unaliased-plain-import)
14
23
  import "@croptop/core-v6/script/helpers/CroptopDeploymentLib.sol";
24
+ // forge-lint: disable-next-line(unaliased-plain-import)
15
25
  import "@bananapus/router-terminal-v6/script/helpers/RouterTerminalDeploymentLib.sol";
16
26
 
17
27
  import {JBConstants} from "@bananapus/core-v6/src/libraries/JBConstants.sol";
18
28
  import {JBAccountingContext} from "@bananapus/core-v6/src/structs/JBAccountingContext.sol";
19
- import {REVLoans} from "../src/REVLoans.sol";
20
29
  import {REVStageConfig, REVAutoIssuance} from "../src/structs/REVStageConfig.sol";
21
30
  import {REVDescription} from "../src/structs/REVDescription.sol";
22
31
  import {IREVLoans} from "./../src/interfaces/IREVLoans.sol";
@@ -26,7 +35,7 @@ import {JBTokenMapping} from "@bananapus/suckers-v6/src/structs/JBTokenMapping.s
26
35
  import {JB721TiersHookDeployer} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
27
36
  import {JBArbitrumSuckerDeployer} from "@bananapus/suckers-v6/src/deployers/JBArbitrumSuckerDeployer.sol";
28
37
  import {JBArbitrumSucker, JBLayer, IArbGatewayRouter, IInbox} from "@bananapus/suckers-v6/src/JBArbitrumSucker.sol";
29
- import {JBAddToBalanceMode} from "@bananapus/suckers-v6/src/enums/JBAddToBalanceMode.sol";
38
+
30
39
  import {JB721TiersHook} from "@bananapus/721-hook-v6/src/JB721TiersHook.sol";
31
40
  import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
32
41
  import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
@@ -40,28 +49,43 @@ struct FeeProjectConfig {
40
49
 
41
50
  contract REVnet_Integrations is TestBaseWorkflow {
42
51
  /// @notice the salts that are used to deploy the contracts.
52
+ // forge-lint: disable-next-line(mixed-case-variable)
43
53
  bytes32 REV_DEPLOYER_SALT = "REVDeployer";
54
+ // forge-lint: disable-next-line(mixed-case-variable)
44
55
  bytes32 ERC20_SALT = "REV_TOKEN";
45
56
 
57
+ // forge-lint: disable-next-line(mixed-case-variable)
46
58
  REVDeployer REV_DEPLOYER;
59
+ // forge-lint: disable-next-line(mixed-case-variable)
47
60
  JB721TiersHook EXAMPLE_HOOK;
48
61
 
49
62
  /// @notice Deploys tiered ERC-721 hooks for revnets.
63
+ // forge-lint: disable-next-line(mixed-case-variable)
50
64
  IJB721TiersHookDeployer HOOK_DEPLOYER;
65
+ // forge-lint: disable-next-line(mixed-case-variable)
51
66
  IJB721TiersHookStore HOOK_STORE;
67
+ // forge-lint: disable-next-line(mixed-case-variable)
52
68
  IJBAddressRegistry ADDRESS_REGISTRY;
53
69
 
70
+ // forge-lint: disable-next-line(mixed-case-variable)
54
71
  IREVLoans LOANS_CONTRACT;
55
72
 
56
73
  /// @notice Deploys and tracks suckers for revnets.
74
+ // forge-lint: disable-next-line(mixed-case-variable)
57
75
  IJBSuckerRegistry SUCKER_REGISTRY;
76
+ // forge-lint: disable-next-line(mixed-case-variable)
58
77
  IJBSuckerDeployer ARB_SUCKER_DEPLOYER;
78
+ // forge-lint: disable-next-line(mixed-case-variable)
59
79
  bytes ENCODED_CONFIG;
60
80
 
81
+ // forge-lint: disable-next-line(mixed-case-variable)
61
82
  CTPublisher PUBLISHER;
83
+ // forge-lint: disable-next-line(mixed-case-variable)
62
84
  MockBuybackDataHook MOCK_BUYBACK;
63
85
 
86
+ // forge-lint: disable-next-line(mixed-case-variable)
64
87
  uint256 FEE_PROJECT_ID;
88
+ // forge-lint: disable-next-line(mixed-case-variable)
65
89
  uint256 REVNET_ID;
66
90
  uint256 decimals = 18;
67
91
  uint256 decimalMultiplier = 10 ** decimals;
@@ -71,6 +95,7 @@ contract REVnet_Integrations is TestBaseWorkflow {
71
95
 
72
96
  uint256 firstStageId;
73
97
 
98
+ // forge-lint: disable-next-line(mixed-case-variable)
74
99
  address USER = makeAddr("user");
75
100
 
76
101
  function getFeeProjectConfig() internal returns (FeeProjectConfig memory) {
@@ -97,7 +122,11 @@ contract REVnet_Integrations is TestBaseWorkflow {
97
122
 
98
123
  REVAutoIssuance[] memory issuanceConfs = new REVAutoIssuance[](1);
99
124
  issuanceConfs[0] = REVAutoIssuance({
100
- chainId: uint32(block.chainid), count: uint104(70_000 * decimalMultiplier), beneficiary: multisig()
125
+ // forge-lint: disable-next-line(unsafe-typecast)
126
+ chainId: uint32(block.chainid),
127
+ // forge-lint: disable-next-line(unsafe-typecast)
128
+ count: uint104(70_000 * decimalMultiplier),
129
+ beneficiary: multisig()
101
130
  });
102
131
 
103
132
  JBSplit[] memory splits = new JBSplit[](1);
@@ -112,6 +141,7 @@ contract REVnet_Integrations is TestBaseWorkflow {
112
141
  autoIssuances: issuanceConfs,
113
142
  splitPercent: 2000, // 20%
114
143
  splits: splits,
144
+ // forge-lint: disable-next-line(unsafe-typecast)
115
145
  initialIssuance: uint112(1000 * decimalMultiplier),
116
146
  issuanceCutFrequency: 90 days,
117
147
  issuanceCutPercent: JBConstants.MAX_WEIGHT_CUT_PERCENT / 2,
@@ -146,6 +176,7 @@ contract REVnet_Integrations is TestBaseWorkflow {
146
176
 
147
177
  // The project's revnet configuration
148
178
  REVConfig memory revnetConfiguration = REVConfig({
179
+ // forge-lint: disable-next-line(named-struct-fields)
149
180
  description: REVDescription(name, symbol, projectUri, ERC20_SALT),
150
181
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
151
182
  splitOperator: multisig(),
@@ -177,8 +208,9 @@ contract REVnet_Integrations is TestBaseWorkflow {
177
208
 
178
209
  HOOK_STORE = new JB721TiersHookStore();
179
210
 
180
- EXAMPLE_HOOK =
181
- new JB721TiersHook(jbDirectory(), jbPermissions(), jbRulesets(), HOOK_STORE, jbSplits(), multisig());
211
+ EXAMPLE_HOOK = new JB721TiersHook(
212
+ jbDirectory(), jbPermissions(), jbPrices(), jbRulesets(), HOOK_STORE, jbSplits(), multisig()
213
+ );
182
214
 
183
215
  ADDRESS_REGISTRY = new JBAddressRegistry();
184
216
 
@@ -204,9 +236,8 @@ contract REVnet_Integrations is TestBaseWorkflow {
204
236
  ARB_SUCKER_DEPLOYER = IJBSuckerDeployer(address(_deployer));
205
237
 
206
238
  // Deploy the ARB sucker singleton.
207
- JBArbitrumSucker _singleton = new JBArbitrumSucker(
208
- _deployer, jbDirectory(), jbPermissions(), jbTokens(), JBAddToBalanceMode.MANUAL, address(0)
209
- );
239
+ JBArbitrumSucker _singleton =
240
+ new JBArbitrumSucker(_deployer, jbDirectory(), jbPermissions(), jbTokens(), 1, SUCKER_REGISTRY, address(0));
210
241
 
211
242
  // Set the layer specific confguration.
212
243
  _deployer.setChainSpecificConstants(JBLayer.L1, IInbox(address(1)), IArbGatewayRouter(address(1)));
@@ -226,11 +257,13 @@ contract REVnet_Integrations is TestBaseWorkflow {
226
257
 
227
258
  // Configure the project.
228
259
  vm.prank(address(multisig()));
229
- REVNET_ID = REV_DEPLOYER.deployFor({
260
+ (REVNET_ID,) = REV_DEPLOYER.deployFor({
230
261
  revnetId: FEE_PROJECT_ID, // Zero to deploy a new revnet
231
262
  configuration: feeProjectConfig.configuration,
232
263
  terminalConfigurations: feeProjectConfig.terminalConfigurations,
233
- suckerDeploymentConfiguration: feeProjectConfig.suckerDeploymentConfiguration
264
+ suckerDeploymentConfiguration: feeProjectConfig.suckerDeploymentConfiguration,
265
+ tiered721HookConfiguration: REVEmpty721Config.empty721Config(uint32(uint160(JBConstants.NATIVE_TOKEN))),
266
+ allowedPosts: REVEmpty721Config.emptyAllowedPosts()
234
267
  });
235
268
  }
236
269
 
@@ -279,6 +312,101 @@ contract REVnet_Integrations is TestBaseWorkflow {
279
312
  assertEq(isNewOperator, true);
280
313
  }
281
314
 
315
+ function test_operator_has_default_permissions() public view {
316
+ address operator = multisig();
317
+
318
+ // Base permissions every split operator should have.
319
+ assertTrue(
320
+ jbPermissions()
321
+ .hasPermission(
322
+ operator, address(REV_DEPLOYER), REVNET_ID, JBPermissionIds.SET_SPLIT_GROUPS, false, false
323
+ ),
324
+ "operator missing SET_SPLIT_GROUPS"
325
+ );
326
+ assertTrue(
327
+ jbPermissions()
328
+ .hasPermission(
329
+ operator, address(REV_DEPLOYER), REVNET_ID, JBPermissionIds.SET_BUYBACK_POOL, false, false
330
+ ),
331
+ "operator missing SET_BUYBACK_POOL"
332
+ );
333
+ assertTrue(
334
+ jbPermissions()
335
+ .hasPermission(
336
+ operator, address(REV_DEPLOYER), REVNET_ID, JBPermissionIds.SET_BUYBACK_TWAP, false, false
337
+ ),
338
+ "operator missing SET_BUYBACK_TWAP"
339
+ );
340
+ assertTrue(
341
+ jbPermissions()
342
+ .hasPermission(
343
+ operator, address(REV_DEPLOYER), REVNET_ID, JBPermissionIds.SET_PROJECT_URI, false, false
344
+ ),
345
+ "operator missing SET_PROJECT_URI"
346
+ );
347
+ assertTrue(
348
+ jbPermissions()
349
+ .hasPermission(
350
+ operator, address(REV_DEPLOYER), REVNET_ID, JBPermissionIds.ADD_PRICE_FEED, false, false
351
+ ),
352
+ "operator missing ADD_PRICE_FEED"
353
+ );
354
+ assertTrue(
355
+ jbPermissions()
356
+ .hasPermission(operator, address(REV_DEPLOYER), REVNET_ID, JBPermissionIds.SUCKER_SAFETY, false, false),
357
+ "operator missing SUCKER_SAFETY"
358
+ );
359
+ assertTrue(
360
+ jbPermissions()
361
+ .hasPermission(
362
+ operator, address(REV_DEPLOYER), REVNET_ID, JBPermissionIds.SET_BUYBACK_HOOK, false, false
363
+ ),
364
+ "operator missing SET_BUYBACK_HOOK"
365
+ );
366
+ assertTrue(
367
+ jbPermissions()
368
+ .hasPermission(
369
+ operator, address(REV_DEPLOYER), REVNET_ID, JBPermissionIds.SET_ROUTER_TERMINAL, false, false
370
+ ),
371
+ "operator missing SET_ROUTER_TERMINAL"
372
+ );
373
+ assertTrue(
374
+ jbPermissions()
375
+ .hasPermission(
376
+ operator, address(REV_DEPLOYER), REVNET_ID, JBPermissionIds.SET_TOKEN_METADATA, false, false
377
+ ),
378
+ "operator missing SET_TOKEN_METADATA"
379
+ );
380
+
381
+ // 721 hook permissions (always granted since every revnet gets a 721 hook).
382
+ assertTrue(
383
+ jbPermissions()
384
+ .hasPermission(
385
+ operator, address(REV_DEPLOYER), REVNET_ID, JBPermissionIds.ADJUST_721_TIERS, false, false
386
+ ),
387
+ "operator missing ADJUST_721_TIERS"
388
+ );
389
+ assertTrue(
390
+ jbPermissions()
391
+ .hasPermission(
392
+ operator, address(REV_DEPLOYER), REVNET_ID, JBPermissionIds.SET_721_METADATA, false, false
393
+ ),
394
+ "operator missing SET_721_METADATA"
395
+ );
396
+ assertTrue(
397
+ jbPermissions()
398
+ .hasPermission(operator, address(REV_DEPLOYER), REVNET_ID, JBPermissionIds.MINT_721, false, false),
399
+ "operator missing MINT_721"
400
+ );
401
+ assertTrue(
402
+ jbPermissions()
403
+ .hasPermission(
404
+ operator, address(REV_DEPLOYER), REVNET_ID, JBPermissionIds.SET_721_DISCOUNT_PERCENT, false, false
405
+ ),
406
+ "operator missing SET_721_DISCOUNT_PERCENT"
407
+ );
408
+ }
409
+
282
410
  function test_sucker_deploy() public {
283
411
  JBSuckerDeployerConfig[] memory suckerDeployerConfig = new JBSuckerDeployerConfig[](1);
284
412
 
@@ -286,10 +414,7 @@ contract REVnet_Integrations is TestBaseWorkflow {
286
414
 
287
415
  address token = makeAddr("someToken");
288
416
  tokenMapping[0] = JBTokenMapping({
289
- localToken: token,
290
- minGas: 200_000,
291
- remoteToken: bytes32(uint256(uint160(makeAddr("someOtherToken")))),
292
- minBridgeAmount: 100 // emoji
417
+ localToken: token, minGas: 200_000, remoteToken: bytes32(uint256(uint160(makeAddr("someOtherToken"))))
293
418
  });
294
419
 
295
420
  suckerDeployerConfig[0] = JBSuckerDeployerConfig({deployer: ARB_SUCKER_DEPLOYER, mappings: tokenMapping});
@@ -355,11 +480,13 @@ contract REVnet_Integrations is TestBaseWorkflow {
355
480
  projectConfig.configuration.stageConfigurations = stageConfigurations;
356
481
  projectConfig.configuration.description.salt = "FeeChange";
357
482
 
358
- uint256 revnetProjectId = REV_DEPLOYER.deployFor({
483
+ (uint256 revnetProjectId,) = REV_DEPLOYER.deployFor({
359
484
  revnetId: 0, // Zero to deploy a new revnet
360
485
  configuration: projectConfig.configuration,
361
486
  terminalConfigurations: projectConfig.terminalConfigurations,
362
- suckerDeploymentConfiguration: projectConfig.suckerDeploymentConfiguration
487
+ suckerDeploymentConfiguration: projectConfig.suckerDeploymentConfiguration,
488
+ tiered721HookConfiguration: REVEmpty721Config.empty721Config(uint32(uint160(JBConstants.NATIVE_TOKEN))),
489
+ allowedPosts: REVEmpty721Config.emptyAllowedPosts()
363
490
  });
364
491
 
365
492
  {
@@ -411,11 +538,13 @@ contract REVnet_Integrations is TestBaseWorkflow {
411
538
  abi.encodeWithSelector(REVDeployer.REVDeployer_Unauthorized.selector, FEE_PROJECT_ID, address(this))
412
539
  );
413
540
  // Configure the project.
414
- REVNET_ID = REV_DEPLOYER.deployFor({
541
+ (REVNET_ID,) = REV_DEPLOYER.deployFor({
415
542
  revnetId: FEE_PROJECT_ID, // Zero to deploy a new revnet
416
543
  configuration: feeProjectConfig.configuration,
417
544
  terminalConfigurations: feeProjectConfig.terminalConfigurations,
418
- suckerDeploymentConfiguration: feeProjectConfig.suckerDeploymentConfiguration
545
+ suckerDeploymentConfiguration: feeProjectConfig.suckerDeploymentConfiguration,
546
+ tiered721HookConfiguration: REVEmpty721Config.empty721Config(uint32(uint160(JBConstants.NATIVE_TOKEN))),
547
+ allowedPosts: REVEmpty721Config.emptyAllowedPosts()
419
548
  });
420
549
  }
421
550
  }
@@ -1,24 +1,32 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity 0.8.26;
3
3
 
4
+ // forge-lint: disable-next-line(unaliased-plain-import)
4
5
  import "forge-std/Test.sol";
6
+ // forge-lint: disable-next-line(unaliased-plain-import)
5
7
  import /* {*} from */ "@bananapus/core-v6/test/helpers/TestBaseWorkflow.sol";
6
- import /* {*} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
8
+ // import /* {*} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
9
+ // forge-lint: disable-next-line(unaliased-plain-import)
7
10
  import /* {*} from */ "./../src/REVDeployer.sol";
11
+ // forge-lint: disable-next-line(unaliased-plain-import)
8
12
  import "@croptop/core-v6/src/CTPublisher.sol";
9
13
  import {MockBuybackDataHook} from "./mock/MockBuybackDataHook.sol";
10
14
 
15
+ // forge-lint: disable-next-line(unaliased-plain-import)
11
16
  import "@bananapus/core-v6/script/helpers/CoreDeploymentLib.sol";
17
+ // forge-lint: disable-next-line(unaliased-plain-import)
12
18
  import "@bananapus/721-hook-v6/script/helpers/Hook721DeploymentLib.sol";
19
+ // forge-lint: disable-next-line(unaliased-plain-import)
13
20
  import "@bananapus/suckers-v6/script/helpers/SuckerDeploymentLib.sol";
21
+ // forge-lint: disable-next-line(unaliased-plain-import)
14
22
  import "@croptop/core-v6/script/helpers/CroptopDeploymentLib.sol";
23
+ // forge-lint: disable-next-line(unaliased-plain-import)
15
24
  import "@bananapus/router-terminal-v6/script/helpers/RouterTerminalDeploymentLib.sol";
16
25
 
17
26
  import {JBConstants} from "@bananapus/core-v6/src/libraries/JBConstants.sol";
18
27
  import {JBAccountingContext} from "@bananapus/core-v6/src/structs/JBAccountingContext.sol";
19
28
  import {REVStageConfig, REVAutoIssuance} from "../src/structs/REVStageConfig.sol";
20
29
  import {REVDescription} from "../src/structs/REVDescription.sol";
21
- import {IREVLoans} from "./../src/interfaces/IREVLoans.sol";
22
30
  import {JBSuckerDeployerConfig} from "@bananapus/suckers-v6/src/structs/JBSuckerDeployerConfig.sol";
23
31
  import {JBSuckerRegistry} from "@bananapus/suckers-v6/src/JBSuckerRegistry.sol";
24
32
  import {JB721TiersHookDeployer} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
@@ -26,22 +34,33 @@ import {JB721TiersHook} from "@bananapus/721-hook-v6/src/JB721TiersHook.sol";
26
34
  import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
27
35
  import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
28
36
  import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
37
+ import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
29
38
 
30
39
  /// @notice Fuzz tests for REVDeployer multi-stage auto-issuance.
31
40
  /// Tests stage ID computation consistency and multi-stage claiming behavior.
32
41
  /// Stage IDs use block.timestamp + i which may mismatch actual ruleset IDs.
33
42
  contract REVAutoIssuanceFuzz_Local is TestBaseWorkflow {
43
+ // forge-lint: disable-next-line(mixed-case-variable)
34
44
  bytes32 REV_DEPLOYER_SALT = "REVDeployer";
35
45
 
46
+ // forge-lint: disable-next-line(mixed-case-variable)
36
47
  REVDeployer REV_DEPLOYER;
48
+ // forge-lint: disable-next-line(mixed-case-variable)
37
49
  JB721TiersHook EXAMPLE_HOOK;
50
+ // forge-lint: disable-next-line(mixed-case-variable)
38
51
  IJB721TiersHookDeployer HOOK_DEPLOYER;
52
+ // forge-lint: disable-next-line(mixed-case-variable)
39
53
  IJB721TiersHookStore HOOK_STORE;
54
+ // forge-lint: disable-next-line(mixed-case-variable)
40
55
  IJBAddressRegistry ADDRESS_REGISTRY;
56
+ // forge-lint: disable-next-line(mixed-case-variable)
41
57
  IJBSuckerRegistry SUCKER_REGISTRY;
58
+ // forge-lint: disable-next-line(mixed-case-variable)
42
59
  CTPublisher PUBLISHER;
60
+ // forge-lint: disable-next-line(mixed-case-variable)
43
61
  MockBuybackDataHook MOCK_BUYBACK;
44
62
 
63
+ // forge-lint: disable-next-line(mixed-case-variable)
45
64
  uint256 FEE_PROJECT_ID;
46
65
  uint256 decimals = 18;
47
66
  uint256 decimalMultiplier = 10 ** decimals;
@@ -55,8 +74,9 @@ contract REVAutoIssuanceFuzz_Local is TestBaseWorkflow {
55
74
 
56
75
  SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
57
76
  HOOK_STORE = new JB721TiersHookStore();
58
- EXAMPLE_HOOK =
59
- new JB721TiersHook(jbDirectory(), jbPermissions(), jbRulesets(), HOOK_STORE, jbSplits(), multisig());
77
+ EXAMPLE_HOOK = new JB721TiersHook(
78
+ jbDirectory(), jbPermissions(), jbPrices(), jbRulesets(), HOOK_STORE, jbSplits(), multisig()
79
+ );
60
80
  ADDRESS_REGISTRY = new JBAddressRegistry();
61
81
  HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
62
82
  PUBLISHER = new CTPublisher(jbDirectory(), jbPermissions(), FEE_PROJECT_ID, multisig());
@@ -96,6 +116,7 @@ contract REVAutoIssuanceFuzz_Local is TestBaseWorkflow {
96
116
  REVAutoIssuance[] memory autoIssuances = new REVAutoIssuance[](1);
97
117
  autoIssuances[0] = REVAutoIssuance({
98
118
  chainId: uint32(block.chainid),
119
+ // forge-lint: disable-next-line(unsafe-typecast)
99
120
  count: uint104((10_000 + i * 1000) * decimalMultiplier),
100
121
  beneficiary: multisig()
101
122
  });
@@ -116,6 +137,7 @@ contract REVAutoIssuanceFuzz_Local is TestBaseWorkflow {
116
137
  autoIssuances: autoIssuances,
117
138
  splitPercent: 2000,
118
139
  splits: splits,
140
+ // forge-lint: disable-next-line(unsafe-typecast)
119
141
  initialIssuance: uint112(1000 * decimalMultiplier),
120
142
  issuanceCutFrequency: 90 days,
121
143
  issuanceCutPercent: JBConstants.MAX_WEIGHT_CUT_PERCENT / 2,
@@ -128,6 +150,7 @@ contract REVAutoIssuanceFuzz_Local is TestBaseWorkflow {
128
150
  }
129
151
 
130
152
  REVConfig memory config = REVConfig({
153
+ // forge-lint: disable-next-line(named-struct-fields)
131
154
  description: REVDescription("TestRevnet", "TREV", "ipfs://test", bytes32(uint256(numStages))),
132
155
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
133
156
  splitOperator: multisig(),
@@ -135,14 +158,16 @@ contract REVAutoIssuanceFuzz_Local is TestBaseWorkflow {
135
158
  });
136
159
 
137
160
  vm.prank(multisig());
138
- revnetId = REV_DEPLOYER.deployFor({
161
+ (revnetId,) = REV_DEPLOYER.deployFor({
139
162
  revnetId: 0,
140
163
  configuration: config,
141
164
  terminalConfigurations: terminalConfigs,
142
165
  suckerDeploymentConfiguration: REVSuckerDeploymentConfig({
143
166
  deployerConfigurations: new JBSuckerDeployerConfig[](0),
144
167
  salt: keccak256(abi.encodePacked("AUTOISSUE", numStages))
145
- })
168
+ }),
169
+ tiered721HookConfiguration: REVEmpty721Config.empty721Config(uint32(uint160(JBConstants.NATIVE_TOKEN))),
170
+ allowedPosts: REVEmpty721Config.emptyAllowedPosts()
146
171
  });
147
172
  }
148
173
 
@@ -1,17 +1,27 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity 0.8.26;
3
3
 
4
+ // forge-lint: disable-next-line(unaliased-plain-import)
4
5
  import "forge-std/Test.sol";
6
+ // forge-lint: disable-next-line(unaliased-plain-import)
5
7
  import /* {*} from */ "@bananapus/core-v6/test/helpers/TestBaseWorkflow.sol";
6
- import /* {*} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
8
+ // import /* {*} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
9
+ // forge-lint: disable-next-line(unaliased-plain-import)
7
10
  import /* {*} from */ "./../src/REVDeployer.sol";
11
+ // forge-lint: disable-next-line(unaliased-plain-import)
8
12
  import "@croptop/core-v6/src/CTPublisher.sol";
9
13
  import {MockBuybackDataHook} from "./mock/MockBuybackDataHook.sol";
14
+ import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
10
15
 
16
+ // forge-lint: disable-next-line(unaliased-plain-import)
11
17
  import "@bananapus/core-v6/script/helpers/CoreDeploymentLib.sol";
18
+ // forge-lint: disable-next-line(unaliased-plain-import)
12
19
  import "@bananapus/721-hook-v6/script/helpers/Hook721DeploymentLib.sol";
20
+ // forge-lint: disable-next-line(unaliased-plain-import)
13
21
  import "@bananapus/suckers-v6/script/helpers/SuckerDeploymentLib.sol";
22
+ // forge-lint: disable-next-line(unaliased-plain-import)
14
23
  import "@croptop/core-v6/script/helpers/CroptopDeploymentLib.sol";
24
+ // forge-lint: disable-next-line(unaliased-plain-import)
15
25
  import "@bananapus/router-terminal-v6/script/helpers/RouterTerminalDeploymentLib.sol";
16
26
 
17
27
  import {JBConstants} from "@bananapus/core-v6/src/libraries/JBConstants.sol";
@@ -32,19 +42,31 @@ import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/
32
42
  contract REVDeployerRegressions is TestBaseWorkflow {
33
43
  using JBRulesetMetadataResolver for JBRuleset;
34
44
 
45
+ // forge-lint: disable-next-line(mixed-case-variable)
35
46
  bytes32 REV_DEPLOYER_SALT = "REVDeployer";
47
+ // forge-lint: disable-next-line(mixed-case-variable)
36
48
  bytes32 ERC20_SALT = "REV_TOKEN";
37
49
 
50
+ // forge-lint: disable-next-line(mixed-case-variable)
38
51
  REVDeployer REV_DEPLOYER;
52
+ // forge-lint: disable-next-line(mixed-case-variable)
39
53
  JB721TiersHook EXAMPLE_HOOK;
54
+ // forge-lint: disable-next-line(mixed-case-variable)
40
55
  IJB721TiersHookDeployer HOOK_DEPLOYER;
56
+ // forge-lint: disable-next-line(mixed-case-variable)
41
57
  IJB721TiersHookStore HOOK_STORE;
58
+ // forge-lint: disable-next-line(mixed-case-variable)
42
59
  IJBAddressRegistry ADDRESS_REGISTRY;
60
+ // forge-lint: disable-next-line(mixed-case-variable)
43
61
  IREVLoans LOANS_CONTRACT;
62
+ // forge-lint: disable-next-line(mixed-case-variable)
44
63
  IJBSuckerRegistry SUCKER_REGISTRY;
64
+ // forge-lint: disable-next-line(mixed-case-variable)
45
65
  CTPublisher PUBLISHER;
66
+ // forge-lint: disable-next-line(mixed-case-variable)
46
67
  MockBuybackDataHook MOCK_BUYBACK;
47
68
 
69
+ // forge-lint: disable-next-line(mixed-case-variable)
48
70
  uint256 FEE_PROJECT_ID;
49
71
 
50
72
  address private constant TRUSTED_FORWARDER = 0xB2b5841DBeF766d4b521221732F9B618fCf34A87;
@@ -56,8 +78,9 @@ contract REVDeployerRegressions is TestBaseWorkflow {
56
78
 
57
79
  SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
58
80
  HOOK_STORE = new JB721TiersHookStore();
59
- EXAMPLE_HOOK =
60
- new JB721TiersHook(jbDirectory(), jbPermissions(), jbRulesets(), HOOK_STORE, jbSplits(), multisig());
81
+ EXAMPLE_HOOK = new JB721TiersHook(
82
+ jbDirectory(), jbPermissions(), jbPrices(), jbRulesets(), HOOK_STORE, jbSplits(), multisig()
83
+ );
61
84
  ADDRESS_REGISTRY = new JBAddressRegistry();
62
85
  HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
63
86
  PUBLISHER = new CTPublisher(jbDirectory(), jbPermissions(), FEE_PROJECT_ID, multisig());
@@ -167,6 +190,7 @@ contract REVDeployerRegressions is TestBaseWorkflow {
167
190
  });
168
191
 
169
192
  REVConfig memory revnetConfiguration = REVConfig({
193
+ // forge-lint: disable-next-line(named-struct-fields)
170
194
  description: REVDescription("Test", "TST", "ipfs://test", "TEST_SALT"),
171
195
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
172
196
  splitOperator: multisig(),
@@ -174,13 +198,15 @@ contract REVDeployerRegressions is TestBaseWorkflow {
174
198
  });
175
199
 
176
200
  vm.prank(multisig());
177
- uint256 revnetId = REV_DEPLOYER.deployFor({
201
+ (uint256 revnetId,) = REV_DEPLOYER.deployFor({
178
202
  revnetId: FEE_PROJECT_ID,
179
203
  configuration: revnetConfiguration,
180
204
  terminalConfigurations: terminalConfigurations,
181
205
  suckerDeploymentConfiguration: REVSuckerDeploymentConfig({
182
206
  deployerConfigurations: new JBSuckerDeployerConfig[](0), salt: keccak256("C4_TEST")
183
- })
207
+ }),
208
+ tiered721HookConfiguration: REVEmpty721Config.empty721Config(uint32(uint160(JBConstants.NATIVE_TOKEN))),
209
+ allowedPosts: REVEmpty721Config.emptyAllowedPosts()
184
210
  });
185
211
 
186
212
  // hasMintPermissionFor should return false for random addresses
@@ -226,7 +252,11 @@ contract REVDeployerRegressions is TestBaseWorkflow {
226
252
  {
227
253
  REVAutoIssuance[] memory issuanceConfs = new REVAutoIssuance[](1);
228
254
  issuanceConfs[0] = REVAutoIssuance({
229
- chainId: uint32(block.chainid), count: uint104(50_000 * decimalMultiplier), beneficiary: multisig()
255
+ // forge-lint: disable-next-line(unsafe-typecast)
256
+ chainId: uint32(block.chainid),
257
+ // forge-lint: disable-next-line(unsafe-typecast)
258
+ count: uint104(50_000 * decimalMultiplier),
259
+ beneficiary: multisig()
230
260
  });
231
261
 
232
262
  stageConfigurations[0] = REVStageConfig({
@@ -234,6 +264,7 @@ contract REVDeployerRegressions is TestBaseWorkflow {
234
264
  autoIssuances: issuanceConfs,
235
265
  splitPercent: 2000,
236
266
  splits: splits,
267
+ // forge-lint: disable-next-line(unsafe-typecast)
237
268
  initialIssuance: uint112(1000 * decimalMultiplier),
238
269
  issuanceCutFrequency: 90 days,
239
270
  issuanceCutPercent: JBConstants.MAX_WEIGHT_CUT_PERCENT / 2,
@@ -246,7 +277,11 @@ contract REVDeployerRegressions is TestBaseWorkflow {
246
277
  {
247
278
  REVAutoIssuance[] memory issuanceConfs = new REVAutoIssuance[](1);
248
279
  issuanceConfs[0] = REVAutoIssuance({
249
- chainId: uint32(block.chainid), count: uint104(30_000 * decimalMultiplier), beneficiary: multisig()
280
+ // forge-lint: disable-next-line(unsafe-typecast)
281
+ chainId: uint32(block.chainid),
282
+ // forge-lint: disable-next-line(unsafe-typecast)
283
+ count: uint104(30_000 * decimalMultiplier),
284
+ beneficiary: multisig()
250
285
  });
251
286
 
252
287
  stageConfigurations[1] = REVStageConfig({
@@ -276,6 +311,7 @@ contract REVDeployerRegressions is TestBaseWorkflow {
276
311
  });
277
312
 
278
313
  REVConfig memory revnetConfiguration = REVConfig({
314
+ // forge-lint: disable-next-line(named-struct-fields)
279
315
  description: REVDescription("H5Test", "H5T", "ipfs://h5test", "H5_TOKEN"),
280
316
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
281
317
  splitOperator: multisig(),
@@ -283,13 +319,15 @@ contract REVDeployerRegressions is TestBaseWorkflow {
283
319
  });
284
320
 
285
321
  vm.prank(multisig());
286
- uint256 revnetId = REV_DEPLOYER.deployFor({
322
+ (uint256 revnetId,) = REV_DEPLOYER.deployFor({
287
323
  revnetId: 0,
288
324
  configuration: revnetConfiguration,
289
325
  terminalConfigurations: terminalConfigurations,
290
326
  suckerDeploymentConfiguration: REVSuckerDeploymentConfig({
291
327
  deployerConfigurations: new JBSuckerDeployerConfig[](0), salt: keccak256("H5_TEST")
292
- })
328
+ }),
329
+ tiered721HookConfiguration: REVEmpty721Config.empty721Config(uint32(uint160(JBConstants.NATIVE_TOKEN))),
330
+ allowedPosts: REVEmpty721Config.emptyAllowedPosts()
293
331
  });
294
332
 
295
333
  // Verify the revnet was deployed