@rev-net/core-v6 0.0.17 → 0.0.19

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 (66) hide show
  1. package/ADMINISTRATION.md +14 -4
  2. package/ARCHITECTURE.md +14 -10
  3. package/AUDIT_INSTRUCTIONS.md +40 -17
  4. package/CHANGE_LOG.md +87 -0
  5. package/README.md +10 -5
  6. package/RISKS.md +15 -10
  7. package/SKILLS.md +31 -15
  8. package/USER_JOURNEYS.md +16 -12
  9. package/foundry.toml +1 -1
  10. package/package.json +8 -8
  11. package/script/Deploy.s.sol +60 -19
  12. package/src/REVDeployer.sol +21 -303
  13. package/src/REVLoans.sol +31 -0
  14. package/src/REVOwner.sol +430 -0
  15. package/src/interfaces/IREVDeployer.sol +4 -10
  16. package/src/interfaces/IREVOwner.sol +10 -0
  17. package/src/structs/REVBaseline721HookConfig.sol +0 -2
  18. package/test/REV.integrations.t.sol +14 -1
  19. package/test/REVAutoIssuanceFuzz.t.sol +14 -1
  20. package/test/REVDeployerRegressions.t.sol +17 -2
  21. package/test/REVInvincibility.t.sol +31 -3
  22. package/test/REVLifecycle.t.sol +16 -1
  23. package/test/REVLoans.invariants.t.sol +16 -1
  24. package/test/REVLoansAttacks.t.sol +16 -1
  25. package/test/REVLoansFeeRecovery.t.sol +16 -1
  26. package/test/REVLoansFindings.t.sol +16 -1
  27. package/test/REVLoansRegressions.t.sol +16 -1
  28. package/test/REVLoansSourceFeeRecovery.t.sol +16 -1
  29. package/test/REVLoansSourced.t.sol +16 -1
  30. package/test/REVLoansUnSourced.t.sol +16 -1
  31. package/test/TestBurnHeldTokens.t.sol +16 -1
  32. package/test/TestCEIPattern.t.sol +16 -1
  33. package/test/TestCashOutCallerValidation.t.sol +19 -4
  34. package/test/TestConversionDocumentation.t.sol +16 -1
  35. package/test/TestCrossCurrencyReclaim.t.sol +16 -1
  36. package/test/TestCrossSourceReallocation.t.sol +16 -1
  37. package/test/TestERC2771MetaTx.t.sol +16 -1
  38. package/test/TestEmptyBuybackSpecs.t.sol +18 -3
  39. package/test/TestFlashLoanSurplus.t.sol +16 -1
  40. package/test/TestHookArrayOOB.t.sol +17 -2
  41. package/test/TestLiquidationBehavior.t.sol +16 -1
  42. package/test/TestLoanSourceRotation.t.sol +16 -1
  43. package/test/TestLoansCashOutDelay.t.sol +482 -0
  44. package/test/TestLongTailEconomics.t.sol +16 -1
  45. package/test/TestLowFindings.t.sol +16 -1
  46. package/test/TestMixedFixes.t.sol +16 -1
  47. package/test/TestPermit2Signatures.t.sol +16 -1
  48. package/test/TestReallocationSandwich.t.sol +16 -1
  49. package/test/TestRevnetRegressions.t.sol +16 -1
  50. package/test/TestSplitWeightAdjustment.t.sol +43 -19
  51. package/test/TestSplitWeightE2E.t.sol +26 -3
  52. package/test/TestSplitWeightFork.t.sol +16 -2
  53. package/test/TestStageTransitionBorrowable.t.sol +16 -1
  54. package/test/TestSwapTerminalPermission.t.sol +16 -1
  55. package/test/TestUint112Overflow.t.sol +16 -1
  56. package/test/TestZeroRepayment.t.sol +16 -1
  57. package/test/audit/LoanIdOverflowGuard.t.sol +16 -1
  58. package/test/fork/ForkTestBase.sol +16 -2
  59. package/test/fork/TestPermit2PaymentFork.t.sol +4 -3
  60. package/test/helpers/REVEmpty721Config.sol +0 -1
  61. package/test/regression/TestBurnPermissionRequired.t.sol +16 -1
  62. package/test/regression/TestCashOutBuybackFeeLeak.t.sol +15 -1
  63. package/test/regression/TestCrossRevnetLiquidation.t.sol +16 -1
  64. package/test/regression/TestCumulativeLoanCounter.t.sol +16 -1
  65. package/test/regression/TestLiquidateGapHandling.t.sol +16 -1
  66. package/test/regression/TestZeroPriceFeed.t.sol +16 -1
