@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
|
@@ -7,26 +7,43 @@ 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";
|
|
13
14
|
import {IJBSuckerRegistry} from "@bananapus/suckers-v6/src/interfaces/IJBSuckerRegistry.sol";
|
|
14
15
|
import {CTPublisher} from "@croptop/core-v6/src/CTPublisher.sol";
|
|
15
|
-
|
|
16
16
|
import {REVConfig} from "../structs/REVConfig.sol";
|
|
17
17
|
import {REVCroptopAllowedPost} from "../structs/REVCroptopAllowedPost.sol";
|
|
18
18
|
import {REVDeploy721TiersHookConfig} from "../structs/REVDeploy721TiersHookConfig.sol";
|
|
19
19
|
import {REVSuckerDeploymentConfig} from "../structs/REVSuckerDeploymentConfig.sol";
|
|
20
20
|
|
|
21
|
+
/// @notice Deploys and manages revnets -- Juicebox projects with pre-configured tokenomics.
|
|
21
22
|
interface IREVDeployer {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
/// @notice Emitted when tokens are auto-issued for a beneficiary during a stage.
|
|
24
|
+
/// @param revnetId The ID of the revnet.
|
|
25
|
+
/// @param stageId The ID of the stage.
|
|
26
|
+
/// @param beneficiary The address receiving the auto-issued tokens.
|
|
27
|
+
/// @param count The number of tokens auto-issued.
|
|
28
|
+
/// @param caller The address that triggered the auto-issuance.
|
|
29
|
+
event AutoIssue(
|
|
30
|
+
uint256 indexed revnetId, uint256 indexed stageId, address indexed beneficiary, uint256 count, address caller
|
|
28
31
|
);
|
|
29
32
|
|
|
33
|
+
/// @notice Emitted when held tokens are burned from the deployer contract.
|
|
34
|
+
/// @param revnetId The ID of the revnet whose tokens were burned.
|
|
35
|
+
/// @param count The number of tokens burned.
|
|
36
|
+
/// @param caller The address that triggered the burn.
|
|
37
|
+
event BurnHeldTokens(uint256 indexed revnetId, uint256 count, address caller);
|
|
38
|
+
|
|
39
|
+
/// @notice Emitted when a new revnet is deployed.
|
|
40
|
+
/// @param revnetId The ID of the deployed revnet.
|
|
41
|
+
/// @param configuration The revnet's configuration.
|
|
42
|
+
/// @param terminalConfigurations The terminals configured for the revnet.
|
|
43
|
+
/// @param suckerDeploymentConfiguration The sucker deployment configuration.
|
|
44
|
+
/// @param rulesetConfigurations The rulesets configured for the revnet.
|
|
45
|
+
/// @param encodedConfigurationHash The hash of the encoded configuration.
|
|
46
|
+
/// @param caller The address that deployed the revnet.
|
|
30
47
|
event DeployRevnet(
|
|
31
48
|
uint256 indexed revnetId,
|
|
32
49
|
REVConfig configuration,
|
|
@@ -37,42 +54,64 @@ interface IREVDeployer {
|
|
|
37
54
|
address caller
|
|
38
55
|
);
|
|
39
56
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
57
|
+
/// @notice Emitted when suckers are deployed for a revnet.
|
|
58
|
+
/// @param revnetId The ID of the revnet.
|
|
59
|
+
/// @param encodedConfigurationHash The hash of the encoded configuration.
|
|
60
|
+
/// @param suckerDeploymentConfiguration The sucker deployment configuration.
|
|
61
|
+
/// @param caller The address that deployed the suckers.
|
|
62
|
+
event DeploySuckers(
|
|
63
|
+
uint256 indexed revnetId,
|
|
64
|
+
bytes32 encodedConfigurationHash,
|
|
65
|
+
REVSuckerDeploymentConfig suckerDeploymentConfiguration,
|
|
66
|
+
address caller
|
|
44
67
|
);
|
|
45
68
|
|
|
69
|
+
/// @notice Emitted when the split operator of a revnet is replaced.
|
|
70
|
+
/// @param revnetId The ID of the revnet.
|
|
71
|
+
/// @param newSplitOperator The address of the new split operator.
|
|
72
|
+
/// @param caller The address that replaced the split operator.
|
|
73
|
+
event ReplaceSplitOperator(uint256 indexed revnetId, address indexed newSplitOperator, address caller);
|
|
74
|
+
|
|
75
|
+
/// @notice Emitted when the cash out delay is set for a revnet.
|
|
76
|
+
/// @param revnetId The ID of the revnet.
|
|
77
|
+
/// @param cashOutDelay The cash out delay in seconds.
|
|
78
|
+
/// @param caller The address that set the delay.
|
|
79
|
+
event SetCashOutDelay(uint256 indexed revnetId, uint256 cashOutDelay, address caller);
|
|
80
|
+
|
|
81
|
+
/// @notice Emitted when an auto-issuance amount is stored for a beneficiary during a stage.
|
|
82
|
+
/// @param revnetId The ID of the revnet.
|
|
83
|
+
/// @param stageId The ID of the stage.
|
|
84
|
+
/// @param beneficiary The address the tokens will be issued to.
|
|
85
|
+
/// @param count The number of tokens stored for auto-issuance.
|
|
86
|
+
/// @param caller The address that stored the amount.
|
|
46
87
|
event StoreAutoIssuanceAmount(
|
|
47
88
|
uint256 indexed revnetId, uint256 indexed stageId, address indexed beneficiary, uint256 count, address caller
|
|
48
89
|
);
|
|
49
90
|
|
|
50
|
-
|
|
91
|
+
/// @notice The number of revnet tokens that can be auto-minted for a beneficiary during a stage.
|
|
92
|
+
/// @param revnetId The ID of the revnet.
|
|
93
|
+
/// @param stageId The ID of the stage.
|
|
94
|
+
/// @param beneficiary The beneficiary of the auto-mint.
|
|
95
|
+
/// @return The number of tokens available to auto-issue.
|
|
96
|
+
function amountToAutoIssue(uint256 revnetId, uint256 stageId, address beneficiary) external view returns (uint256);
|
|
97
|
+
|
|
98
|
+
/// @notice The buyback hook used as a data hook to route payments through buyback pools.
|
|
99
|
+
/// @return The buyback hook contract.
|
|
100
|
+
function BUYBACK_HOOK() external view returns (IJBBuybackHookRegistry);
|
|
51
101
|
|
|
52
102
|
/// @notice The number of seconds until a revnet's participants can cash out after deploying to a new network.
|
|
53
103
|
/// @return The cash out delay in seconds.
|
|
54
104
|
function CASH_OUT_DELAY() external view returns (uint256);
|
|
55
105
|
|
|
106
|
+
/// @notice The timestamp when cash outs become available for a revnet's participants.
|
|
107
|
+
/// @param revnetId The ID of the revnet.
|
|
108
|
+
/// @return The cash out delay timestamp.
|
|
109
|
+
function cashOutDelayOf(uint256 revnetId) external view returns (uint256);
|
|
110
|
+
|
|
56
111
|
/// @notice The controller used to create and manage Juicebox projects for revnets.
|
|
57
112
|
/// @return The controller contract.
|
|
58
113
|
function CONTROLLER() external view returns (IJBController);
|
|
59
114
|
|
|
60
|
-
/// @notice The directory of terminals and controllers for Juicebox projects.
|
|
61
|
-
/// @return The directory contract.
|
|
62
|
-
function DIRECTORY() external view returns (IJBDirectory);
|
|
63
|
-
|
|
64
|
-
/// @notice The contract that mints ERC-721s representing project ownership.
|
|
65
|
-
/// @return The projects contract.
|
|
66
|
-
function PROJECTS() external view returns (IJBProjects);
|
|
67
|
-
|
|
68
|
-
/// @notice The contract that stores Juicebox project access permissions.
|
|
69
|
-
/// @return The permissions contract.
|
|
70
|
-
function PERMISSIONS() external view returns (IJBPermissions);
|
|
71
|
-
|
|
72
|
-
/// @notice The cash out fee as a fraction out of `JBConstants.MAX_FEE`.
|
|
73
|
-
/// @return The fee value.
|
|
74
|
-
function FEE() external view returns (uint256);
|
|
75
|
-
|
|
76
115
|
/// @notice The default Uniswap pool fee tier for auto-configured buyback pools.
|
|
77
116
|
/// @return The fee tier (10_000 = 1%).
|
|
78
117
|
function DEFAULT_BUYBACK_POOL_FEE() external view returns (uint24);
|
|
@@ -81,63 +120,52 @@ interface IREVDeployer {
|
|
|
81
120
|
/// @return The TWAP window in seconds.
|
|
82
121
|
function DEFAULT_BUYBACK_TWAP_WINDOW() external view returns (uint32);
|
|
83
122
|
|
|
84
|
-
/// @notice The
|
|
85
|
-
/// @return The
|
|
86
|
-
function
|
|
123
|
+
/// @notice The directory of terminals and controllers for Juicebox projects.
|
|
124
|
+
/// @return The directory contract.
|
|
125
|
+
function DIRECTORY() external view returns (IJBDirectory);
|
|
126
|
+
|
|
127
|
+
/// @notice The cash out fee as a fraction out of `JBConstants.MAX_FEE`.
|
|
128
|
+
/// @return The fee value.
|
|
129
|
+
function FEE() external view returns (uint256);
|
|
87
130
|
|
|
88
131
|
/// @notice The Juicebox project ID of the revnet that receives cash out fees.
|
|
89
132
|
/// @return The fee revnet ID.
|
|
90
133
|
function FEE_REVNET_ID() external view returns (uint256);
|
|
91
134
|
|
|
92
|
-
/// @notice The
|
|
93
|
-
/// @
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
/// @notice The buyback hook used as a data hook to route payments through buyback pools.
|
|
97
|
-
/// @return The buyback hook contract.
|
|
98
|
-
function BUYBACK_HOOK() external view returns (IJBRulesetDataHook);
|
|
135
|
+
/// @notice The hashed encoded configuration of each revnet.
|
|
136
|
+
/// @param revnetId The ID of the revnet.
|
|
137
|
+
/// @return The hashed encoded configuration.
|
|
138
|
+
function hashedEncodedConfigurationOf(uint256 revnetId) external view returns (bytes32);
|
|
99
139
|
|
|
100
140
|
/// @notice The deployer used to create tiered ERC-721 hooks for revnets.
|
|
101
141
|
/// @return The hook deployer contract.
|
|
102
142
|
function HOOK_DEPLOYER() external view returns (IJB721TiersHookDeployer);
|
|
103
143
|
|
|
144
|
+
/// @notice Whether an address is a revnet's split operator.
|
|
145
|
+
/// @param revnetId The ID of the revnet.
|
|
146
|
+
/// @param addr The address to check.
|
|
147
|
+
/// @return A flag indicating whether the address is the revnet's split operator.
|
|
148
|
+
function isSplitOperatorOf(uint256 revnetId, address addr) external view returns (bool);
|
|
149
|
+
|
|
104
150
|
/// @notice The loan contract used by all revnets.
|
|
105
151
|
/// @return The loans contract address.
|
|
106
152
|
function LOANS() external view returns (address);
|
|
107
153
|
|
|
108
|
-
/// @notice The
|
|
109
|
-
/// @
|
|
110
|
-
|
|
111
|
-
/// @param beneficiary The beneficiary of the auto-mint.
|
|
112
|
-
/// @return The number of tokens available to auto-issue.
|
|
113
|
-
function amountToAutoIssue(uint256 revnetId, uint256 stageId, address beneficiary) external view returns (uint256);
|
|
114
|
-
|
|
115
|
-
/// @notice The timestamp when cash outs become available for a revnet's participants.
|
|
116
|
-
/// @param revnetId The ID of the revnet.
|
|
117
|
-
/// @return The cash out delay timestamp.
|
|
118
|
-
function cashOutDelayOf(uint256 revnetId) external view returns (uint256);
|
|
154
|
+
/// @notice The contract that stores Juicebox project access permissions.
|
|
155
|
+
/// @return The permissions contract.
|
|
156
|
+
function PERMISSIONS() external view returns (IJBPermissions);
|
|
119
157
|
|
|
120
|
-
/// @notice
|
|
121
|
-
/// @
|
|
122
|
-
|
|
123
|
-
/// @return suckers The addresses of the deployed suckers.
|
|
124
|
-
function deploySuckersFor(
|
|
125
|
-
uint256 revnetId,
|
|
126
|
-
REVSuckerDeploymentConfig calldata suckerDeploymentConfiguration
|
|
127
|
-
)
|
|
128
|
-
external
|
|
129
|
-
returns (address[] memory suckers);
|
|
158
|
+
/// @notice The contract that mints ERC-721s representing project ownership.
|
|
159
|
+
/// @return The projects contract.
|
|
160
|
+
function PROJECTS() external view returns (IJBProjects);
|
|
130
161
|
|
|
131
|
-
/// @notice The
|
|
132
|
-
/// @
|
|
133
|
-
|
|
134
|
-
function hashedEncodedConfigurationOf(uint256 revnetId) external view returns (bytes32);
|
|
162
|
+
/// @notice The croptop publisher revnets can use to publish ERC-721 posts to their tiered ERC-721 hooks.
|
|
163
|
+
/// @return The publisher contract.
|
|
164
|
+
function PUBLISHER() external view returns (CTPublisher);
|
|
135
165
|
|
|
136
|
-
/// @notice
|
|
137
|
-
/// @
|
|
138
|
-
|
|
139
|
-
/// @return A flag indicating whether the address is the revnet's split operator.
|
|
140
|
-
function isSplitOperatorOf(uint256 revnetId, address addr) external view returns (bool);
|
|
166
|
+
/// @notice The registry that deploys and tracks suckers for revnets.
|
|
167
|
+
/// @return The sucker registry contract.
|
|
168
|
+
function SUCKER_REGISTRY() external view returns (IJBSuckerRegistry);
|
|
141
169
|
|
|
142
170
|
/// @notice Each revnet's tiered ERC-721 hook.
|
|
143
171
|
/// @param revnetId The ID of the revnet.
|
|
@@ -150,6 +178,10 @@ interface IREVDeployer {
|
|
|
150
178
|
/// @param beneficiary The address to auto-mint tokens to.
|
|
151
179
|
function autoIssueFor(uint256 revnetId, uint256 stageId, address beneficiary) external;
|
|
152
180
|
|
|
181
|
+
/// @notice Burn any of a revnet's tokens held by this contract.
|
|
182
|
+
/// @param revnetId The ID of the revnet whose tokens should be burned.
|
|
183
|
+
function burnHeldTokensOf(uint256 revnetId) external;
|
|
184
|
+
|
|
153
185
|
/// @notice Deploy a revnet, or initialize an existing Juicebox project as a revnet.
|
|
154
186
|
/// @param revnetId The ID of the Juicebox project to initialize. Send 0 to deploy a new revnet.
|
|
155
187
|
/// @param configuration Core revnet configuration.
|
|
@@ -165,6 +197,17 @@ interface IREVDeployer {
|
|
|
165
197
|
external
|
|
166
198
|
returns (uint256);
|
|
167
199
|
|
|
200
|
+
/// @notice Deploy new suckers for an existing revnet.
|
|
201
|
+
/// @param revnetId The ID of the revnet to deploy suckers for.
|
|
202
|
+
/// @param suckerDeploymentConfiguration The suckers to set up for the revnet.
|
|
203
|
+
/// @return suckers The addresses of the deployed suckers.
|
|
204
|
+
function deploySuckersFor(
|
|
205
|
+
uint256 revnetId,
|
|
206
|
+
REVSuckerDeploymentConfig calldata suckerDeploymentConfiguration
|
|
207
|
+
)
|
|
208
|
+
external
|
|
209
|
+
returns (address[] memory suckers);
|
|
210
|
+
|
|
168
211
|
/// @notice Deploy a revnet with tiered ERC-721s and optional croptop posting support.
|
|
169
212
|
/// @param revnetId The ID of the Juicebox project to initialize. Send 0 to deploy a new revnet.
|
|
170
213
|
/// @param configuration Core revnet configuration.
|
|
@@ -189,8 +232,4 @@ interface IREVDeployer {
|
|
|
189
232
|
/// @param revnetId The ID of the revnet.
|
|
190
233
|
/// @param newSplitOperator The new split operator's address.
|
|
191
234
|
function setSplitOperatorOf(uint256 revnetId, address newSplitOperator) external;
|
|
192
|
-
|
|
193
|
-
/// @notice Burn any of a revnet's tokens held by this contract.
|
|
194
|
-
/// @param revnetId The ID of the revnet whose tokens should be burned.
|
|
195
|
-
function burnHeldTokensOf(uint256 revnetId) external;
|
|
196
235
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
pragma solidity ^0.8.0;
|
|
3
3
|
|
|
4
|
-
import {IPermit2} from "@uniswap/permit2/src/interfaces/IPermit2.sol";
|
|
5
4
|
import {IJBController} from "@bananapus/core-v6/src/interfaces/IJBController.sol";
|
|
6
5
|
import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
|
|
7
6
|
import {IJBPayoutTerminal} from "@bananapus/core-v6/src/interfaces/IJBPayoutTerminal.sol";
|
|
@@ -9,11 +8,22 @@ import {IJBPrices} from "@bananapus/core-v6/src/interfaces/IJBPrices.sol";
|
|
|
9
8
|
import {IJBProjects} from "@bananapus/core-v6/src/interfaces/IJBProjects.sol";
|
|
10
9
|
import {IJBTokenUriResolver} from "@bananapus/core-v6/src/interfaces/IJBTokenUriResolver.sol";
|
|
11
10
|
import {JBSingleAllowance} from "@bananapus/core-v6/src/structs/JBSingleAllowance.sol";
|
|
12
|
-
|
|
11
|
+
import {IPermit2} from "@uniswap/permit2/src/interfaces/IPermit2.sol";
|
|
13
12
|
import {REVLoan} from "./../structs/REVLoan.sol";
|
|
14
13
|
import {REVLoanSource} from "./../structs/REVLoanSource.sol";
|
|
15
14
|
|
|
15
|
+
/// @notice Manages loans against revnet token collateral.
|
|
16
16
|
interface IREVLoans {
|
|
17
|
+
/// @notice Emitted when a loan is created by borrowing from a revnet.
|
|
18
|
+
/// @param loanId The ID of the newly created loan.
|
|
19
|
+
/// @param revnetId The ID of the revnet being borrowed from.
|
|
20
|
+
/// @param loan The loan data.
|
|
21
|
+
/// @param source The source of the loan (terminal and token).
|
|
22
|
+
/// @param borrowAmount The amount borrowed.
|
|
23
|
+
/// @param collateralCount The amount of collateral tokens locked.
|
|
24
|
+
/// @param sourceFeeAmount The fee amount charged by the source.
|
|
25
|
+
/// @param beneficiary The address receiving the borrowed funds.
|
|
26
|
+
/// @param caller The address that created the loan.
|
|
17
27
|
event Borrow(
|
|
18
28
|
uint256 indexed loanId,
|
|
19
29
|
uint256 indexed revnetId,
|
|
@@ -25,7 +35,41 @@ interface IREVLoans {
|
|
|
25
35
|
address payable beneficiary,
|
|
26
36
|
address caller
|
|
27
37
|
);
|
|
38
|
+
|
|
39
|
+
/// @notice Emitted when a loan is liquidated after exceeding the liquidation duration.
|
|
40
|
+
/// @param loanId The ID of the liquidated loan.
|
|
41
|
+
/// @param revnetId The ID of the revnet the loan was from.
|
|
42
|
+
/// @param loan The liquidated loan data.
|
|
43
|
+
/// @param caller The address that triggered the liquidation.
|
|
28
44
|
event Liquidate(uint256 indexed loanId, uint256 indexed revnetId, REVLoan loan, address caller);
|
|
45
|
+
|
|
46
|
+
/// @notice Emitted when collateral is reallocated from one loan to a new loan.
|
|
47
|
+
/// @param loanId The ID of the original loan.
|
|
48
|
+
/// @param revnetId The ID of the revnet.
|
|
49
|
+
/// @param reallocatedLoanId The ID of the loan after reallocation.
|
|
50
|
+
/// @param reallocatedLoan The reallocated loan data.
|
|
51
|
+
/// @param removedCollateralCount The amount of collateral removed from the original loan.
|
|
52
|
+
/// @param caller The address that triggered the reallocation.
|
|
53
|
+
event ReallocateCollateral(
|
|
54
|
+
uint256 indexed loanId,
|
|
55
|
+
uint256 indexed revnetId,
|
|
56
|
+
uint256 indexed reallocatedLoanId,
|
|
57
|
+
REVLoan reallocatedLoan,
|
|
58
|
+
uint256 removedCollateralCount,
|
|
59
|
+
address caller
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
/// @notice Emitted when a loan is repaid.
|
|
63
|
+
/// @param loanId The ID of the loan being repaid.
|
|
64
|
+
/// @param revnetId The ID of the revnet.
|
|
65
|
+
/// @param paidOffLoanId The ID of the loan after repayment.
|
|
66
|
+
/// @param loan The original loan data.
|
|
67
|
+
/// @param paidOffLoan The loan data after repayment.
|
|
68
|
+
/// @param repayBorrowAmount The amount repaid.
|
|
69
|
+
/// @param sourceFeeAmount The fee amount charged by the source.
|
|
70
|
+
/// @param collateralCountToReturn The amount of collateral returned.
|
|
71
|
+
/// @param beneficiary The address receiving the returned collateral.
|
|
72
|
+
/// @param caller The address that repaid the loan.
|
|
29
73
|
event RepayLoan(
|
|
30
74
|
uint256 indexed loanId,
|
|
31
75
|
uint256 indexed revnetId,
|
|
@@ -38,55 +82,11 @@ interface IREVLoans {
|
|
|
38
82
|
address payable beneficiary,
|
|
39
83
|
address caller
|
|
40
84
|
);
|
|
41
|
-
event ReallocateCollateral(
|
|
42
|
-
uint256 indexed loanId,
|
|
43
|
-
uint256 indexed revnetId,
|
|
44
|
-
uint256 indexed reallocatedLoanId,
|
|
45
|
-
REVLoan reallocatedLoan,
|
|
46
|
-
uint256 removedCollateralCount,
|
|
47
|
-
address caller
|
|
48
|
-
);
|
|
49
|
-
event SetTokenUriResolver(IJBTokenUriResolver indexed resolver, address caller);
|
|
50
|
-
|
|
51
|
-
/// @notice The duration after which a loan expires and its collateral is permanently lost.
|
|
52
|
-
/// @return The loan liquidation duration in seconds.
|
|
53
|
-
function LOAN_LIQUIDATION_DURATION() external view returns (uint256);
|
|
54
|
-
|
|
55
|
-
/// @notice The permit2 utility used for token transfers.
|
|
56
|
-
/// @return The permit2 contract.
|
|
57
|
-
function PERMIT2() external view returns (IPermit2);
|
|
58
85
|
|
|
59
|
-
/// @notice
|
|
60
|
-
/// @
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
/// @notice The directory of terminals and controllers for revnets.
|
|
64
|
-
/// @return The directory contract.
|
|
65
|
-
function DIRECTORY() external view returns (IJBDirectory);
|
|
66
|
-
|
|
67
|
-
/// @notice The contract that stores prices for each revnet.
|
|
68
|
-
/// @return The prices contract.
|
|
69
|
-
function PRICES() external view returns (IJBPrices);
|
|
70
|
-
|
|
71
|
-
/// @notice The contract that mints ERC-721s representing project ownership.
|
|
72
|
-
/// @return The projects contract.
|
|
73
|
-
function PROJECTS() external view returns (IJBProjects);
|
|
74
|
-
|
|
75
|
-
/// @notice The ID of the REV revnet that receives protocol fees from loans.
|
|
76
|
-
/// @return The REV revnet ID.
|
|
77
|
-
function REV_ID() external view returns (uint256);
|
|
78
|
-
|
|
79
|
-
/// @notice The fee percent charged by the REV revnet on each loan, in terms of `JBConstants.MAX_FEE`.
|
|
80
|
-
/// @return The REV prepaid fee percent.
|
|
81
|
-
function REV_PREPAID_FEE_PERCENT() external view returns (uint256);
|
|
82
|
-
|
|
83
|
-
/// @notice The minimum fee percent that must be prepaid when borrowing, in terms of `JBConstants.MAX_FEE`.
|
|
84
|
-
/// @return The minimum prepaid fee percent.
|
|
85
|
-
function MIN_PREPAID_FEE_PERCENT() external view returns (uint256);
|
|
86
|
-
|
|
87
|
-
/// @notice The maximum fee percent that can be prepaid when borrowing, in terms of `JBConstants.MAX_FEE`.
|
|
88
|
-
/// @return The maximum prepaid fee percent.
|
|
89
|
-
function MAX_PREPAID_FEE_PERCENT() external view returns (uint256);
|
|
86
|
+
/// @notice Emitted when the token URI resolver is changed.
|
|
87
|
+
/// @param resolver The new token URI resolver.
|
|
88
|
+
/// @param caller The address that set the resolver.
|
|
89
|
+
event SetTokenUriResolver(IJBTokenUriResolver indexed resolver, address caller);
|
|
90
90
|
|
|
91
91
|
/// @notice The amount that can be borrowed from a revnet given a certain amount of collateral.
|
|
92
92
|
/// @param revnetId The ID of the revnet to check for borrowable assets from.
|
|
@@ -104,6 +104,10 @@ interface IREVLoans {
|
|
|
104
104
|
view
|
|
105
105
|
returns (uint256);
|
|
106
106
|
|
|
107
|
+
/// @notice The controller that manages revnets using this loans contract.
|
|
108
|
+
/// @return The controller contract.
|
|
109
|
+
function CONTROLLER() external view returns (IJBController);
|
|
110
|
+
|
|
107
111
|
/// @notice Determines the source fee amount for a loan being paid off a certain amount.
|
|
108
112
|
/// @param loan The loan having its source fee amount determined.
|
|
109
113
|
/// @param amount The amount being paid off.
|
|
@@ -116,6 +120,10 @@ interface IREVLoans {
|
|
|
116
120
|
view
|
|
117
121
|
returns (uint256 sourceFeeAmount);
|
|
118
122
|
|
|
123
|
+
/// @notice The directory of terminals and controllers for revnets.
|
|
124
|
+
/// @return The directory contract.
|
|
125
|
+
function DIRECTORY() external view returns (IJBDirectory);
|
|
126
|
+
|
|
119
127
|
/// @notice Whether a revnet currently has outstanding loans from the specified terminal in the specified token.
|
|
120
128
|
/// @param revnetId The ID of the revnet issuing the loan.
|
|
121
129
|
/// @param terminal The terminal that the loan is issued from.
|
|
@@ -123,6 +131,10 @@ interface IREVLoans {
|
|
|
123
131
|
/// @return A flag indicating if the revnet has an active loan source.
|
|
124
132
|
function isLoanSourceOf(uint256 revnetId, IJBPayoutTerminal terminal, address token) external view returns (bool);
|
|
125
133
|
|
|
134
|
+
/// @notice The duration after which a loan expires and its collateral is permanently lost.
|
|
135
|
+
/// @return The loan liquidation duration in seconds.
|
|
136
|
+
function LOAN_LIQUIDATION_DURATION() external view returns (uint256);
|
|
137
|
+
|
|
126
138
|
/// @notice Get a loan's details.
|
|
127
139
|
/// @param loanId The ID of the loan to retrieve.
|
|
128
140
|
/// @return The loan data.
|
|
@@ -136,13 +148,33 @@ interface IREVLoans {
|
|
|
136
148
|
/// @return The array of loan sources.
|
|
137
149
|
function loanSourcesOf(uint256 revnetId) external view returns (REVLoanSource[] memory);
|
|
138
150
|
|
|
139
|
-
/// @notice The
|
|
140
|
-
/// @
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
/// @
|
|
144
|
-
/// @return The
|
|
145
|
-
function
|
|
151
|
+
/// @notice The maximum fee percent that can be prepaid when borrowing, in terms of `JBConstants.MAX_FEE`.
|
|
152
|
+
/// @return The maximum prepaid fee percent.
|
|
153
|
+
function MAX_PREPAID_FEE_PERCENT() external view returns (uint256);
|
|
154
|
+
|
|
155
|
+
/// @notice The minimum fee percent that must be prepaid when borrowing, in terms of `JBConstants.MAX_FEE`.
|
|
156
|
+
/// @return The minimum prepaid fee percent.
|
|
157
|
+
function MIN_PREPAID_FEE_PERCENT() external view returns (uint256);
|
|
158
|
+
|
|
159
|
+
/// @notice The permit2 utility used for token transfers.
|
|
160
|
+
/// @return The permit2 contract.
|
|
161
|
+
function PERMIT2() external view returns (IPermit2);
|
|
162
|
+
|
|
163
|
+
/// @notice The contract that stores prices for each revnet.
|
|
164
|
+
/// @return The prices contract.
|
|
165
|
+
function PRICES() external view returns (IJBPrices);
|
|
166
|
+
|
|
167
|
+
/// @notice The contract that mints ERC-721s representing project ownership.
|
|
168
|
+
/// @return The projects contract.
|
|
169
|
+
function PROJECTS() external view returns (IJBProjects);
|
|
170
|
+
|
|
171
|
+
/// @notice The ID of the REV revnet that receives protocol fees from loans.
|
|
172
|
+
/// @return The REV revnet ID.
|
|
173
|
+
function REV_ID() external view returns (uint256);
|
|
174
|
+
|
|
175
|
+
/// @notice The fee percent charged by the REV revnet on each loan, in terms of `JBConstants.MAX_FEE`.
|
|
176
|
+
/// @return The REV prepaid fee percent.
|
|
177
|
+
function REV_PREPAID_FEE_PERCENT() external view returns (uint256);
|
|
146
178
|
|
|
147
179
|
/// @notice The revnet ID for the loan with the provided loan ID.
|
|
148
180
|
/// @param loanId The loan ID to get the revnet ID of.
|
|
@@ -172,6 +204,14 @@ interface IREVLoans {
|
|
|
172
204
|
/// @return The total collateral count.
|
|
173
205
|
function totalCollateralOf(uint256 revnetId) external view returns (uint256);
|
|
174
206
|
|
|
207
|
+
/// @notice The cumulative number of loans ever created for a revnet, used as a loan ID sequence counter.
|
|
208
|
+
/// @dev This counter only increments and never decrements. It does NOT represent the count of currently active
|
|
209
|
+
/// loans -- repaid and liquidated loans leave permanent gaps in the sequence. Do not use this value to determine
|
|
210
|
+
/// how many loans are currently outstanding.
|
|
211
|
+
/// @param revnetId The ID of the revnet to get the cumulative loan count for.
|
|
212
|
+
/// @return The cumulative number of loans ever created.
|
|
213
|
+
function totalLoansBorrowedFor(uint256 revnetId) external view returns (uint256);
|
|
214
|
+
|
|
175
215
|
/// @notice Open a loan by borrowing from a revnet. Collateral tokens are burned and only re-minted upon repayment.
|
|
176
216
|
/// @param revnetId The ID of the revnet being borrowed from.
|
|
177
217
|
/// @param source The source of the loan (terminal and token).
|
|
@@ -198,25 +238,6 @@ interface IREVLoans {
|
|
|
198
238
|
/// @param count The number of loans to iterate over.
|
|
199
239
|
function liquidateExpiredLoansFrom(uint256 revnetId, uint256 startingLoanId, uint256 count) external;
|
|
200
240
|
|
|
201
|
-
/// @notice Repay a loan or return excess collateral no longer needed to support the loan.
|
|
202
|
-
/// @param loanId The ID of the loan being repaid.
|
|
203
|
-
/// @param maxRepayBorrowAmount The maximum amount to repay, denominated in the source's token.
|
|
204
|
-
/// @param collateralCountToReturn The amount of collateral to return from the loan.
|
|
205
|
-
/// @param beneficiary The address receiving the returned collateral and fee payment tokens.
|
|
206
|
-
/// @param allowance A permit2 allowance to facilitate the repayment transfer.
|
|
207
|
-
/// @return paidOffLoanId The ID of the loan after it has been paid off.
|
|
208
|
-
/// @return paidOffloan The loan after it has been paid off.
|
|
209
|
-
function repayLoan(
|
|
210
|
-
uint256 loanId,
|
|
211
|
-
uint256 maxRepayBorrowAmount,
|
|
212
|
-
uint256 collateralCountToReturn,
|
|
213
|
-
address payable beneficiary,
|
|
214
|
-
JBSingleAllowance calldata allowance
|
|
215
|
-
)
|
|
216
|
-
external
|
|
217
|
-
payable
|
|
218
|
-
returns (uint256 paidOffLoanId, REVLoan memory paidOffloan);
|
|
219
|
-
|
|
220
241
|
/// @notice Refinance a loan by transferring extra collateral from an existing loan to a new loan.
|
|
221
242
|
/// @param loanId The ID of the loan to reallocate collateral from.
|
|
222
243
|
/// @param collateralCountToTransfer The amount of collateral to transfer from the original loan.
|
|
@@ -241,6 +262,25 @@ interface IREVLoans {
|
|
|
241
262
|
external
|
|
242
263
|
returns (uint256 reallocatedLoanId, uint256 newLoanId, REVLoan memory reallocatedLoan, REVLoan memory newLoan);
|
|
243
264
|
|
|
265
|
+
/// @notice Repay a loan or return excess collateral no longer needed to support the loan.
|
|
266
|
+
/// @param loanId The ID of the loan being repaid.
|
|
267
|
+
/// @param maxRepayBorrowAmount The maximum amount to repay, denominated in the source's token.
|
|
268
|
+
/// @param collateralCountToReturn The amount of collateral to return from the loan.
|
|
269
|
+
/// @param beneficiary The address receiving the returned collateral and fee payment tokens.
|
|
270
|
+
/// @param allowance A permit2 allowance to facilitate the repayment transfer.
|
|
271
|
+
/// @return paidOffLoanId The ID of the loan after it has been paid off.
|
|
272
|
+
/// @return paidOffloan The loan after it has been paid off.
|
|
273
|
+
function repayLoan(
|
|
274
|
+
uint256 loanId,
|
|
275
|
+
uint256 maxRepayBorrowAmount,
|
|
276
|
+
uint256 collateralCountToReturn,
|
|
277
|
+
address payable beneficiary,
|
|
278
|
+
JBSingleAllowance calldata allowance
|
|
279
|
+
)
|
|
280
|
+
external
|
|
281
|
+
payable
|
|
282
|
+
returns (uint256 paidOffLoanId, REVLoan memory paidOffloan);
|
|
283
|
+
|
|
244
284
|
/// @notice Sets the address of the resolver used to retrieve the token URI of loans.
|
|
245
285
|
/// @param resolver The new token URI resolver.
|
|
246
286
|
function setTokenUriResolver(IJBTokenUriResolver resolver) external;
|
|
@@ -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
|
);
|