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