@@ -48,6 +48,8 @@ import {mulDiv} from "@prb/math/src/Common.sol";
48
48
  import {REVInvincibilityHandler} from "./REVInvincibilityHandler.sol";
49
49
  import {BrokenFeeTerminal} from "./helpers/MaliciousContracts.sol";
50
50
  import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
51
+ import {REVOwner} from "../src/REVOwner.sol";
52
+ import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
51
53
 
52
54
  // =========================================================================
53
55
  // Shared config struct
@@ -87,6 +89,8 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
87
89
  CTPublisher PUBLISHER;
88
90
  // forge-lint: disable-next-line(mixed-case-variable)
89
91
  MockBuybackDataHook MOCK_BUYBACK;
92
+ // forge-lint: disable-next-line(mixed-case-variable)
93
+ REVOwner REV_OWNER;
90
94
 
91
95
  // forge-lint: disable-next-line(mixed-case-variable)
92
96
  uint256 FEE_PROJECT_ID;
@@ -247,6 +251,14 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
247
251
  trustedForwarder: TRUSTED_FORWARDER
248
252
  });
249
253
 
254
+ REV_OWNER = new REVOwner(
255
+ IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
256
+ jbDirectory(),
257
+ FEE_PROJECT_ID,
258
+ SUCKER_REGISTRY,
259
+ address(LOANS_CONTRACT)
260
+ );
261
+
250
262
  REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
251
263
  jbController(),
252
264
  SUCKER_REGISTRY,
@@ -255,9 +267,12 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
255
267
  PUBLISHER,
256
268
  IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
257
269
  address(LOANS_CONTRACT),
258
- TRUSTED_FORWARDER
270
+ TRUSTED_FORWARDER,
271
+ address(REV_OWNER)
259
272
  );
260
273
 
274
+ REV_OWNER.initialize(IREVDeployer(address(REV_DEPLOYER)));
275
+
261
276
  // Deploy fee project
262
277
  vm.prank(multisig());
263
278
  jbProjects().approve(address(REV_DEPLOYER), FEE_PROJECT_ID);
@@ -415,7 +430,7 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow {
415
430
 
416
431
  // hasMintPermissionFor should return false for random addresses
417
432
  address randomAddr = address(0x12345);
418
- bool hasPerm = REV_DEPLOYER.hasMintPermissionFor(FEE_PROJECT_ID, currentRuleset, randomAddr);
433
+ bool hasPerm = REV_OWNER.hasMintPermissionFor(FEE_PROJECT_ID, currentRuleset, randomAddr);
419
434
  assertFalse(hasPerm, "random address should not have mint permission");
420
435
  }
421
436
 
@@ -959,6 +974,8 @@ contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow {
959
974
  // forge-lint: disable-next-line(mixed-case-variable)
960
975
  REVDeployer REV_DEPLOYER;
961
976
  // forge-lint: disable-next-line(mixed-case-variable)
977
+ REVOwner REV_OWNER;
978
+ // forge-lint: disable-next-line(mixed-case-variable)
962
979
  JB721TiersHook EXAMPLE_HOOK;
963
980
  // forge-lint: disable-next-line(mixed-case-variable)
964
981
  IJB721TiersHookDeployer HOOK_DEPLOYER;
@@ -1018,6 +1035,14 @@ contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow {
1018
1035
  trustedForwarder: TRUSTED_FORWARDER
1019
1036
  });
1020
1037
 
1038
+ REV_OWNER = new REVOwner(
1039
+ IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
1040
+ jbDirectory(),
1041
+ FEE_PROJECT_ID,
1042
+ SUCKER_REGISTRY,
1043
+ address(LOANS_CONTRACT)
1044
+ );
1045
+
1021
1046
  REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
1022
1047
  jbController(),
1023
1048
  SUCKER_REGISTRY,
@@ -1026,9 +1051,12 @@ contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow {
1026
1051
  PUBLISHER,
1027
1052
  IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
1028
1053
  address(LOANS_CONTRACT),
1029
- TRUSTED_FORWARDER
1054
+ TRUSTED_FORWARDER,
1055
+ address(REV_OWNER)
1030
1056
  );
