@rev-net/core-v6 0.0.7 → 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 +13 -10
- package/script/Deploy.s.sol +3 -2
- package/src/REVDeployer.sol +129 -72
- package/src/REVLoans.sol +174 -165
- package/src/interfaces/IREVDeployer.sol +111 -72
- package/src/interfaces/IREVLoans.sol +116 -76
- 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 +11 -4
- package/test/mock/MockBuybackDataHookMintPath.sol +11 -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
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
pragma solidity 0.8.26;
|
|
3
3
|
|
|
4
|
+
import {ERC2771Context} from "@openzeppelin/contracts/metatx/ERC2771Context.sol";
|
|
4
5
|
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
6
|
+
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
5
7
|
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
|
|
6
8
|
import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
|
|
7
|
-
import {ERC2771Context} from "@openzeppelin/contracts/metatx/ERC2771Context.sol";
|
|
8
|
-
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
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 {
|
|
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";
|
|
13
15
|
import {IJBCashOutHook} from "@bananapus/core-v6/src/interfaces/IJBCashOutHook.sol";
|
|
14
16
|
import {IJBController} from "@bananapus/core-v6/src/interfaces/IJBController.sol";
|
|
15
17
|
import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
|
|
@@ -26,19 +28,20 @@ import {JBConstants} from "@bananapus/core-v6/src/libraries/JBConstants.sol";
|
|
|
26
28
|
import {JBSplitGroupIds} from "@bananapus/core-v6/src/libraries/JBSplitGroupIds.sol";
|
|
27
29
|
import {JBAccountingContext} from "@bananapus/core-v6/src/structs/JBAccountingContext.sol";
|
|
28
30
|
import {JBAfterCashOutRecordedContext} from "@bananapus/core-v6/src/structs/JBAfterCashOutRecordedContext.sol";
|
|
29
|
-
import {JBBeforePayRecordedContext} from "@bananapus/core-v6/src/structs/JBBeforePayRecordedContext.sol";
|
|
30
31
|
import {JBBeforeCashOutRecordedContext} from "@bananapus/core-v6/src/structs/JBBeforeCashOutRecordedContext.sol";
|
|
32
|
+
import {JBBeforePayRecordedContext} from "@bananapus/core-v6/src/structs/JBBeforePayRecordedContext.sol";
|
|
33
|
+
import {JBCashOutHookSpecification} from "@bananapus/core-v6/src/structs/JBCashOutHookSpecification.sol";
|
|
31
34
|
import {JBCurrencyAmount} from "@bananapus/core-v6/src/structs/JBCurrencyAmount.sol";
|
|
32
35
|
import {JBFundAccessLimitGroup} from "@bananapus/core-v6/src/structs/JBFundAccessLimitGroup.sol";
|
|
33
|
-
import {JBPermissionsData} from "@bananapus/core-v6/src/structs/JBPermissionsData.sol";
|
|
34
36
|
import {JBPayHookSpecification} from "@bananapus/core-v6/src/structs/JBPayHookSpecification.sol";
|
|
37
|
+
import {JBPermissionsData} from "@bananapus/core-v6/src/structs/JBPermissionsData.sol";
|
|
35
38
|
import {JBRuleset} from "@bananapus/core-v6/src/structs/JBRuleset.sol";
|
|
36
39
|
import {JBRulesetConfig} from "@bananapus/core-v6/src/structs/JBRulesetConfig.sol";
|
|
37
40
|
import {JBRulesetMetadata} from "@bananapus/core-v6/src/structs/JBRulesetMetadata.sol";
|
|
38
41
|
import {JBSplit} from "@bananapus/core-v6/src/structs/JBSplit.sol";
|
|
42
|
+
import {JBTokenAmount} from "@bananapus/core-v6/src/structs/JBTokenAmount.sol";
|
|
39
43
|
import {JBSplitGroup} from "@bananapus/core-v6/src/structs/JBSplitGroup.sol";
|
|
40
44
|
import {JBTerminalConfig} from "@bananapus/core-v6/src/structs/JBTerminalConfig.sol";
|
|
41
|
-
import {JBCashOutHookSpecification} from "@bananapus/core-v6/src/structs/JBCashOutHookSpecification.sol";
|
|
42
45
|
import {JBPermissionIds} from "@bananapus/permission-ids-v6/src/JBPermissionIds.sol";
|
|
43
46
|
import {IJBSuckerRegistry} from "@bananapus/suckers-v6/src/interfaces/IJBSuckerRegistry.sol";
|
|
44
47
|
import {CTPublisher} from "@croptop/core-v6/src/CTPublisher.sol";
|
|
@@ -67,11 +70,11 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
67
70
|
error REVDeployer_CashOutsCantBeTurnedOffCompletely(uint256 cashOutTaxRate, uint256 maxCashOutTaxRate);
|
|
68
71
|
error REVDeployer_MustHaveSplits();
|
|
69
72
|
error REVDeployer_NothingToAutoIssue();
|
|
73
|
+
error REVDeployer_NothingToBurn();
|
|
70
74
|
error REVDeployer_RulesetDoesNotAllowDeployingSuckers();
|
|
71
75
|
error REVDeployer_StageNotStarted(uint256 stageId);
|
|
72
76
|
error REVDeployer_StagesRequired();
|
|
73
77
|
error REVDeployer_StageTimesMustIncrease();
|
|
74
|
-
error REVDeployer_NothingToBurn();
|
|
75
78
|
error REVDeployer_Unauthorized(uint256 revnetId, address caller);
|
|
76
79
|
|
|
77
80
|
//*********************************************************************//
|
|
@@ -95,6 +98,10 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
95
98
|
/// @dev 10_000 = 1%. This is the standard fee tier for most project token pairs.
|
|
96
99
|
uint24 public constant DEFAULT_BUYBACK_POOL_FEE = 10_000;
|
|
97
100
|
|
|
101
|
+
/// @notice The default tick spacing used when auto-configuring buyback pools.
|
|
102
|
+
/// @dev 60 is the standard tick spacing for the 1% fee tier.
|
|
103
|
+
int24 public constant DEFAULT_BUYBACK_TICK_SPACING = 60;
|
|
104
|
+
|
|
98
105
|
/// @notice The default TWAP window used when auto-configuring buyback pools.
|
|
99
106
|
/// @dev 2 days provides robust manipulation resistance.
|
|
100
107
|
uint32 public constant DEFAULT_BUYBACK_TWAP_WINDOW = 2 days;
|
|
@@ -104,7 +111,7 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
104
111
|
//*********************************************************************//
|
|
105
112
|
|
|
106
113
|
/// @notice The buyback hook used as a data hook to route payments through buyback pools.
|
|
107
|
-
|
|
114
|
+
IJBBuybackHookRegistry public immutable override BUYBACK_HOOK;
|
|
108
115
|
|
|
109
116
|
/// @notice The controller used to create and manage Juicebox projects for revnets.
|
|
110
117
|
IJBController public immutable override CONTROLLER;
|
|
@@ -193,7 +200,7 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
193
200
|
uint256 feeRevnetId,
|
|
194
201
|
IJB721TiersHookDeployer hookDeployer,
|
|
195
202
|
CTPublisher publisher,
|
|
196
|
-
|
|
203
|
+
IJBBuybackHookRegistry buybackHook,
|
|
197
204
|
address loans,
|
|
198
205
|
address trustedForwarder
|
|
199
206
|
)
|
|
@@ -218,55 +225,15 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
218
225
|
|
|
219
226
|
// Give the loan contract permission to use the surplus allowance of all revnets.
|
|
220
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});
|
|
221
231
|
}
|
|
222
232
|
|
|
223
233
|
//*********************************************************************//
|
|
224
234
|
// ------------------------- external views -------------------------- //
|
|
225
235
|
//*********************************************************************//
|
|
226
236
|
|
|
227
|
-
/// @notice Before a revnet processes an incoming payment, determine the weight and pay hooks to use.
|
|
228
|
-
/// @dev This function is part of `IJBRulesetDataHook`, and gets called before the revnet processes a payment.
|
|
229
|
-
/// @param context Standard Juicebox payment context. See `JBBeforePayRecordedContext`.
|
|
230
|
-
/// @return weight The weight which revnet tokens are minted relative to. This can be used to customize how many
|
|
231
|
-
/// tokens get minted by a payment.
|
|
232
|
-
/// @return hookSpecifications Amounts (out of what's being paid in) to be sent to pay hooks instead of being paid
|
|
233
|
-
/// into the revnet. Useful for automatically routing funds from a treasury as payments come in.
|
|
234
|
-
function beforePayRecordedWith(JBBeforePayRecordedContext calldata context)
|
|
235
|
-
external
|
|
236
|
-
view
|
|
237
|
-
override
|
|
238
|
-
returns (uint256 weight, JBPayHookSpecification[] memory hookSpecifications)
|
|
239
|
-
{
|
|
240
|
-
// Keep a reference to the specifications provided by the buyback hook.
|
|
241
|
-
JBPayHookSpecification[] memory buybackHookSpecifications;
|
|
242
|
-
|
|
243
|
-
// Read the weight and specifications from the buyback hook.
|
|
244
|
-
(weight, buybackHookSpecifications) = BUYBACK_HOOK.beforePayRecordedWith(context);
|
|
245
|
-
|
|
246
|
-
// Keep a reference to the revnet's tiered ERC-721 hook.
|
|
247
|
-
IJB721TiersHook tiered721Hook = tiered721HookOf[context.projectId];
|
|
248
|
-
|
|
249
|
-
// Is there a tiered ERC-721 hook?
|
|
250
|
-
bool usesTiered721Hook = address(tiered721Hook) != address(0);
|
|
251
|
-
|
|
252
|
-
// Did the buyback hook return any specifications? (It won't when direct minting is cheaper than swapping.)
|
|
253
|
-
bool usesBuybackHook = buybackHookSpecifications.length > 0;
|
|
254
|
-
|
|
255
|
-
// Initialize the returned specification array with only the hooks that are present.
|
|
256
|
-
hookSpecifications = new JBPayHookSpecification[]((usesTiered721Hook ? 1 : 0) + (usesBuybackHook ? 1 : 0));
|
|
257
|
-
|
|
258
|
-
// If we have a tiered ERC-721 hook, add it to the array.
|
|
259
|
-
if (usesTiered721Hook) {
|
|
260
|
-
hookSpecifications[0] =
|
|
261
|
-
JBPayHookSpecification({hook: IJBPayHook(address(tiered721Hook)), amount: 0, metadata: bytes("")});
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Add the buyback hook specification if present.
|
|
265
|
-
if (usesBuybackHook) {
|
|
266
|
-
hookSpecifications[usesTiered721Hook ? 1 : 0] = buybackHookSpecifications[0];
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
237
|
/// @notice Determine how a cash out from a revnet should be processed.
|
|
271
238
|
/// @dev This function is part of `IJBRulesetDataHook`, and gets called before the revnet processes a cash out.
|
|
272
239
|
/// @dev If a sucker is cashing out, no taxes or fees are imposed.
|
|
@@ -339,6 +306,63 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
339
306
|
return (context.cashOutTaxRate, nonFeeCashOutCount, context.totalSupply, hookSpecifications);
|
|
340
307
|
}
|
|
341
308
|
|
|
309
|
+
/// @notice Before a revnet processes an incoming payment, determine the weight and pay hooks to use.
|
|
310
|
+
/// @dev This function is part of `IJBRulesetDataHook`, and gets called before the revnet processes a payment.
|
|
311
|
+
/// @param context Standard Juicebox payment context. See `JBBeforePayRecordedContext`.
|
|
312
|
+
/// @return weight The weight which revnet tokens are minted relative to. This can be used to customize how many
|
|
313
|
+
/// tokens get minted by a payment.
|
|
314
|
+
/// @return hookSpecifications Amounts (out of what's being paid in) to be sent to pay hooks instead of being paid
|
|
315
|
+
/// into the revnet. Useful for automatically routing funds from a treasury as payments come in.
|
|
316
|
+
function beforePayRecordedWith(JBBeforePayRecordedContext calldata context)
|
|
317
|
+
external
|
|
318
|
+
view
|
|
319
|
+
override
|
|
320
|
+
returns (uint256 weight, JBPayHookSpecification[] memory hookSpecifications)
|
|
321
|
+
{
|
|
322
|
+
// Get the 721 hook's spec and total split amount.
|
|
323
|
+
IJB721TiersHook tiered721Hook = tiered721HookOf[context.projectId];
|
|
324
|
+
JBPayHookSpecification memory tiered721HookSpec;
|
|
325
|
+
uint256 totalSplitAmount;
|
|
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
|
+
}
|
|
336
|
+
|
|
337
|
+
// The amount entering the project after tier splits.
|
|
338
|
+
uint256 projectAmount = totalSplitAmount >= context.amount.value ? 0 : context.amount.value - totalSplitAmount;
|
|
339
|
+
|
|
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);
|
|
346
|
+
}
|
|
347
|
+
|
|
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);
|
|
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];
|
|
364
|
+
}
|
|
365
|
+
|
|
342
366
|
/// @notice A flag indicating whether an address has permission to mint a revnet's tokens on-demand.
|
|
343
367
|
/// @dev Required by the `IJBRulesetDataHook` interface.
|
|
344
368
|
/// @param revnetId The ID of the revnet to check permissions for.
|
|
@@ -459,18 +483,30 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
459
483
|
});
|
|
460
484
|
|
|
461
485
|
// Configure a buyback pool for this terminal token with default fee and TWAP window.
|
|
462
|
-
// slither-disable-next-line
|
|
463
|
-
|
|
464
|
-
.setPoolFor({
|
|
465
|
-
projectId: revnetId,
|
|
466
|
-
fee: DEFAULT_BUYBACK_POOL_FEE,
|
|
467
|
-
twapWindow: DEFAULT_BUYBACK_TWAP_WINDOW,
|
|
468
|
-
terminalToken: accountingContext.token
|
|
469
|
-
});
|
|
486
|
+
// slither-disable-next-line calls-loop
|
|
487
|
+
_trySetBuybackPoolFor(revnetId, accountingContext.token);
|
|
470
488
|
}
|
|
471
489
|
}
|
|
472
490
|
}
|
|
473
491
|
|
|
492
|
+
/// @notice Try to configure a buyback pool for a terminal token. Silently catches failures (e.g., if the Uniswap V4
|
|
493
|
+
/// pool isn't initialized yet).
|
|
494
|
+
/// @param revnetId The ID of the revnet.
|
|
495
|
+
/// @param terminalToken The terminal token to configure a buyback pool for.
|
|
496
|
+
function _trySetBuybackPoolFor(uint256 revnetId, address terminalToken) internal {
|
|
497
|
+
// Try to set the pool — if the pool isn't initialized in the PoolManager yet, this will revert and be caught.
|
|
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
|
+
}) {}
|
|
507
|
+
catch {} // Pool may not be initialized yet — that's OK.
|
|
508
|
+
}
|
|
509
|
+
|
|
474
510
|
/// @notice Make a ruleset configuration for a revnet's stage.
|
|
475
511
|
/// @param baseCurrency The base currency of the revnet.
|
|
476
512
|
/// @param stageConfiguration The stage configuration to make a ruleset for.
|
|
@@ -696,6 +732,17 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
696
732
|
return revnetId;
|
|
697
733
|
}
|
|
698
734
|
|
|
735
|
+
/// @notice Burn any of a revnet's tokens held by this contract.
|
|
736
|
+
/// @dev Project tokens can end up here from reserved token distribution when splits don't sum to 100%.
|
|
737
|
+
/// @param revnetId The ID of the revnet whose tokens should be burned.
|
|
738
|
+
function burnHeldTokensOf(uint256 revnetId) external override {
|
|
739
|
+
uint256 balance = CONTROLLER.TOKENS().totalBalanceOf({holder: address(this), projectId: revnetId});
|
|
740
|
+
if (balance == 0) revert REVDeployer_NothingToBurn();
|
|
741
|
+
CONTROLLER.burnTokensOf({holder: address(this), projectId: revnetId, tokenCount: balance, memo: ""});
|
|
742
|
+
// slither-disable-next-line reentrancy-events
|
|
743
|
+
emit BurnHeldTokens(revnetId, balance, _msgSender());
|
|
744
|
+
}
|
|
745
|
+
|
|
699
746
|
/// @notice Deploy new suckers for an existing revnet.
|
|
700
747
|
/// @dev Only the revnet's split operator can deploy new suckers.
|
|
701
748
|
/// @param revnetId The ID of the revnet to deploy suckers for.
|
|
@@ -777,17 +824,6 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
777
824
|
return (revnetId, hook);
|
|
778
825
|
}
|
|
779
826
|
|
|
780
|
-
/// @notice Burn any of a revnet's tokens held by this contract.
|
|
781
|
-
/// @dev Project tokens can end up here from reserved token distribution when splits don't sum to 100%.
|
|
782
|
-
/// @param revnetId The ID of the revnet whose tokens should be burned.
|
|
783
|
-
function burnHeldTokensOf(uint256 revnetId) external override {
|
|
784
|
-
uint256 balance = CONTROLLER.TOKENS().totalBalanceOf({holder: address(this), projectId: revnetId});
|
|
785
|
-
if (balance == 0) revert REVDeployer_NothingToBurn();
|
|
786
|
-
CONTROLLER.burnTokensOf({holder: address(this), projectId: revnetId, tokenCount: balance, memo: ""});
|
|
787
|
-
// slither-disable-next-line reentrancy-events
|
|
788
|
-
emit BurnHeldTokens(revnetId, balance, _msgSender());
|
|
789
|
-
}
|
|
790
|
-
|
|
791
827
|
/// @notice Change a revnet's split operator.
|
|
792
828
|
/// @dev Only a revnet's current split operator can set a new split operator.
|
|
793
829
|
/// @param revnetId The ID of the revnet to set the split operator of.
|
|
@@ -852,11 +888,32 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
852
888
|
revnetId: revnetId, configuration: configuration, terminalConfigurations: terminalConfigurations
|
|
853
889
|
});
|
|
854
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
|
+
|
|
855
912
|
// Deploy the tiered ERC-721 hook contract.
|
|
856
913
|
// slither-disable-next-line reentrancy-benign
|
|
857
914
|
hook = HOOK_DEPLOYER.deployHookFor({
|
|
858
915
|
projectId: revnetId,
|
|
859
|
-
deployTiersHookConfig:
|
|
916
|
+
deployTiersHookConfig: hookConfig,
|
|
860
917
|
salt: keccak256(abi.encode(tiered721HookConfiguration.salt, encodedConfigurationHash, _msgSender()))
|
|
861
918
|
});
|
|
862
919
|
|