@rev-net/core-v6 0.0.12 → 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 (78) hide show
  1. package/AUDIT_INSTRUCTIONS.md +295 -0
  2. package/CHANGE_LOG.md +316 -0
  3. package/README.md +2 -2
  4. package/RISKS.md +180 -35
  5. package/SKILLS.md +1 -1
  6. package/USER_JOURNEYS.md +489 -0
  7. package/package.json +9 -9
  8. package/script/Deploy.s.sol +40 -6
  9. package/script/helpers/RevnetCoreDeploymentLib.sol +7 -1
  10. package/src/REVDeployer.sol +63 -47
  11. package/src/REVLoans.sol +51 -15
  12. package/src/interfaces/IREVDeployer.sol +0 -1
  13. package/src/structs/REV721TiersHookFlags.sol +1 -0
  14. package/src/structs/REVAutoIssuance.sol +1 -0
  15. package/src/structs/REVBaseline721HookConfig.sol +1 -0
  16. package/src/structs/REVConfig.sol +1 -0
  17. package/src/structs/REVCroptopAllowedPost.sol +1 -0
  18. package/src/structs/REVDeploy721TiersHookConfig.sol +1 -0
  19. package/src/structs/REVDescription.sol +1 -0
  20. package/src/structs/REVLoan.sol +1 -0
  21. package/src/structs/REVLoanSource.sol +1 -0
  22. package/src/structs/REVStageConfig.sol +1 -0
  23. package/src/structs/REVSuckerDeploymentConfig.sol +1 -0
  24. package/test/REV.integrations.t.sol +132 -12
  25. package/test/REVAutoIssuanceFuzz.t.sol +23 -3
  26. package/test/REVDeployerRegressions.t.sol +35 -4
  27. package/test/REVInvincibility.t.sol +58 -8
  28. package/test/REVInvincibilityHandler.sol +29 -0
  29. package/test/REVLifecycle.t.sol +28 -3
  30. package/test/REVLoans.invariants.t.sol +52 -5
  31. package/test/REVLoansAttacks.t.sol +43 -5
  32. package/test/REVLoansFeeRecovery.t.sol +50 -11
  33. package/test/REVLoansFindings.t.sol +27 -3
  34. package/test/REVLoansRegressions.t.sol +25 -3
  35. package/test/REVLoansSourceFeeRecovery.t.sol +491 -0
  36. package/test/REVLoansSourced.t.sol +56 -7
  37. package/test/REVLoansUnSourced.t.sol +49 -5
  38. package/test/TestBurnHeldTokens.t.sol +32 -5
  39. package/test/TestCEIPattern.t.sol +26 -2
  40. package/test/TestCashOutCallerValidation.t.sol +30 -4
  41. package/test/TestConversionDocumentation.t.sol +26 -5
  42. package/test/TestCrossCurrencyReclaim.t.sol +584 -0
  43. package/test/TestCrossSourceReallocation.t.sol +26 -2
  44. package/test/TestERC2771MetaTx.t.sol +557 -0
  45. package/test/TestEmptyBuybackSpecs.t.sol +23 -3
  46. package/test/TestFlashLoanSurplus.t.sol +28 -3
  47. package/test/TestHookArrayOOB.t.sol +24 -4
  48. package/test/TestLiquidationBehavior.t.sol +26 -3
  49. package/test/TestLoanSourceRotation.t.sol +525 -0
  50. package/test/TestLongTailEconomics.t.sol +651 -0
  51. package/test/TestLowFindings.t.sol +65 -2
  52. package/test/TestMixedFixes.t.sol +28 -3
  53. package/test/TestPermit2Signatures.t.sol +657 -0
  54. package/test/TestReallocationSandwich.t.sol +384 -0
  55. package/test/TestRevnetRegressions.t.sol +324 -0
  56. package/test/TestSplitWeightAdjustment.t.sol +24 -2
  57. package/test/TestSplitWeightE2E.t.sol +29 -2
  58. package/test/TestSplitWeightFork.t.sol +46 -7
  59. package/test/TestStageTransitionBorrowable.t.sol +24 -2
  60. package/test/TestSwapTerminalPermission.t.sol +23 -3
  61. package/test/TestUint112Overflow.t.sol +28 -2
  62. package/test/TestZeroRepayment.t.sol +26 -2
  63. package/test/fork/ForkTestBase.sol +46 -3
  64. package/test/fork/TestCashOutFork.t.sol +1 -1
  65. package/test/fork/TestLoanBorrowFork.t.sol +1 -0
  66. package/test/fork/TestLoanCrossRulesetFork.t.sol +3 -1
  67. package/test/fork/TestLoanLiquidationFork.t.sol +1 -0
  68. package/test/fork/TestLoanReallocateFork.t.sol +1 -0
  69. package/test/fork/TestLoanRepayFork.t.sol +1 -0
  70. package/test/fork/TestLoanTransferFork.t.sol +133 -0
  71. package/test/fork/TestSplitWeightFork.t.sol +3 -0
  72. package/test/helpers/REVEmpty721Config.sol +1 -0
  73. package/test/mock/MockBuybackDataHook.sol +1 -0
  74. package/test/regression/TestBurnPermissionRequired.t.sol +267 -0
  75. package/test/regression/TestCrossRevnetLiquidation.t.sol +228 -0
  76. package/test/regression/TestCumulativeLoanCounter.t.sol +27 -4
  77. package/test/regression/TestLiquidateGapHandling.t.sol +29 -4
  78. package/test/regression/TestZeroPriceFeed.t.sol +396 -0
