@rev-net/core-v6 0.0.29 → 0.0.31
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.
- package/ADMINISTRATION.md +19 -9
- package/ARCHITECTURE.md +3 -0
- package/AUDIT_INSTRUCTIONS.md +11 -1
- package/CHANGELOG.md +26 -0
- package/README.md +1 -0
- package/RISKS.md +28 -4
- package/SKILLS.md +2 -1
- package/USER_JOURNEYS.md +28 -3
- package/package.json +8 -8
- package/references/operations.md +1 -1
- package/script/Deploy.s.sol +26 -4
- package/src/REVDeployer.sol +4 -2
- package/src/REVHiddenTokens.sol +149 -0
- package/src/REVLoans.sol +192 -199
- package/src/REVOwner.sol +51 -14
- package/src/interfaces/IREVHiddenTokens.sol +53 -0
- package/src/interfaces/IREVLoans.sol +8 -6
- package/test/REV.integrations.t.sol +12 -2
- package/test/REVAutoIssuanceFuzz.t.sol +12 -2
- package/test/REVDeployerRegressions.t.sol +14 -3
- package/test/REVInvincibility.t.sol +27 -8
- package/test/REVInvincibilityHandler.sol +1 -1
- package/test/REVLifecycle.t.sol +14 -3
- package/test/REVLoans.invariants.t.sol +15 -4
- package/test/REVLoansAttacks.t.sol +19 -7
- package/test/REVLoansFeeRecovery.t.sol +24 -13
- package/test/REVLoansFindings.t.sol +16 -5
- package/test/REVLoansRegressions.t.sol +15 -4
- package/test/REVLoansSourceFeeRecovery.t.sol +16 -5
- package/test/REVLoansSourced.t.sol +60 -25
- package/test/REVLoansUnSourced.t.sol +15 -4
- package/test/TestBurnHeldTokens.t.sol +14 -3
- package/test/TestCEIPattern.t.sol +19 -7
- package/test/TestCashOutCallerValidation.t.sol +15 -4
- package/test/TestConversionDocumentation.t.sol +14 -3
- package/test/TestCrossCurrencyReclaim.t.sol +14 -3
- package/test/TestCrossSourceReallocation.t.sol +15 -4
- package/test/TestERC2771MetaTx.t.sol +18 -5
- package/test/TestEmptyBuybackSpecs.t.sol +14 -3
- package/test/TestFlashLoanSurplus.t.sol +15 -4
- package/test/TestHiddenTokens.t.sol +431 -0
- package/test/TestHookArrayOOB.t.sol +14 -3
- package/test/TestLiquidationBehavior.t.sol +16 -5
- package/test/TestLoanSourceRotation.t.sol +20 -7
- package/test/TestLoansCashOutDelay.t.sol +18 -7
- package/test/TestLongTailEconomics.t.sol +14 -3
- package/test/TestLowFindings.t.sol +25 -9
- package/test/TestMixedFixes.t.sol +19 -8
- package/test/TestPermit2Signatures.t.sol +15 -4
- package/test/TestReallocationSandwich.t.sol +16 -4
- package/test/TestRevnetRegressions.t.sol +16 -5
- package/test/TestSplitWeightAdjustment.t.sol +16 -4
- package/test/TestSplitWeightE2E.t.sol +18 -4
- package/test/TestSplitWeightFork.t.sol +16 -3
- package/test/TestStageTransitionBorrowable.t.sol +14 -3
- package/test/TestSwapTerminalPermission.t.sol +14 -3
- package/test/TestUint112Overflow.t.sol +15 -4
- package/test/TestZeroAmountLoanGuard.t.sol +15 -4
- package/test/TestZeroRepayment.t.sol +15 -4
- package/test/audit/CodexPhantomSurplusTerminal.t.sol +367 -0
- package/test/audit/LoanIdOverflowGuard.t.sol +16 -5
- package/test/audit/NemesisOperatorDelegation.t.sol +289 -0
- package/test/fork/ForkTestBase.sol +18 -4
- package/test/fork/TestLoanBorrowFork.t.sol +2 -1
- package/test/fork/TestLoanERC20Fork.t.sol +4 -2
- package/test/fork/TestLoanTransferFork.t.sol +12 -2
- package/test/helpers/MaliciousContracts.sol +1 -1
- package/test/mock/MockBuybackCashOutRecorder.sol +2 -0
- package/test/mock/MockBuybackDataHook.sol +3 -1
- package/test/mock/MockBuybackDataHookMintPath.sol +2 -0
- package/test/mock/MockSuckerRegistry.sol +17 -0
- package/test/regression/TestBurnPermissionRequired.t.sol +16 -5
- package/test/regression/TestCashOutBuybackFeeLeak.t.sol +16 -3
- package/test/regression/TestCrossRevnetLiquidation.t.sol +14 -3
- package/test/regression/TestCumulativeLoanCounter.t.sol +15 -4
- package/test/regression/TestLiquidateGapHandling.t.sol +15 -4
- package/test/regression/TestZeroPriceFeed.t.sol +17 -6
|
@@ -32,6 +32,8 @@ import {JBSuckerRegistry} from "@bananapus/suckers-v6/src/JBSuckerRegistry.sol";
|
|
|
32
32
|
import {JB721TiersHookDeployer} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
|
|
33
33
|
import {JB721TiersHook} from "@bananapus/721-hook-v6/src/JB721TiersHook.sol";
|
|
34
34
|
import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
|
|
35
|
+
import {JB721CheckpointsDeployer} from "@bananapus/721-hook-v6/src/JB721CheckpointsDeployer.sol";
|
|
36
|
+
import {IJB721CheckpointsDeployer} from "@bananapus/721-hook-v6/src/interfaces/IJB721CheckpointsDeployer.sol";
|
|
35
37
|
import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
|
|
36
38
|
import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
|
|
37
39
|
import {JBBeforePayRecordedContext} from "@bananapus/core-v6/src/structs/JBBeforePayRecordedContext.sol";
|
|
@@ -40,6 +42,7 @@ import {JBTokenAmount} from "@bananapus/core-v6/src/structs/JBTokenAmount.sol";
|
|
|
40
42
|
import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
|
|
41
43
|
import {REVOwner} from "../src/REVOwner.sol";
|
|
42
44
|
import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
|
|
45
|
+
import {MockSuckerRegistry} from "./mock/MockSuckerRegistry.sol";
|
|
43
46
|
|
|
44
47
|
/// @notice Tests for PR #22: fix/c2-hook-array-oob
|
|
45
48
|
/// Verifies that the fix for the hook array out-of-bounds bug works correctly.
|
|
@@ -84,7 +87,14 @@ contract TestHookArrayOOB is TestBaseWorkflow {
|
|
|
84
87
|
SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
|
|
85
88
|
HOOK_STORE = new JB721TiersHookStore();
|
|
86
89
|
EXAMPLE_HOOK = new JB721TiersHook(
|
|
87
|
-
jbDirectory(),
|
|
90
|
+
jbDirectory(),
|
|
91
|
+
jbPermissions(),
|
|
92
|
+
jbPrices(),
|
|
93
|
+
jbRulesets(),
|
|
94
|
+
HOOK_STORE,
|
|
95
|
+
jbSplits(),
|
|
96
|
+
IJB721CheckpointsDeployer(address(new JB721CheckpointsDeployer())),
|
|
97
|
+
multisig()
|
|
88
98
|
);
|
|
89
99
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
90
100
|
HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
|
|
@@ -92,7 +102,7 @@ contract TestHookArrayOOB is TestBaseWorkflow {
|
|
|
92
102
|
MOCK_BUYBACK = new MockBuybackDataHook();
|
|
93
103
|
LOANS_CONTRACT = new REVLoans({
|
|
94
104
|
controller: jbController(),
|
|
95
|
-
|
|
105
|
+
suckerRegistry: IJBSuckerRegistry(address(new MockSuckerRegistry())),
|
|
96
106
|
revId: FEE_PROJECT_ID,
|
|
97
107
|
owner: address(this),
|
|
98
108
|
permit2: permit2(),
|
|
@@ -103,7 +113,8 @@ contract TestHookArrayOOB is TestBaseWorkflow {
|
|
|
103
113
|
jbDirectory(),
|
|
104
114
|
FEE_PROJECT_ID,
|
|
105
115
|
SUCKER_REGISTRY,
|
|
106
|
-
address(LOANS_CONTRACT)
|
|
116
|
+
address(LOANS_CONTRACT),
|
|
117
|
+
address(0)
|
|
107
118
|
);
|
|
108
119
|
|
|
109
120
|
REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
|
|
@@ -37,11 +37,14 @@ import {JBSuckerRegistry} from "@bananapus/suckers-v6/src/JBSuckerRegistry.sol";
|
|
|
37
37
|
import {JB721TiersHookDeployer} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
|
|
38
38
|
import {JB721TiersHook} from "@bananapus/721-hook-v6/src/JB721TiersHook.sol";
|
|
39
39
|
import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
|
|
40
|
+
import {JB721CheckpointsDeployer} from "@bananapus/721-hook-v6/src/JB721CheckpointsDeployer.sol";
|
|
41
|
+
import {IJB721CheckpointsDeployer} from "@bananapus/721-hook-v6/src/interfaces/IJB721CheckpointsDeployer.sol";
|
|
40
42
|
import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
|
|
41
43
|
import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
|
|
42
44
|
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
|
|
43
45
|
import {REVOwner} from "../src/REVOwner.sol";
|
|
44
46
|
import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
|
|
47
|
+
import {MockSuckerRegistry} from "./mock/MockSuckerRegistry.sol";
|
|
45
48
|
|
|
46
49
|
/// @notice Tests for PR #10: liquidation behavior documentation and collateral burn mechanics.
|
|
47
50
|
contract TestLiquidationBehavior is TestBaseWorkflow {
|
|
@@ -87,7 +90,14 @@ contract TestLiquidationBehavior is TestBaseWorkflow {
|
|
|
87
90
|
SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
|
|
88
91
|
HOOK_STORE = new JB721TiersHookStore();
|
|
89
92
|
EXAMPLE_HOOK = new JB721TiersHook(
|
|
90
|
-
jbDirectory(),
|
|
93
|
+
jbDirectory(),
|
|
94
|
+
jbPermissions(),
|
|
95
|
+
jbPrices(),
|
|
96
|
+
jbRulesets(),
|
|
97
|
+
HOOK_STORE,
|
|
98
|
+
jbSplits(),
|
|
99
|
+
IJB721CheckpointsDeployer(address(new JB721CheckpointsDeployer())),
|
|
100
|
+
multisig()
|
|
91
101
|
);
|
|
92
102
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
93
103
|
HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
|
|
@@ -100,7 +110,7 @@ contract TestLiquidationBehavior is TestBaseWorkflow {
|
|
|
100
110
|
.addPriceFeedFor(0, uint32(uint160(address(TOKEN))), uint32(uint160(JBConstants.NATIVE_TOKEN)), priceFeed);
|
|
101
111
|
LOANS_CONTRACT = new REVLoans({
|
|
102
112
|
controller: jbController(),
|
|
103
|
-
|
|
113
|
+
suckerRegistry: IJBSuckerRegistry(address(new MockSuckerRegistry())),
|
|
104
114
|
revId: FEE_PROJECT_ID,
|
|
105
115
|
owner: address(this),
|
|
106
116
|
permit2: permit2(),
|
|
@@ -111,7 +121,8 @@ contract TestLiquidationBehavior is TestBaseWorkflow {
|
|
|
111
121
|
jbDirectory(),
|
|
112
122
|
FEE_PROJECT_ID,
|
|
113
123
|
SUCKER_REGISTRY,
|
|
114
|
-
address(LOANS_CONTRACT)
|
|
124
|
+
address(LOANS_CONTRACT),
|
|
125
|
+
address(0)
|
|
115
126
|
);
|
|
116
127
|
|
|
117
128
|
REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
|
|
@@ -247,7 +258,7 @@ contract TestLiquidationBehavior is TestBaseWorkflow {
|
|
|
247
258
|
);
|
|
248
259
|
REVLoanSource memory source = REVLoanSource({token: JBConstants.NATIVE_TOKEN, terminal: jbMultiTerminal()});
|
|
249
260
|
vm.prank(user);
|
|
250
|
-
(loanId,) = LOANS_CONTRACT.borrowFrom(REVNET_ID, source, 0, tokenCount, payable(user), prepaidFee);
|
|
261
|
+
(loanId,) = LOANS_CONTRACT.borrowFrom(REVNET_ID, source, 0, tokenCount, payable(user), prepaidFee, user);
|
|
251
262
|
}
|
|
252
263
|
|
|
253
264
|
/// @notice Verify that collateral is burned (not escrowed) — totalCollateralOf increases and loans contract holds
|
|
@@ -273,7 +284,7 @@ contract TestLiquidationBehavior is TestBaseWorkflow {
|
|
|
273
284
|
);
|
|
274
285
|
REVLoanSource memory source = REVLoanSource({token: JBConstants.NATIVE_TOKEN, terminal: jbMultiTerminal()});
|
|
275
286
|
vm.prank(USER);
|
|
276
|
-
LOANS_CONTRACT.borrowFrom(REVNET_ID, source, 0, tokenCount, payable(USER), 25);
|
|
287
|
+
LOANS_CONTRACT.borrowFrom(REVNET_ID, source, 0, tokenCount, payable(USER), 25, USER);
|
|
277
288
|
|
|
278
289
|
uint256 totalCollateralAfterBorrow = LOANS_CONTRACT.totalCollateralOf(REVNET_ID);
|
|
279
290
|
|
|
@@ -36,12 +36,15 @@ import {JBSuckerRegistry} from "@bananapus/suckers-v6/src/JBSuckerRegistry.sol";
|
|
|
36
36
|
import {JB721TiersHookDeployer} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
|
|
37
37
|
import {JB721TiersHook} from "@bananapus/721-hook-v6/src/JB721TiersHook.sol";
|
|
38
38
|
import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
|
|
39
|
+
import {JB721CheckpointsDeployer} from "@bananapus/721-hook-v6/src/JB721CheckpointsDeployer.sol";
|
|
40
|
+
import {IJB721CheckpointsDeployer} from "@bananapus/721-hook-v6/src/interfaces/IJB721CheckpointsDeployer.sol";
|
|
39
41
|
import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
|
|
40
42
|
import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
|
|
41
43
|
import {JBSingleAllowance} from "@bananapus/core-v6/src/structs/JBSingleAllowance.sol";
|
|
42
44
|
import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
|
|
43
45
|
import {REVOwner} from "../src/REVOwner.sol";
|
|
44
46
|
import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
|
|
47
|
+
import {MockSuckerRegistry} from "./mock/MockSuckerRegistry.sol";
|
|
45
48
|
|
|
46
49
|
/// @notice Tests for loan source rotation: verify behavior when loans are taken from different sources (tokens)
|
|
47
50
|
/// and that existing loans remain valid and repayable after new sources are introduced.
|
|
@@ -90,7 +93,14 @@ contract TestLoanSourceRotation is TestBaseWorkflow {
|
|
|
90
93
|
SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
|
|
91
94
|
HOOK_STORE = new JB721TiersHookStore();
|
|
92
95
|
EXAMPLE_HOOK = new JB721TiersHook(
|
|
93
|
-
jbDirectory(),
|
|
96
|
+
jbDirectory(),
|
|
97
|
+
jbPermissions(),
|
|
98
|
+
jbPrices(),
|
|
99
|
+
jbRulesets(),
|
|
100
|
+
HOOK_STORE,
|
|
101
|
+
jbSplits(),
|
|
102
|
+
IJB721CheckpointsDeployer(address(new JB721CheckpointsDeployer())),
|
|
103
|
+
multisig()
|
|
94
104
|
);
|
|
95
105
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
96
106
|
HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
|
|
@@ -108,7 +118,7 @@ contract TestLoanSourceRotation is TestBaseWorkflow {
|
|
|
108
118
|
|
|
109
119
|
LOANS_CONTRACT = new REVLoans({
|
|
110
120
|
controller: jbController(),
|
|
111
|
-
|
|
121
|
+
suckerRegistry: IJBSuckerRegistry(address(new MockSuckerRegistry())),
|
|
112
122
|
revId: FEE_PROJECT_ID,
|
|
113
123
|
owner: address(this),
|
|
114
124
|
permit2: permit2(),
|
|
@@ -120,7 +130,8 @@ contract TestLoanSourceRotation is TestBaseWorkflow {
|
|
|
120
130
|
jbDirectory(),
|
|
121
131
|
FEE_PROJECT_ID,
|
|
122
132
|
SUCKER_REGISTRY,
|
|
123
|
-
address(LOANS_CONTRACT)
|
|
133
|
+
address(LOANS_CONTRACT),
|
|
134
|
+
address(0)
|
|
124
135
|
);
|
|
125
136
|
|
|
126
137
|
REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
|
|
@@ -271,7 +282,7 @@ contract TestLoanSourceRotation is TestBaseWorkflow {
|
|
|
271
282
|
);
|
|
272
283
|
|
|
273
284
|
vm.prank(user);
|
|
274
|
-
(loanId,) = LOANS_CONTRACT.borrowFrom(REVNET_ID, source, 0, tokenCount, payable(user), 25);
|
|
285
|
+
(loanId,) = LOANS_CONTRACT.borrowFrom(REVNET_ID, source, 0, tokenCount, payable(user), 25, user);
|
|
275
286
|
}
|
|
276
287
|
|
|
277
288
|
//*********************************************************************//
|
|
@@ -323,7 +334,8 @@ contract TestLoanSourceRotation is TestBaseWorkflow {
|
|
|
323
334
|
);
|
|
324
335
|
|
|
325
336
|
vm.prank(user2);
|
|
326
|
-
(uint256 loanId2,) =
|
|
337
|
+
(uint256 loanId2,) =
|
|
338
|
+
LOANS_CONTRACT.borrowFrom(REVNET_ID, tokenSource, 0, user2Tokens, payable(user2), 25, user2);
|
|
327
339
|
assertGt(loanId2, 0, "TOKEN loan should be created");
|
|
328
340
|
|
|
329
341
|
// Both sources should now be registered.
|
|
@@ -415,7 +427,8 @@ contract TestLoanSourceRotation is TestBaseWorkflow {
|
|
|
415
427
|
);
|
|
416
428
|
|
|
417
429
|
vm.prank(user2);
|
|
418
|
-
(uint256 loanId2,) =
|
|
430
|
+
(uint256 loanId2,) =
|
|
431
|
+
LOANS_CONTRACT.borrowFrom(REVNET_ID, ethSource2, 0, user2Tokens, payable(user2), 25, user2);
|
|
419
432
|
assertGt(loanId2, 0, "second loan should be created");
|
|
420
433
|
|
|
421
434
|
// First loan should be unaffected.
|
|
@@ -530,7 +543,7 @@ contract TestLoanSourceRotation is TestBaseWorkflow {
|
|
|
530
543
|
);
|
|
531
544
|
|
|
532
545
|
vm.prank(user2);
|
|
533
|
-
(uint256 loanId2,) = LOANS_CONTRACT.borrowFrom(REVNET_ID, ethSource, 0, tokens, payable(user2), 25);
|
|
546
|
+
(uint256 loanId2,) = LOANS_CONTRACT.borrowFrom(REVNET_ID, ethSource, 0, tokens, payable(user2), 25, user2);
|
|
534
547
|
assertGt(loanId2, 0, "second loan should succeed");
|
|
535
548
|
|
|
536
549
|
uint256 countAfterSecond = LOANS_CONTRACT.totalLoansBorrowedFor(REVNET_ID);
|
|
@@ -34,11 +34,14 @@ import {JBSuckerRegistry} from "@bananapus/suckers-v6/src/JBSuckerRegistry.sol";
|
|
|
34
34
|
import {JB721TiersHookDeployer} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
|
|
35
35
|
import {JB721TiersHook} from "@bananapus/721-hook-v6/src/JB721TiersHook.sol";
|
|
36
36
|
import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
|
|
37
|
+
import {JB721CheckpointsDeployer} from "@bananapus/721-hook-v6/src/JB721CheckpointsDeployer.sol";
|
|
38
|
+
import {IJB721CheckpointsDeployer} from "@bananapus/721-hook-v6/src/interfaces/IJB721CheckpointsDeployer.sol";
|
|
37
39
|
import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
|
|
38
40
|
import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
|
|
39
41
|
import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
|
|
40
42
|
import {REVOwner} from "../src/REVOwner.sol";
|
|
41
43
|
import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
|
|
44
|
+
import {MockSuckerRegistry} from "./mock/MockSuckerRegistry.sol";
|
|
42
45
|
|
|
43
46
|
struct FeeProjectConfig {
|
|
44
47
|
REVConfig configuration;
|
|
@@ -202,7 +205,14 @@ contract TestLoansCashOutDelay is TestBaseWorkflow {
|
|
|
202
205
|
SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
|
|
203
206
|
HOOK_STORE = new JB721TiersHookStore();
|
|
204
207
|
EXAMPLE_HOOK = new JB721TiersHook(
|
|
205
|
-
jbDirectory(),
|
|
208
|
+
jbDirectory(),
|
|
209
|
+
jbPermissions(),
|
|
210
|
+
jbPrices(),
|
|
211
|
+
jbRulesets(),
|
|
212
|
+
HOOK_STORE,
|
|
213
|
+
jbSplits(),
|
|
214
|
+
IJB721CheckpointsDeployer(address(new JB721CheckpointsDeployer())),
|
|
215
|
+
multisig()
|
|
206
216
|
);
|
|
207
217
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
208
218
|
HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
|
|
@@ -211,7 +221,7 @@ contract TestLoansCashOutDelay is TestBaseWorkflow {
|
|
|
211
221
|
|
|
212
222
|
LOANS_CONTRACT = new REVLoans({
|
|
213
223
|
controller: jbController(),
|
|
214
|
-
|
|
224
|
+
suckerRegistry: IJBSuckerRegistry(address(new MockSuckerRegistry())),
|
|
215
225
|
revId: FEE_PROJECT_ID,
|
|
216
226
|
owner: address(this),
|
|
217
227
|
permit2: permit2(),
|
|
@@ -223,7 +233,8 @@ contract TestLoansCashOutDelay is TestBaseWorkflow {
|
|
|
223
233
|
jbDirectory(),
|
|
224
234
|
FEE_PROJECT_ID,
|
|
225
235
|
SUCKER_REGISTRY,
|
|
226
|
-
address(LOANS_CONTRACT)
|
|
236
|
+
address(LOANS_CONTRACT),
|
|
237
|
+
address(0)
|
|
227
238
|
);
|
|
228
239
|
|
|
229
240
|
REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
|
|
@@ -347,7 +358,7 @@ contract TestLoansCashOutDelay is TestBaseWorkflow {
|
|
|
347
358
|
abi.encodeWithSelector(REVLoans.REVLoans_CashOutDelayNotFinished.selector, cashOutDelay, block.timestamp)
|
|
348
359
|
);
|
|
349
360
|
vm.prank(USER);
|
|
350
|
-
LOANS_CONTRACT.borrowFrom(DELAYED_REVNET_ID, source, 1, tokenCount, payable(USER), 25);
|
|
361
|
+
LOANS_CONTRACT.borrowFrom(DELAYED_REVNET_ID, source, 1, tokenCount, payable(USER), 25, USER);
|
|
351
362
|
}
|
|
352
363
|
|
|
353
364
|
/// @notice After warping past the delay, borrowableAmountFrom should return a non-zero value.
|
|
@@ -393,7 +404,7 @@ contract TestLoansCashOutDelay is TestBaseWorkflow {
|
|
|
393
404
|
// Borrow — should succeed.
|
|
394
405
|
vm.prank(USER);
|
|
395
406
|
(uint256 loanId,) =
|
|
396
|
-
LOANS_CONTRACT.borrowFrom(DELAYED_REVNET_ID, source, borrowable, tokenCount, payable(USER), 25);
|
|
407
|
+
LOANS_CONTRACT.borrowFrom(DELAYED_REVNET_ID, source, borrowable, tokenCount, payable(USER), 25, USER);
|
|
397
408
|
assertGt(loanId, 0, "Should have created a loan");
|
|
398
409
|
}
|
|
399
410
|
|
|
@@ -431,7 +442,7 @@ contract TestLoansCashOutDelay is TestBaseWorkflow {
|
|
|
431
442
|
// Borrow — should succeed without any delay.
|
|
432
443
|
vm.prank(USER);
|
|
433
444
|
(uint256 loanId,) =
|
|
434
|
-
LOANS_CONTRACT.borrowFrom(NORMAL_REVNET_ID, source, borrowable, tokenCount, payable(USER), 25);
|
|
445
|
+
LOANS_CONTRACT.borrowFrom(NORMAL_REVNET_ID, source, borrowable, tokenCount, payable(USER), 25, USER);
|
|
435
446
|
assertGt(loanId, 0, "Should have created a loan");
|
|
436
447
|
}
|
|
437
448
|
|
|
@@ -477,6 +488,6 @@ contract TestLoansCashOutDelay is TestBaseWorkflow {
|
|
|
477
488
|
abi.encodeWithSelector(REVLoans.REVLoans_CashOutDelayNotFinished.selector, cashOutDelay, block.timestamp)
|
|
478
489
|
);
|
|
479
490
|
vm.prank(USER);
|
|
480
|
-
LOANS_CONTRACT.borrowFrom(DELAYED_REVNET_ID, source, 1, tokenCount, payable(USER), 25);
|
|
491
|
+
LOANS_CONTRACT.borrowFrom(DELAYED_REVNET_ID, source, 1, tokenCount, payable(USER), 25, USER);
|
|
481
492
|
}
|
|
482
493
|
}
|
|
@@ -32,11 +32,14 @@ import {JBSuckerRegistry} from "@bananapus/suckers-v6/src/JBSuckerRegistry.sol";
|
|
|
32
32
|
import {JB721TiersHookDeployer} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
|
|
33
33
|
import {JB721TiersHook} from "@bananapus/721-hook-v6/src/JB721TiersHook.sol";
|
|
34
34
|
import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
|
|
35
|
+
import {JB721CheckpointsDeployer} from "@bananapus/721-hook-v6/src/JB721CheckpointsDeployer.sol";
|
|
36
|
+
import {IJB721CheckpointsDeployer} from "@bananapus/721-hook-v6/src/interfaces/IJB721CheckpointsDeployer.sol";
|
|
35
37
|
import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
|
|
36
38
|
import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
|
|
37
39
|
import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
|
|
38
40
|
import {REVOwner} from "../src/REVOwner.sol";
|
|
39
41
|
import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
|
|
42
|
+
import {MockSuckerRegistry} from "./mock/MockSuckerRegistry.sol";
|
|
40
43
|
|
|
41
44
|
/// @notice Long-tail economic simulation: run a revnet through multiple stage transitions with many payments
|
|
42
45
|
/// and cash outs, verifying value conservation and bonding curve consistency.
|
|
@@ -92,7 +95,14 @@ contract TestLongTailEconomics is TestBaseWorkflow {
|
|
|
92
95
|
SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
|
|
93
96
|
HOOK_STORE = new JB721TiersHookStore();
|
|
94
97
|
EXAMPLE_HOOK = new JB721TiersHook(
|
|
95
|
-
jbDirectory(),
|
|
98
|
+
jbDirectory(),
|
|
99
|
+
jbPermissions(),
|
|
100
|
+
jbPrices(),
|
|
101
|
+
jbRulesets(),
|
|
102
|
+
HOOK_STORE,
|
|
103
|
+
jbSplits(),
|
|
104
|
+
IJB721CheckpointsDeployer(address(new JB721CheckpointsDeployer())),
|
|
105
|
+
multisig()
|
|
96
106
|
);
|
|
97
107
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
98
108
|
HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
|
|
@@ -101,7 +111,7 @@ contract TestLongTailEconomics is TestBaseWorkflow {
|
|
|
101
111
|
|
|
102
112
|
LOANS_CONTRACT = new REVLoans({
|
|
103
113
|
controller: jbController(),
|
|
104
|
-
|
|
114
|
+
suckerRegistry: IJBSuckerRegistry(address(new MockSuckerRegistry())),
|
|
105
115
|
revId: FEE_PROJECT_ID,
|
|
106
116
|
owner: address(this),
|
|
107
117
|
permit2: permit2(),
|
|
@@ -113,7 +123,8 @@ contract TestLongTailEconomics is TestBaseWorkflow {
|
|
|
113
123
|
jbDirectory(),
|
|
114
124
|
FEE_PROJECT_ID,
|
|
115
125
|
SUCKER_REGISTRY,
|
|
116
|
-
address(LOANS_CONTRACT)
|
|
126
|
+
address(LOANS_CONTRACT),
|
|
127
|
+
address(0)
|
|
117
128
|
);
|
|
118
129
|
|
|
119
130
|
REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
|
|
@@ -37,11 +37,14 @@ import {JBSuckerRegistry} from "@bananapus/suckers-v6/src/JBSuckerRegistry.sol";
|
|
|
37
37
|
import {JB721TiersHookDeployer} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
|
|
38
38
|
import {JB721TiersHook} from "@bananapus/721-hook-v6/src/JB721TiersHook.sol";
|
|
39
39
|
import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
|
|
40
|
+
import {JB721CheckpointsDeployer} from "@bananapus/721-hook-v6/src/JB721CheckpointsDeployer.sol";
|
|
41
|
+
import {IJB721CheckpointsDeployer} from "@bananapus/721-hook-v6/src/interfaces/IJB721CheckpointsDeployer.sol";
|
|
40
42
|
import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
|
|
41
43
|
import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
|
|
42
44
|
import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
|
|
43
45
|
import {REVOwner} from "../src/REVOwner.sol";
|
|
44
46
|
import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
|
|
47
|
+
import {MockSuckerRegistry} from "./mock/MockSuckerRegistry.sol";
|
|
45
48
|
|
|
46
49
|
struct FeeProjectConfig {
|
|
47
50
|
REVConfig configuration;
|
|
@@ -275,7 +278,14 @@ contract TestLowFindings is TestBaseWorkflow {
|
|
|
275
278
|
SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
|
|
276
279
|
HOOK_STORE = new JB721TiersHookStore();
|
|
277
280
|
EXAMPLE_HOOK = new JB721TiersHook(
|
|
278
|
-
jbDirectory(),
|
|
281
|
+
jbDirectory(),
|
|
282
|
+
jbPermissions(),
|
|
283
|
+
jbPrices(),
|
|
284
|
+
jbRulesets(),
|
|
285
|
+
HOOK_STORE,
|
|
286
|
+
jbSplits(),
|
|
287
|
+
IJB721CheckpointsDeployer(address(new JB721CheckpointsDeployer())),
|
|
288
|
+
multisig()
|
|
279
289
|
);
|
|
280
290
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
281
291
|
HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
|
|
@@ -290,7 +300,7 @@ contract TestLowFindings is TestBaseWorkflow {
|
|
|
290
300
|
|
|
291
301
|
LOANS_CONTRACT = new REVLoans({
|
|
292
302
|
controller: jbController(),
|
|
293
|
-
|
|
303
|
+
suckerRegistry: IJBSuckerRegistry(address(new MockSuckerRegistry())),
|
|
294
304
|
revId: FEE_PROJECT_ID,
|
|
295
305
|
owner: address(this),
|
|
296
306
|
permit2: permit2(),
|
|
@@ -302,7 +312,8 @@ contract TestLowFindings is TestBaseWorkflow {
|
|
|
302
312
|
jbDirectory(),
|
|
303
313
|
FEE_PROJECT_ID,
|
|
304
314
|
SUCKER_REGISTRY,
|
|
305
|
-
address(LOANS_CONTRACT)
|
|
315
|
+
address(LOANS_CONTRACT),
|
|
316
|
+
address(0)
|
|
306
317
|
);
|
|
307
318
|
|
|
308
319
|
REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
|
|
@@ -388,7 +399,8 @@ contract TestLowFindings is TestBaseWorkflow {
|
|
|
388
399
|
uint256 minPrepaid = LOANS_CONTRACT.MIN_PREPAID_FEE_PERCENT();
|
|
389
400
|
|
|
390
401
|
vm.prank(USER);
|
|
391
|
-
(uint256 loanId,) =
|
|
402
|
+
(uint256 loanId,) =
|
|
403
|
+
LOANS_CONTRACT.borrowFrom(revnetId, source, loanable, tokens, payable(USER), minPrepaid, USER);
|
|
392
404
|
|
|
393
405
|
REVLoan memory loanBefore = LOANS_CONTRACT.loanOf(loanId);
|
|
394
406
|
assertGt(loanBefore.amount, 0, "Loan should have an amount");
|
|
@@ -435,7 +447,8 @@ contract TestLowFindings is TestBaseWorkflow {
|
|
|
435
447
|
uint256 minPrepaid = LOANS_CONTRACT.MIN_PREPAID_FEE_PERCENT();
|
|
436
448
|
|
|
437
449
|
vm.prank(USER);
|
|
438
|
-
(uint256 loanId,) =
|
|
450
|
+
(uint256 loanId,) =
|
|
451
|
+
LOANS_CONTRACT.borrowFrom(revnetId, source, loanable, tokens, payable(USER), minPrepaid, USER);
|
|
439
452
|
|
|
440
453
|
REVLoan memory loanBefore = LOANS_CONTRACT.loanOf(loanId);
|
|
441
454
|
assertGt(loanBefore.amount, 0, "Loan should exist before liquidation");
|
|
@@ -479,7 +492,8 @@ contract TestLowFindings is TestBaseWorkflow {
|
|
|
479
492
|
uint256 minPrepaid = LOANS_CONTRACT.MIN_PREPAID_FEE_PERCENT();
|
|
480
493
|
|
|
481
494
|
vm.prank(USER);
|
|
482
|
-
(uint256 loanId,) =
|
|
495
|
+
(uint256 loanId,) =
|
|
496
|
+
LOANS_CONTRACT.borrowFrom(revnetId, source, loanable, tokens, payable(USER), minPrepaid, USER);
|
|
483
497
|
|
|
484
498
|
REVLoan memory loanBefore = LOANS_CONTRACT.loanOf(loanId);
|
|
485
499
|
assertGt(loanBefore.collateral, 1, "Need >1 collateral for partial return");
|
|
@@ -536,7 +550,8 @@ contract TestLowFindings is TestBaseWorkflow {
|
|
|
536
550
|
uint256 minPrepaid = LOANS_CONTRACT.MIN_PREPAID_FEE_PERCENT();
|
|
537
551
|
|
|
538
552
|
vm.prank(USER);
|
|
539
|
-
(uint256 loanId,) =
|
|
553
|
+
(uint256 loanId,) =
|
|
554
|
+
LOANS_CONTRACT.borrowFrom(revnetId, source, loanable, tokens, payable(USER), minPrepaid, USER);
|
|
540
555
|
|
|
541
556
|
REVLoan memory loan = LOANS_CONTRACT.loanOf(loanId);
|
|
542
557
|
|
|
@@ -587,7 +602,8 @@ contract TestLowFindings is TestBaseWorkflow {
|
|
|
587
602
|
|
|
588
603
|
// Borrow the full max against all tokens.
|
|
589
604
|
vm.prank(USER);
|
|
590
|
-
(uint256 loanId,) =
|
|
605
|
+
(uint256 loanId,) =
|
|
606
|
+
LOANS_CONTRACT.borrowFrom(revnetId, source, loanable, tokens, payable(USER), minPrepaid, USER);
|
|
591
607
|
|
|
592
608
|
REVLoan memory loanBefore = LOANS_CONTRACT.loanOf(loanId);
|
|
593
609
|
assertGt(loanBefore.collateral, 0, "Loan should have collateral");
|
|
@@ -656,6 +672,6 @@ contract TestLowFindings is TestBaseWorkflow {
|
|
|
656
672
|
// Attempt to borrow with 1 wei of collateral -- bonding curve returns 0, should revert.
|
|
657
673
|
vm.prank(USER);
|
|
658
674
|
vm.expectRevert(REVLoans.REVLoans_ZeroBorrowAmount.selector);
|
|
659
|
-
LOANS_CONTRACT.borrowFrom(revnetId, source, 0, 1, payable(USER), minPrepaid);
|
|
675
|
+
LOANS_CONTRACT.borrowFrom(revnetId, source, 0, 1, payable(USER), minPrepaid, USER);
|
|
660
676
|
}
|
|
661
677
|
}
|
|
@@ -35,11 +35,14 @@ import {JBSuckerRegistry} from "@bananapus/suckers-v6/src/JBSuckerRegistry.sol";
|
|
|
35
35
|
import {JB721TiersHookDeployer} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
|
|
36
36
|
import {JB721TiersHook} from "@bananapus/721-hook-v6/src/JB721TiersHook.sol";
|
|
37
37
|
import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
|
|
38
|
+
import {JB721CheckpointsDeployer} from "@bananapus/721-hook-v6/src/JB721CheckpointsDeployer.sol";
|
|
39
|
+
import {IJB721CheckpointsDeployer} from "@bananapus/721-hook-v6/src/interfaces/IJB721CheckpointsDeployer.sol";
|
|
38
40
|
import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
|
|
39
41
|
import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
|
|
40
42
|
import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
|
|
41
43
|
import {REVOwner} from "../src/REVOwner.sol";
|
|
42
44
|
import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
|
|
45
|
+
import {MockSuckerRegistry} from "./mock/MockSuckerRegistry.sol";
|
|
43
46
|
|
|
44
47
|
/// @notice Tests for PR #32: liquidation boundary, reallocate msg.value, and decimal normalization fixes.
|
|
45
48
|
contract TestMixedFixes is TestBaseWorkflow {
|
|
@@ -85,7 +88,14 @@ contract TestMixedFixes is TestBaseWorkflow {
|
|
|
85
88
|
SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
|
|
86
89
|
HOOK_STORE = new JB721TiersHookStore();
|
|
87
90
|
EXAMPLE_HOOK = new JB721TiersHook(
|
|
88
|
-
jbDirectory(),
|
|
91
|
+
jbDirectory(),
|
|
92
|
+
jbPermissions(),
|
|
93
|
+
jbPrices(),
|
|
94
|
+
jbRulesets(),
|
|
95
|
+
HOOK_STORE,
|
|
96
|
+
jbSplits(),
|
|
97
|
+
IJB721CheckpointsDeployer(address(new JB721CheckpointsDeployer())),
|
|
98
|
+
multisig()
|
|
89
99
|
);
|
|
90
100
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
91
101
|
HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
|
|
@@ -98,7 +108,7 @@ contract TestMixedFixes is TestBaseWorkflow {
|
|
|
98
108
|
.addPriceFeedFor(0, uint32(uint160(address(TOKEN))), uint32(uint160(JBConstants.NATIVE_TOKEN)), priceFeed);
|
|
99
109
|
LOANS_CONTRACT = new REVLoans({
|
|
100
110
|
controller: jbController(),
|
|
101
|
-
|
|
111
|
+
suckerRegistry: IJBSuckerRegistry(address(new MockSuckerRegistry())),
|
|
102
112
|
revId: FEE_PROJECT_ID,
|
|
103
113
|
owner: address(this),
|
|
104
114
|
permit2: permit2(),
|
|
@@ -109,7 +119,8 @@ contract TestMixedFixes is TestBaseWorkflow {
|
|
|
109
119
|
jbDirectory(),
|
|
110
120
|
FEE_PROJECT_ID,
|
|
111
121
|
SUCKER_REGISTRY,
|
|
112
|
-
address(LOANS_CONTRACT)
|
|
122
|
+
address(LOANS_CONTRACT),
|
|
123
|
+
address(0)
|
|
113
124
|
);
|
|
114
125
|
|
|
115
126
|
REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
|
|
@@ -245,7 +256,7 @@ contract TestMixedFixes is TestBaseWorkflow {
|
|
|
245
256
|
);
|
|
246
257
|
REVLoanSource memory source = REVLoanSource({token: JBConstants.NATIVE_TOKEN, terminal: jbMultiTerminal()});
|
|
247
258
|
vm.prank(user);
|
|
248
|
-
(loanId,) = LOANS_CONTRACT.borrowFrom(REVNET_ID, source, 0, tokenCount, payable(user), prepaidFee);
|
|
259
|
+
(loanId,) = LOANS_CONTRACT.borrowFrom(REVNET_ID, source, 0, tokenCount, payable(user), prepaidFee, user);
|
|
249
260
|
}
|
|
250
261
|
|
|
251
262
|
/// @notice At exactly LOAN_LIQUIDATION_DURATION, determineSourceFeeAmount should revert with LoanExpired (>=
|
|
@@ -431,7 +442,7 @@ contract TestMixedFixes is TestBaseWorkflow {
|
|
|
431
442
|
REVLoanSource memory ethSource = REVLoanSource({token: JBConstants.NATIVE_TOKEN, terminal: jbMultiTerminal()});
|
|
432
443
|
vm.prank(USER);
|
|
433
444
|
(uint256 loanId, REVLoan memory loan) =
|
|
434
|
-
LOANS_CONTRACT.borrowFrom(MIXED_REVNET_ID, ethSource, 0, tokenCount, payable(USER), 25);
|
|
445
|
+
LOANS_CONTRACT.borrowFrom(MIXED_REVNET_ID, ethSource, 0, tokenCount, payable(USER), 25, USER);
|
|
435
446
|
|
|
436
447
|
// Verify loan created and TOKEN source has zero borrowed.
|
|
437
448
|
assertTrue(loanId != 0, "ETH loan should be created");
|
|
@@ -481,7 +492,7 @@ contract TestMixedFixes is TestBaseWorkflow {
|
|
|
481
492
|
REVLoanSource memory tokenSource = REVLoanSource({token: address(TOKEN), terminal: jbMultiTerminal()});
|
|
482
493
|
vm.prank(USER);
|
|
483
494
|
(uint256 loanId, REVLoan memory loan) =
|
|
484
|
-
LOANS_CONTRACT.borrowFrom(MIXED_REVNET_ID, tokenSource, 0, smallCollateral, payable(USER), 25);
|
|
495
|
+
LOANS_CONTRACT.borrowFrom(MIXED_REVNET_ID, tokenSource, 0, smallCollateral, payable(USER), 25, USER);
|
|
485
496
|
|
|
486
497
|
assertTrue(loanId != 0, "TOKEN loan should be created");
|
|
487
498
|
assertTrue(loan.amount > 0, "Loan amount should be nonzero");
|
|
@@ -537,7 +548,7 @@ contract TestMixedFixes is TestBaseWorkflow {
|
|
|
537
548
|
REVLoanSource memory tokenSource = REVLoanSource({token: address(TOKEN), terminal: jbMultiTerminal()});
|
|
538
549
|
vm.prank(USER);
|
|
539
550
|
(uint256 tokenLoanId,) =
|
|
540
|
-
LOANS_CONTRACT.borrowFrom(MIXED_REVNET_ID, tokenSource, 0, smallCollateral, payable(USER), 25);
|
|
551
|
+
LOANS_CONTRACT.borrowFrom(MIXED_REVNET_ID, tokenSource, 0, smallCollateral, payable(USER), 25, USER);
|
|
541
552
|
assertTrue(tokenLoanId != 0, "TOKEN loan should be created");
|
|
542
553
|
|
|
543
554
|
// STEP 3: Pay ETH to create ETH surplus.
|
|
@@ -558,7 +569,7 @@ contract TestMixedFixes is TestBaseWorkflow {
|
|
|
558
569
|
REVLoanSource memory ethSource = REVLoanSource({token: JBConstants.NATIVE_TOKEN, terminal: jbMultiTerminal()});
|
|
559
570
|
vm.prank(USER);
|
|
560
571
|
(uint256 ethLoanId,) =
|
|
561
|
-
LOANS_CONTRACT.borrowFrom(MIXED_REVNET_ID, ethSource, 0, ethCollateral, payable(USER), 25);
|
|
572
|
+
LOANS_CONTRACT.borrowFrom(MIXED_REVNET_ID, ethSource, 0, ethCollateral, payable(USER), 25, USER);
|
|
562
573
|
assertTrue(ethLoanId != 0, "ETH loan should be created");
|
|
563
574
|
|
|
564
575
|
// Both sources should have tracked borrows.
|
|
@@ -38,6 +38,8 @@ import {JBSuckerRegistry} from "@bananapus/suckers-v6/src/JBSuckerRegistry.sol";
|
|
|
38
38
|
import {JB721TiersHookDeployer} from "@bananapus/721-hook-v6/src/JB721TiersHookDeployer.sol";
|
|
39
39
|
import {JB721TiersHook} from "@bananapus/721-hook-v6/src/JB721TiersHook.sol";
|
|
40
40
|
import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
|
|
41
|
+
import {JB721CheckpointsDeployer} from "@bananapus/721-hook-v6/src/JB721CheckpointsDeployer.sol";
|
|
42
|
+
import {IJB721CheckpointsDeployer} from "@bananapus/721-hook-v6/src/interfaces/IJB721CheckpointsDeployer.sol";
|
|
41
43
|
import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
|
|
42
44
|
import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
|
|
43
45
|
import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
|
|
@@ -47,6 +49,7 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
|
47
49
|
import {JBFees} from "@bananapus/core-v6/src/libraries/JBFees.sol";
|
|
48
50
|
import {REVOwner} from "../src/REVOwner.sol";
|
|
49
51
|
import {IREVDeployer} from "../src/interfaces/IREVDeployer.sol";
|
|
52
|
+
import {MockSuckerRegistry} from "./mock/MockSuckerRegistry.sol";
|
|
50
53
|
|
|
51
54
|
struct Permit2ProjectConfig {
|
|
52
55
|
REVConfig configuration;
|
|
@@ -243,7 +246,14 @@ contract TestPermit2Signatures is TestBaseWorkflow {
|
|
|
243
246
|
SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
|
|
244
247
|
HOOK_STORE = new JB721TiersHookStore();
|
|
245
248
|
EXAMPLE_HOOK = new JB721TiersHook(
|
|
246
|
-
jbDirectory(),
|
|
249
|
+
jbDirectory(),
|
|
250
|
+
jbPermissions(),
|
|
251
|
+
jbPrices(),
|
|
252
|
+
jbRulesets(),
|
|
253
|
+
HOOK_STORE,
|
|
254
|
+
jbSplits(),
|
|
255
|
+
IJB721CheckpointsDeployer(address(new JB721CheckpointsDeployer())),
|
|
256
|
+
multisig()
|
|
247
257
|
);
|
|
248
258
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
249
259
|
HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
|
|
@@ -258,7 +268,7 @@ contract TestPermit2Signatures is TestBaseWorkflow {
|
|
|
258
268
|
|
|
259
269
|
LOANS_CONTRACT = new REVLoans({
|
|
260
270
|
controller: jbController(),
|
|
261
|
-
|
|
271
|
+
suckerRegistry: IJBSuckerRegistry(address(new MockSuckerRegistry())),
|
|
262
272
|
revId: FEE_PROJECT_ID,
|
|
263
273
|
owner: address(this),
|
|
264
274
|
permit2: permit2(),
|
|
@@ -270,7 +280,8 @@ contract TestPermit2Signatures is TestBaseWorkflow {
|
|
|
270
280
|
jbDirectory(),
|
|
271
281
|
FEE_PROJECT_ID,
|
|
272
282
|
SUCKER_REGISTRY,
|
|
273
|
-
address(LOANS_CONTRACT)
|
|
283
|
+
address(LOANS_CONTRACT),
|
|
284
|
+
address(0)
|
|
274
285
|
);
|
|
275
286
|
|
|
276
287
|
REV_DEPLOYER = new REVDeployer{salt: REV_DEPLOYER_SALT}(
|
|
@@ -398,7 +409,7 @@ contract TestPermit2Signatures is TestBaseWorkflow {
|
|
|
398
409
|
REVLoanSource memory source = REVLoanSource({token: address(TOKEN), terminal: jbMultiTerminal()});
|
|
399
410
|
|
|
400
411
|
vm.prank(user);
|
|
401
|
-
(loanId,) = LOANS_CONTRACT.borrowFrom(REVNET_ID, source, 0, tokenCount, payable(user), prepaidFee);
|
|
412
|
+
(loanId,) = LOANS_CONTRACT.borrowFrom(REVNET_ID, source, 0, tokenCount, payable(user), prepaidFee, user);
|
|
402
413
|
}
|
|
403
414
|
|
|
404
415
|
// =========================================================================
|