@rev-net/core-v6 0.0.8 → 0.0.9
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 +186 -0
- package/ARCHITECTURE.md +87 -0
- package/README.md +4 -2
- package/RISKS.md +49 -0
- package/SKILLS.md +22 -2
- package/STYLE_GUIDE.md +482 -0
- package/foundry.toml +6 -6
- package/package.json +8 -8
- package/script/Deploy.s.sol +3 -2
- package/src/REVDeployer.sol +75 -52
- package/src/REVLoans.sol +13 -4
- package/src/interfaces/IREVDeployer.sol +2 -1
- package/src/structs/REV721TiersHookFlags.sol +14 -0
- package/src/structs/REVBaseline721HookConfig.sol +27 -0
- package/src/structs/REVDeploy721TiersHookConfig.sol +2 -2
- package/test/REV.integrations.t.sol +4 -3
- package/test/REVAutoIssuanceFuzz.t.sol +12 -8
- package/test/REVDeployerAuditRegressions.t.sol +4 -3
- package/test/REVInvincibility.t.sol +8 -6
- package/test/REVInvincibilityHandler.sol +1 -0
- package/test/REVLifecycle.t.sol +4 -3
- package/test/REVLoans.invariants.t.sol +5 -3
- package/test/REVLoansAttacks.t.sol +4 -3
- package/test/REVLoansAuditRegressions.t.sol +13 -24
- package/test/REVLoansFeeRecovery.t.sol +4 -3
- package/test/REVLoansSourced.t.sol +4 -3
- package/test/REVLoansUnSourced.t.sol +4 -3
- package/test/REVLoans_AuditFindings.t.sol +644 -0
- package/test/TestEmptyBuybackSpecs.t.sol +4 -3
- package/test/TestPR09_ConversionDocumentation.t.sol +4 -3
- package/test/TestPR10_LiquidationBehavior.t.sol +4 -3
- package/test/TestPR11_LowFindings.t.sol +4 -3
- package/test/TestPR12_FlashLoanSurplus.t.sol +4 -3
- package/test/TestPR13_CrossSourceReallocation.t.sol +4 -3
- package/test/TestPR15_CashOutCallerValidation.t.sol +4 -3
- package/test/TestPR16_ZeroRepayment.t.sol +4 -3
- package/test/TestPR21_Uint112Overflow.t.sol +4 -3
- package/test/TestPR22_HookArrayOOB.t.sol +4 -3
- package/test/TestPR26_BurnHeldTokens.t.sol +4 -3
- package/test/TestPR27_CEIPattern.t.sol +4 -3
- package/test/TestPR29_SwapTerminalPermission.t.sol +4 -3
- package/test/TestPR32_MixedFixes.t.sol +4 -3
- package/test/TestSplitWeightAdjustment.t.sol +445 -0
- package/test/TestSplitWeightE2E.t.sol +528 -0
- package/test/TestSplitWeightFork.t.sol +821 -0
- package/test/TestStageTransitionBorrowable.t.sol +4 -3
- package/test/fork/ForkTestBase.sol +617 -0
- package/test/fork/TestCashOutFork.t.sol +245 -0
- package/test/fork/TestLoanBorrowFork.t.sol +163 -0
- package/test/fork/TestLoanLiquidationFork.t.sol +129 -0
- package/test/fork/TestLoanReallocateFork.t.sol +103 -0
- package/test/fork/TestLoanRepayFork.t.sol +184 -0
- package/test/fork/TestSplitWeightFork.t.sol +186 -0
- package/test/mock/MockBuybackDataHook.sol +7 -4
- package/test/mock/MockBuybackDataHookMintPath.sol +7 -3
- package/test/regression/TestI20_CumulativeLoanCounter.t.sol +6 -5
- package/test/regression/TestL27_LiquidateGapHandling.t.sol +7 -6
- package/SECURITY.md +0 -68
package/src/REVDeployer.sol
CHANGED
|
@@ -9,10 +9,9 @@ import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Recei
|
|
|
9
9
|
import {mulDiv} from "@prb/math/src/Common.sol";
|
|
10
10
|
import {IJB721TiersHook} from "@bananapus/721-hook-v6/src/interfaces/IJB721TiersHook.sol";
|
|
11
11
|
import {IJB721TiersHookDeployer} from "@bananapus/721-hook-v6/src/interfaces/IJB721TiersHookDeployer.sol";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
|
|
12
|
+
import {JB721TiersHookFlags} from "@bananapus/721-hook-v6/src/structs/JB721TiersHookFlags.sol";
|
|
13
|
+
import {JBDeploy721TiersHookConfig} from "@bananapus/721-hook-v6/src/structs/JBDeploy721TiersHookConfig.sol";
|
|
14
|
+
import {IJBBuybackHookRegistry} from "@bananapus/buyback-hook-v6/src/interfaces/IJBBuybackHookRegistry.sol";
|
|
16
15
|
import {IJBCashOutHook} from "@bananapus/core-v6/src/interfaces/IJBCashOutHook.sol";
|
|
17
16
|
import {IJBController} from "@bananapus/core-v6/src/interfaces/IJBController.sol";
|
|
18
17
|
import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
|
|
@@ -40,6 +39,7 @@ import {JBRuleset} from "@bananapus/core-v6/src/structs/JBRuleset.sol";
|
|
|
40
39
|
import {JBRulesetConfig} from "@bananapus/core-v6/src/structs/JBRulesetConfig.sol";
|
|
41
40
|
import {JBRulesetMetadata} from "@bananapus/core-v6/src/structs/JBRulesetMetadata.sol";
|
|
42
41
|
import {JBSplit} from "@bananapus/core-v6/src/structs/JBSplit.sol";
|
|
42
|
+
import {JBTokenAmount} from "@bananapus/core-v6/src/structs/JBTokenAmount.sol";
|
|
43
43
|
import {JBSplitGroup} from "@bananapus/core-v6/src/structs/JBSplitGroup.sol";
|
|
44
44
|
import {JBTerminalConfig} from "@bananapus/core-v6/src/structs/JBTerminalConfig.sol";
|
|
45
45
|
import {JBPermissionIds} from "@bananapus/permission-ids-v6/src/JBPermissionIds.sol";
|
|
@@ -111,7 +111,7 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
111
111
|
//*********************************************************************//
|
|
112
112
|
|
|
113
113
|
/// @notice The buyback hook used as a data hook to route payments through buyback pools.
|
|
114
|
-
|
|
114
|
+
IJBBuybackHookRegistry public immutable override BUYBACK_HOOK;
|
|
115
115
|
|
|
116
116
|
/// @notice The controller used to create and manage Juicebox projects for revnets.
|
|
117
117
|
IJBController public immutable override CONTROLLER;
|
|
@@ -200,7 +200,7 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
200
200
|
uint256 feeRevnetId,
|
|
201
201
|
IJB721TiersHookDeployer hookDeployer,
|
|
202
202
|
CTPublisher publisher,
|
|
203
|
-
|
|
203
|
+
IJBBuybackHookRegistry buybackHook,
|
|
204
204
|
address loans,
|
|
205
205
|
address trustedForwarder
|
|
206
206
|
)
|
|
@@ -225,6 +225,9 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
225
225
|
|
|
226
226
|
// Give the loan contract permission to use the surplus allowance of all revnets.
|
|
227
227
|
_setPermission({operator: LOANS, revnetId: 0, permissionId: JBPermissionIds.USE_ALLOWANCE});
|
|
228
|
+
|
|
229
|
+
// Give the buyback hook (registry) permission to configure pools on all revnets.
|
|
230
|
+
_setPermission({operator: address(BUYBACK_HOOK), revnetId: 0, permissionId: JBPermissionIds.SET_BUYBACK_POOL});
|
|
228
231
|
}
|
|
229
232
|
|
|
230
233
|
//*********************************************************************//
|
|
@@ -316,34 +319,48 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
316
319
|
override
|
|
317
320
|
returns (uint256 weight, JBPayHookSpecification[] memory hookSpecifications)
|
|
318
321
|
{
|
|
319
|
-
//
|
|
320
|
-
JBPayHookSpecification[] memory buybackHookSpecifications;
|
|
321
|
-
|
|
322
|
-
// Read the weight and specifications from the buyback hook.
|
|
323
|
-
(weight, buybackHookSpecifications) = BUYBACK_HOOK.beforePayRecordedWith(context);
|
|
324
|
-
|
|
325
|
-
// Keep a reference to the revnet's tiered ERC-721 hook.
|
|
322
|
+
// Get the 721 hook's spec and total split amount.
|
|
326
323
|
IJB721TiersHook tiered721Hook = tiered721HookOf[context.projectId];
|
|
327
|
-
|
|
328
|
-
|
|
324
|
+
JBPayHookSpecification memory tiered721HookSpec;
|
|
325
|
+
uint256 totalSplitAmount;
|
|
329
326
|
bool usesTiered721Hook = address(tiered721Hook) != address(0);
|
|
327
|
+
if (usesTiered721Hook) {
|
|
328
|
+
JBPayHookSpecification[] memory specs;
|
|
329
|
+
(, specs) = IJBRulesetDataHook(address(tiered721Hook)).beforePayRecordedWith(context);
|
|
330
|
+
// The 721 hook returns a single spec (itself) whose amount is the total split amount.
|
|
331
|
+
if (specs.length > 0) {
|
|
332
|
+
tiered721HookSpec = specs[0];
|
|
333
|
+
totalSplitAmount = tiered721HookSpec.amount;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
330
336
|
|
|
331
|
-
//
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
// Initialize the returned specification array with only the hooks that are present.
|
|
335
|
-
hookSpecifications = new JBPayHookSpecification[]((usesTiered721Hook ? 1 : 0) + (usesBuybackHook ? 1 : 0));
|
|
337
|
+
// The amount entering the project after tier splits.
|
|
338
|
+
uint256 projectAmount = totalSplitAmount >= context.amount.value ? 0 : context.amount.value - totalSplitAmount;
|
|
336
339
|
|
|
337
|
-
//
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
340
|
+
// Get the buyback hook's weight and specs. Reduce the amount so it only considers funds entering the project.
|
|
341
|
+
JBPayHookSpecification[] memory buybackHookSpecs;
|
|
342
|
+
{
|
|
343
|
+
JBBeforePayRecordedContext memory buybackHookContext = context;
|
|
344
|
+
buybackHookContext.amount.value = projectAmount;
|
|
345
|
+
(weight, buybackHookSpecs) = BUYBACK_HOOK.beforePayRecordedWith(buybackHookContext);
|
|
341
346
|
}
|
|
342
347
|
|
|
343
|
-
//
|
|
344
|
-
|
|
345
|
-
|
|
348
|
+
// Scale the buyback hook's weight for splits so the terminal mints tokens only for the project's share.
|
|
349
|
+
// The terminal uses the full context.amount.value for minting (tokenCount = amount * weight / weightRatio),
|
|
350
|
+
// but only projectAmount actually enters the project. Without scaling, payers get token credit for the split
|
|
351
|
+
// portion too. Preserves weight=0 from the buyback hook (buying back, not minting).
|
|
352
|
+
if (projectAmount == 0) {
|
|
353
|
+
weight = 0;
|
|
354
|
+
} else if (projectAmount < context.amount.value) {
|
|
355
|
+
weight = mulDiv(weight, projectAmount, context.amount.value);
|
|
346
356
|
}
|
|
357
|
+
|
|
358
|
+
// Merge hook specifications: 721 hook spec first, then buyback hook spec.
|
|
359
|
+
bool usesBuybackHook = buybackHookSpecs.length > 0;
|
|
360
|
+
hookSpecifications = new JBPayHookSpecification[]((usesTiered721Hook ? 1 : 0) + (usesBuybackHook ? 1 : 0));
|
|
361
|
+
|
|
362
|
+
if (usesTiered721Hook) hookSpecifications[0] = tiered721HookSpec;
|
|
363
|
+
if (usesBuybackHook) hookSpecifications[usesTiered721Hook ? 1 : 0] = buybackHookSpecs[0];
|
|
347
364
|
}
|
|
348
365
|
|
|
349
366
|
/// @notice A flag indicating whether an address has permission to mint a revnet's tokens on-demand.
|
|
@@ -477,31 +494,16 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
477
494
|
/// @param revnetId The ID of the revnet.
|
|
478
495
|
/// @param terminalToken The terminal token to configure a buyback pool for.
|
|
479
496
|
function _trySetBuybackPoolFor(uint256 revnetId, address terminalToken) internal {
|
|
480
|
-
// Normalize the terminal token (use WETH for native) and get the project token.
|
|
481
|
-
address normalizedTerminalToken = terminalToken == JBConstants.NATIVE_TOKEN
|
|
482
|
-
? address(IJBBuybackHook(address(BUYBACK_HOOK)).WETH())
|
|
483
|
-
: terminalToken;
|
|
484
|
-
address projectToken = address(CONTROLLER.TOKENS().tokenOf(revnetId));
|
|
485
|
-
|
|
486
|
-
// Sort currencies numerically for the pool key (lower address = currency0).
|
|
487
|
-
(Currency currency0, Currency currency1) = normalizedTerminalToken < projectToken
|
|
488
|
-
? (Currency.wrap(normalizedTerminalToken), Currency.wrap(projectToken))
|
|
489
|
-
: (Currency.wrap(projectToken), Currency.wrap(normalizedTerminalToken));
|
|
490
|
-
|
|
491
497
|
// Try to set the pool — if the pool isn't initialized in the PoolManager yet, this will revert and be caught.
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
}),
|
|
502
|
-
twapWindow: DEFAULT_BUYBACK_TWAP_WINDOW,
|
|
503
|
-
terminalToken: terminalToken
|
|
504
|
-
}) {}
|
|
498
|
+
// The buyback hook constructs the PoolKey internally from the project token, terminal token, and pool params.
|
|
499
|
+
// slither-disable-next-line calls-loop
|
|
500
|
+
try BUYBACK_HOOK.setPoolFor({
|
|
501
|
+
projectId: revnetId,
|
|
502
|
+
fee: DEFAULT_BUYBACK_POOL_FEE,
|
|
503
|
+
tickSpacing: DEFAULT_BUYBACK_TICK_SPACING,
|
|
504
|
+
twapWindow: DEFAULT_BUYBACK_TWAP_WINDOW,
|
|
505
|
+
terminalToken: terminalToken
|
|
506
|
+
}) {}
|
|
505
507
|
catch {} // Pool may not be initialized yet — that's OK.
|
|
506
508
|
}
|
|
507
509
|
|
|
@@ -886,11 +888,32 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
886
888
|
revnetId: revnetId, configuration: configuration, terminalConfigurations: terminalConfigurations
|
|
887
889
|
});
|
|
888
890
|
|
|
891
|
+
// Convert the REVBaseline721HookConfig to JBDeploy721TiersHookConfig, forcing issueTokensForSplits to false.
|
|
892
|
+
// Revnets do their own weight adjustment for splits, so the 721 hook must not also adjust.
|
|
893
|
+
JBDeploy721TiersHookConfig memory hookConfig = JBDeploy721TiersHookConfig({
|
|
894
|
+
name: tiered721HookConfiguration.baseline721HookConfiguration.name,
|
|
895
|
+
symbol: tiered721HookConfiguration.baseline721HookConfiguration.symbol,
|
|
896
|
+
baseUri: tiered721HookConfiguration.baseline721HookConfiguration.baseUri,
|
|
897
|
+
tokenUriResolver: tiered721HookConfiguration.baseline721HookConfiguration.tokenUriResolver,
|
|
898
|
+
contractUri: tiered721HookConfiguration.baseline721HookConfiguration.contractUri,
|
|
899
|
+
tiersConfig: tiered721HookConfiguration.baseline721HookConfiguration.tiersConfig,
|
|
900
|
+
reserveBeneficiary: tiered721HookConfiguration.baseline721HookConfiguration.reserveBeneficiary,
|
|
901
|
+
flags: JB721TiersHookFlags({
|
|
902
|
+
noNewTiersWithReserves: tiered721HookConfiguration.baseline721HookConfiguration.flags
|
|
903
|
+
.noNewTiersWithReserves,
|
|
904
|
+
noNewTiersWithVotes: tiered721HookConfiguration.baseline721HookConfiguration.flags.noNewTiersWithVotes,
|
|
905
|
+
noNewTiersWithOwnerMinting: tiered721HookConfiguration.baseline721HookConfiguration.flags
|
|
906
|
+
.noNewTiersWithOwnerMinting,
|
|
907
|
+
preventOverspending: tiered721HookConfiguration.baseline721HookConfiguration.flags.preventOverspending,
|
|
908
|
+
issueTokensForSplits: false
|
|
909
|
+
})
|
|
910
|
+
});
|
|
911
|
+
|
|
889
912
|
// Deploy the tiered ERC-721 hook contract.
|
|
890
913
|
// slither-disable-next-line reentrancy-benign
|
|
891
914
|
hook = HOOK_DEPLOYER.deployHookFor({
|
|
892
915
|
projectId: revnetId,
|
|
893
|
-
deployTiersHookConfig:
|
|
916
|
+
deployTiersHookConfig: hookConfig,
|
|
894
917
|
salt: keccak256(abi.encode(tiered721HookConfiguration.salt, encodedConfigurationHash, _msgSender()))
|
|
895
918
|
});
|
|
896
919
|
|
package/src/REVLoans.sol
CHANGED
|
@@ -57,6 +57,7 @@ contract REVLoans is ERC721, ERC2771Context, Ownable, IREVLoans {
|
|
|
57
57
|
|
|
58
58
|
error REVLoans_CollateralExceedsLoan(uint256 collateralToReturn, uint256 loanCollateral);
|
|
59
59
|
error REVLoans_InvalidPrepaidFeePercent(uint256 prepaidFeePercent, uint256 min, uint256 max);
|
|
60
|
+
error REVLoans_InvalidTerminal(address terminal, uint256 revnetId);
|
|
60
61
|
error REVLoans_LoanExpired(uint256 timeSinceLoanCreated, uint256 loanLiquidationDuration);
|
|
61
62
|
error REVLoans_NewBorrowAmountGreaterThanLoanAmount(uint256 newBorrowAmount, uint256 loanAmount);
|
|
62
63
|
error REVLoans_NoMsgValueAllowed();
|
|
@@ -556,6 +557,11 @@ contract REVLoans is ERC721, ERC2771Context, Ownable, IREVLoans {
|
|
|
556
557
|
// A loan needs to have collateral.
|
|
557
558
|
if (collateralCount == 0) revert REVLoans_ZeroCollateralLoanIsInvalid();
|
|
558
559
|
|
|
560
|
+
// Make sure the source terminal is registered in the directory for this revnet.
|
|
561
|
+
if (!DIRECTORY.isTerminalOf(revnetId, IJBTerminal(address(source.terminal)))) {
|
|
562
|
+
revert REVLoans_InvalidTerminal(address(source.terminal), revnetId);
|
|
563
|
+
}
|
|
564
|
+
|
|
559
565
|
// Make sure the prepaid fee percent is between `MIN_PREPAID_FEE_PERCENT` and `MAX_PREPAID_FEE_PERCENT`. Meaning
|
|
560
566
|
// an 16 year loan can be paid upfront with a
|
|
561
567
|
// payment of 50% of the borrowed assets, the cheapest possible rate.
|
|
@@ -1218,6 +1224,9 @@ contract REVLoans is ERC721, ERC2771Context, Ownable, IREVLoans {
|
|
|
1218
1224
|
// If the loan will carry no more amount or collateral, store its changes directly.
|
|
1219
1225
|
// slither-disable-next-line incorrect-equality
|
|
1220
1226
|
if (collateralCountToReturn == loan.collateral) {
|
|
1227
|
+
// Snapshot the loan to memory BEFORE _adjust zeroes the storage pointer.
|
|
1228
|
+
REVLoan memory loanSnapshot = loan;
|
|
1229
|
+
|
|
1221
1230
|
// Borrow in.
|
|
1222
1231
|
_adjust({
|
|
1223
1232
|
loan: loan,
|
|
@@ -1228,15 +1237,15 @@ contract REVLoans is ERC721, ERC2771Context, Ownable, IREVLoans {
|
|
|
1228
1237
|
beneficiary: beneficiary
|
|
1229
1238
|
});
|
|
1230
1239
|
|
|
1231
|
-
// Snapshot the loan
|
|
1232
|
-
REVLoan memory
|
|
1240
|
+
// Snapshot the zeroed loan for the return value (reflects post-repay state).
|
|
1241
|
+
REVLoan memory paidOffSnapshot = loan;
|
|
1233
1242
|
|
|
1234
1243
|
emit RepayLoan({
|
|
1235
1244
|
loanId: loanId,
|
|
1236
1245
|
revnetId: revnetId,
|
|
1237
1246
|
paidOffLoanId: loanId,
|
|
1238
1247
|
loan: loanSnapshot,
|
|
1239
|
-
paidOffLoan:
|
|
1248
|
+
paidOffLoan: paidOffSnapshot,
|
|
1240
1249
|
repayBorrowAmount: repayBorrowAmount,
|
|
1241
1250
|
sourceFeeAmount: sourceFeeAmount,
|
|
1242
1251
|
collateralCountToReturn: collateralCountToReturn,
|
|
@@ -1247,7 +1256,7 @@ contract REVLoans is ERC721, ERC2771Context, Ownable, IREVLoans {
|
|
|
1247
1256
|
// Clear stale loan data for gas refund.
|
|
1248
1257
|
delete _loanOf[loanId];
|
|
1249
1258
|
|
|
1250
|
-
return (loanId,
|
|
1259
|
+
return (loanId, paidOffSnapshot);
|
|
1251
1260
|
} else {
|
|
1252
1261
|
// Make a new loan with the remaining amount and collateral.
|
|
1253
1262
|
// Get a reference to the replacement loan ID.
|
|
@@ -7,6 +7,7 @@ import {IJBController} from "@bananapus/core-v6/src/interfaces/IJBController.sol
|
|
|
7
7
|
import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
|
|
8
8
|
import {IJBPermissions} from "@bananapus/core-v6/src/interfaces/IJBPermissions.sol";
|
|
9
9
|
import {IJBProjects} from "@bananapus/core-v6/src/interfaces/IJBProjects.sol";
|
|
10
|
+
import {IJBBuybackHookRegistry} from "@bananapus/buyback-hook-v6/src/interfaces/IJBBuybackHookRegistry.sol";
|
|
10
11
|
import {IJBRulesetDataHook} from "@bananapus/core-v6/src/interfaces/IJBRulesetDataHook.sol";
|
|
11
12
|
import {JBRulesetConfig} from "@bananapus/core-v6/src/structs/JBRulesetConfig.sol";
|
|
12
13
|
import {JBTerminalConfig} from "@bananapus/core-v6/src/structs/JBTerminalConfig.sol";
|
|
@@ -96,7 +97,7 @@ interface IREVDeployer {
|
|
|
96
97
|
|
|
97
98
|
/// @notice The buyback hook used as a data hook to route payments through buyback pools.
|
|
98
99
|
/// @return The buyback hook contract.
|
|
99
|
-
function BUYBACK_HOOK() external view returns (
|
|
100
|
+
function BUYBACK_HOOK() external view returns (IJBBuybackHookRegistry);
|
|
100
101
|
|
|
101
102
|
/// @notice The number of seconds until a revnet's participants can cash out after deploying to a new network.
|
|
102
103
|
/// @return The cash out delay in seconds.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.0;
|
|
3
|
+
|
|
4
|
+
/// @custom:member noNewTiersWithReserves A flag indicating if new tiers with non-zero reserve frequency are forbidden.
|
|
5
|
+
/// @custom:member noNewTiersWithVotes A flag indicating if new tiers with voting units are forbidden.
|
|
6
|
+
/// @custom:member noNewTiersWithOwnerMinting A flag indicating if new tiers with owner minting are forbidden.
|
|
7
|
+
/// @custom:member preventOverspending A flag indicating if payments exceeding the price of minted NFTs should be
|
|
8
|
+
/// prevented.
|
|
9
|
+
struct REV721TiersHookFlags {
|
|
10
|
+
bool noNewTiersWithReserves;
|
|
11
|
+
bool noNewTiersWithVotes;
|
|
12
|
+
bool noNewTiersWithOwnerMinting;
|
|
13
|
+
bool preventOverspending;
|
|
14
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.0;
|
|
3
|
+
|
|
4
|
+
import {IJB721TokenUriResolver} from "@bananapus/721-hook-v6/src/interfaces/IJB721TokenUriResolver.sol";
|
|
5
|
+
import {JB721InitTiersConfig} from "@bananapus/721-hook-v6/src/structs/JB721InitTiersConfig.sol";
|
|
6
|
+
|
|
7
|
+
import {REV721TiersHookFlags} from "./REV721TiersHookFlags.sol";
|
|
8
|
+
|
|
9
|
+
/// @custom:member name The name of the NFT collection.
|
|
10
|
+
/// @custom:member symbol The symbol of the NFT collection.
|
|
11
|
+
/// @custom:member baseUri The base URI for the NFT collection.
|
|
12
|
+
/// @custom:member tokenUriResolver The token URI resolver for the NFT collection.
|
|
13
|
+
/// @custom:member contractUri The contract URI for the NFT collection.
|
|
14
|
+
/// @custom:member tiersConfig The tier configuration for the NFT collection.
|
|
15
|
+
/// @custom:member reserveBeneficiary The default reserve beneficiary for the NFT collection.
|
|
16
|
+
/// @custom:member flags A set of flags that configure the 721 hook. Omits `issueTokensForSplits` since revnets
|
|
17
|
+
/// always force it to `false`.
|
|
18
|
+
struct REVBaseline721HookConfig {
|
|
19
|
+
string name;
|
|
20
|
+
string symbol;
|
|
21
|
+
string baseUri;
|
|
22
|
+
IJB721TokenUriResolver tokenUriResolver;
|
|
23
|
+
string contractUri;
|
|
24
|
+
JB721InitTiersConfig tiersConfig;
|
|
25
|
+
address reserveBeneficiary;
|
|
26
|
+
REV721TiersHookFlags flags;
|
|
27
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
pragma solidity ^0.8.0;
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {REVBaseline721HookConfig} from "./REVBaseline721HookConfig.sol";
|
|
5
5
|
|
|
6
6
|
/// @custom:member baseline721HookConfiguration The baseline config.
|
|
7
7
|
/// @custom:member salt The salt to base the collection's address on.
|
|
@@ -16,7 +16,7 @@ import {JBDeploy721TiersHookConfig} from "@bananapus/721-hook-v6/src/structs/JBD
|
|
|
16
16
|
/// the
|
|
17
17
|
/// discount of a tier.
|
|
18
18
|
struct REVDeploy721TiersHookConfig {
|
|
19
|
-
|
|
19
|
+
REVBaseline721HookConfig baseline721HookConfiguration;
|
|
20
20
|
bytes32 salt;
|
|
21
21
|
bool splitOperatorCanAdjustTiers;
|
|
22
22
|
bool splitOperatorCanUpdateMetadata;
|
|
@@ -38,7 +38,7 @@ struct FeeProjectConfig {
|
|
|
38
38
|
REVSuckerDeploymentConfig suckerDeploymentConfiguration;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
contract REVnet_Integrations is TestBaseWorkflow
|
|
41
|
+
contract REVnet_Integrations is TestBaseWorkflow {
|
|
42
42
|
/// @notice the salts that are used to deploy the contracts.
|
|
43
43
|
bytes32 REV_DEPLOYER_SALT = "REVDeployer";
|
|
44
44
|
bytes32 ERC20_SALT = "REV_TOKEN";
|
|
@@ -177,7 +177,8 @@ contract REVnet_Integrations is TestBaseWorkflow, JBTest {
|
|
|
177
177
|
|
|
178
178
|
HOOK_STORE = new JB721TiersHookStore();
|
|
179
179
|
|
|
180
|
-
EXAMPLE_HOOK =
|
|
180
|
+
EXAMPLE_HOOK =
|
|
181
|
+
new JB721TiersHook(jbDirectory(), jbPermissions(), jbRulesets(), HOOK_STORE, jbSplits(), multisig());
|
|
181
182
|
|
|
182
183
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
183
184
|
|
|
@@ -192,7 +193,7 @@ contract REVnet_Integrations is TestBaseWorkflow, JBTest {
|
|
|
192
193
|
FEE_PROJECT_ID,
|
|
193
194
|
HOOK_DEPLOYER,
|
|
194
195
|
PUBLISHER,
|
|
195
|
-
|
|
196
|
+
IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
|
|
196
197
|
makeAddr("loans"),
|
|
197
198
|
TRUSTED_FORWARDER
|
|
198
199
|
);
|
|
@@ -30,7 +30,7 @@ import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/
|
|
|
30
30
|
/// @notice Fuzz tests for REVDeployer multi-stage auto-issuance.
|
|
31
31
|
/// Tests stage ID computation consistency and multi-stage claiming behavior.
|
|
32
32
|
/// Stage IDs use block.timestamp + i which may mismatch actual ruleset IDs.
|
|
33
|
-
contract REVAutoIssuanceFuzz_Local is TestBaseWorkflow
|
|
33
|
+
contract REVAutoIssuanceFuzz_Local is TestBaseWorkflow {
|
|
34
34
|
bytes32 REV_DEPLOYER_SALT = "REVDeployer";
|
|
35
35
|
|
|
36
36
|
REVDeployer REV_DEPLOYER;
|
|
@@ -55,7 +55,8 @@ contract REVAutoIssuanceFuzz_Local is TestBaseWorkflow, JBTest {
|
|
|
55
55
|
|
|
56
56
|
SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
|
|
57
57
|
HOOK_STORE = new JB721TiersHookStore();
|
|
58
|
-
EXAMPLE_HOOK =
|
|
58
|
+
EXAMPLE_HOOK =
|
|
59
|
+
new JB721TiersHook(jbDirectory(), jbPermissions(), jbRulesets(), HOOK_STORE, jbSplits(), multisig());
|
|
59
60
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
60
61
|
HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
|
|
61
62
|
PUBLISHER = new CTPublisher(jbDirectory(), jbPermissions(), FEE_PROJECT_ID, multisig());
|
|
@@ -67,7 +68,7 @@ contract REVAutoIssuanceFuzz_Local is TestBaseWorkflow, JBTest {
|
|
|
67
68
|
FEE_PROJECT_ID,
|
|
68
69
|
HOOK_DEPLOYER,
|
|
69
70
|
PUBLISHER,
|
|
70
|
-
|
|
71
|
+
IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
|
|
71
72
|
makeAddr("loans"),
|
|
72
73
|
TRUSTED_FORWARDER
|
|
73
74
|
);
|
|
@@ -165,9 +166,12 @@ contract REVAutoIssuanceFuzz_Local is TestBaseWorkflow, JBTest {
|
|
|
165
166
|
|
|
166
167
|
/// @notice Deploy 3-stage revnet, advance time, claim auto-issuance from each stage.
|
|
167
168
|
function test_multiStage_allStagesClaimable() external {
|
|
169
|
+
// Save the deploy timestamp for absolute warp targets.
|
|
170
|
+
uint256 deployTs = block.timestamp;
|
|
171
|
+
|
|
168
172
|
(uint256 revnetId, uint256[] memory stageIds) = _deployMultiStageRevnet(3);
|
|
169
173
|
|
|
170
|
-
// Stage 0 starts at
|
|
174
|
+
// Stage 0 starts at deploy time — immediately claimable.
|
|
171
175
|
REV_DEPLOYER.autoIssueFor(revnetId, stageIds[0], multisig());
|
|
172
176
|
|
|
173
177
|
uint256 stage0Amount = (10_000) * decimalMultiplier;
|
|
@@ -175,8 +179,8 @@ contract REVAutoIssuanceFuzz_Local is TestBaseWorkflow, JBTest {
|
|
|
175
179
|
IJBToken(jbTokens().tokenOf(revnetId)).balanceOf(multisig()), stage0Amount, "Stage 0 auto-issuance claimed"
|
|
176
180
|
);
|
|
177
181
|
|
|
178
|
-
// Stage 1 starts at
|
|
179
|
-
vm.warp(
|
|
182
|
+
// Stage 1 starts at deployTs + 180 days.
|
|
183
|
+
vm.warp(deployTs + 180 days);
|
|
180
184
|
REV_DEPLOYER.autoIssueFor(revnetId, stageIds[1], multisig());
|
|
181
185
|
|
|
182
186
|
uint256 stage1Amount = (11_000) * decimalMultiplier;
|
|
@@ -186,8 +190,8 @@ contract REVAutoIssuanceFuzz_Local is TestBaseWorkflow, JBTest {
|
|
|
186
190
|
"Stage 1 auto-issuance claimed"
|
|
187
191
|
);
|
|
188
192
|
|
|
189
|
-
// Stage 2 starts at
|
|
190
|
-
vm.warp(
|
|
193
|
+
// Stage 2 starts at deployTs + 360 days.
|
|
194
|
+
vm.warp(deployTs + 360 days);
|
|
191
195
|
REV_DEPLOYER.autoIssueFor(revnetId, stageIds[2], multisig());
|
|
192
196
|
|
|
193
197
|
uint256 stage2Amount = (12_000) * decimalMultiplier;
|
|
@@ -29,7 +29,7 @@ import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressReg
|
|
|
29
29
|
import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
|
|
30
30
|
|
|
31
31
|
/// @notice Regression tests for REVDeployer.
|
|
32
|
-
contract REVDeployerRegressions_Local is TestBaseWorkflow
|
|
32
|
+
contract REVDeployerRegressions_Local is TestBaseWorkflow {
|
|
33
33
|
using JBRulesetMetadataResolver for JBRuleset;
|
|
34
34
|
|
|
35
35
|
bytes32 REV_DEPLOYER_SALT = "REVDeployer";
|
|
@@ -56,7 +56,8 @@ contract REVDeployerRegressions_Local is TestBaseWorkflow, JBTest {
|
|
|
56
56
|
|
|
57
57
|
SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
|
|
58
58
|
HOOK_STORE = new JB721TiersHookStore();
|
|
59
|
-
EXAMPLE_HOOK =
|
|
59
|
+
EXAMPLE_HOOK =
|
|
60
|
+
new JB721TiersHook(jbDirectory(), jbPermissions(), jbRulesets(), HOOK_STORE, jbSplits(), multisig());
|
|
60
61
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
61
62
|
HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
|
|
62
63
|
PUBLISHER = new CTPublisher(jbDirectory(), jbPermissions(), FEE_PROJECT_ID, multisig());
|
|
@@ -77,7 +78,7 @@ contract REVDeployerRegressions_Local is TestBaseWorkflow, JBTest {
|
|
|
77
78
|
FEE_PROJECT_ID,
|
|
78
79
|
HOOK_DEPLOYER,
|
|
79
80
|
PUBLISHER,
|
|
80
|
-
|
|
81
|
+
IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
|
|
81
82
|
address(LOANS_CONTRACT),
|
|
82
83
|
TRUSTED_FORWARDER
|
|
83
84
|
);
|
|
@@ -53,7 +53,7 @@ struct InvincibilityProjectConfig {
|
|
|
53
53
|
// =========================================================================
|
|
54
54
|
// Section A + B: Property Verification & Economic Tests
|
|
55
55
|
// =========================================================================
|
|
56
|
-
contract REVInvincibility_PropertyTests is TestBaseWorkflow
|
|
56
|
+
contract REVInvincibility_PropertyTests is TestBaseWorkflow {
|
|
57
57
|
using JBRulesetMetadataResolver for JBRuleset;
|
|
58
58
|
|
|
59
59
|
bytes32 REV_DEPLOYER_SALT = "REVDeployer";
|
|
@@ -202,7 +202,8 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow, JBTest {
|
|
|
202
202
|
|
|
203
203
|
SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
|
|
204
204
|
HOOK_STORE = new JB721TiersHookStore();
|
|
205
|
-
EXAMPLE_HOOK =
|
|
205
|
+
EXAMPLE_HOOK =
|
|
206
|
+
new JB721TiersHook(jbDirectory(), jbPermissions(), jbRulesets(), HOOK_STORE, jbSplits(), multisig());
|
|
206
207
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
207
208
|
HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
|
|
208
209
|
PUBLISHER = new CTPublisher(jbDirectory(), jbPermissions(), FEE_PROJECT_ID, multisig());
|
|
@@ -224,7 +225,7 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow, JBTest {
|
|
|
224
225
|
FEE_PROJECT_ID,
|
|
225
226
|
HOOK_DEPLOYER,
|
|
226
227
|
PUBLISHER,
|
|
227
|
-
|
|
228
|
+
IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
|
|
228
229
|
address(LOANS_CONTRACT),
|
|
229
230
|
TRUSTED_FORWARDER
|
|
230
231
|
);
|
|
@@ -922,7 +923,7 @@ contract REVInvincibility_PropertyTests is TestBaseWorkflow, JBTest {
|
|
|
922
923
|
// =========================================================================
|
|
923
924
|
// Section C: Invariant Properties (6 invariants)
|
|
924
925
|
// =========================================================================
|
|
925
|
-
contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow
|
|
926
|
+
contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow {
|
|
926
927
|
using JBRulesetMetadataResolver for JBRuleset;
|
|
927
928
|
|
|
928
929
|
bytes32 REV_DEPLOYER_SALT = "REVDeployer_INV";
|
|
@@ -956,7 +957,8 @@ contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow, JBTest {
|
|
|
956
957
|
|
|
957
958
|
SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
|
|
958
959
|
HOOK_STORE = new JB721TiersHookStore();
|
|
959
|
-
EXAMPLE_HOOK =
|
|
960
|
+
EXAMPLE_HOOK =
|
|
961
|
+
new JB721TiersHook(jbDirectory(), jbPermissions(), jbRulesets(), HOOK_STORE, jbSplits(), multisig());
|
|
960
962
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
961
963
|
HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
|
|
962
964
|
PUBLISHER = new CTPublisher(jbDirectory(), jbPermissions(), FEE_PROJECT_ID, multisig());
|
|
@@ -977,7 +979,7 @@ contract REVInvincibility_Invariants is StdInvariant, TestBaseWorkflow, JBTest {
|
|
|
977
979
|
FEE_PROJECT_ID,
|
|
978
980
|
HOOK_DEPLOYER,
|
|
979
981
|
PUBLISHER,
|
|
980
|
-
|
|
982
|
+
IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
|
|
981
983
|
address(LOANS_CONTRACT),
|
|
982
984
|
TRUSTED_FORWARDER
|
|
983
985
|
);
|
|
@@ -11,6 +11,7 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
|
11
11
|
import {IREVLoans} from "../src/interfaces/IREVLoans.sol";
|
|
12
12
|
import {REVLoan} from "../src/structs/REVLoan.sol";
|
|
13
13
|
import {REVLoanSource} from "../src/structs/REVLoanSource.sol";
|
|
14
|
+
import {JBTest} from "@bananapus/core-v6/test/helpers/JBTest.sol";
|
|
14
15
|
|
|
15
16
|
/// @title REVInvincibilityHandler
|
|
16
17
|
/// @notice Stateful fuzzing handler for the revnet + loans interaction surface.
|
package/test/REVLifecycle.t.sol
CHANGED
|
@@ -30,7 +30,7 @@ import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressReg
|
|
|
30
30
|
import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
|
|
31
31
|
|
|
32
32
|
/// @notice Full revnet lifecycle E2E: deploy 3-stage -> pay -> advance stages -> cash out.
|
|
33
|
-
contract REVLifecycle_Local is TestBaseWorkflow
|
|
33
|
+
contract REVLifecycle_Local is TestBaseWorkflow {
|
|
34
34
|
bytes32 REV_DEPLOYER_SALT = "REVDeployer";
|
|
35
35
|
bytes32 ERC20_SALT = "REV_TOKEN";
|
|
36
36
|
|
|
@@ -61,7 +61,8 @@ contract REVLifecycle_Local is TestBaseWorkflow, JBTest {
|
|
|
61
61
|
|
|
62
62
|
SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
|
|
63
63
|
HOOK_STORE = new JB721TiersHookStore();
|
|
64
|
-
EXAMPLE_HOOK =
|
|
64
|
+
EXAMPLE_HOOK =
|
|
65
|
+
new JB721TiersHook(jbDirectory(), jbPermissions(), jbRulesets(), HOOK_STORE, jbSplits(), multisig());
|
|
65
66
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
66
67
|
HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
|
|
67
68
|
PUBLISHER = new CTPublisher(jbDirectory(), jbPermissions(), FEE_PROJECT_ID, multisig());
|
|
@@ -82,7 +83,7 @@ contract REVLifecycle_Local is TestBaseWorkflow, JBTest {
|
|
|
82
83
|
FEE_PROJECT_ID,
|
|
83
84
|
HOOK_DEPLOYER,
|
|
84
85
|
PUBLISHER,
|
|
85
|
-
|
|
86
|
+
IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
|
|
86
87
|
address(LOANS_CONTRACT),
|
|
87
88
|
TRUSTED_FORWARDER
|
|
88
89
|
);
|
|
@@ -31,6 +31,7 @@ import {JB721TiersHook} from "@bananapus/721-hook-v6/src/JB721TiersHook.sol";
|
|
|
31
31
|
import {JB721TiersHookStore} from "@bananapus/721-hook-v6/src/JB721TiersHookStore.sol";
|
|
32
32
|
import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressRegistry.sol";
|
|
33
33
|
import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
|
|
34
|
+
import {JBTest} from "@bananapus/core-v6/test/helpers/JBTest.sol";
|
|
34
35
|
|
|
35
36
|
struct FeeProjectConfig {
|
|
36
37
|
REVConfig configuration;
|
|
@@ -252,7 +253,7 @@ contract REVLoansCallHandler is JBTest {
|
|
|
252
253
|
}
|
|
253
254
|
}
|
|
254
255
|
|
|
255
|
-
contract InvariantREVLoansTests is StdInvariant, TestBaseWorkflow
|
|
256
|
+
contract InvariantREVLoansTests is StdInvariant, TestBaseWorkflow {
|
|
256
257
|
// A library that parses the packed ruleset metadata into a friendlier format.
|
|
257
258
|
using JBRulesetMetadataResolver for JBRuleset;
|
|
258
259
|
|
|
@@ -475,7 +476,8 @@ contract InvariantREVLoansTests is StdInvariant, TestBaseWorkflow, JBTest {
|
|
|
475
476
|
|
|
476
477
|
HOOK_STORE = new JB721TiersHookStore();
|
|
477
478
|
|
|
478
|
-
EXAMPLE_HOOK =
|
|
479
|
+
EXAMPLE_HOOK =
|
|
480
|
+
new JB721TiersHook(jbDirectory(), jbPermissions(), jbRulesets(), HOOK_STORE, jbSplits(), multisig());
|
|
479
481
|
|
|
480
482
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
481
483
|
|
|
@@ -499,7 +501,7 @@ contract InvariantREVLoansTests is StdInvariant, TestBaseWorkflow, JBTest {
|
|
|
499
501
|
FEE_PROJECT_ID,
|
|
500
502
|
HOOK_DEPLOYER,
|
|
501
503
|
PUBLISHER,
|
|
502
|
-
|
|
504
|
+
IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
|
|
503
505
|
address(LOANS_CONTRACT),
|
|
504
506
|
TRUSTED_FORWARDER
|
|
505
507
|
);
|
|
@@ -176,7 +176,7 @@ struct AttackProjectConfig {
|
|
|
176
176
|
/// @title REVLoansAttacks
|
|
177
177
|
/// @notice Attack tests for REVLoans covering uint112 truncation, reentrancy,
|
|
178
178
|
/// collateral race conditions, liquidation edge cases, and fuzz testing.
|
|
179
|
-
contract REVLoansAttacks is TestBaseWorkflow
|
|
179
|
+
contract REVLoansAttacks is TestBaseWorkflow {
|
|
180
180
|
bytes32 REV_DEPLOYER_SALT = "REVDeployer";
|
|
181
181
|
bytes32 ERC20_SALT = "REV_TOKEN";
|
|
182
182
|
|
|
@@ -318,7 +318,8 @@ contract REVLoansAttacks is TestBaseWorkflow, JBTest {
|
|
|
318
318
|
|
|
319
319
|
SUCKER_REGISTRY = new JBSuckerRegistry(jbDirectory(), jbPermissions(), multisig(), address(0));
|
|
320
320
|
HOOK_STORE = new JB721TiersHookStore();
|
|
321
|
-
EXAMPLE_HOOK =
|
|
321
|
+
EXAMPLE_HOOK =
|
|
322
|
+
new JB721TiersHook(jbDirectory(), jbPermissions(), jbRulesets(), HOOK_STORE, jbSplits(), multisig());
|
|
322
323
|
ADDRESS_REGISTRY = new JBAddressRegistry();
|
|
323
324
|
HOOK_DEPLOYER = new JB721TiersHookDeployer(EXAMPLE_HOOK, HOOK_STORE, ADDRESS_REGISTRY, multisig());
|
|
324
325
|
PUBLISHER = new CTPublisher(jbDirectory(), jbPermissions(), FEE_PROJECT_ID, multisig());
|
|
@@ -345,7 +346,7 @@ contract REVLoansAttacks is TestBaseWorkflow, JBTest {
|
|
|
345
346
|
FEE_PROJECT_ID,
|
|
346
347
|
HOOK_DEPLOYER,
|
|
347
348
|
PUBLISHER,
|
|
348
|
-
|
|
349
|
+
IJBBuybackHookRegistry(address(MOCK_BUYBACK)),
|
|
349
350
|
address(LOANS_CONTRACT),
|
|
350
351
|
TRUSTED_FORWARDER
|
|
351
352
|
);
|