@@ -1,24 +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";
10
14
  import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
11
- import {REVCroptopAllowedPost} from "../src/structs/REVCroptopAllowedPost.sol";
12
15
 
16
+ // forge-lint: disable-next-line(unaliased-plain-import)
13
17
  import "@bananapus/core-v6/script/helpers/CoreDeploymentLib.sol";
18
+ // forge-lint: disable-next-line(unaliased-plain-import)
14
19
  import "@bananapus/721-hook-v6/script/helpers/Hook721DeploymentLib.sol";
20
+ // forge-lint: disable-next-line(unaliased-plain-import)
15
21
  import "@bananapus/suckers-v6/script/helpers/SuckerDeploymentLib.sol";
22
+ // forge-lint: disable-next-line(unaliased-plain-import)
16
23
  import "@croptop/core-v6/script/helpers/CroptopDeploymentLib.sol";
24
+ // forge-lint: disable-next-line(unaliased-plain-import)
17
25
  import "@bananapus/router-terminal-v6/script/helpers/RouterTerminalDeploymentLib.sol";
18
26
 
19
27
  import {JBConstants} from "@bananapus/core-v6/src/libraries/JBConstants.sol";
20
28
  import {JBAccountingContext} from "@bananapus/core-v6/src/structs/JBAccountingContext.sol";
21
- import {REVLoans} from "../src/REVLoans.sol";
22
29
  import {REVStageConfig, REVAutoIssuance} from "../src/structs/REVStageConfig.sol";
23
30
  import {REVDescription} from "../src/structs/REVDescription.sol";
24
31
  import {IREVLoans} from "./../src/interfaces/IREVLoans.sol";
@@ -28,7 +35,7 @@ import {JBTokenMapping} from "@bananapus/suckers-v6/src/structs/JBTokenMapping.s
28
35
  import {JB721TiersHookDeployer} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
29
36
  import {JBArbitrumSuckerDeployer} from "@bananapus/suckers-v6/src/deployers/JBArbitrumSuckerDeployer.sol";
30
37
  import {JBArbitrumSucker, JBLayer, IArbGatewayRouter, IInbox} from "@bananapus/suckers-v6/src/JBArbitrumSucker.sol";
31
- import {JBAddToBalanceMode} from "@bananapus/suckers-v6/src/enums/JBAddToBalanceMode.sol";
38
+
32
39
  import {JB721TiersHook} from "@bananapus/721-hook-v6/src/JB721TiersHook.sol";
33
40
  import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
34
41
  import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