1031
1057
 
1058
+ REV_OWNER.initialize(IREVDeployer(address(REV_DEPLOYER)));
1059
+
1032
1060
  // Deploy fee project
1033
1061
  {
1034
1062
  JBAccountingContext[] memory ctx = new JBAccountingContext[](1);
@@ -37,6 +37,8 @@ import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStor
37
37
  import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
38
38
  import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
39
39
  import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
40
+ import {REVOwner} from "../src/REVOwner.sol";
41
+ import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
40
42
 
41
43
  /// @notice Full revnet lifecycle E2E: deploy 3-stage -> pay -> advance stages -> cash out.
42
44
  contract REVLifecycle_Local is TestBaseWorkflow {
@@ -48,6 +50,8 @@ contract REVLifecycle_Local is TestBaseWorkflow {
48
50
  // forge-lint: disable-next-line(mixed-case-variable)
49
51
  REVDeployer REV_DEPLOYER;
50
52
  // forge-lint: disable-next-line(mixed-case-variable)
53
+ REVOwner REV_OWNER;
54
+ // forge-lint: disable-next-line(mixed-case-variable)
51
55
  JB721TiersHook EXAMPLE_HOOK;
52
56
  // forge-lint: disable-next-line(mixed-case-variable)
53
57
  IJB721TiersHookDeployer HOOK_DEPLOYER;
@@ -103,6 +107,14 @@ contract REVLifecycle_Local is TestBaseWorkflow {
103
107
  trustedForwarder: TRUSTED_FORWARDER
104
108
  });
105
109
 
110
+ REV_OWNER = new REVOwner(
111
+ IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
112
+ jbDirectory(),
113
+ FEE_PROJECT_ID,
114
+ SUCKER_REGISTRY,
115
+ address(LOANS_CONTRACT)
116
+ );
117
+
106
118
  REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
107
119
  jbController(),
108
120
  SUCKER_REGISTRY,
@@ -111,9 +123,12 @@ contract REVLifecycle_Local is TestBaseWorkflow {
111
123
  PUBLISHER,
112
124
  IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
113
125
  address(LOANS_CONTRACT),
114
- TRUSTED_FORWARDER
126
+ TRUSTED_FORWARDER,
127
+ address(REV_OWNER)
115
128
  );
116
129
 
130
+ REV_OWNER.initialize(IREVDeployer(address(REV_DEPLOYER)));
131
+
117
132
  vm.prank(multisig());
118
133
  jbProjects().approve(address(REV_DEPLOYER), FEE_PROJECT_ID);
119
134
 
@@ -42,6 +42,8 @@ import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStor
42
42
  import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
43
43
  import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
44
44
  import {JBTest} from "@bananapus/core-v6/test/helpers/JBTest.sol";
45
+ import {REVOwner} from "../src/REVOwner.sol";
46
+ import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
45
47
 
46
48
  struct FeeProjectConfig {
47
49
  REVConfig configuration;
@@ -291,6 +293,8 @@ contract InvariantREVLoansTests is StdInvariant, TestBaseWorkflow {
291
293
  // forge-lint: disable-next-line(mixed-case-variable)
292
294
  REVDeployer REV_DEPLOYER;
293
295
  // forge-lint: disable-next-line(mixed-case-variable)
296
+ REVOwner REV_OWNER;
297
+ // forge-lint: disable-next-line(mixed-case-variable)
294
298
  JB721TiersHook EXAMPLE_HOOK;
295
299
 
296
300
  /// @notice Deploys tiered ERC-721 hooks for revnets.
@@ -545,6 +549,14 @@ contract InvariantREVLoansTests is StdInvariant, TestBaseWorkflow {
545
549
  trustedForwarder: TRUSTED_FORWARDER
546
550
  });
547
551
 
552
+ REV_OWNER = new REVOwner(
553
+ IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
554
+ jbDirectory(),
555
+ FEE_PROJECT_ID,
556
+ SUCKER_REGISTRY,
557
+ address(LOANS_CONTRACT)
558
+ );
559
+
548
560
  REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
549
561
  jbController(),
550
562
  SUCKER_REGISTRY,
@@ -553,9 +565,12 @@ contract InvariantREVLoansTests is StdInvariant, TestBaseWorkflow {
553
565
  PUBLISHER,
554
566
  IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
555
567
  address(LOANS_CONTRACT),
556
- TRUSTED_FORWARDER
568
+ TRUSTED_FORWARDER,
569
+ address(REV_OWNER)
557
570
  );
558
571
 
572
+ REV_OWNER.initialize(IREVDeployer(address(REV_DEPLOYER)));
573
+
559
574
  // Approve the basic deployer to configure the project.
560
575
  vm.prank(address(multisig()));
561
576
  jbProjects().approve(address(REV_DEPLOYER), FEE_PROJECT_ID);
@@ -44,6 +44,8 @@ import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
44
44
  import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
45
45
  import {JBRuleset} from "@bananapus/core-v6/src/structs/JBRuleset.sol";
46
46
  import {JBPayHookSpecification} from "@bananapus/core-v6/src/structs/JBPayHookSpecification.sol";
47
+ import {REVOwner} from "../src/REVOwner.sol";
48
+ import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
47
49
 
48
50
  /// @notice A malicious terminal that re-enters REVLoans during fee payment in _adjust().
49
51
  /// @dev Reentrancy during pay() callback in _adjust.
@@ -202,6 +204,8 @@ contract REVLoansAttacks is TestBaseWorkflow {
202
204
  // forge-lint: disable-next-line(mixed-case-variable)
203
205
  REVDeployer REV_DEPLOYER;
204
206
  // forge-lint: disable-next-line(mixed-case-variable)
207
+ REVOwner REV_OWNER;
208
+ // forge-lint: disable-next-line(mixed-case-variable)
205
209
  JB721TiersHook EXAMPLE_HOOK;
206
210
  // forge-lint: disable-next-line(mixed-case-variable)
207
211
  IJB721TiersHookDeployer HOOK_DEPLOYER;
@@ -386,6 +390,14 @@ contract REVLoansAttacks is TestBaseWorkflow {
386
390
  trustedForwarder: TRUSTED_FORWARDER
387
391
  });
388
392
 
393
+ REV_OWNER = new REVOwner(
394
+ IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
395
+ jbDirectory(),
396
+ FEE_PROJECT_ID,
397
+ SUCKER_REGISTRY,
398
+ address(LOANS_CONTRACT)
399
+ );
400
+
389
401
  REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
390
402
  jbController(),
391
403
  SUCKER_REGISTRY,
@@ -394,9 +406,12 @@ contract REVLoansAttacks is TestBaseWorkflow {
394
406
  PUBLISHER,
395
407
  IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
396
408
  address(LOANS_CONTRACT),
397
- TRUSTED_FORWARDER
409
+ TRUSTED_FORWARDER,
410
+ address(REV_OWNER)
398
411
  );
399
412
 
413
+ REV_OWNER.initialize(IREVDeployer(address(REV_DEPLOYER)));
414
+
400
415
  // Deploy fee project
401
416
  vm.prank(address(multisig()));
402
417
  jbProjects().approve(address(REV_DEPLOYER), FEE_PROJECT_ID);
@@ -45,6 +45,8 @@ import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
45
45
  import {JBRuleset} from "@bananapus/core-v6/src/structs/JBRuleset.sol";
46
46
  import {JBPayHookSpecification} from "@bananapus/core-v6/src/structs/JBPayHookSpecification.sol";
47
47
  import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
48
+ import {REVOwner} from "../src/REVOwner.sol";
49
+ import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
48
50
 
49
51
  /// @notice A terminal mock that always reverts on pay(), used to simulate fee payment failure.
50
52
  contract RevertingFeeTerminal is ERC165, IJBPayoutTerminal {
@@ -162,6 +164,8 @@ contract REVLoansFeeRecovery is TestBaseWorkflow {
162
164
  // forge-lint: disable-next-line(mixed-case-variable)
163
165
  REVDeployer REV_DEPLOYER;
164
166
  // forge-lint: disable-next-line(mixed-case-variable)
167
+ REVOwner REV_OWNER;
168
+ // forge-lint: disable-next-line(mixed-case-variable)
165
169
  JB721TiersHook EXAMPLE_HOOK;
166
170
  // forge-lint: disable-next-line(mixed-case-variable)
167
171
  IJB721TiersHookDeployer HOOK_DEPLOYER;
@@ -352,6 +356,14 @@ contract REVLoansFeeRecovery is TestBaseWorkflow {
352
356
  trustedForwarder: TRUSTED_FORWARDER
353
357
  });
354
358
 
359
+ REV_OWNER = new REVOwner(
360
+ IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
361
+ jbDirectory(),
362
+ FEE_PROJECT_ID,
363
+ SUCKER_REGISTRY,
364
+ address(LOANS_CONTRACT)
365
+ );
366
+
355
367
  REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
356
368
  jbController(),
357
369
  SUCKER_REGISTRY,
@@ -360,9 +372,12 @@ contract REVLoansFeeRecovery is TestBaseWorkflow {
360
372
  PUBLISHER,
361
373
  IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
362
374
  address(LOANS_CONTRACT),
363
- TRUSTED_FORWARDER
375
+ TRUSTED_FORWARDER,
376
+ address(REV_OWNER)
364
377
  );
365
378
 
379
+ REV_OWNER.initialize(IREVDeployer(address(REV_DEPLOYER)));
380
+
366
381
  // Deploy fee project.
367
382
  vm.prank(multisig());
368
383
  jbProjects().approve(address(REV_DEPLOYER), FEE_PROJECT_ID);
@@ -45,6 +45,8 @@ import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/
45
45
  import {JBRuleset} from "@bananapus/core-v6/src/structs/JBRuleset.sol";
46
46
  import {JBPayHookSpecification} from "@bananapus/core-v6/src/structs/JBPayHookSpecification.sol";
47
47
  import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
48
+ import {REVOwner} from "../src/REVOwner.sol";
49
+ import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
48
50
 
49
51
  /// @notice A fake terminal that returns garbage accounting contexts.
50
52
  /// Used to test unvalidated loan source terminal rejection.
@@ -160,6 +162,8 @@ contract REVLoansFindings is TestBaseWorkflow {
160
162
  // forge-lint: disable-next-line(mixed-case-variable)
161
163
  REVDeployer REV_DEPLOYER;
162
164
  // forge-lint: disable-next-line(mixed-case-variable)
165
+ REVOwner REV_OWNER;
166
+ // forge-lint: disable-next-line(mixed-case-variable)
163
167
  JB721TiersHook EXAMPLE_HOOK;
164
168
  // forge-lint: disable-next-line(mixed-case-variable)
165
169
  IJB721TiersHookDeployer HOOK_DEPLOYER;
@@ -210,6 +214,14 @@ contract REVLoansFindings is TestBaseWorkflow {
210
214
  trustedForwarder: TRUSTED_FORWARDER
211
215
  });
212
216
 
217
+ REV_OWNER = new REVOwner(
218
+ IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
219
+ jbDirectory(),
220
+ FEE_PROJECT_ID,
221
+ SUCKER_REGISTRY,
222
+ address(LOANS_CONTRACT)
223
+ );
224
+
213
225
  REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
214
226
  jbController(),
215
227
  SUCKER_REGISTRY,
@@ -218,9 +230,12 @@ contract REVLoansFindings is TestBaseWorkflow {
218
230
  PUBLISHER,
219
231
  IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
220
232
  address(LOANS_CONTRACT),
221
- TRUSTED_FORWARDER
233
+ TRUSTED_FORWARDER,
234
+ address(REV_OWNER)
222
235
  );
223
236
 
237
+ REV_OWNER.initialize(IREVDeployer(address(REV_DEPLOYER)));
238
+
224
239
  vm.prank(multisig());
225
240
  jbProjects().approve(address(REV_DEPLOYER), FEE_PROJECT_ID);
226
241
 
@@ -41,6 +41,8 @@ import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
41
41
  import {JBRuleset} from "@bananapus/core-v6/src/structs/JBRuleset.sol";
42
42
  import {JBPayHookSpecification} from "@bananapus/core-v6/src/structs/JBPayHookSpecification.sol";
43
43
  import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
44
+ import {REVOwner} from "../src/REVOwner.sol";
45
+ import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
44
46
 
45
47
  /// @notice A fake terminal that tracks whether useAllowanceOf was called.
46
48
  /// @dev REVLoans.borrowFrom does not validate source terminal registration.
@@ -155,6 +157,8 @@ contract REVLoansRegressions is TestBaseWorkflow {
155
157
  // forge-lint: disable-next-line(mixed-case-variable)
156
158
  REVDeployer REV_DEPLOYER;
157
159
  // forge-lint: disable-next-line(mixed-case-variable)
160
+ REVOwner REV_OWNER;
161
+ // forge-lint: disable-next-line(mixed-case-variable)
158
162
  JB721TiersHook EXAMPLE_HOOK;
159
163
  // forge-lint: disable-next-line(mixed-case-variable)
160
164
  IJB721TiersHookDeployer HOOK_DEPLOYER;
@@ -205,6 +209,14 @@ contract REVLoansRegressions is TestBaseWorkflow {
205
209
  trustedForwarder: TRUSTED_FORWARDER
206
210
  });
207
211
 
212
+ REV_OWNER = new REVOwner(
213
+ IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
214
+ jbDirectory(),
215
+ FEE_PROJECT_ID,
216
+ SUCKER_REGISTRY,
217
+ address(LOANS_CONTRACT)
218
+ );
219
+
208
220
  REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
209
221
  jbController(),
210
222
  SUCKER_REGISTRY,
@@ -213,9 +225,12 @@ contract REVLoansRegressions is TestBaseWorkflow {
213
225
  PUBLISHER,
214
226
  IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
215
227
  address(LOANS_CONTRACT),
216
- TRUSTED_FORWARDER
228
+ TRUSTED_FORWARDER,
229
+ address(REV_OWNER)
217
230
  );
218
231
 
232
+ REV_OWNER.initialize(IREVDeployer(address(REV_DEPLOYER)));
233
+
219
234
  vm.prank(multisig());
220
235
  jbProjects().approve(address(REV_DEPLOYER), FEE_PROJECT_ID);
221
236
 
@@ -38,6 +38,8 @@ import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStor
38
38
  import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
39
39
  import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
40
40
  import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
41
+ import {REVOwner} from "../src/REVOwner.sol";
42
+ import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
41
43
 
42
44
  struct SourceFeeProjectConfig {
43
45
  REVConfig configuration;
@@ -58,6 +60,8 @@ contract REVLoansSourceFeeRecovery is TestBaseWorkflow {
58
60
  // forge-lint: disable-next-line(mixed-case-variable)
59
61
  REVDeployer REV_DEPLOYER;
60
62
  // forge-lint: disable-next-line(mixed-case-variable)
63
+ REVOwner REV_OWNER;
64
+ // forge-lint: disable-next-line(mixed-case-variable)
61
65
  JB721TiersHook EXAMPLE_HOOK;
62
66
  // forge-lint: disable-next-line(mixed-case-variable)
63
67
  IJB721TiersHookDeployer HOOK_DEPLOYER;
@@ -232,6 +236,14 @@ contract REVLoansSourceFeeRecovery is TestBaseWorkflow {
232
236
  trustedForwarder: TRUSTED_FORWARDER
233
237
  });
234
238
 
239
+ REV_OWNER = new REVOwner(
240
+ IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
241
+ jbDirectory(),
242
+ FEE_PROJECT_ID,
243
+ SUCKER_REGISTRY,
244
+ address(LOANS_CONTRACT)
245
+ );
246
+
235
247
  REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
236
248
  jbController(),
237
249
  SUCKER_REGISTRY,
@@ -240,9 +252,12 @@ contract REVLoansSourceFeeRecovery is TestBaseWorkflow {
240
252
  PUBLISHER,
241
253
  IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
242
254
  address(LOANS_CONTRACT),
243
- TRUSTED_FORWARDER
255
+ TRUSTED_FORWARDER,
256
+ address(REV_OWNER)
244
257
  );
245
258
 
259
+ REV_OWNER.initialize(IREVDeployer(address(REV_DEPLOYER)));
260
+
246
261
  // Deploy fee project.
247
262
  vm.prank(multisig());
248
263
  jbProjects().approve(address(REV_DEPLOYER), FEE_PROJECT_ID);
@@ -41,6 +41,8 @@ import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStor
41
41
  import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
42
42
  import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
43
43
  import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
44
+ import {REVOwner} from "../src/REVOwner.sol";
45
+ import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
44
46
 
45
47
  struct FeeProjectConfig {
46
48
  REVConfig configuration;
@@ -58,6 +60,8 @@ contract REVLoansSourcedTests is TestBaseWorkflow {
58
60
  // forge-lint: disable-next-line(mixed-case-variable)
59
61
  REVDeployer REV_DEPLOYER;
60
62
  // forge-lint: disable-next-line(mixed-case-variable)
63
+ REVOwner REV_OWNER;
64
+ // forge-lint: disable-next-line(mixed-case-variable)
61
65
  JB721TiersHook EXAMPLE_HOOK;
62
66
 
63
67
  /// @notice Deploys tiered ERC-721 hooks for revnets.
@@ -331,6 +335,14 @@ contract REVLoansSourcedTests is TestBaseWorkflow {
331
335
  trustedForwarder: TRUSTED_FORWARDER
332
336
  });
333
337
 
338
+ REV_OWNER = new REVOwner(
339
+ IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
340
+ jbDirectory(),
341
+ FEE_PROJECT_ID,
342
+ SUCKER_REGISTRY,
343
+ address(LOANS_CONTRACT)
344
+ );
345
+
334
346
  REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
335
347
  jbController(),
336
348
  SUCKER_REGISTRY,
@@ -339,9 +351,12 @@ contract REVLoansSourcedTests is TestBaseWorkflow {
339
351
  PUBLISHER,
340
352
  IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
341
353
  address(LOANS_CONTRACT),
342
- TRUSTED_FORWARDER
354
+ TRUSTED_FORWARDER,
355
+ address(REV_OWNER)
343
356
  );
344
357
 
358
+ REV_OWNER.initialize(IREVDeployer(address(REV_DEPLOYER)));
359
+
345
360
  // Approve the basic deployer to configure the project.
346
361
  vm.prank(address(multisig()));
347
362
  jbProjects().approve(address(REV_DEPLOYER), FEE_PROJECT_ID);
@@ -40,6 +40,8 @@ import {JB721TiersHook} from "@bananapus/721-hook-v6/src/JB721TiersHook.sol";
40
40
  import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
41
41
  import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
42
42
  import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
43
+ import {REVOwner} from "../src/REVOwner.sol";
44
+ import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
43
45
 
44
46
  struct FeeProjectConfig {
45
47
  REVConfig configuration;
@@ -57,6 +59,8 @@ contract REVLoansUnsourcedTests is TestBaseWorkflow {
57
59
  // forge-lint: disable-next-line(mixed-case-variable)
58
60
  REVDeployer REV_DEPLOYER;
59
61
  // forge-lint: disable-next-line(mixed-case-variable)
62
+ REVOwner REV_OWNER;
63
+ // forge-lint: disable-next-line(mixed-case-variable)
60
64
  JB721TiersHook EXAMPLE_HOOK;
61
65
 
62
66
  /// @notice Deploys tiered ERC-721 hooks for revnets.
@@ -307,6 +311,14 @@ contract REVLoansUnsourcedTests is TestBaseWorkflow {
307
311
  trustedForwarder: TRUSTED_FORWARDER
308
312
  });
309
313
 
314
+ REV_OWNER = new REVOwner(
315
+ IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
316
+ jbDirectory(),
317
+ FEE_PROJECT_ID,
318
+ SUCKER_REGISTRY,
319
+ address(LOANS_CONTRACT)
320
+ );
321
+
310
322
  REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
311
323
  jbController(),
312
324
  SUCKER_REGISTRY,
@@ -315,9 +327,12 @@ contract REVLoansUnsourcedTests is TestBaseWorkflow {
315
327
  PUBLISHER,
316
328
  IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
317
329
  address(LOANS_CONTRACT),
318
- TRUSTED_FORWARDER
330
+ TRUSTED_FORWARDER,
331
+ address(REV_OWNER)
319
332
  );
320
333
 
334
+ REV_OWNER.initialize(IREVDeployer(address(REV_DEPLOYER)));
335
+
321
336
  // Approve the basic deployer to configure the project.
322
337
  vm.prank(address(multisig()));
323
338
  jbProjects().approve(address(REV_DEPLOYER), FEE_PROJECT_ID);
@@ -37,6 +37,8 @@ import {JB721TiersHook} from "@bananapus/721-hook-v6/src/JB721TiersHook.sol";
37
37
  import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
38
38
  import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
39
39
  import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
40
+ import {REVOwner} from "../src/REVOwner.sol";
41
+ import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
40
42
 
41
43
  struct FeeProjectConfig {
42
44
  REVConfig configuration;
@@ -53,6 +55,8 @@ contract TestBurnHeldTokens is TestBaseWorkflow {
53
55
  // forge-lint: disable-next-line(mixed-case-variable)
54
56
  REVDeployer REV_DEPLOYER;
55
57
  // forge-lint: disable-next-line(mixed-case-variable)
58
+ REVOwner REV_OWNER;
59
+ // forge-lint: disable-next-line(mixed-case-variable)
56
60
  JB721TiersHook EXAMPLE_HOOK;
57
61
  // forge-lint: disable-next-line(mixed-case-variable)
58
62
  IJB721TiersHookDeployer HOOK_DEPLOYER;
@@ -210,6 +214,14 @@ contract TestBurnHeldTokens is TestBaseWorkflow {
210
214
  trustedForwarder: TRUSTED_FORWARDER
211
215
  });
212
216
 
217
+ REV_OWNER = new REVOwner(
218
+ IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
219
+ jbDirectory(),
220
+ FEE_PROJECT_ID,
221
+ SUCKER_REGISTRY,
222
+ address(LOANS_CONTRACT)
223
+ );
224
+
213
225
  REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
214
226
  jbController(),
215
227
  SUCKER_REGISTRY,
@@ -218,9 +230,12 @@ contract TestBurnHeldTokens is TestBaseWorkflow {
218
230
  PUBLISHER,
219
231
  IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
220
232
  address(LOANS_CONTRACT),
221
- TRUSTED_FORWARDER
233
+ TRUSTED_FORWARDER,
234
+ address(REV_OWNER)
222
235
  );
223
236
 
237
+ REV_OWNER.initialize(IREVDeployer(address(REV_DEPLOYER)));
238
+
224
239
  // Deploy fee project.
225
240
  vm.prank(multisig());
226
241
  jbProjects().approve(address(REV_DEPLOYER), FEE_PROJECT_ID);
@@ -40,6 +40,8 @@ import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStor
40
40
  import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
41
41
  import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
42
42
  import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
43
+ import {REVOwner} from "../src/REVOwner.sol";
44
+ import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
43
45
 
44
46
  /// @notice Contract that reenters REVLoans when it receives ETH during a borrow payout.
45
47
  /// Records the loan state it observes during reentrancy to verify CEI correctness.
@@ -86,6 +88,8 @@ contract TestCEIPattern is TestBaseWorkflow {
86
88
  // forge-lint: disable-next-line(mixed-case-variable)
87
89
  REVDeployer REV_DEPLOYER;
88
90
  // forge-lint: disable-next-line(mixed-case-variable)
91
+ REVOwner REV_OWNER;
92
+ // forge-lint: disable-next-line(mixed-case-variable)
89
93
  JB721TiersHook EXAMPLE_HOOK;
90
94
  // forge-lint: disable-next-line(mixed-case-variable)
91
95
  IJB721TiersHookDeployer HOOK_DEPLOYER;
@@ -138,6 +142,14 @@ contract TestCEIPattern is TestBaseWorkflow {
138
142
  permit2: permit2(),
139
143
  trustedForwarder: TRUSTED_FORWARDER
140
144
  });
145
+ REV_OWNER = new REVOwner(
146
+ IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
147
+ jbDirectory(),
148
+ FEE_PROJECT_ID,
149
+ SUCKER_REGISTRY,
150
+ address(LOANS_CONTRACT)
151
+ );
152
+
141
153
  REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
142
154
  jbController(),
143
155
  SUCKER_REGISTRY,
@@ -146,8 +158,11 @@ contract TestCEIPattern is TestBaseWorkflow {
146
158
  PUBLISHER,
147
159
  IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
148
160
  address(LOANS_CONTRACT),
149
- TRUSTED_FORWARDER
161
+ TRUSTED_FORWARDER,
162
+ address(REV_OWNER)
150
163
  );
164
+
165
+ REV_OWNER.initialize(IREVDeployer(address(REV_DEPLOYER)));
151
166
  vm.prank(multisig());
152
167
  jbProjects().approve(address(REV_DEPLOYER), FEE_PROJECT_ID);
153
168
  _deployFeeProject();