@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.
- package/ADMINISTRATION.md +7 -7
- package/ARCHITECTURE.md +11 -11
- package/AUDIT_INSTRUCTIONS.md +295 -0
- package/CHANGE_LOG.md +316 -0
- package/README.md +9 -6
- package/RISKS.md +180 -35
- package/SKILLS.md +9 -11
- package/STYLE_GUIDE.md +14 -1
- package/USER_JOURNEYS.md +489 -0
- package/package.json +9 -9
- package/script/Deploy.s.sol +124 -40
- package/script/helpers/RevnetCoreDeploymentLib.sol +19 -6
- package/src/REVDeployer.sol +183 -175
- package/src/REVLoans.sol +65 -28
- package/src/interfaces/IREVDeployer.sol +25 -23
- package/src/structs/REV721TiersHookFlags.sol +1 -0
- package/src/structs/REVAutoIssuance.sol +1 -0
- package/src/structs/REVBaseline721HookConfig.sol +1 -0
- package/src/structs/REVConfig.sol +1 -0
- package/src/structs/REVCroptopAllowedPost.sol +1 -0
- package/src/structs/REVDeploy721TiersHookConfig.sol +13 -14
- package/src/structs/REVDescription.sol +1 -0
- package/src/structs/REVLoan.sol +1 -0
- package/src/structs/REVLoanSource.sol +1 -0
- package/src/structs/REVStageConfig.sol +1 -0
- package/src/structs/REVSuckerDeploymentConfig.sol +1 -0
- package/test/REV.integrations.t.sol +148 -19
- package/test/REVAutoIssuanceFuzz.t.sol +31 -6
- package/test/REVDeployerRegressions.t.sol +47 -9
- package/test/REVInvincibility.t.sol +83 -19
- package/test/REVInvincibilityHandler.sol +29 -0
- package/test/REVLifecycle.t.sol +36 -6
- package/test/REVLoans.invariants.t.sol +64 -10
- package/test/REVLoansAttacks.t.sol +54 -9
- package/test/REVLoansFeeRecovery.t.sol +61 -15
- package/test/REVLoansFindings.t.sol +42 -9
- package/test/REVLoansRegressions.t.sol +33 -6
- package/test/REVLoansSourceFeeRecovery.t.sol +491 -0
- package/test/REVLoansSourced.t.sol +79 -17
- package/test/REVLoansUnSourced.t.sol +61 -10
- package/test/TestBurnHeldTokens.t.sol +47 -11
- package/test/TestCEIPattern.t.sol +37 -6
- package/test/TestCashOutCallerValidation.t.sol +41 -8
- package/test/TestConversionDocumentation.t.sol +50 -13
- package/test/TestCrossCurrencyReclaim.t.sol +584 -0
- package/test/TestCrossSourceReallocation.t.sol +37 -6
- package/test/TestERC2771MetaTx.t.sol +557 -0
- package/test/TestEmptyBuybackSpecs.t.sol +45 -10
- package/test/TestFlashLoanSurplus.t.sol +39 -7
- package/test/TestHookArrayOOB.t.sol +42 -13
- package/test/TestLiquidationBehavior.t.sol +37 -7
- package/test/TestLoanSourceRotation.t.sol +525 -0
- package/test/TestLongTailEconomics.t.sol +651 -0
- package/test/TestLowFindings.t.sol +80 -8
- package/test/TestMixedFixes.t.sol +43 -9
- package/test/TestPermit2Signatures.t.sol +657 -0
- package/test/TestReallocationSandwich.t.sol +384 -0
- package/test/TestRevnetRegressions.t.sol +324 -0
- package/test/TestSplitWeightAdjustment.t.sol +52 -13
- package/test/TestSplitWeightE2E.t.sol +53 -18
- package/test/TestSplitWeightFork.t.sol +66 -21
- package/test/TestStageTransitionBorrowable.t.sol +38 -6
- package/test/TestSwapTerminalPermission.t.sol +37 -7
- package/test/TestUint112Overflow.t.sol +39 -6
- package/test/TestZeroRepayment.t.sol +37 -6
- package/test/fork/ForkTestBase.sol +66 -17
- package/test/fork/TestCashOutFork.t.sol +9 -3
- package/test/fork/TestLoanBorrowFork.t.sol +1 -0
- package/test/fork/TestLoanCrossRulesetFork.t.sol +11 -3
- package/test/fork/TestLoanLiquidationFork.t.sol +1 -0
- package/test/fork/TestLoanReallocateFork.t.sol +1 -0
- package/test/fork/TestLoanRepayFork.t.sol +1 -0
- package/test/fork/TestLoanTransferFork.t.sol +133 -0
- package/test/fork/TestSplitWeightFork.t.sol +3 -0
- package/test/helpers/REVEmpty721Config.sol +46 -0
- package/test/mock/MockBuybackDataHook.sol +1 -0
- package/test/regression/TestBurnPermissionRequired.t.sol +267 -0
- package/test/regression/TestCrossRevnetLiquidation.t.sol +228 -0
- package/test/regression/TestCumulativeLoanCounter.t.sol +38 -8
- package/test/regression/TestLiquidateGapHandling.t.sol +40 -8
- package/test/regression/TestZeroPriceFeed.t.sol +396 -0
|
@@ -1,22 +1,32 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
pragma solidity 0.8.26;
|
|
3
3
|
|
|
4
|
+
// forge-lint: disable-next-line(unaliased-plain-import)
|
|
4
5
|
import "forge-std/Test.sol";
|
|
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";
|
|
17
|
+
import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
|
|
12
18
|
|
|
19
|
+
// forge-lint: disable-next-line(unaliased-plain-import)
|
|
13
20
|
import "@bananapus/core-v6/script/helpers/CoreDeploymentLib.sol";
|
|
21
|
+
// forge-lint: disable-next-line(unaliased-plain-import)
|
|
14
22
|
import "@bananapus/721-hook-v6/script/helpers/Hook721DeploymentLib.sol";
|
|
23
|
+
// forge-lint: disable-next-line(unaliased-plain-import)
|
|
15
24
|
import "@bananapus/suckers-v6/script/helpers/SuckerDeploymentLib.sol";
|
|
25
|
+
// forge-lint: disable-next-line(unaliased-plain-import)
|
|
16
26
|
import "@croptop/core-v6/script/helpers/CroptopDeploymentLib.sol";
|
|
27
|
+
// forge-lint: disable-next-line(unaliased-plain-import)
|
|
17
28
|
import "@bananapus/router-terminal-v6/script/helpers/RouterTerminalDeploymentLib.sol";
|
|
18
29
|
|
|
19
|
-
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
32
|
import {REVLoans} from "../src/REVLoans.sol";
|
|
@@ -40,17 +50,28 @@ struct FeeProjectConfig {
|
|
|
40
50
|
}
|
|
41
51
|
|
|
42
52
|
contract REVLoansCallHandler is JBTest {
|
|
53
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
43
54
|
uint256 public COLLATERAL_SUM;
|
|
55
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
44
56
|
uint256 public COLLATERAL_RETURNED;
|
|
57
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
45
58
|
uint256 public BORROWED_SUM;
|
|
59
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
46
60
|
uint256 public RUNS;
|
|
61
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
47
62
|
uint256 REVNET_ID;
|
|
63
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
48
64
|
uint256 LAST_LOAN_MODIFIED;
|
|
65
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
49
66
|
address USER;
|
|
50
67
|
|
|
68
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
51
69
|
IJBMultiTerminal TERMINAL;
|
|
70
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
52
71
|
IREVLoans LOANS;
|
|
72
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
53
73
|
IJBPermissions PERMS;
|
|
74
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
54
75
|
IJBTokens TOKENS;
|
|
55
76
|
|
|
56
77
|
constructor(
|
|
@@ -258,34 +279,50 @@ contract InvariantREVLoansTests is StdInvariant, TestBaseWorkflow {
|
|
|
258
279
|
using JBRulesetMetadataResolver for JBRuleset;
|
|
259
280
|
|
|
260
281
|
/// @notice the salts that are used to deploy the contracts.
|
|
282
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
261
283
|
bytes32 REV_DEPLOYER_SALT = "REVDeployer";
|
|
284
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
262
285
|
bytes32 ERC20_SALT = "REV_TOKEN";
|
|
263
286
|
|
|
264
287
|
// Handlers
|
|
288
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
265
289
|
REVLoansCallHandler PAY_HANDLER;
|
|
266
290
|
|
|
291
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
267
292
|
REVDeployer REV_DEPLOYER;
|
|
293
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
268
294
|
JB721TiersHook EXAMPLE_HOOK;
|
|
269
295
|
|
|
270
296
|
/// @notice Deploys tiered ERC-721 hooks for revnets.
|
|
297
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
271
298
|
IJB721TiersHookDeployer HOOK_DEPLOYER;
|
|
299
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
272
300
|
IJB721TiersHookStore HOOK_STORE;
|
|
301
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
273
302
|
IJBAddressRegistry ADDRESS_REGISTRY;
|
|
274
303
|
|
|
304
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
275
305
|
IREVLoans LOANS_CONTRACT;
|
|
276
306
|
|
|
277
307
|
/// @notice Deploys and tracks suckers for revnets.
|
|
308
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
278
309
|
IJBSuckerRegistry SUCKER_REGISTRY;
|
|
279
310
|
|
|
311
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
280
312
|
CTPublisher PUBLISHER;
|
|
313
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
281
314
|
MockBuybackDataHook MOCK_BUYBACK;
|
|
282
315
|
|
|
283
316
|
// When the second project is deployed, track the block.timestamp.
|
|
317
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
284
318
|
uint256 INITIAL_TIMESTAMP;
|
|
285
319
|
|
|
320
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
286
321
|
uint256 FEE_PROJECT_ID;
|
|
322
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
287
323
|
uint256 REVNET_ID;
|
|
288
324
|
|
|
325
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
289
326
|
address USER = makeAddr("user");
|
|
290
327
|
|
|
291
328
|
/// @notice The address that is allowed to forward calls.
|
|
@@ -322,7 +359,11 @@ contract InvariantREVLoansTests is StdInvariant, TestBaseWorkflow {
|
|
|
322
359
|
{
|
|
323
360
|
REVAutoIssuance[] memory issuanceConfs = new REVAutoIssuance[](1);
|
|
324
361
|
issuanceConfs[0] = REVAutoIssuance({
|
|
325
|
-
|
|
362
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
363
|
+
chainId: uint32(block.chainid),
|
|
364
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
365
|
+
count: uint104(70_000 * decimalMultiplier),
|
|
366
|
+
beneficiary: multisig()
|
|
326
367
|
});
|
|
327
368
|
|
|
328
369
|
stageConfigurations[0] = REVStageConfig({
|
|
@@ -330,6 +371,7 @@ contract InvariantREVLoansTests is StdInvariant, TestBaseWorkflow {
|
|
|
330
371
|
autoIssuances: issuanceConfs,
|
|
331
372
|
splitPercent: 2000, // 20%
|
|
332
373
|
splits: splits,
|
|
374
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
333
375
|
initialIssuance: uint112(1000 * decimalMultiplier),
|
|
334
376
|
issuanceCutFrequency: 90 days,
|
|
335
377
|
issuanceCutPercent: JBConstants.MAX_WEIGHT_CUT_PERCENT / 2,
|
|
@@ -364,6 +406,7 @@ contract InvariantREVLoansTests is StdInvariant, TestBaseWorkflow {
|
|
|
364
406
|
|
|
365
407
|
// The project's revnet configuration
|
|
366
408
|
REVConfig memory revnetConfiguration = REVConfig({
|
|
409
|
+
// forge-lint: disable-next-line(named-struct-fields)
|
|
367
410
|
description: REVDescription(name, symbol, projectUri, ERC20_SALT),
|
|
368
411
|
baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
|
|
369
412
|
splitOperator: multisig(),
|
|
@@ -410,7 +453,11 @@ contract InvariantREVLoansTests is StdInvariant, TestBaseWorkflow {
|
|
|
410
453
|
{
|
|
411
454
|
REVAutoIssuance[] memory issuanceConfs = new REVAutoIssuance[](1);
|
|
412
455
|
issuanceConfs[0] = REVAutoIssuance({
|
|
413
|
-
|
|
456
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
457
|
+
chainId: uint32(block.chainid),
|
|
458
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
459
|
+
count: uint104(70_000 * decimalMultiplier),
|
|
460
|
+
beneficiary: multisig()
|
|
414
461
|
});
|
|
415
462
|
|
|
416
463
|
stageConfigurations[0] = REVStageConfig({
|
|
@@ -418,6 +465,7 @@ contract InvariantREVLoansTests is StdInvariant, TestBaseWorkflow {
|
|
|
418
465
|
autoIssuances: issuanceConfs,
|
|
419
466
|
splitPercent: 2000, // 20%
|
|
420
467
|
splits: splits,
|
|
468
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
421
469
|
initialIssuance: uint112(1000 * decimalMultiplier),
|
|
422
470
|
issuanceCutFrequency: 90 days,
|
|
423
471
|
issuanceCutPercent: JBConstants.MAX_WEIGHT_CUT_PERCENT / 2,
|
|
@@ -452,6 +500,7 @@ contract InvariantREVLoansTests is StdInvariant, TestBaseWorkflow {
|
|
|
452
500
|
|
|
453
501
|
// The project's revnet configuration
|
|
454
502
|
REVConfig memory revnetConfiguration = REVConfig({
|
|
503
|
+
// forge-lint: disable-next-line(named-struct-fields)
|
|
455
504
|
description: REVDescription(name, symbol, projectUri, "NANA_TOKEN"),
|
|
456
505
|
baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
|
|
457
506
|
splitOperator: multisig(),
|
|
@@ -476,8 +525,9 @@ contract InvariantREVLoansTests is StdInvariant, TestBaseWorkflow {
|
|
|
476
525
|
|
|
477
526
|
HOOK_STORE = new JB721TiersHookStore();
|
|
478
527
|
|
|
479
|
-
EXAMPLE_HOOK =
|
|
480
|
-
|
|
528
|
+
EXAMPLE_HOOK = new JB721TiersHook(
|
|
529
|
+
jbDirectory(), jbPermissions(), jbPrices(), jbRulesets(), HOOK_STORE, jbSplits(), multisig()
|
|
530
|
+
);
|
|
481
531
|
|
|
482
532
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
483
533
|
|
|
@@ -515,22 +565,26 @@ contract InvariantREVLoansTests is StdInvariant, TestBaseWorkflow {
|
|
|
515
565
|
|
|
516
566
|
// Configure the project.
|
|
517
567
|
vm.prank(address(multisig()));
|
|
518
|
-
REVNET_ID = REV_DEPLOYER.deployFor({
|
|
568
|
+
(REVNET_ID,) = REV_DEPLOYER.deployFor({
|
|
519
569
|
revnetId: FEE_PROJECT_ID, // Zero to deploy a new revnet
|
|
520
570
|
configuration: feeProjectConfig.configuration,
|
|
521
571
|
terminalConfigurations: feeProjectConfig.terminalConfigurations,
|
|
522
|
-
suckerDeploymentConfiguration: feeProjectConfig.suckerDeploymentConfiguration
|
|
572
|
+
suckerDeploymentConfiguration: feeProjectConfig.suckerDeploymentConfiguration,
|
|
573
|
+
tiered721HookConfiguration: REVEmpty721Config.empty721Config(uint32(uint160(JBConstants.NATIVE_TOKEN))),
|
|
574
|
+
allowedPosts: REVEmpty721Config.emptyAllowedPosts()
|
|
523
575
|
});
|
|
524
576
|
|
|
525
577
|
// Configure second revnet
|
|
526
578
|
FeeProjectConfig memory fee2Config = getSecondProjectConfig();
|
|
527
579
|
|
|
528
580
|
// Configure the second project.
|
|
529
|
-
REVNET_ID = REV_DEPLOYER.deployFor({
|
|
581
|
+
(REVNET_ID,) = REV_DEPLOYER.deployFor({
|
|
530
582
|
revnetId: 0, // Zero to deploy a new revnet
|
|
531
583
|
configuration: fee2Config.configuration,
|
|
532
584
|
terminalConfigurations: fee2Config.terminalConfigurations,
|
|
533
|
-
suckerDeploymentConfiguration: fee2Config.suckerDeploymentConfiguration
|
|
585
|
+
suckerDeploymentConfiguration: fee2Config.suckerDeploymentConfiguration,
|
|
586
|
+
tiered721HookConfiguration: REVEmpty721Config.empty721Config(uint32(uint160(JBConstants.NATIVE_TOKEN))),
|
|
587
|
+
allowedPosts: REVEmpty721Config.emptyAllowedPosts()
|
|
534
588
|
});
|
|
535
589
|
|
|
536
590
|
INITIAL_TIMESTAMP = block.timestamp;
|
|
@@ -1,17 +1,26 @@
|
|
|
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";
|
|
@@ -31,8 +40,8 @@ import {JB721TiersHook} from "@bananapus/721-hook-v6/src/JB721TiersHook.sol";
|
|
|
31
40
|
import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
|
|
32
41
|
import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
|
|
33
42
|
import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
|
|
43
|
+
import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
|
|
34
44
|
import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
|
|
35
|
-
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
36
45
|
|
|
37
46
|
/// @notice A malicious terminal that re-enters REVLoans during fee payment in _adjust().
|
|
38
47
|
/// @dev Reentrancy during pay() callback in _adjust.
|
|
@@ -177,24 +186,40 @@ struct AttackProjectConfig {
|
|
|
177
186
|
/// @notice Attack tests for REVLoans covering uint112 truncation, reentrancy,
|
|
178
187
|
/// collateral race conditions, liquidation edge cases, and fuzz testing.
|
|
179
188
|
contract REVLoansAttacks is TestBaseWorkflow {
|
|
189
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
180
190
|
bytes32 REV_DEPLOYER_SALT = "REVDeployer";
|
|
191
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
181
192
|
bytes32 ERC20_SALT = "REV_TOKEN";
|
|
182
193
|
|
|
194
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
183
195
|
REVDeployer REV_DEPLOYER;
|
|
196
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
184
197
|
JB721TiersHook EXAMPLE_HOOK;
|
|
198
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
185
199
|
IJB721TiersHookDeployer HOOK_DEPLOYER;
|
|
200
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
186
201
|
IJB721TiersHookStore HOOK_STORE;
|
|
202
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
187
203
|
IJBAddressRegistry ADDRESS_REGISTRY;
|
|
204
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
188
205
|
IREVLoans LOANS_CONTRACT;
|
|
206
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
189
207
|
MockERC20 TOKEN;
|
|
208
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
190
209
|
IJBSuckerRegistry SUCKER_REGISTRY;
|
|
210
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
191
211
|
CTPublisher PUBLISHER;
|
|
212
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
192
213
|
MockBuybackDataHook MOCK_BUYBACK;
|
|
193
214
|
|
|
215
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
194
216
|
uint256 FEE_PROJECT_ID;
|
|
217
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
195
218
|
uint256 REVNET_ID;
|
|
196
219
|
|
|
220
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
197
221
|
address USER = makeAddr("user");
|
|
222
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
198
223
|
address ATTACKER = makeAddr("attacker");
|
|
199
224
|
|
|
200
225
|
address private constant TRUSTED_FORWARDER = 0xB2b5841DBeF766d4b521221732F9B618fCf34A87;
|
|
@@ -224,7 +249,11 @@ contract REVLoansAttacks is TestBaseWorkflow {
|
|
|
224
249
|
|
|
225
250
|
REVAutoIssuance[] memory issuanceConfs = new REVAutoIssuance[](1);
|
|
226
251
|
issuanceConfs[0] = REVAutoIssuance({
|
|
227
|
-
|
|
252
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
253
|
+
chainId: uint32(block.chainid),
|
|
254
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
255
|
+
count: uint104(70_000 * decimalMultiplier),
|
|
256
|
+
beneficiary: multisig()
|
|
228
257
|
});
|
|
229
258
|
|
|
230
259
|
stageConfigurations[0] = REVStageConfig({
|
|
@@ -232,6 +261,7 @@ contract REVLoansAttacks is TestBaseWorkflow {
|
|
|
232
261
|
autoIssuances: issuanceConfs,
|
|
233
262
|
splitPercent: 2000,
|
|
234
263
|
splits: splits,
|
|
264
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
235
265
|
initialIssuance: uint112(1000 * decimalMultiplier),
|
|
236
266
|
issuanceCutFrequency: 90 days,
|
|
237
267
|
issuanceCutPercent: JBConstants.MAX_WEIGHT_CUT_PERCENT / 2,
|
|
@@ -240,6 +270,7 @@ contract REVLoansAttacks is TestBaseWorkflow {
|
|
|
240
270
|
});
|
|
241
271
|
|
|
242
272
|
REVConfig memory revnetConfiguration = REVConfig({
|
|
273
|
+
// forge-lint: disable-next-line(named-struct-fields)
|
|
243
274
|
description: REVDescription(name, symbol, projectUri, ERC20_SALT),
|
|
244
275
|
baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
|
|
245
276
|
splitOperator: multisig(),
|
|
@@ -280,7 +311,11 @@ contract REVLoansAttacks is TestBaseWorkflow {
|
|
|
280
311
|
REVStageConfig[] memory stageConfigurations = new REVStageConfig[](1);
|
|
281
312
|
REVAutoIssuance[] memory issuanceConfs = new REVAutoIssuance[](1);
|
|
282
313
|
issuanceConfs[0] = REVAutoIssuance({
|
|
283
|
-
|
|
314
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
315
|
+
chainId: uint32(block.chainid),
|
|
316
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
317
|
+
count: uint104(70_000 * decimalMultiplier),
|
|
318
|
+
beneficiary: multisig()
|
|
284
319
|
});
|
|
285
320
|
|
|
286
321
|
stageConfigurations[0] = REVStageConfig({
|
|
@@ -288,6 +323,7 @@ contract REVLoansAttacks is TestBaseWorkflow {
|
|
|
288
323
|
autoIssuances: issuanceConfs,
|
|
289
324
|
splitPercent: 2000,
|
|
290
325
|
splits: splits,
|
|
326
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
291
327
|
initialIssuance: uint112(1000 * decimalMultiplier),
|
|
292
328
|
issuanceCutFrequency: 90 days,
|
|
293
329
|
issuanceCutPercent: JBConstants.MAX_WEIGHT_CUT_PERCENT / 2,
|
|
@@ -296,6 +332,7 @@ contract REVLoansAttacks is TestBaseWorkflow {
|
|
|
296
332
|
});
|
|
297
333
|
|
|
298
334
|
REVConfig memory revnetConfiguration = REVConfig({
|
|
335
|
+
// forge-lint: disable-next-line(named-struct-fields)
|
|
299
336
|
description: REVDescription(name, symbol, projectUri, "NANA_TOKEN"),
|
|
300
337
|
baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
|
|
301
338
|
splitOperator: multisig(),
|
|
@@ -318,8 +355,9 @@ contract REVLoansAttacks is TestBaseWorkflow {
|
|
|
318
355
|
|
|
319
356
|
SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
|
|
320
357
|
HOOK_STORE = new JB721TiersHookStore();
|
|
321
|
-
EXAMPLE_HOOK =
|
|
322
|
-
|
|
358
|
+
EXAMPLE_HOOK = new JB721TiersHook(
|
|
359
|
+
jbDirectory(), jbPermissions(), jbPrices(), jbRulesets(), HOOK_STORE, jbSplits(), multisig()
|
|
360
|
+
);
|
|
323
361
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
324
362
|
HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
|
|
325
363
|
PUBLISHER = new CTPublisher(jbDirectory(), jbPermissions(), FEE_PROJECT_ID, multisig());
|
|
@@ -361,16 +399,20 @@ contract REVLoansAttacks is TestBaseWorkflow {
|
|
|
361
399
|
revnetId: FEE_PROJECT_ID,
|
|
362
400
|
configuration: feeProjectConfig.configuration,
|
|
363
401
|
terminalConfigurations: feeProjectConfig.terminalConfigurations,
|
|
364
|
-
suckerDeploymentConfiguration: feeProjectConfig.suckerDeploymentConfiguration
|
|
402
|
+
suckerDeploymentConfiguration: feeProjectConfig.suckerDeploymentConfiguration,
|
|
403
|
+
tiered721HookConfiguration: REVEmpty721Config.empty721Config(uint32(uint160(JBConstants.NATIVE_TOKEN))),
|
|
404
|
+
allowedPosts: REVEmpty721Config.emptyAllowedPosts()
|
|
365
405
|
});
|
|
366
406
|
|
|
367
407
|
// Deploy second revnet with loans enabled
|
|
368
408
|
AttackProjectConfig memory revnetConfig = _getRevnetConfig();
|
|
369
|
-
REVNET_ID = REV_DEPLOYER.deployFor({
|
|
409
|
+
(REVNET_ID,) = REV_DEPLOYER.deployFor({
|
|
370
410
|
revnetId: 0,
|
|
371
411
|
configuration: revnetConfig.configuration,
|
|
372
412
|
terminalConfigurations: revnetConfig.terminalConfigurations,
|
|
373
|
-
suckerDeploymentConfiguration: revnetConfig.suckerDeploymentConfiguration
|
|
413
|
+
suckerDeploymentConfiguration: revnetConfig.suckerDeploymentConfiguration,
|
|
414
|
+
tiered721HookConfiguration: REVEmpty721Config.empty721Config(uint32(uint160(JBConstants.NATIVE_TOKEN))),
|
|
415
|
+
allowedPosts: REVEmpty721Config.emptyAllowedPosts()
|
|
374
416
|
});
|
|
375
417
|
|
|
376
418
|
vm.deal(USER, 1000e18);
|
|
@@ -440,11 +482,13 @@ contract REVLoansAttacks is TestBaseWorkflow {
|
|
|
440
482
|
// Now verify that the uint112 cast would truncate if somehow a larger value were used.
|
|
441
483
|
// We can directly verify the truncation behavior:
|
|
442
484
|
uint256 overflowValue = uint256(type(uint112).max) + 1;
|
|
485
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
443
486
|
uint112 truncated = uint112(overflowValue);
|
|
444
487
|
assertEq(truncated, 0, "uint112 truncation of max+1 should wrap to 0");
|
|
445
488
|
|
|
446
489
|
// And for a value just slightly above max:
|
|
447
490
|
uint256 slightlyOver = uint256(type(uint112).max) + 1000;
|
|
491
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
448
492
|
uint112 truncated2 = uint112(slightlyOver);
|
|
449
493
|
assertEq(truncated2, 999, "uint112 truncation should wrap around");
|
|
450
494
|
}
|
|
@@ -460,6 +504,7 @@ contract REVLoansAttacks is TestBaseWorkflow {
|
|
|
460
504
|
uint256 overflowCollateral = maxCollateral + 1;
|
|
461
505
|
|
|
462
506
|
// Direct cast would truncate
|
|
507
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
463
508
|
uint112 truncated = uint112(overflowCollateral);
|
|
464
509
|
assertEq(truncated, 0, "Collateral overflow should truncate to 0");
|
|
465
510
|
|
|
@@ -1,17 +1,26 @@
|
|
|
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";
|
|
@@ -33,7 +42,7 @@ import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStor
|
|
|
33
42
|
import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
|
|
34
43
|
import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
|
|
35
44
|
import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
|
|
36
|
-
import {
|
|
45
|
+
import {REVEmpty721Config} from "./helpers/REVEmpty721Config.sol";
|
|
37
46
|
|
|
38
47
|
/// @notice A terminal mock that always reverts on pay(), used to simulate fee payment failure.
|
|
39
48
|
contract RevertingFeeTerminal is ERC165, IJBPayoutTerminal {
|
|
@@ -137,24 +146,40 @@ struct FeeRecoveryProjectConfig {
|
|
|
137
146
|
/// @dev When feeTerminal.pay() reverts, the borrower should receive the fee amount back
|
|
138
147
|
/// instead of losing it. For ERC-20 tokens, the dangling allowance must also be cleaned up.
|
|
139
148
|
contract REVLoansFeeRecovery is TestBaseWorkflow {
|
|
149
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
140
150
|
bytes32 REV_DEPLOYER_SALT = "REVDeployer";
|
|
151
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
141
152
|
bytes32 ERC20_SALT = "REV_TOKEN";
|
|
142
153
|
|
|
154
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
143
155
|
REVDeployer REV_DEPLOYER;
|
|
156
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
144
157
|
JB721TiersHook EXAMPLE_HOOK;
|
|
158
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
145
159
|
IJB721TiersHookDeployer HOOK_DEPLOYER;
|
|
160
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
146
161
|
IJB721TiersHookStore HOOK_STORE;
|
|
162
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
147
163
|
IJBAddressRegistry ADDRESS_REGISTRY;
|
|
164
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
148
165
|
IREVLoans LOANS_CONTRACT;
|
|
166
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
149
167
|
MockERC20 TOKEN;
|
|
168
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
150
169
|
IJBSuckerRegistry SUCKER_REGISTRY;
|
|
170
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
151
171
|
CTPublisher PUBLISHER;
|
|
172
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
152
173
|
MockBuybackDataHook MOCK_BUYBACK;
|
|
174
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
153
175
|
RevertingFeeTerminal REVERTING_TERMINAL;
|
|
154
176
|
|
|
177
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
155
178
|
uint256 FEE_PROJECT_ID;
|
|
179
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
156
180
|
uint256 REVNET_ID;
|
|
157
181
|
|
|
182
|
+
// forge-lint: disable-next-line(mixed-case-variable)
|
|
158
183
|
address USER = makeAddr("user");
|
|
159
184
|
address private constant TRUSTED_FORWARDER = 0xB2b5841DBeF766d4b521221732F9B618fCf34A87;
|
|
160
185
|
|
|
@@ -180,7 +205,11 @@ contract REVLoansFeeRecovery is TestBaseWorkflow {
|
|
|
180
205
|
|
|
181
206
|
REVAutoIssuance[] memory issuanceConfs = new REVAutoIssuance[](1);
|
|
182
207
|
issuanceConfs[0] = REVAutoIssuance({
|
|
183
|
-
|
|
208
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
209
|
+
chainId: uint32(block.chainid),
|
|
210
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
211
|
+
count: uint104(70_000 * decimalMultiplier),
|
|
212
|
+
beneficiary: multisig()
|
|
184
213
|
});
|
|
185
214
|
|
|
186
215
|
stageConfigurations[0] = REVStageConfig({
|
|
@@ -188,6 +217,7 @@ contract REVLoansFeeRecovery is TestBaseWorkflow {
|
|
|
188
217
|
autoIssuances: issuanceConfs,
|
|
189
218
|
splitPercent: 2000,
|
|
190
219
|
splits: splits,
|
|
220
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
191
221
|
initialIssuance: uint112(1000 * decimalMultiplier),
|
|
192
222
|
issuanceCutFrequency: 90 days,
|
|
193
223
|
issuanceCutPercent: JBConstants.MAX_WEIGHT_CUT_PERCENT / 2,
|
|
@@ -196,9 +226,12 @@ contract REVLoansFeeRecovery is TestBaseWorkflow {
|
|
|
196
226
|
});
|
|
197
227
|
|
|
198
228
|
REVConfig memory revnetConfiguration = REVConfig({
|
|
199
|
-
description: REVDescription(
|
|
200
|
-
"Revnet",
|
|
201
|
-
|
|
229
|
+
description: REVDescription({
|
|
230
|
+
name: "Revnet",
|
|
231
|
+
ticker: "$REV",
|
|
232
|
+
uri: "ipfs://QmNRHT91HcDgMcenebYX7rJigt77cgNcosvuhX21wkF3tx",
|
|
233
|
+
salt: ERC20_SALT
|
|
234
|
+
}),
|
|
202
235
|
baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
|
|
203
236
|
splitOperator: multisig(),
|
|
204
237
|
stageConfigurations: stageConfigurations
|
|
@@ -235,7 +268,11 @@ contract REVLoansFeeRecovery is TestBaseWorkflow {
|
|
|
235
268
|
REVStageConfig[] memory stageConfigurations = new REVStageConfig[](1);
|
|
236
269
|
REVAutoIssuance[] memory issuanceConfs = new REVAutoIssuance[](1);
|
|
237
270
|
issuanceConfs[0] = REVAutoIssuance({
|
|
238
|
-
|
|
271
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
272
|
+
chainId: uint32(block.chainid),
|
|
273
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
274
|
+
count: uint104(70_000 * decimalMultiplier),
|
|
275
|
+
beneficiary: multisig()
|
|
239
276
|
});
|
|
240
277
|
|
|
241
278
|
stageConfigurations[0] = REVStageConfig({
|
|
@@ -243,6 +280,7 @@ contract REVLoansFeeRecovery is TestBaseWorkflow {
|
|
|
243
280
|
autoIssuances: issuanceConfs,
|
|
244
281
|
splitPercent: 2000,
|
|
245
282
|
splits: splits,
|
|
283
|
+
// forge-lint: disable-next-line(unsafe-typecast)
|
|
246
284
|
initialIssuance: uint112(1000 * decimalMultiplier),
|
|
247
285
|
issuanceCutFrequency: 90 days,
|
|
248
286
|
issuanceCutPercent: JBConstants.MAX_WEIGHT_CUT_PERCENT / 2,
|
|
@@ -255,9 +293,12 @@ contract REVLoansFeeRecovery is TestBaseWorkflow {
|
|
|
255
293
|
_loanSources[1] = REVLoanSource({token: address(TOKEN), terminal: jbMultiTerminal()});
|
|
256
294
|
|
|
257
295
|
REVConfig memory revnetConfiguration = REVConfig({
|
|
258
|
-
description: REVDescription(
|
|
259
|
-
|
|
260
|
-
|
|
296
|
+
description: REVDescription({
|
|
297
|
+
name: "NANA",
|
|
298
|
+
ticker: "$NANA",
|
|
299
|
+
uri: "ipfs://QmNRHT91HcDgMcenebYX7rJigt77cgNxosvuhX21wkF3tx",
|
|
300
|
+
salt: "NANA_TOKEN"
|
|
301
|
+
}),
|
|
261
302
|
baseCurrency: uint32(uint160(JBConstants.NATIVE_TOKEN)),
|
|
262
303
|
splitOperator: multisig(),
|
|
263
304
|
stageConfigurations: stageConfigurations
|
|
@@ -279,8 +320,9 @@ contract REVLoansFeeRecovery is TestBaseWorkflow {
|
|
|
279
320
|
|
|
280
321
|
SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
|
|
281
322
|
HOOK_STORE = new JB721TiersHookStore();
|
|
282
|
-
EXAMPLE_HOOK =
|
|
283
|
-
|
|
323
|
+
EXAMPLE_HOOK = new JB721TiersHook(
|
|
324
|
+
jbDirectory(), jbPermissions(), jbPrices(), jbRulesets(), HOOK_STORE, jbSplits(), multisig()
|
|
325
|
+
);
|
|
284
326
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
285
327
|
HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
|
|
286
328
|
PUBLISHER = new CTPublisher(jbDirectory(), jbPermissions(), FEE_PROJECT_ID, multisig());
|
|
@@ -323,16 +365,20 @@ contract REVLoansFeeRecovery is TestBaseWorkflow {
|
|
|
323
365
|
revnetId: FEE_PROJECT_ID,
|
|
324
366
|
configuration: feeProjectConfig.configuration,
|
|
325
367
|
terminalConfigurations: feeProjectConfig.terminalConfigurations,
|
|
326
|
-
suckerDeploymentConfiguration: feeProjectConfig.suckerDeploymentConfiguration
|
|
368
|
+
suckerDeploymentConfiguration: feeProjectConfig.suckerDeploymentConfiguration,
|
|
369
|
+
tiered721HookConfiguration: REVEmpty721Config.empty721Config(uint32(uint160(JBConstants.NATIVE_TOKEN))),
|
|
370
|
+
allowedPosts: REVEmpty721Config.emptyAllowedPosts()
|
|
327
371
|
});
|
|
328
372
|
|
|
329
373
|
// Deploy revnet with loans enabled.
|
|
330
374
|
FeeRecoveryProjectConfig memory revnetConfig = _getRevnetConfig();
|
|
331
|
-
REVNET_ID = REV_DEPLOYER.deployFor({
|
|
375
|
+
(REVNET_ID,) = REV_DEPLOYER.deployFor({
|
|
332
376
|
revnetId: 0,
|
|
333
377
|
configuration: revnetConfig.configuration,
|
|
334
378
|
terminalConfigurations: revnetConfig.terminalConfigurations,
|
|
335
|
-
suckerDeploymentConfiguration: revnetConfig.suckerDeploymentConfiguration
|
|
379
|
+
suckerDeploymentConfiguration: revnetConfig.suckerDeploymentConfiguration,
|
|
380
|
+
tiered721HookConfiguration: REVEmpty721Config.empty721Config(uint32(uint160(JBConstants.NATIVE_TOKEN))),
|
|
381
|
+
allowedPosts: REVEmpty721Config.emptyAllowedPosts()
|
|
336
382
|
});
|
|
337
383
|
|
|
338
384
|
vm.deal(USER, 1000e18);
|