@@ -42,28 +49,43 @@ struct FeeProjectConfig {
42
49
 
43
50
  contract REVnet_Integrations is TestBaseWorkflow {
44
51
  /// @notice the salts that are used to deploy the contracts.
52
+ // forge-lint: disable-next-line(mixed-case-variable)
45
53
  bytes32 REV_DEPLOYER_SALT = "REVDeployer";
54
+ // forge-lint: disable-next-line(mixed-case-variable)
46
55
  bytes32 ERC20_SALT = "REV_TOKEN";
47
56
 
57
+ // forge-lint: disable-next-line(mixed-case-variable)
48
58
  REVDeployer REV_DEPLOYER;
59
+ // forge-lint: disable-next-line(mixed-case-variable)
49
60
  JB721TiersHook EXAMPLE_HOOK;
50
61
 
51
62
  /// @notice Deploys tiered ERC-721 hooks for revnets.
63
+ // forge-lint: disable-next-line(mixed-case-variable)
52
64
  IJB721TiersHookDeployer HOOK_DEPLOYER;
65
+ // forge-lint: disable-next-line(mixed-case-variable)
53
66
  IJB721TiersHookStore HOOK_STORE;
67
+ // forge-lint: disable-next-line(mixed-case-variable)
54
68
  IJBAddressRegistry ADDRESS_REGISTRY;
55
69
 
70
+ // forge-lint: disable-next-line(mixed-case-variable)
56
71
  IREVLoans LOANS_CONTRACT;
57
72
 
58
73
  /// @notice Deploys and tracks suckers for revnets.
74
+ // forge-lint: disable-next-line(mixed-case-variable)
59
75
  IJBSuckerRegistry SUCKER_REGISTRY;
76
+ // forge-lint: disable-next-line(mixed-case-variable)
60
77
  IJBSuckerDeployer ARB_SUCKER_DEPLOYER;
78
+ // forge-lint: disable-next-line(mixed-case-variable)
61
79
  bytes ENCODED_CONFIG;
62
80
 
81
+ // forge-lint: disable-next-line(mixed-case-variable)
63
82
  CTPublisher PUBLISHER;
83
+ // forge-lint: disable-next-line(mixed-case-variable)
64
84
  MockBuybackDataHook MOCK_BUYBACK;
65
85
 
86
+ // forge-lint: disable-next-line(mixed-case-variable)
66
87
  uint256 FEE_PROJECT_ID;
88
+ // forge-lint: disable-next-line(mixed-case-variable)
67
89
  uint256 REVNET_ID;
68
90
  uint256 decimals = 18;
69
91
  uint256 decimalMultiplier = 10 ** decimals;
@@ -73,6 +95,7 @@ contract REVnet_Integrations is TestBaseWorkflow {
73
95
 
74
96
  uint256 firstStageId;
75
97
 
98
+ // forge-lint: disable-next-line(mixed-case-variable)
76
99
  address USER = makeAddr("user");
77
100
 
78
101
  function getFeeProjectConfig() internal returns (FeeProjectConfig memory) {
@@ -99,7 +122,11 @@ contract REVnet_Integrations is TestBaseWorkflow {
99
122
 
100
123
  REVAutoIssuance[] memory issuanceConfs = new REVAutoIssuance[](1);
101
124
  issuanceConfs[0] = REVAutoIssuance({
102
- 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()
103
130
  });
104
131
 
105
132
  JBSplit[] memory splits = new JBSplit[](1);
@@ -114,6 +141,7 @@ contract REVnet_Integrations is TestBaseWorkflow {
114
141
  autoIssuances: issuanceConfs,
115
142
  splitPercent: 2000, // 20%
116
143
  splits: splits,
144
+ // forge-lint: disable-next-line(unsafe-typecast)
117
145
  initialIssuance: uint112(1000 * decimalMultiplier),
118
146
  issuanceCutFrequency: 90 days,
119
147
  issuanceCutPercent: JBConstants.MAX_WEIGHT_CUT_PERCENT / 2,
@@ -148,6 +176,7 @@ contract REVnet_Integrations is TestBaseWorkflow {
148
176
 
149
177
  // The project's revnet configuration
150
178
  REVConfig memory revnetConfiguration = REVConfig({
179
+ // forge-lint: disable-next-line(named-struct-fields)
151
180
  description: REVDescription(name, symbol, projectUri, ERC20_SALT),
152
181
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
153
182
  splitOperator: multisig(),
@@ -207,9 +236,8 @@ contract REVnet_Integrations is TestBaseWorkflow {
207
236
  ARB_SUCKER_DEPLOYER = IJBSuckerDeployer(address(_deployer));
208
237
 
209
238
  // Deploy the ARB sucker singleton.
210
- JBArbitrumSucker _singleton = new JBArbitrumSucker(
211
- _deployer, jbDirectory(), jbPermissions(), jbTokens(), JBAddToBalanceMode.MANUAL, address(0)
212
- );
239
+ JBArbitrumSucker _singleton =
240
+ new JBArbitrumSucker(_deployer, jbDirectory(), jbPermissions(), jbTokens(), 1, SUCKER_REGISTRY, address(0));
213
241
 
214
242
  // Set the layer specific confguration.
215
243
  _deployer.setChainSpecificConstants(JBLayer.L1, IInbox(address(1)), IArbGatewayRouter(address(1)));
@@ -284,6 +312,101 @@ contract REVnet_Integrations is TestBaseWorkflow {
284
312
  assertEq(isNewOperator, true);
285
313
  }
286
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
+
287
410
  function test_sucker_deploy() public {
288
411
  JBSuckerDeployerConfig[] memory suckerDeployerConfig = new JBSuckerDeployerConfig[](1);
289
412
 
@@ -291,10 +414,7 @@ contract REVnet_Integrations is TestBaseWorkflow {
291
414
 
292
415
  address token = makeAddr("someToken");
293
416
  tokenMapping[0] = JBTokenMapping({
294
- localToken: token,
295
- minGas: 200_000,
296
- remoteToken: bytes32(uint256(uint160(makeAddr("someOtherToken")))),
297
- minBridgeAmount: 100 // emoji
417
+ localToken: token, minGas: 200_000, remoteToken: bytes32(uint256(uint160(makeAddr("someOtherToken"))))
298
418
  });
299
419
 
300
420
  suckerDeployerConfig[0] = JBSuckerDeployerConfig({deployer: ARB_SUCKER_DEPLOYER, mappings: tokenMapping});
@@ -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";
@@ -27,23 +35,32 @@ import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStor
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";
29
37
  import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
30
- import {REVCroptopAllowedPost} from "../src/structs/REVCroptopAllowedPost.sol";
31
38
 
32
39
  /// @notice Fuzz tests for REVDeployer multi-stage auto-issuance.
33
40
  /// Tests stage ID computation consistency and multi-stage claiming behavior.
34
41
  /// Stage IDs use block.timestamp + i which may mismatch actual ruleset IDs.
35
42
  contract REVAutoIssuanceFuzz_Local is TestBaseWorkflow {
43
+ // forge-lint: disable-next-line(mixed-case-variable)
36
44
  bytes32 REV_DEPLOYER_SALT = "REVDeployer";
37
45
 
46
+ // forge-lint: disable-next-line(mixed-case-variable)
38
47
  REVDeployer REV_DEPLOYER;
48
+ // forge-lint: disable-next-line(mixed-case-variable)
39
49
  JB721TiersHook EXAMPLE_HOOK;
50
+ // forge-lint: disable-next-line(mixed-case-variable)
40
51
  IJB721TiersHookDeployer HOOK_DEPLOYER;
52
+ // forge-lint: disable-next-line(mixed-case-variable)
41
53
  IJB721TiersHookStore HOOK_STORE;
54
+ // forge-lint: disable-next-line(mixed-case-variable)
42
55
  IJBAddressRegistry ADDRESS_REGISTRY;
56
+ // forge-lint: disable-next-line(mixed-case-variable)
43
57
  IJBSuckerRegistry SUCKER_REGISTRY;
58
+ // forge-lint: disable-next-line(mixed-case-variable)
44
59
  CTPublisher PUBLISHER;
60
+ // forge-lint: disable-next-line(mixed-case-variable)
45
61
  MockBuybackDataHook MOCK_BUYBACK;
46
62
 
63
+ // forge-lint: disable-next-line(mixed-case-variable)
47
64
  uint256 FEE_PROJECT_ID;
48
65
  uint256 decimals = 18;
49
66
  uint256 decimalMultiplier = 10 ** decimals;
@@ -99,6 +116,7 @@ contract REVAutoIssuanceFuzz_Local is TestBaseWorkflow {
99
116
  REVAutoIssuance[] memory autoIssuances = new REVAutoIssuance[](1);
100
117
  autoIssuances[0] = REVAutoIssuance({
101
118
  chainId: uint32(block.chainid),
119
+ // forge-lint: disable-next-line(unsafe-typecast)
102
120
  count: uint104((10_000 + i * 1000) * decimalMultiplier),
103
121
  beneficiary: multisig()
104
122
  });
@@ -119,6 +137,7 @@ contract REVAutoIssuanceFuzz_Local is TestBaseWorkflow {
119
137
  autoIssuances: autoIssuances,
120
138
  splitPercent: 2000,
121
139
  splits: splits,
140
+ // forge-lint: disable-next-line(unsafe-typecast)
122
141
  initialIssuance: uint112(1000 * decimalMultiplier),
123
142
  issuanceCutFrequency: 90 days,
124
143
  issuanceCutPercent: JBConstants.MAX_WEIGHT_CUT_PERCENT / 2,
@@ -131,6 +150,7 @@ contract REVAutoIssuanceFuzz_Local is TestBaseWorkflow {
131
150
  }
132
151
 
133
152
  REVConfig memory config = REVConfig({
153
+ // forge-lint: disable-next-line(named-struct-fields)
134
154
  description: REVDescription("TestRevnet", "TREV", "ipfs://test", bytes32(uint256(numStages))),
135
155
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
136
156
  splitOperator: multisig(),
@@ -1,19 +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";
10
14
  import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
11
- import {REVCroptopAllowedPost} from "../src/structs/REVCroptopAllowedPost.sol";
12
15
 
16
+ // forge-lint: disable-next-line(unaliased-plain-import)
13
17
  import "@bananapus/core-v6/script/helpers/CoreDeploymentLib.sol";
18
+ // forge-lint: disable-next-line(unaliased-plain-import)
14
19
  import "@bananapus/721-hook-v6/script/helpers/Hook721DeploymentLib.sol";
20
+ // forge-lint: disable-next-line(unaliased-plain-import)
15
21
  import "@bananapus/suckers-v6/script/helpers/SuckerDeploymentLib.sol";
22
+ // forge-lint: disable-next-line(unaliased-plain-import)
16
23
  import "@croptop/core-v6/script/helpers/CroptopDeploymentLib.sol";
24
+ // forge-lint: disable-next-line(unaliased-plain-import)
17
25
  import "@bananapus/router-terminal-v6/script/helpers/RouterTerminalDeploymentLib.sol";
18
26
 
19
27
  import {JBConstants} from "@bananapus/core-v6/src/libraries/JBConstants.sol";
@@ -34,19 +42,31 @@ import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/
34
42
  contract REVDeployerRegressions is TestBaseWorkflow {
35
43
  using JBRulesetMetadataResolver for JBRuleset;
36
44
 
45
+ // forge-lint: disable-next-line(mixed-case-variable)
37
46
  bytes32 REV_DEPLOYER_SALT = "REVDeployer";
47
+ // forge-lint: disable-next-line(mixed-case-variable)
38
48
  bytes32 ERC20_SALT = "REV_TOKEN";
39
49
 
50
+ // forge-lint: disable-next-line(mixed-case-variable)
40
51
  REVDeployer REV_DEPLOYER;
52
+ // forge-lint: disable-next-line(mixed-case-variable)
41
53
  JB721TiersHook EXAMPLE_HOOK;
54
+ // forge-lint: disable-next-line(mixed-case-variable)
42
55
  IJB721TiersHookDeployer HOOK_DEPLOYER;
56
+ // forge-lint: disable-next-line(mixed-case-variable)
43
57
  IJB721TiersHookStore HOOK_STORE;
58
+ // forge-lint: disable-next-line(mixed-case-variable)
44
59
  IJBAddressRegistry ADDRESS_REGISTRY;
60
+ // forge-lint: disable-next-line(mixed-case-variable)
45
61
  IREVLoans LOANS_CONTRACT;
62
+ // forge-lint: disable-next-line(mixed-case-variable)
46
63
  IJBSuckerRegistry SUCKER_REGISTRY;
64
+ // forge-lint: disable-next-line(mixed-case-variable)
47
65
  CTPublisher PUBLISHER;
66
+ // forge-lint: disable-next-line(mixed-case-variable)
48
67
  MockBuybackDataHook MOCK_BUYBACK;
49
68
 
69
+ // forge-lint: disable-next-line(mixed-case-variable)
50
70
  uint256 FEE_PROJECT_ID;
51
71
 
52
72
  address private constant TRUSTED_FORWARDER = 0xB2b5841DBeF766d4b521221732F9B618fCf34A87;
@@ -170,6 +190,7 @@ contract REVDeployerRegressions is TestBaseWorkflow {
170
190
  });
171
191
 
172
192
  REVConfig memory revnetConfiguration = REVConfig({
193
+ // forge-lint: disable-next-line(named-struct-fields)
173
194
  description: REVDescription("Test", "TST", "ipfs://test", "TEST_SALT"),
174
195
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
175
196
  splitOperator: multisig(),
@@ -231,7 +252,11 @@ contract REVDeployerRegressions is TestBaseWorkflow {
231
252
  {
232
253
  REVAutoIssuance[] memory issuanceConfs = new REVAutoIssuance[](1);
233
254
  issuanceConfs[0] = REVAutoIssuance({
234
- 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()
235
260
  });
236
261
 
237
262
  stageConfigurations[0] = REVStageConfig({
@@ -239,6 +264,7 @@ contract REVDeployerRegressions is TestBaseWorkflow {
239
264
  autoIssuances: issuanceConfs,
240
265
  splitPercent: 2000,
241
266
  splits: splits,
267
+ // forge-lint: disable-next-line(unsafe-typecast)
242
268
  initialIssuance: uint112(1000 * decimalMultiplier),
243
269
  issuanceCutFrequency: 90 days,
244
270
  issuanceCutPercent: JBConstants.MAX_WEIGHT_CUT_PERCENT / 2,
@@ -251,7 +277,11 @@ contract REVDeployerRegressions is TestBaseWorkflow {
251
277
  {
252
278
  REVAutoIssuance[] memory issuanceConfs = new REVAutoIssuance[](1);
253
279
  issuanceConfs[0] = REVAutoIssuance({
254
- 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()
255
285
  });
256
286
 
257
287
  stageConfigurations[1] = REVStageConfig({
@@ -281,6 +311,7 @@ contract REVDeployerRegressions is TestBaseWorkflow {
281
311
  });
282
312
 
283
313
  REVConfig memory revnetConfiguration = REVConfig({
314
+ // forge-lint: disable-next-line(named-struct-fields)
284
315
  description: REVDescription("H5Test", "H5T", "ipfs://h5test", "H5_TOKEN"),
285
316
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
286
317
  splitOperator: multisig(),
@@ -1,25 +1,34 @@
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";
5
6
  import {StdInvariant} from "forge-std/StdInvariant.sol";
7
+ // forge-lint: disable-next-line(unaliased-plain-import)
6
8
  import /* {*} from */ "@bananapus/core-v6/test/helpers/TestBaseWorkflow.sol";
7
- import /* {*} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
9
+ // import /* {*} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
10
+ // forge-lint: disable-next-line(unaliased-plain-import)
8
11
  import /* {*} from */ "./../src/REVDeployer.sol";
12
+ // forge-lint: disable-next-line(unaliased-plain-import)
9
13
  import /* {*} from */ "./../src/REVLoans.sol";
14
+ // forge-lint: disable-next-line(unaliased-plain-import)
10
15
  import "@croptop/core-v6/src/CTPublisher.sol";
11
16
  import {MockBuybackDataHook} from "./mock/MockBuybackDataHook.sol";
12
17
 
18
+ // forge-lint: disable-next-line(unaliased-plain-import)
13
19
  import "@bananapus/core-v6/script/helpers/CoreDeploymentLib.sol";
20
+ // forge-lint: disable-next-line(unaliased-plain-import)
14
21
  import "@bananapus/721-hook-v6/script/helpers/Hook721DeploymentLib.sol";
22
+ // forge-lint: disable-next-line(unaliased-plain-import)
15
23
  import "@bananapus/suckers-v6/script/helpers/SuckerDeploymentLib.sol";
24
+ // forge-lint: disable-next-line(unaliased-plain-import)
16
25
  import "@croptop/core-v6/script/helpers/CroptopDeploymentLib.sol";
26
+ // forge-lint: disable-next-line(unaliased-plain-import)
17
27
  import "@bananapus/router-terminal-v6/script/helpers/RouterTerminalDeploymentLib.sol";
18
28
 
19
29
  import {JBCashOuts} from "@bananapus/core-v6/src/libraries/JBCashOuts.sol";
20
30
  import {JBConstants} from "@bananapus/core-v6/src/libraries/JBConstants.sol";
21
31
  import {JBAccountingContext} from "@bananapus/core-v6/src/structs/JBAccountingContext.sol";
22
- import {MockPriceFeed} from "@bananapus/core-v6/test/mock/MockPriceFeed.sol";
23
32
  import {MockERC20} from "@bananapus/core-v6/test/mock/MockERC20.sol";
24
33
  import {REVLoans} from "../src/REVLoans.sol";
25
34
  import {REVLoan} from "../src/structs/REVLoan.sol";
@@ -34,14 +43,11 @@ import {JB721TiersHook} from "@bananapus/721-hook-v6/src/JB721TiersHook.sol";
34
43
  import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
35
44
  import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
36
45
  import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
37
- import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
38
- import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
39
46
  import {mulDiv} from "@prb/math/src/Common.sol";
40
47
 
41
48
  import {REVInvincibilityHandler} from "./REVInvincibilityHandler.sol";
42
49
  import {BrokenFeeTerminal} from "./helpers/MaliciousContracts.sol";
43
50
  import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
44
- import {REVCroptopAllowedPost} from "../src/structs/REVCroptopAllowedPost.sol";
45
51
 
46
52
  // =========================================================================
47
53
  // Shared config struct
@@ -58,23 +64,38 @@ struct InvincibilityProjectConfig {
58
64
  contract REVInvincibility_PropertyTests is TestBaseWorkflow {
59
65
  using JBRulesetMetadataResolver for JBRuleset;
60
66
 
67
+ // forge-lint: disable-next-line(mixed-case-variable)
61
68
  bytes32 REV_DEPLOYER_SALT = "REVDeployer";
62
69
 
70
+ // forge-lint: disable-next-line(mixed-case-variable)
63
71
  REVDeployer REV_DEPLOYER;
72
+ // forge-lint: disable-next-line(mixed-case-variable)
64
73
  JB721TiersHook EXAMPLE_HOOK;
74
+ // forge-lint: disable-next-line(mixed-case-variable)
65
75
  IJB721TiersHookDeployer HOOK_DEPLOYER;
76
+ // forge-lint: disable-next-line(mixed-case-variable)
66
77
  IJB721TiersHookStore HOOK_STORE;
78
+ // forge-lint: disable-next-line(mixed-case-variable)
67
79
  IJBAddressRegistry ADDRESS_REGISTRY;
80
+ // forge-lint: disable-next-line(mixed-case-variable)
68
81
  IREVLoans LOANS_CONTRACT;
82
+ // forge-lint: disable-next-line(mixed-case-variable)
69
83
  MockERC20 TOKEN;
84
+ // forge-lint: disable-next-line(mixed-case-variable)
70
85
  IJBSuckerRegistry SUCKER_REGISTRY;
86
+ // forge-lint: disable-next-line(mixed-case-variable)
71
87
  CTPublisher PUBLISHER;
88
+ // forge-lint: disable-next-line(mixed-case-variable)
72
89
  MockBuybackDataHook MOCK_BUYBACK;
73
90
 
91
+ // forge-lint: disable-next-line(mixed-case-variable)
74
92
  uint256 FEE_PROJECT_ID;
93
+ // forge-lint: disable-next-line(mixed-case-variable)
75
94
  uint256 REVNET_ID;
76
95
 
96
+ // forge-lint: disable-next-line(mixed-case-variable)
77
97
  address USER = makeAddr("user");
98
+ // forge-lint: disable-next-line(mixed-case-variable)
78
99
  address ATTACKER = makeAddr("attacker");
79
100
 
80
101
  address private constant TRUSTED_FORWARDER = 0xB2b5841DBeF766d4b521221732F9B618fCf34A87;
@@ -114,9 +135,12 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
114
135
 
115
136
  return InvincibilityProjectConfig({
116
137
  configuration: REVConfig({
117
- description: REVDescription(
118
- "Revnet", "$REV", "ipfs://QmNRHT91HcDgMcenebYX7rJigt77cgNcosvuhX21wkF3tx", "REV_TOKEN"
119
- ),
138
+ description: REVDescription({
139
+ name: "Revnet",
140
+ ticker: "$REV",
141
+ uri: "ipfs://QmNRHT91HcDgMcenebYX7rJigt77cgNcosvuhX21wkF3tx",
142
+ salt: "REV_TOKEN"
143
+ }),
120
144
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
121
145
  splitOperator: multisig(),
122
146
  stageConfigurations: stageConfigurations
@@ -185,6 +209,7 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
185
209
 
186
210
  return InvincibilityProjectConfig({
187
211
  configuration: REVConfig({
212
+ // forge-lint: disable-next-line(named-struct-fields)
188
213
  description: REVDescription("NANA", "$NANA", "ipfs://nana", "NANA_TOKEN"),
189
214
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
190
215
  splitOperator: multisig(),
@@ -301,11 +326,13 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
301
326
  function test_fixVerify_uint112Truncation() public {
302
327
  // Prove the truncation math: uint112(max+1) wraps to 0
303
328
  uint256 overflowValue = uint256(type(uint112).max) + 1;
329
+ // forge-lint: disable-next-line(unsafe-typecast)
304
330
  uint112 truncated = uint112(overflowValue);
305
331
  assertEq(truncated, 0, "uint112 truncation wraps max+1 to 0");
306
332
 
307
333
  // Prove a more realistic overflow: max + 1000 wraps to 999
308
334
  uint256 slightlyOver = uint256(type(uint112).max) + 1000;
335
+ // forge-lint: disable-next-line(unsafe-typecast)
309
336
  truncated = uint112(slightlyOver);
310
337
  assertEq(truncated, 999, "uint112 truncation wraps to low bits");
311
338
 
@@ -332,6 +359,7 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
332
359
 
333
360
  // The bug: code writes to hookSpecifications[1] (OOB for size-1 array)
334
361
  // The fix: should write to index 0 when no tiered721Hook
362
+ // forge-lint: disable-next-line(mixed-case-variable)
335
363
  bool wouldOOB = (!usesTiered721Hook && usesBuybackHook);
336
364
  assertTrue(wouldOOB, "this config triggers the OOB write at index [1]");
337
365
 
@@ -490,6 +518,7 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
490
518
  (uint256 h5RevnetId,) = REV_DEPLOYER.deployFor({
491
519
  revnetId: 0,
492
520
  configuration: REVConfig({
521
+ // forge-lint: disable-next-line(named-struct-fields)
493
522
  description: REVDescription("H5Test", "H5T", "ipfs://h5", "H5_TOKEN"),
494
523
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
495
524
  splitOperator: multisig(),
@@ -931,26 +960,43 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
931
960
  contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow {
932
961
  using JBRulesetMetadataResolver for JBRuleset;
933
962
 
963
+ // forge-lint: disable-next-line(mixed-case-variable)
934
964
  bytes32 REV_DEPLOYER_SALT = "REVDeployer_INV";
935
965
 
966
+ // forge-lint: disable-next-line(mixed-case-variable)
936
967
  REVDeployer REV_DEPLOYER;
968
+ // forge-lint: disable-next-line(mixed-case-variable)
937
969
  JB721TiersHook EXAMPLE_HOOK;
970
+ // forge-lint: disable-next-line(mixed-case-variable)
938
971
  IJB721TiersHookDeployer HOOK_DEPLOYER;
972
+ // forge-lint: disable-next-line(mixed-case-variable)
939
973
  IJB721TiersHookStore HOOK_STORE;
974
+ // forge-lint: disable-next-line(mixed-case-variable)
940
975
  IJBAddressRegistry ADDRESS_REGISTRY;
976
+ // forge-lint: disable-next-line(mixed-case-variable)
941
977
  IREVLoans LOANS_CONTRACT;
978
+ // forge-lint: disable-next-line(mixed-case-variable)
942
979
  IJBSuckerRegistry SUCKER_REGISTRY;
980
+ // forge-lint: disable-next-line(mixed-case-variable)
943
981
  CTPublisher PUBLISHER;
982
+ // forge-lint: disable-next-line(mixed-case-variable)
944
983
  MockBuybackDataHook MOCK_BUYBACK;
945
984
 
985
+ // forge-lint: disable-next-line(mixed-case-variable)
946
986
  REVInvincibilityHandler HANDLER;
947
987
 
988
+ // forge-lint: disable-next-line(mixed-case-variable)
948
989
  uint256 FEE_PROJECT_ID;
990
+ // forge-lint: disable-next-line(mixed-case-variable)
949
991
  uint256 REVNET_ID;
992
+ // forge-lint: disable-next-line(mixed-case-variable)
950
993
  uint256 INITIAL_TIMESTAMP;
994
+ // forge-lint: disable-next-line(mixed-case-variable)
951
995
  uint256 STAGE_1_START;
996
+ // forge-lint: disable-next-line(mixed-case-variable)
952
997
  uint256 STAGE_2_START;
953
998
 
999
+ // forge-lint: disable-next-line(mixed-case-variable)
954
1000
  address USER = makeAddr("invUser");
955
1001
 
956
1002
  address private constant TRUSTED_FORWARDER = 0xB2b5841DBeF766d4b521221732F9B618fCf34A87;
@@ -1028,6 +1074,7 @@ contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow {
1028
1074
  REV_DEPLOYER.deployFor({
1029
1075
  revnetId: FEE_PROJECT_ID,
1030
1076
  configuration: REVConfig({
1077
+ // forge-lint: disable-next-line(named-struct-fields)
1031
1078
  description: REVDescription("Revnet", "$REV", "ipfs://rev", "REV_TOKEN_INV"),
1032
1079
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
1033
1080
  splitOperator: multisig(),
@@ -1076,6 +1123,7 @@ contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow {
1076
1123
  });
1077
1124
 
1078
1125
  stages[1] = REVStageConfig({
1126
+ // forge-lint: disable-next-line(unsafe-typecast)
1079
1127
  startsAtOrAfter: uint40(STAGE_1_START),
1080
1128
  autoIssuances: new REVAutoIssuance[](0),
1081
1129
  splitPercent: 2000,
@@ -1088,6 +1136,7 @@ contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow {
1088
1136
  });
1089
1137
 
1090
1138
  stages[2] = REVStageConfig({
1139
+ // forge-lint: disable-next-line(unsafe-typecast)
1091
1140
  startsAtOrAfter: uint40(STAGE_2_START),
1092
1141
  autoIssuances: new REVAutoIssuance[](0),
1093
1142
  splitPercent: 0,
@@ -1102,6 +1151,7 @@ contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow {
1102
1151
  (REVNET_ID,) = REV_DEPLOYER.deployFor({
1103
1152
  revnetId: 0,
1104
1153
  configuration: REVConfig({
1154
+ // forge-lint: disable-next-line(named-struct-fields)
1105
1155
  description: REVDescription("NANA", "$NANA", "ipfs://nana", "NANA_TOKEN_INV"),
1106
1156
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
1107
1157
  splitOperator: multisig(),