@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,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,12 +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";
50
+ import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
43
51
 
44
52
  // =========================================================================
45
53
  // Shared config struct
@@ -56,23 +64,38 @@ struct InvincibilityProjectConfig {
56
64
  contract REVInvincibility_PropertyTests is TestBaseWorkflow {
57
65
  using JBRulesetMetadataResolver for JBRuleset;
58
66
 
67
+ // forge-lint: disable-next-line(mixed-case-variable)
59
68
  bytes32 REV_DEPLOYER_SALT = "REVDeployer";
60
69
 
70
+ // forge-lint: disable-next-line(mixed-case-variable)
61
71
  REVDeployer REV_DEPLOYER;
72
+ // forge-lint: disable-next-line(mixed-case-variable)
62
73
  JB721TiersHook EXAMPLE_HOOK;
74
+ // forge-lint: disable-next-line(mixed-case-variable)
63
75
  IJB721TiersHookDeployer HOOK_DEPLOYER;
76
+ // forge-lint: disable-next-line(mixed-case-variable)
64
77
  IJB721TiersHookStore HOOK_STORE;
78
+ // forge-lint: disable-next-line(mixed-case-variable)
65
79
  IJBAddressRegistry ADDRESS_REGISTRY;
80
+ // forge-lint: disable-next-line(mixed-case-variable)
66
81
  IREVLoans LOANS_CONTRACT;
82
+ // forge-lint: disable-next-line(mixed-case-variable)
67
83
  MockERC20 TOKEN;
84
+ // forge-lint: disable-next-line(mixed-case-variable)
68
85
  IJBSuckerRegistry SUCKER_REGISTRY;
86
+ // forge-lint: disable-next-line(mixed-case-variable)
69
87
  CTPublisher PUBLISHER;
88
+ // forge-lint: disable-next-line(mixed-case-variable)
70
89
  MockBuybackDataHook MOCK_BUYBACK;
71
90
 
91
+ // forge-lint: disable-next-line(mixed-case-variable)
72
92
  uint256 FEE_PROJECT_ID;
93
+ // forge-lint: disable-next-line(mixed-case-variable)
73
94
  uint256 REVNET_ID;
74
95
 
96
+ // forge-lint: disable-next-line(mixed-case-variable)
75
97
  address USER = makeAddr("user");
98
+ // forge-lint: disable-next-line(mixed-case-variable)
76
99
  address ATTACKER = makeAddr("attacker");
77
100
 
78
101
  address private constant TRUSTED_FORWARDER = 0xB2b5841DBeF766d4b521221732F9B618fCf34A87;
@@ -112,9 +135,12 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
112
135
 
113
136
  return InvincibilityProjectConfig({
114
137
  configuration: REVConfig({
115
- description: REVDescription(
116
- "Revnet", "$REV", "ipfs://QmNRHT91HcDgMcenebYX7rJigt77cgNcosvuhX21wkF3tx", "REV_TOKEN"
117
- ),
138
+ description: REVDescription({
139
+ name: "Revnet",
140
+ ticker: "$REV",
141
+ uri: "ipfs://QmNRHT91HcDgMcenebYX7rJigt77cgNcosvuhX21wkF3tx",
142
+ salt: "REV_TOKEN"
143
+ }),
118
144
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
119
145
  splitOperator: multisig(),
120
146
  stageConfigurations: stageConfigurations
@@ -183,6 +209,7 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
183
209
 
184
210
  return InvincibilityProjectConfig({
185
211
  configuration: REVConfig({
212
+ // forge-lint: disable-next-line(named-struct-fields)
186
213
  description: REVDescription("NANA", "$NANA", "ipfs://nana", "NANA_TOKEN"),
187
214
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
188
215
  splitOperator: multisig(),
@@ -202,8 +229,9 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
202
229
 
203
230
  SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
204
231
  HOOK_STORE = new JB721TiersHookStore();
205
- EXAMPLE_HOOK =
206
- new JB721TiersHook(jbDirectory(), jbPermissions(), jbRulesets(), HOOK_STORE, jbSplits(), multisig());
232
+ EXAMPLE_HOOK = new JB721TiersHook(
233
+ jbDirectory(), jbPermissions(), jbPrices(), jbRulesets(), HOOK_STORE, jbSplits(), multisig()
234
+ );
207
235
  ADDRESS_REGISTRY = new JBAddressRegistry();
208
236
  HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
209
237
  PUBLISHER = new CTPublisher(jbDirectory(), jbPermissions(), FEE_PROJECT_ID, multisig());
@@ -240,16 +268,20 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
240
268
  revnetId: FEE_PROJECT_ID,
241
269
  configuration: feeConfig.configuration,
242
270
  terminalConfigurations: feeConfig.terminalConfigurations,
243
- suckerDeploymentConfiguration: feeConfig.suckerDeploymentConfiguration
271
+ suckerDeploymentConfiguration: feeConfig.suckerDeploymentConfiguration,
272
+ tiered721HookConfiguration: REVEmpty721Config.empty721Config(uint32(uint160(JBConstants.NATIVE_TOKEN))),
273
+ allowedPosts: REVEmpty721Config.emptyAllowedPosts()
244
274
  });
245
275
 
246
276
  // Deploy second revnet with loans
247
277
  InvincibilityProjectConfig memory revConfig = _getRevnetConfig();
248
- REVNET_ID = REV_DEPLOYER.deployFor({
278
+ (REVNET_ID,) = REV_DEPLOYER.deployFor({
249
279
  revnetId: 0,
250
280
  configuration: revConfig.configuration,
251
281
  terminalConfigurations: revConfig.terminalConfigurations,
252
- suckerDeploymentConfiguration: revConfig.suckerDeploymentConfiguration
282
+ suckerDeploymentConfiguration: revConfig.suckerDeploymentConfiguration,
283
+ tiered721HookConfiguration: REVEmpty721Config.empty721Config(uint32(uint160(JBConstants.NATIVE_TOKEN))),
284
+ allowedPosts: REVEmpty721Config.emptyAllowedPosts()
253
285
  });
254
286
 
255
287
  vm.deal(USER, 10_000e18);
@@ -294,11 +326,13 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
294
326
  function test_fixVerify_uint112Truncation() public {
295
327
  // Prove the truncation math: uint112(max+1) wraps to 0
296
328
  uint256 overflowValue = uint256(type(uint112).max) + 1;
329
+ // forge-lint: disable-next-line(unsafe-typecast)
297
330
  uint112 truncated = uint112(overflowValue);
298
331
  assertEq(truncated, 0, "uint112 truncation wraps max+1 to 0");
299
332
 
300
333
  // Prove a more realistic overflow: max + 1000 wraps to 999
301
334
  uint256 slightlyOver = uint256(type(uint112).max) + 1000;
335
+ // forge-lint: disable-next-line(unsafe-typecast)
302
336
  truncated = uint112(slightlyOver);
303
337
  assertEq(truncated, 999, "uint112 truncation wraps to low bits");
304
338
 
@@ -325,6 +359,7 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
325
359
 
326
360
  // The bug: code writes to hookSpecifications[1] (OOB for size-1 array)
327
361
  // The fix: should write to index 0 when no tiered721Hook
362
+ // forge-lint: disable-next-line(mixed-case-variable)
328
363
  bool wouldOOB = (!usesTiered721Hook && usesBuybackHook);
329
364
  assertTrue(wouldOOB, "this config triggers the OOB write at index [1]");
330
365
 
@@ -480,9 +515,10 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
480
515
  });
481
516
 
482
517
  vm.prank(multisig());
483
- uint256 h5RevnetId = REV_DEPLOYER.deployFor({
518
+ (uint256 h5RevnetId,) = REV_DEPLOYER.deployFor({
484
519
  revnetId: 0,
485
520
  configuration: REVConfig({
521
+ // forge-lint: disable-next-line(named-struct-fields)
486
522
  description: REVDescription("H5Test", "H5T", "ipfs://h5", "H5_TOKEN"),
487
523
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
488
524
  splitOperator: multisig(),
@@ -491,7 +527,9 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
491
527
  terminalConfigurations: tc,
492
528
  suckerDeploymentConfiguration: REVSuckerDeploymentConfig({
493
529
  deployerConfigurations: new JBSuckerDeployerConfig[](0), salt: keccak256("H5_INVINCIBILITY")
494
- })
530
+ }),
531
+ tiered721HookConfiguration: REVEmpty721Config.empty721Config(uint32(uint160(JBConstants.NATIVE_TOKEN))),
532
+ allowedPosts: REVEmpty721Config.emptyAllowedPosts()
495
533
  });
496
534
 
497
535
  // Stage 0 auto-issuance stored at block.timestamp
@@ -922,26 +960,43 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
922
960
  contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow {
923
961
  using JBRulesetMetadataResolver for JBRuleset;
924
962
 
963
+ // forge-lint: disable-next-line(mixed-case-variable)
925
964
  bytes32 REV_DEPLOYER_SALT = "REVDeployer_INV";
926
965
 
966
+ // forge-lint: disable-next-line(mixed-case-variable)
927
967
  REVDeployer REV_DEPLOYER;
968
+ // forge-lint: disable-next-line(mixed-case-variable)
928
969
  JB721TiersHook EXAMPLE_HOOK;
970
+ // forge-lint: disable-next-line(mixed-case-variable)
929
971
  IJB721TiersHookDeployer HOOK_DEPLOYER;
972
+ // forge-lint: disable-next-line(mixed-case-variable)
930
973
  IJB721TiersHookStore HOOK_STORE;
974
+ // forge-lint: disable-next-line(mixed-case-variable)
931
975
  IJBAddressRegistry ADDRESS_REGISTRY;
976
+ // forge-lint: disable-next-line(mixed-case-variable)
932
977
  IREVLoans LOANS_CONTRACT;
978
+ // forge-lint: disable-next-line(mixed-case-variable)
933
979
  IJBSuckerRegistry SUCKER_REGISTRY;
980
+ // forge-lint: disable-next-line(mixed-case-variable)
934
981
  CTPublisher PUBLISHER;
982
+ // forge-lint: disable-next-line(mixed-case-variable)
935
983
  MockBuybackDataHook MOCK_BUYBACK;
936
984
 
985
+ // forge-lint: disable-next-line(mixed-case-variable)
937
986
  REVInvincibilityHandler HANDLER;
938
987
 
988
+ // forge-lint: disable-next-line(mixed-case-variable)
939
989
  uint256 FEE_PROJECT_ID;
990
+ // forge-lint: disable-next-line(mixed-case-variable)
940
991
  uint256 REVNET_ID;
992
+ // forge-lint: disable-next-line(mixed-case-variable)
941
993
  uint256 INITIAL_TIMESTAMP;
994
+ // forge-lint: disable-next-line(mixed-case-variable)
942
995
  uint256 STAGE_1_START;
996
+ // forge-lint: disable-next-line(mixed-case-variable)
943
997
  uint256 STAGE_2_START;
944
998
 
999
+ // forge-lint: disable-next-line(mixed-case-variable)
945
1000
  address USER = makeAddr("invUser");
946
1001
 
947
1002
  address private constant TRUSTED_FORWARDER = 0xB2b5841DBeF766d4b521221732F9B618fCf34A87;
@@ -953,8 +1008,9 @@ contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow {
953
1008
 
954
1009
  SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
955
1010
  HOOK_STORE = new JB721TiersHookStore();
956
- EXAMPLE_HOOK =
957
- new JB721TiersHook(jbDirectory(), jbPermissions(), jbRulesets(), HOOK_STORE, jbSplits(), multisig());
1011
+ EXAMPLE_HOOK = new JB721TiersHook(
1012
+ jbDirectory(), jbPermissions(), jbPrices(), jbRulesets(), HOOK_STORE, jbSplits(), multisig()
1013
+ );
958
1014
  ADDRESS_REGISTRY = new JBAddressRegistry();
959
1015
  HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
960
1016
  PUBLISHER = new CTPublisher(jbDirectory(), jbPermissions(), FEE_PROJECT_ID, multisig());
@@ -1018,6 +1074,7 @@ contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow {
1018
1074
  REV_DEPLOYER.deployFor({
1019
1075
  revnetId: FEE_PROJECT_ID,
1020
1076
  configuration: REVConfig({
1077
+ // forge-lint: disable-next-line(named-struct-fields)
1021
1078
  description: REVDescription("Revnet", "$REV", "ipfs://rev", "REV_TOKEN_INV"),
1022
1079
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
1023
1080
  splitOperator: multisig(),
@@ -1026,7 +1083,9 @@ contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow {
1026
1083
  terminalConfigurations: tc,
1027
1084
  suckerDeploymentConfiguration: REVSuckerDeploymentConfig({
1028
1085
  deployerConfigurations: new JBSuckerDeployerConfig[](0), salt: keccak256("REV_INV")
1029
- })
1086
+ }),
1087
+ tiered721HookConfiguration: REVEmpty721Config.empty721Config(uint32(uint160(JBConstants.NATIVE_TOKEN))),
1088
+ allowedPosts: REVEmpty721Config.emptyAllowedPosts()
1030
1089
  });
1031
1090
  }
1032
1091
 
@@ -1064,6 +1123,7 @@ contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow {
1064
1123
  });
1065
1124
 
1066
1125
  stages[1] = REVStageConfig({
1126
+ // forge-lint: disable-next-line(unsafe-typecast)
1067
1127
  startsAtOrAfter: uint40(STAGE_1_START),
1068
1128
  autoIssuances: new REVAutoIssuance[](0),
1069
1129
  splitPercent: 2000,
@@ -1076,6 +1136,7 @@ contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow {
1076
1136
  });
1077
1137
 
1078
1138
  stages[2] = REVStageConfig({
1139
+ // forge-lint: disable-next-line(unsafe-typecast)
1079
1140
  startsAtOrAfter: uint40(STAGE_2_START),
1080
1141
  autoIssuances: new REVAutoIssuance[](0),
1081
1142
  splitPercent: 0,
@@ -1087,9 +1148,10 @@ contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow {
1087
1148
  extraMetadata: 0
1088
1149
  });
1089
1150
 
1090
- REVNET_ID = REV_DEPLOYER.deployFor({
1151
+ (REVNET_ID,) = REV_DEPLOYER.deployFor({
1091
1152
  revnetId: 0,
1092
1153
  configuration: REVConfig({
1154
+ // forge-lint: disable-next-line(named-struct-fields)
1093
1155
  description: REVDescription("NANA", "$NANA", "ipfs://nana", "NANA_TOKEN_INV"),
1094
1156
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
1095
1157
  splitOperator: multisig(),
@@ -1098,7 +1160,9 @@ contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow {
1098
1160
  terminalConfigurations: tc,
1099
1161
  suckerDeploymentConfiguration: REVSuckerDeploymentConfig({
1100
1162
  deployerConfigurations: new JBSuckerDeployerConfig[](0), salt: keccak256("NANA_INV")
1101
- })
1163
+ }),
1164
+ tiered721HookConfiguration: REVEmpty721Config.empty721Config(uint32(uint160(JBConstants.NATIVE_TOKEN))),
1165
+ allowedPosts: REVEmpty721Config.emptyAllowedPosts()
1102
1166
  });
1103
1167
  }
1104
1168
 
@@ -1,11 +1,15 @@
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
8
  import {JBConstants} from "@bananapus/core-v6/src/libraries/JBConstants.sol";
9
+ // forge-lint: disable-next-line(unused-import)
7
10
  import {JBAccountingContext} from "@bananapus/core-v6/src/structs/JBAccountingContext.sol";
8
11
  import {mulDiv} from "@prb/math/src/Common.sol";
12
+ // forge-lint: disable-next-line(unused-import)
9
13
  import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
10
14
 
11
15
  import {IREVLoans} from "../src/interfaces/IREVLoans.sol";
@@ -20,24 +24,41 @@ contract REVInvincibilityHandler is JBTest {
20
24
  // =========================================================================
21
25
  // Ghost variables
22
26
  // =========================================================================
27
+ // forge-lint: disable-next-line(mixed-case-variable)
23
28
  uint256 public COLLATERAL_SUM;
29
+ // forge-lint: disable-next-line(mixed-case-variable)
24
30
  uint256 public COLLATERAL_RETURNED;
31
+ // forge-lint: disable-next-line(mixed-case-variable)
25
32
  uint256 public BORROWED_SUM;
33
+ // forge-lint: disable-next-line(mixed-case-variable)
26
34
  uint256 public REPAID_SUM;
35
+ // forge-lint: disable-next-line(mixed-case-variable)
27
36
  uint256 public PAID_IN_SUM;
37
+ // forge-lint: disable-next-line(mixed-case-variable)
28
38
  uint256 public CASHED_OUT_SUM;
39
+ // forge-lint: disable-next-line(mixed-case-variable)
29
40
  uint256 public ADDED_TO_BALANCE_SUM;
30
41
 
31
42
  // Per-operation call counts
43
+ // forge-lint: disable-next-line(mixed-case-variable)
32
44
  uint256 public callCount_payAndBorrow;
45
+ // forge-lint: disable-next-line(mixed-case-variable)
33
46
  uint256 public callCount_repayLoan;
47
+ // forge-lint: disable-next-line(mixed-case-variable)
34
48
  uint256 public callCount_reallocateCollateral;
49
+ // forge-lint: disable-next-line(mixed-case-variable)
35
50
  uint256 public callCount_liquidateLoans;
51
+ // forge-lint: disable-next-line(mixed-case-variable)
36
52
  uint256 public callCount_advanceTime;
53
+ // forge-lint: disable-next-line(mixed-case-variable)
37
54
  uint256 public callCount_payInto;
55
+ // forge-lint: disable-next-line(mixed-case-variable)
38
56
  uint256 public callCount_cashOut;
57
+ // forge-lint: disable-next-line(mixed-case-variable)
39
58
  uint256 public callCount_addToBalance;
59
+ // forge-lint: disable-next-line(mixed-case-variable)
40
60
  uint256 public callCount_sendReservedTokens;
61
+ // forge-lint: disable-next-line(mixed-case-variable)
41
62
  uint256 public callCount_changeStage;
42
63
 
43
64
  // Fee project tracking
@@ -46,13 +67,21 @@ contract REVInvincibilityHandler is JBTest {
46
67
  // =========================================================================
47
68
  // Dependencies
48
69
  // =========================================================================
70
+ // forge-lint: disable-next-line(mixed-case-variable)
49
71
  IJBMultiTerminal public TERMINAL;
72
+ // forge-lint: disable-next-line(mixed-case-variable)
50
73
  IREVLoans public LOANS;
74
+ // forge-lint: disable-next-line(mixed-case-variable)
51
75
  IJBPermissions public PERMS;
76
+ // forge-lint: disable-next-line(mixed-case-variable)
52
77
  IJBTokens public TOKENS;
78
+ // forge-lint: disable-next-line(mixed-case-variable)
53
79
  IJBController public CTRL;
80
+ // forge-lint: disable-next-line(mixed-case-variable)
54
81
  uint256 public REVNET_ID;
82
+ // forge-lint: disable-next-line(mixed-case-variable)
55
83
  uint256 public FEE_PROJECT_ID;
84
+ // forge-lint: disable-next-line(mixed-case-variable)
56
85
  address public USER;
57
86
 
58
87
  // Stage boundaries (for changeStage)
@@ -1,23 +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
 
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 {REVLoans} from "../src/REVLoans.sol";
20
- import {REVLoan} from "../src/structs/REVLoan.sol";
21
29
  import {REVStageConfig, REVAutoIssuance} from "../src/structs/REVStageConfig.sol";
22
30
  import {REVDescription} from "../src/structs/REVDescription.sol";
23
31
  import {IREVLoans} from "./../src/interfaces/IREVLoans.sol";
@@ -28,28 +36,45 @@ import {JB721TiersHook} from "@bananapus/721-hook-v6/src/JB721TiersHook.sol";
28
36
  import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
29
37
  import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
30
38
  import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
39
+ import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
31
40
 
32
41
  /// @notice Full revnet lifecycle E2E: deploy 3-stage -> pay -> advance stages -> cash out.
33
42
  contract REVLifecycle_Local is TestBaseWorkflow {
43
+ // forge-lint: disable-next-line(mixed-case-variable)
34
44
  bytes32 REV_DEPLOYER_SALT = "REVDeployer";
45
+ // forge-lint: disable-next-line(mixed-case-variable)
35
46
  bytes32 ERC20_SALT = "REV_TOKEN";
36
47
 
48
+ // forge-lint: disable-next-line(mixed-case-variable)
37
49
  REVDeployer REV_DEPLOYER;
50
+ // forge-lint: disable-next-line(mixed-case-variable)
38
51
  JB721TiersHook EXAMPLE_HOOK;
52
+ // forge-lint: disable-next-line(mixed-case-variable)
39
53
  IJB721TiersHookDeployer HOOK_DEPLOYER;
54
+ // forge-lint: disable-next-line(mixed-case-variable)
40
55
  IJB721TiersHookStore HOOK_STORE;
56
+ // forge-lint: disable-next-line(mixed-case-variable)
41
57
  IJBAddressRegistry ADDRESS_REGISTRY;
58
+ // forge-lint: disable-next-line(mixed-case-variable)
42
59
  IREVLoans LOANS_CONTRACT;
60
+ // forge-lint: disable-next-line(mixed-case-variable)
43
61
  IJBSuckerRegistry SUCKER_REGISTRY;
62
+ // forge-lint: disable-next-line(mixed-case-variable)
44
63
  CTPublisher PUBLISHER;
64
+ // forge-lint: disable-next-line(mixed-case-variable)
45
65
  MockBuybackDataHook MOCK_BUYBACK;
46
66
 
67
+ // forge-lint: disable-next-line(mixed-case-variable)
47
68
  uint256 FEE_PROJECT_ID;
69
+ // forge-lint: disable-next-line(mixed-case-variable)
48
70
  uint256 REVNET_ID;
49
71
 
72
+ // forge-lint: disable-next-line(mixed-case-variable)
50
73
  address USER1 = makeAddr("user1");
74
+ // forge-lint: disable-next-line(mixed-case-variable)
51
75
  address USER2 = makeAddr("user2");
52
76
 
77
+ // forge-lint: disable-next-line(mixed-case-variable)
53
78
  uint256 DECIMAL_MULTIPLIER = 10 ** 18;
54
79
 
55
80
  address private constant TRUSTED_FORWARDER = 0xB2b5841DBeF766d4b521221732F9B618fCf34A87;
@@ -61,8 +86,9 @@ contract REVLifecycle_Local is TestBaseWorkflow {
61
86
 
62
87
  SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
63
88
  HOOK_STORE = new JB721TiersHookStore();
64
- EXAMPLE_HOOK =
65
- new JB721TiersHook(jbDirectory(), jbPermissions(), jbRulesets(), HOOK_STORE, jbSplits(), multisig());
89
+ EXAMPLE_HOOK = new JB721TiersHook(
90
+ jbDirectory(), jbPermissions(), jbPrices(), jbRulesets(), HOOK_STORE, jbSplits(), multisig()
91
+ );
66
92
  ADDRESS_REGISTRY = new JBAddressRegistry();
67
93
  HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
68
94
  PUBLISHER = new CTPublisher(jbDirectory(), jbPermissions(), FEE_PROJECT_ID, multisig());
@@ -121,6 +147,7 @@ contract REVLifecycle_Local is TestBaseWorkflow {
121
147
  autoIssuances: new REVAutoIssuance[](0),
122
148
  splitPercent: 0,
123
149
  splits: splits,
150
+ // forge-lint: disable-next-line(unsafe-typecast)
124
151
  initialIssuance: uint112(1000 * DECIMAL_MULTIPLIER),
125
152
  issuanceCutFrequency: 90 days,
126
153
  issuanceCutPercent: JBConstants.MAX_WEIGHT_CUT_PERCENT / 2,
@@ -155,6 +182,7 @@ contract REVLifecycle_Local is TestBaseWorkflow {
155
182
  });
156
183
 
157
184
  REVConfig memory revnetConfiguration = REVConfig({
185
+ // forge-lint: disable-next-line(named-struct-fields)
158
186
  description: REVDescription("Lifecycle", "LIFE", "ipfs://lifecycle", "LIFE_TOKEN"),
159
187
  baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
160
188
  splitOperator: multisig(),
@@ -162,13 +190,15 @@ contract REVLifecycle_Local is TestBaseWorkflow {
162
190
  });
163
191
 
164
192
  vm.prank(multisig());
165
- REVNET_ID = REV_DEPLOYER.deployFor({
193
+ (REVNET_ID,) = REV_DEPLOYER.deployFor({
166
194
  revnetId: FEE_PROJECT_ID,
167
195
  configuration: revnetConfiguration,
168
196
  terminalConfigurations: terminalConfigurations,
169
197
  suckerDeploymentConfiguration: REVSuckerDeploymentConfig({
170
198
  deployerConfigurations: new JBSuckerDeployerConfig[](0), salt: keccak256("LIFECYCLE_TEST")
171
- })
199
+ }),
200
+ tiered721HookConfiguration: REVEmpty721Config.empty721Config(uint32(uint160(JBConstants.NATIVE_TOKEN))),
201
+ allowedPosts: REVEmpty721Config.emptyAllowedPosts()
172
202
  });
173
203
  }
174
204