@rev-net/core-v6 0.0.1

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.
Files changed (92) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +65 -0
  3. package/REVNET_SECURITY_CHECKLIST.md +164 -0
  4. package/SECURITY.md +68 -0
  5. package/SKILLS.md +166 -0
  6. package/deployments/revnet-core-v5/arbitrum/REVDeployer.json +2821 -0
  7. package/deployments/revnet-core-v5/arbitrum/REVLoans.json +2260 -0
  8. package/deployments/revnet-core-v5/arbitrum_sepolia/REVDeployer.json +2821 -0
  9. package/deployments/revnet-core-v5/arbitrum_sepolia/REVLoans.json +2260 -0
  10. package/deployments/revnet-core-v5/base/REVDeployer.json +2825 -0
  11. package/deployments/revnet-core-v5/base/REVLoans.json +2264 -0
  12. package/deployments/revnet-core-v5/base_sepolia/REVDeployer.json +2825 -0
  13. package/deployments/revnet-core-v5/base_sepolia/REVLoans.json +2264 -0
  14. package/deployments/revnet-core-v5/ethereum/REVDeployer.json +2825 -0
  15. package/deployments/revnet-core-v5/ethereum/REVLoans.json +2264 -0
  16. package/deployments/revnet-core-v5/optimism/REVDeployer.json +2821 -0
  17. package/deployments/revnet-core-v5/optimism/REVLoans.json +2260 -0
  18. package/deployments/revnet-core-v5/optimism_sepolia/REVDeployer.json +2825 -0
  19. package/deployments/revnet-core-v5/optimism_sepolia/REVLoans.json +2264 -0
  20. package/deployments/revnet-core-v5/sepolia/REVDeployer.json +2825 -0
  21. package/deployments/revnet-core-v5/sepolia/REVLoans.json +2264 -0
  22. package/docs/book.css +13 -0
  23. package/docs/book.toml +13 -0
  24. package/docs/solidity.min.js +74 -0
  25. package/docs/src/README.md +88 -0
  26. package/docs/src/SUMMARY.md +20 -0
  27. package/docs/src/src/README.md +7 -0
  28. package/docs/src/src/REVDeployer.sol/contract.REVDeployer.md +968 -0
  29. package/docs/src/src/REVLoans.sol/contract.REVLoans.md +1047 -0
  30. package/docs/src/src/interfaces/IREVDeployer.sol/interface.IREVDeployer.md +243 -0
  31. package/docs/src/src/interfaces/IREVLoans.sol/interface.IREVLoans.md +296 -0
  32. package/docs/src/src/interfaces/README.md +5 -0
  33. package/docs/src/src/structs/README.md +14 -0
  34. package/docs/src/src/structs/REVAutoIssuance.sol/struct.REVAutoIssuance.md +19 -0
  35. package/docs/src/src/structs/REVBuybackHookConfig.sol/struct.REVBuybackHookConfig.md +19 -0
  36. package/docs/src/src/structs/REVBuybackPoolConfig.sol/struct.REVBuybackPoolConfig.md +21 -0
  37. package/docs/src/src/structs/REVConfig.sol/struct.REVConfig.md +35 -0
  38. package/docs/src/src/structs/REVCroptopAllowedPost.sol/struct.REVCroptopAllowedPost.md +28 -0
  39. package/docs/src/src/structs/REVDeploy721TiersHookConfig.sol/struct.REVDeploy721TiersHookConfig.md +34 -0
  40. package/docs/src/src/structs/REVDescription.sol/struct.REVDescription.md +23 -0
  41. package/docs/src/src/structs/REVLoan.sol/struct.REVLoan.md +28 -0
  42. package/docs/src/src/structs/REVLoanSource.sol/struct.REVLoanSource.md +16 -0
  43. package/docs/src/src/structs/REVStageConfig.sol/struct.REVStageConfig.md +44 -0
  44. package/docs/src/src/structs/REVSuckerDeploymentConfig.sol/struct.REVSuckerDeploymentConfig.md +16 -0
  45. package/foundry.lock +11 -0
  46. package/foundry.toml +23 -0
  47. package/package.json +31 -0
  48. package/remappings.txt +1 -0
  49. package/script/Deploy.s.sol +350 -0
  50. package/script/helpers/RevnetCoreDeploymentLib.sol +72 -0
  51. package/slither-ci.config.json +10 -0
  52. package/sphinx.lock +507 -0
  53. package/src/REVDeployer.sol +1257 -0
  54. package/src/REVLoans.sol +1333 -0
  55. package/src/interfaces/IREVDeployer.sol +198 -0
  56. package/src/interfaces/IREVLoans.sol +241 -0
  57. package/src/structs/REVAutoIssuance.sol +11 -0
  58. package/src/structs/REVConfig.sol +17 -0
  59. package/src/structs/REVCroptopAllowedPost.sol +20 -0
  60. package/src/structs/REVDeploy721TiersHookConfig.sol +25 -0
  61. package/src/structs/REVDescription.sol +14 -0
  62. package/src/structs/REVLoan.sol +19 -0
  63. package/src/structs/REVLoanSource.sol +11 -0
  64. package/src/structs/REVStageConfig.sol +34 -0
  65. package/src/structs/REVSuckerDeploymentConfig.sol +11 -0
  66. package/test/REV.integrations.t.sol +420 -0
  67. package/test/REVAutoIssuanceFuzz.t.sol +276 -0
  68. package/test/REVDeployerAuditRegressions.t.sol +328 -0
  69. package/test/REVInvincibility.t.sol +1275 -0
  70. package/test/REVInvincibilityHandler.sol +357 -0
  71. package/test/REVLifecycle.t.sol +364 -0
  72. package/test/REVLoans.invariants.t.sol +642 -0
  73. package/test/REVLoansAttacks.t.sol +739 -0
  74. package/test/REVLoansAuditRegressions.t.sol +314 -0
  75. package/test/REVLoansFeeRecovery.t.sol +704 -0
  76. package/test/REVLoansSourced.t.sol +1732 -0
  77. package/test/REVLoansUnSourced.t.sol +331 -0
  78. package/test/TestPR09_ConversionDocumentation.t.sol +304 -0
  79. package/test/TestPR10_LiquidationBehavior.t.sol +340 -0
  80. package/test/TestPR11_LowFindings.t.sol +571 -0
  81. package/test/TestPR12_FlashLoanSurplus.t.sol +305 -0
  82. package/test/TestPR13_CrossSourceReallocation.t.sol +302 -0
  83. package/test/TestPR15_CashOutCallerValidation.t.sol +320 -0
  84. package/test/TestPR16_ZeroRepayment.t.sol +297 -0
  85. package/test/TestPR21_Uint112Overflow.t.sol +251 -0
  86. package/test/TestPR22_HookArrayOOB.t.sol +221 -0
  87. package/test/TestPR26_BurnHeldTokens.t.sol +331 -0
  88. package/test/TestPR27_CEIPattern.t.sol +448 -0
  89. package/test/TestPR29_SwapTerminalPermission.t.sol +206 -0
  90. package/test/TestPR32_MixedFixes.t.sol +529 -0
  91. package/test/helpers/MaliciousContracts.sol +233 -0
  92. package/test/mock/MockBuybackDataHook.sol +61 -0
@@ -0,0 +1,198 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {IJB721TiersHook} from "@bananapus/721-hook-v6/src/interfaces/IJB721TiersHook.sol";
5
+ import {IJB721TiersHookDeployer} from "@bananapus/721-hook-v6/src/interfaces/IJB721TiersHookDeployer.sol";
6
+ import {IJBController} from "@bananapus/core-v6/src/interfaces/IJBController.sol";
7
+ import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
8
+ import {IJBPermissions} from "@bananapus/core-v6/src/interfaces/IJBPermissions.sol";
9
+ import {IJBProjects} from "@bananapus/core-v6/src/interfaces/IJBProjects.sol";
10
+ import {IJBRulesetDataHook} from "@bananapus/core-v6/src/interfaces/IJBRulesetDataHook.sol";
11
+ import {JBRulesetConfig} from "@bananapus/core-v6/src/structs/JBRulesetConfig.sol";
12
+ import {JBTerminalConfig} from "@bananapus/core-v6/src/structs/JBTerminalConfig.sol";
13
+ import {IJBSuckerRegistry} from "@bananapus/suckers-v6/src/interfaces/IJBSuckerRegistry.sol";
14
+ import {CTPublisher} from "@croptop/core-v6/src/CTPublisher.sol";
15
+
16
+ import {REVConfig} from "../structs/REVConfig.sol";
17
+ import {REVCroptopAllowedPost} from "../structs/REVCroptopAllowedPost.sol";
18
+ import {REVDeploy721TiersHookConfig} from "../structs/REVDeploy721TiersHookConfig.sol";
19
+ import {REVSuckerDeploymentConfig} from "../structs/REVSuckerDeploymentConfig.sol";
20
+
21
+ interface IREVDeployer {
22
+ event ReplaceSplitOperator(uint256 indexed revnetId, address indexed newSplitOperator, address caller);
23
+ event DeploySuckers(
24
+ uint256 indexed revnetId,
25
+ bytes32 encodedConfigurationHash,
26
+ REVSuckerDeploymentConfig suckerDeploymentConfiguration,
27
+ address caller
28
+ );
29
+
30
+ event DeployRevnet(
31
+ uint256 indexed revnetId,
32
+ REVConfig configuration,
33
+ JBTerminalConfig[] terminalConfigurations,
34
+ REVSuckerDeploymentConfig suckerDeploymentConfiguration,
35
+ JBRulesetConfig[] rulesetConfigurations,
36
+ bytes32 encodedConfigurationHash,
37
+ address caller
38
+ );
39
+
40
+ event SetCashOutDelay(uint256 indexed revnetId, uint256 cashOutDelay, address caller);
41
+
42
+ event AutoIssue(
43
+ uint256 indexed revnetId, uint256 indexed stageId, address indexed beneficiary, uint256 count, address caller
44
+ );
45
+
46
+ event StoreAutoIssuanceAmount(
47
+ uint256 indexed revnetId, uint256 indexed stageId, address indexed beneficiary, uint256 count, address caller
48
+ );
49
+
50
+ event SetAdditionalOperator(uint256 revnetId, address additionalOperator, uint256[] permissionIds, address caller);
51
+
52
+ event BurnHeldTokens(uint256 indexed revnetId, uint256 count, address caller);
53
+
54
+ /// @notice The number of seconds until a revnet's participants can cash out after deploying to a new network.
55
+ /// @return The cash out delay in seconds.
56
+ function CASH_OUT_DELAY() external view returns (uint256);
57
+
58
+ /// @notice The controller used to create and manage Juicebox projects for revnets.
59
+ /// @return The controller contract.
60
+ function CONTROLLER() external view returns (IJBController);
61
+
62
+ /// @notice The directory of terminals and controllers for Juicebox projects.
63
+ /// @return The directory contract.
64
+ function DIRECTORY() external view returns (IJBDirectory);
65
+
66
+ /// @notice The contract that mints ERC-721s representing project ownership.
67
+ /// @return The projects contract.
68
+ function PROJECTS() external view returns (IJBProjects);
69
+
70
+ /// @notice The contract that stores Juicebox project access permissions.
71
+ /// @return The permissions contract.
72
+ function PERMISSIONS() external view returns (IJBPermissions);
73
+
74
+ /// @notice The cash out fee as a fraction out of `JBConstants.MAX_FEE`.
75
+ /// @return The fee value.
76
+ function FEE() external view returns (uint256);
77
+
78
+ /// @notice The default Uniswap pool fee tier for auto-configured buyback pools.
79
+ /// @return The fee tier (10_000 = 1%).
80
+ function DEFAULT_BUYBACK_POOL_FEE() external view returns (uint24);
81
+
82
+ /// @notice The default TWAP window for auto-configured buyback pools.
83
+ /// @return The TWAP window in seconds.
84
+ function DEFAULT_BUYBACK_TWAP_WINDOW() external view returns (uint32);
85
+
86
+ /// @notice The registry that deploys and tracks suckers for revnets.
87
+ /// @return The sucker registry contract.
88
+ function SUCKER_REGISTRY() external view returns (IJBSuckerRegistry);
89
+
90
+ /// @notice The Juicebox project ID of the revnet that receives cash out fees.
91
+ /// @return The fee revnet ID.
92
+ function FEE_REVNET_ID() external view returns (uint256);
93
+
94
+ /// @notice The croptop publisher revnets can use to publish ERC-721 posts to their tiered ERC-721 hooks.
95
+ /// @return The publisher contract.
96
+ function PUBLISHER() external view returns (CTPublisher);
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 (IJBRulesetDataHook);
101
+
102
+ /// @notice The deployer used to create tiered ERC-721 hooks for revnets.
103
+ /// @return The hook deployer contract.
104
+ function HOOK_DEPLOYER() external view returns (IJB721TiersHookDeployer);
105
+
106
+ /// @notice The loan contract used by all revnets.
107
+ /// @return The loans contract address.
108
+ function LOANS() external view returns (address);
109
+
110
+ /// @notice The number of revnet tokens that can be auto-minted for a beneficiary during a stage.
111
+ /// @param revnetId The ID of the revnet.
112
+ /// @param stageId The ID of the stage.
113
+ /// @param beneficiary The beneficiary of the auto-mint.
114
+ /// @return The number of tokens available to auto-issue.
115
+ function amountToAutoIssue(uint256 revnetId, uint256 stageId, address beneficiary) external view returns (uint256);
116
+
117
+ /// @notice The timestamp when cash outs become available for a revnet's participants.
118
+ /// @param revnetId The ID of the revnet.
119
+ /// @return The cash out delay timestamp.
120
+ function cashOutDelayOf(uint256 revnetId) external view returns (uint256);
121
+
122
+ /// @notice Deploy new suckers for an existing revnet.
123
+ /// @param revnetId The ID of the revnet to deploy suckers for.
124
+ /// @param suckerDeploymentConfiguration The suckers to set up for the revnet.
125
+ /// @return suckers The addresses of the deployed suckers.
126
+ function deploySuckersFor(
127
+ uint256 revnetId,
128
+ REVSuckerDeploymentConfig calldata suckerDeploymentConfiguration
129
+ )
130
+ external
131
+ returns (address[] memory suckers);
132
+
133
+ /// @notice The hashed encoded configuration of each revnet.
134
+ /// @param revnetId The ID of the revnet.
135
+ /// @return The hashed encoded configuration.
136
+ function hashedEncodedConfigurationOf(uint256 revnetId) external view returns (bytes32);
137
+
138
+ /// @notice Whether an address is a revnet's split operator.
139
+ /// @param revnetId The ID of the revnet.
140
+ /// @param addr The address to check.
141
+ /// @return A flag indicating whether the address is the revnet's split operator.
142
+ function isSplitOperatorOf(uint256 revnetId, address addr) external view returns (bool);
143
+
144
+ /// @notice Each revnet's tiered ERC-721 hook.
145
+ /// @param revnetId The ID of the revnet.
146
+ /// @return The tiered ERC-721 hook.
147
+ function tiered721HookOf(uint256 revnetId) external view returns (IJB721TiersHook);
148
+
149
+ /// @notice Auto-mint a revnet's tokens from a stage for a beneficiary.
150
+ /// @param revnetId The ID of the revnet to auto-mint tokens from.
151
+ /// @param stageId The ID of the stage auto-mint tokens are available from.
152
+ /// @param beneficiary The address to auto-mint tokens to.
153
+ function autoIssueFor(uint256 revnetId, uint256 stageId, address beneficiary) external;
154
+
155
+ /// @notice Deploy a revnet, or initialize an existing Juicebox project as a revnet.
156
+ /// @param revnetId The ID of the Juicebox project to initialize. Send 0 to deploy a new revnet.
157
+ /// @param configuration Core revnet configuration.
158
+ /// @param terminalConfigurations The terminals to set up for the revnet.
159
+ /// @param suckerDeploymentConfiguration The suckers to set up for cross-chain token transfers.
160
+ /// @return The ID of the newly created or initialized revnet.
161
+ function deployFor(
162
+ uint256 revnetId,
163
+ REVConfig memory configuration,
164
+ JBTerminalConfig[] memory terminalConfigurations,
165
+ REVSuckerDeploymentConfig memory suckerDeploymentConfiguration
166
+ )
167
+ external
168
+ returns (uint256);
169
+
170
+ /// @notice Deploy a revnet with tiered ERC-721s and optional croptop posting support.
171
+ /// @param revnetId The ID of the Juicebox project to initialize. Send 0 to deploy a new revnet.
172
+ /// @param configuration Core revnet configuration.
173
+ /// @param terminalConfigurations The terminals to set up for the revnet.
174
+ /// @param suckerDeploymentConfiguration The suckers to set up for cross-chain token transfers.
175
+ /// @param tiered721HookConfiguration How to set up the tiered ERC-721 hook.
176
+ /// @param allowedPosts Restrictions on which croptop posts are allowed on the revnet's ERC-721 tiers.
177
+ /// @return The ID of the newly created or initialized revnet.
178
+ /// @return hook The tiered ERC-721 hook that was deployed for the revnet.
179
+ function deployWith721sFor(
180
+ uint256 revnetId,
181
+ REVConfig calldata configuration,
182
+ JBTerminalConfig[] memory terminalConfigurations,
183
+ REVSuckerDeploymentConfig memory suckerDeploymentConfiguration,
184
+ REVDeploy721TiersHookConfig memory tiered721HookConfiguration,
185
+ REVCroptopAllowedPost[] memory allowedPosts
186
+ )
187
+ external
188
+ returns (uint256, IJB721TiersHook hook);
189
+
190
+ /// @notice Change a revnet's split operator. Only the current split operator can call this.
191
+ /// @param revnetId The ID of the revnet.
192
+ /// @param newSplitOperator The new split operator's address.
193
+ function setSplitOperatorOf(uint256 revnetId, address newSplitOperator) external;
194
+
195
+ /// @notice Burn any of a revnet's tokens held by this contract.
196
+ /// @param revnetId The ID of the revnet whose tokens should be burned.
197
+ function burnHeldTokensOf(uint256 revnetId) external;
198
+ }
@@ -0,0 +1,241 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {IPermit2} from "@uniswap/permit2/src/interfaces/IPermit2.sol";
5
+ import {IJBController} from "@bananapus/core-v6/src/interfaces/IJBController.sol";
6
+ import {IJBDirectory} from "@bananapus/core-v6/src/interfaces/IJBDirectory.sol";
7
+ import {IJBPayoutTerminal} from "@bananapus/core-v6/src/interfaces/IJBPayoutTerminal.sol";
8
+ import {IJBPrices} from "@bananapus/core-v6/src/interfaces/IJBPrices.sol";
9
+ import {IJBProjects} from "@bananapus/core-v6/src/interfaces/IJBProjects.sol";
10
+ import {IJBTokenUriResolver} from "@bananapus/core-v6/src/interfaces/IJBTokenUriResolver.sol";
11
+ import {JBSingleAllowance} from "@bananapus/core-v6/src/structs/JBSingleAllowance.sol";
12
+
13
+ import {REVLoan} from "./../structs/REVLoan.sol";
14
+ import {REVLoanSource} from "./../structs/REVLoanSource.sol";
15
+
16
+ interface IREVLoans {
17
+ event Borrow(
18
+ uint256 indexed loanId,
19
+ uint256 indexed revnetId,
20
+ REVLoan loan,
21
+ REVLoanSource source,
22
+ uint256 borrowAmount,
23
+ uint256 collateralCount,
24
+ uint256 sourceFeeAmount,
25
+ address payable beneficiary,
26
+ address caller
27
+ );
28
+ event Liquidate(uint256 indexed loanId, uint256 indexed revnetId, REVLoan loan, address caller);
29
+ event RepayLoan(
30
+ uint256 indexed loanId,
31
+ uint256 indexed revnetId,
32
+ uint256 indexed paidOffLoanId,
33
+ REVLoan loan,
34
+ REVLoan paidOffLoan,
35
+ uint256 repayBorrowAmount,
36
+ uint256 sourceFeeAmount,
37
+ uint256 collateralCountToReturn,
38
+ address payable beneficiary,
39
+ address caller
40
+ );
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
+
59
+ /// @notice The controller that manages revnets using this loans contract.
60
+ /// @return The controller contract.
61
+ function CONTROLLER() external view returns (IJBController);
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);
90
+
91
+ /// @notice The amount that can be borrowed from a revnet given a certain amount of collateral.
92
+ /// @param revnetId The ID of the revnet to check for borrowable assets from.
93
+ /// @param collateralCount The amount of collateral used to secure the loan.
94
+ /// @param decimals The decimals the resulting fixed point value will include.
95
+ /// @param currency The currency that the resulting amount should be in terms of.
96
+ /// @return The amount that can be borrowed from the revnet.
97
+ function borrowableAmountFrom(
98
+ uint256 revnetId,
99
+ uint256 collateralCount,
100
+ uint256 decimals,
101
+ uint256 currency
102
+ )
103
+ external
104
+ view
105
+ returns (uint256);
106
+
107
+ /// @notice Determines the source fee amount for a loan being paid off a certain amount.
108
+ /// @param loan The loan having its source fee amount determined.
109
+ /// @param amount The amount being paid off.
110
+ /// @return sourceFeeAmount The source fee amount for the loan.
111
+ function determineSourceFeeAmount(
112
+ REVLoan memory loan,
113
+ uint256 amount
114
+ )
115
+ external
116
+ view
117
+ returns (uint256 sourceFeeAmount);
118
+
119
+ /// @notice Whether a revnet currently has outstanding loans from the specified terminal in the specified token.
120
+ /// @param revnetId The ID of the revnet issuing the loan.
121
+ /// @param terminal The terminal that the loan is issued from.
122
+ /// @param token The token being loaned.
123
+ /// @return A flag indicating if the revnet has an active loan source.
124
+ function isLoanSourceOf(uint256 revnetId, IJBPayoutTerminal terminal, address token) external view returns (bool);
125
+
126
+ /// @notice Get a loan's details.
127
+ /// @param loanId The ID of the loan to retrieve.
128
+ /// @return The loan data.
129
+ function loanOf(uint256 loanId) external view returns (REVLoan memory);
130
+
131
+ /// @notice The sources of each revnet's loans.
132
+ /// @param revnetId The ID of the revnet to get the loan sources for.
133
+ /// @return The array of loan sources.
134
+ function loanSourcesOf(uint256 revnetId) external view returns (REVLoanSource[] memory);
135
+
136
+ /// @notice The number of loans that have been created for a revnet.
137
+ /// @param revnetId The ID of the revnet to get the loan count for.
138
+ /// @return The number of loans.
139
+ function numberOfLoansFor(uint256 revnetId) external view returns (uint256);
140
+
141
+ /// @notice The revnet ID for the loan with the provided loan ID.
142
+ /// @param loanId The loan ID to get the revnet ID of.
143
+ /// @return The ID of the revnet.
144
+ function revnetIdOfLoanWith(uint256 loanId) external view returns (uint256);
145
+
146
+ /// @notice The contract resolving each loan ID to its ERC-721 URI.
147
+ /// @return The token URI resolver.
148
+ function tokenUriResolver() external view returns (IJBTokenUriResolver);
149
+
150
+ /// @notice The total amount loaned out by a revnet from a specified terminal in a specified token.
151
+ /// @param revnetId The ID of the revnet issuing the loan.
152
+ /// @param terminal The terminal that the loan is issued from.
153
+ /// @param token The token being loaned.
154
+ /// @return The total amount borrowed.
155
+ function totalBorrowedFrom(
156
+ uint256 revnetId,
157
+ IJBPayoutTerminal terminal,
158
+ address token
159
+ )
160
+ external
161
+ view
162
+ returns (uint256);
163
+
164
+ /// @notice The total amount of collateral supporting a revnet's loans.
165
+ /// @param revnetId The ID of the revnet.
166
+ /// @return The total collateral count.
167
+ function totalCollateralOf(uint256 revnetId) external view returns (uint256);
168
+
169
+ /// @notice Open a loan by borrowing from a revnet. Collateral tokens are burned and only re-minted upon repayment.
170
+ /// @param revnetId The ID of the revnet being borrowed from.
171
+ /// @param source The source of the loan (terminal and token).
172
+ /// @param minBorrowAmount The minimum amount to borrow, denominated in the source's token.
173
+ /// @param collateralCount The amount of tokens to use as collateral for the loan.
174
+ /// @param beneficiary The address that will receive the borrowed funds and fee payment tokens.
175
+ /// @param prepaidFeePercent The fee percent to charge upfront, in terms of `JBConstants.MAX_FEE`.
176
+ /// @return loanId The ID of the loan created from borrowing.
177
+ /// @return The loan created from borrowing.
178
+ function borrowFrom(
179
+ uint256 revnetId,
180
+ REVLoanSource calldata source,
181
+ uint256 minBorrowAmount,
182
+ uint256 collateralCount,
183
+ address payable beneficiary,
184
+ uint256 prepaidFeePercent
185
+ )
186
+ external
187
+ returns (uint256 loanId, REVLoan memory);
188
+
189
+ /// @notice Liquidates loans that have exceeded the liquidation duration, permanently destroying their collateral.
190
+ /// @param revnetId The ID of the revnet to liquidate loans from.
191
+ /// @param startingLoanId The loan number to start iterating from.
192
+ /// @param count The number of loans to iterate over.
193
+ function liquidateExpiredLoansFrom(uint256 revnetId, uint256 startingLoanId, uint256 count) external;
194
+
195
+ /// @notice Repay a loan or return excess collateral no longer needed to support the loan.
196
+ /// @param loanId The ID of the loan being repaid.
197
+ /// @param maxRepayBorrowAmount The maximum amount to repay, denominated in the source's token.
198
+ /// @param collateralCountToReturn The amount of collateral to return from the loan.
199
+ /// @param beneficiary The address receiving the returned collateral and fee payment tokens.
200
+ /// @param allowance A permit2 allowance to facilitate the repayment transfer.
201
+ /// @return paidOffLoanId The ID of the loan after it has been paid off.
202
+ /// @return paidOffloan The loan after it has been paid off.
203
+ function repayLoan(
204
+ uint256 loanId,
205
+ uint256 maxRepayBorrowAmount,
206
+ uint256 collateralCountToReturn,
207
+ address payable beneficiary,
208
+ JBSingleAllowance calldata allowance
209
+ )
210
+ external
211
+ payable
212
+ returns (uint256 paidOffLoanId, REVLoan memory paidOffloan);
213
+
214
+ /// @notice Refinance a loan by transferring extra collateral from an existing loan to a new loan.
215
+ /// @param loanId The ID of the loan to reallocate collateral from.
216
+ /// @param collateralCountToTransfer The amount of collateral to transfer from the original loan.
217
+ /// @param source The source of the new loan (terminal and token). Must match the existing loan's source.
218
+ /// @param minBorrowAmount The minimum amount to borrow for the new loan.
219
+ /// @param collateralCountToAdd Additional collateral to add to the new loan from the caller's balance.
220
+ /// @param beneficiary The address that will receive the borrowed funds and fee payment tokens.
221
+ /// @param prepaidFeePercent The fee percent to charge upfront for the new loan.
222
+ /// @return reallocatedLoanId The ID of the reallocated (reduced) loan.
223
+ /// @return newLoanId The ID of the newly created loan.
224
+ /// @return reallocatedLoan The reallocated loan data.
225
+ /// @return newLoan The new loan data.
226
+ function reallocateCollateralFromLoan(
227
+ uint256 loanId,
228
+ uint256 collateralCountToTransfer,
229
+ REVLoanSource calldata source,
230
+ uint256 minBorrowAmount,
231
+ uint256 collateralCountToAdd,
232
+ address payable beneficiary,
233
+ uint256 prepaidFeePercent
234
+ )
235
+ external
236
+ returns (uint256 reallocatedLoanId, uint256 newLoanId, REVLoan memory reallocatedLoan, REVLoan memory newLoan);
237
+
238
+ /// @notice Sets the address of the resolver used to retrieve the token URI of loans.
239
+ /// @param resolver The new token URI resolver.
240
+ function setTokenUriResolver(IJBTokenUriResolver resolver) external;
241
+ }
@@ -0,0 +1,11 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ /// @custom:member chainId The ID of the chain on which the mint should be honored.
5
+ /// @custom:member count The number of tokens that should be minted.
6
+ /// @custom:member beneficiary The address that will receive the minted tokens.
7
+ struct REVAutoIssuance {
8
+ uint32 chainId;
9
+ uint104 count;
10
+ address beneficiary;
11
+ }
@@ -0,0 +1,17 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {REVDescription} from "./REVDescription.sol";
5
+ import {REVStageConfig} from "./REVStageConfig.sol";
6
+
7
+ /// @custom:member description The description of the revnet.
8
+ /// @custom:member baseCurrency The currency that the issuance is based on.
9
+ /// @custom:member splitOperator The address that will receive the token premint and initial production split,
10
+ /// and who is allowed to change who the operator is. Only the operator can replace itself after deployment.
11
+ /// @custom:member stageConfigurations The periods of changing constraints.
12
+ struct REVConfig {
13
+ REVDescription description;
14
+ uint32 baseCurrency;
15
+ address splitOperator;
16
+ REVStageConfig[] stageConfigurations;
17
+ }
@@ -0,0 +1,20 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ /// @notice Criteria for allowed posts.
5
+ /// @custom:member category A category that should allow posts.
6
+ /// @custom:member minimumPrice The minimum price that a post to the specified category should cost.
7
+ /// @custom:member minimumTotalSupply The minimum total supply of NFTs that can be made available when minting.
8
+ /// @custom:member maxTotalSupply The max total supply of NFTs that can be made available when minting. Leave as 0 for
9
+ /// max.
10
+ /// @custom:member maximumSplitPercent The maximum split percent (out of JBConstants.SPLITS_TOTAL_PERCENT) that a
11
+ /// poster can set. 0 means splits are not allowed.
12
+ /// @custom:member allowedAddresses A list of addresses that are allowed to post on the category through Croptop.
13
+ struct REVCroptopAllowedPost {
14
+ uint24 category;
15
+ uint104 minimumPrice;
16
+ uint32 minimumTotalSupply;
17
+ uint32 maximumTotalSupply;
18
+ uint32 maximumSplitPercent;
19
+ address[] allowedAddresses;
20
+ }
@@ -0,0 +1,25 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {JBDeploy721TiersHookConfig} from "@bananapus/721-hook-v6/src/structs/JBDeploy721TiersHookConfig.sol";
5
+
6
+ /// @custom:member baseline721HookConfiguration The baseline config.
7
+ /// @custom:member salt The salt to base the collection's address on.
8
+ /// @custom:member splitOperatorCanAdjustTiers A flag indicating if the revnet's split operator can add tiers and remove
9
+ /// tiers if
10
+ /// the tier is allowed to be removed
11
+ /// @custom:member splitOperatorCanUpdateMetadata A flag indicating if the revnet's split operator can update the 721's
12
+ /// metadata.
13
+ /// @custom:member splitOperatorCanMint A flag indicating if the revnet's split operator can mint 721's from tiers that
14
+ /// allow it.
15
+ /// @custom:member splitOperatorCanIncreaseDiscountPercent A flag indicating if the revnet's split operator can increase
16
+ /// the
17
+ /// discount of a tier.
18
+ struct REVDeploy721TiersHookConfig {
19
+ JBDeploy721TiersHookConfig baseline721HookConfiguration;
20
+ bytes32 salt;
21
+ bool splitOperatorCanAdjustTiers;
22
+ bool splitOperatorCanUpdateMetadata;
23
+ bool splitOperatorCanMint;
24
+ bool splitOperatorCanIncreaseDiscountPercent;
25
+ }
@@ -0,0 +1,14 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ /// @custom:member name The name of the ERC-20 token being create for the revnet.
5
+ /// @custom:member ticker The ticker of the ERC-20 token being created for the revnet.
6
+ /// @custom:member uri The metadata URI containing revnet's info.
7
+ /// @custom:member salt Revnets deployed across chains by the same address with the same salt will have the same
8
+ /// address.
9
+ struct REVDescription {
10
+ string name;
11
+ string ticker;
12
+ string uri;
13
+ bytes32 salt;
14
+ }
@@ -0,0 +1,19 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {REVLoanSource} from "./REVLoanSource.sol";
5
+
6
+ /// @custom:member borrowedAmount The amount that is being borrowed.
7
+ /// @custom:member collateralTokenCount The number of collateral tokens currently accounted for.
8
+ /// @custom:member createdAt The timestamp when the loan was created.
9
+ /// @custom:member prepaidFeePercent The percentage of the loan's fees that were prepaid.
10
+ /// @custom:member prepaidDuration The duration that the loan was prepaid for.
11
+ /// @custom:member source The source of the loan.
12
+ struct REVLoan {
13
+ uint112 amount;
14
+ uint112 collateral;
15
+ uint48 createdAt;
16
+ uint16 prepaidFeePercent;
17
+ uint32 prepaidDuration;
18
+ REVLoanSource source;
19
+ }
@@ -0,0 +1,11 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {IJBPayoutTerminal} from "@bananapus/core-v6/src/interfaces/IJBPayoutTerminal.sol";
5
+
6
+ /// @custom:member token The token that is being loaned.
7
+ /// @custom:member terminal The terminal that the loan is being made from.
8
+ struct REVLoanSource {
9
+ address token;
10
+ IJBPayoutTerminal terminal;
11
+ }
@@ -0,0 +1,34 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {JBSplit} from "@bananapus/core-v6/src/structs/JBSplit.sol";
5
+
6
+ import {REVAutoIssuance} from "./REVAutoIssuance.sol";
7
+
8
+ /// @custom:member startsAtOrAfter The timestamp to start a stage at the given rate at or after.
9
+ /// @custom:member autoIssuances The configurations of mints during this stage.
10
+ /// @custom:member splitPercent The percentage of newly issued tokens that should be split with the operator, out
11
+ /// of 10_000 (JBConstants.MAX_RESERVED_PERCENT).
12
+ /// @custom:member splits The splits for the revnet.
13
+ /// @custom:member initialIssuance The number of revnet tokens that one unit of the revnet's base currency will buy, as
14
+ /// a fixed point number
15
+ /// with 18 decimals.
16
+ /// @custom:member issuanceCutFrequency The number of seconds between applied issuance decreases. This
17
+ /// should be at least 24 hours.
18
+ /// @custom:member issuanceCutPercent The percent that issuance should decrease over time. This percentage is out
19
+ /// of 1_000_000_000 (JBConstants.MAX_CUT_PERCENT). 0% corresponds to no issuance increase.
20
+ /// @custom:member cashOutTaxRate The factor determining how much each token can cash out from the revnet once
21
+ /// cashed out. This rate is out of 10_000 (JBConstants.MAX_CASH_OUT_TAX_RATE). 0% corresponds to no tax when cashing
22
+ /// out.
23
+ /// @custom:member extraMetadata Extra info to attach set into this stage that may affect hooks.
24
+ struct REVStageConfig {
25
+ uint48 startsAtOrAfter;
26
+ REVAutoIssuance[] autoIssuances;
27
+ uint16 splitPercent;
28
+ JBSplit[] splits;
29
+ uint112 initialIssuance;
30
+ uint32 issuanceCutFrequency;
31
+ uint32 issuanceCutPercent;
32
+ uint16 cashOutTaxRate;
33
+ uint16 extraMetadata;
34
+ }
@@ -0,0 +1,11 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.0;
3
+
4
+ import {JBSuckerDeployerConfig} from "@bananapus/suckers-v6/src/structs/JBSuckerDeployerConfig.sol";
5
+
6
+ /// @custom:member deployerConfigurations The information for how to suck tokens to other chains.
7
+ /// @custom:member salt The salt to use for creating suckers so that they use the same address across chains.
8
+ struct REVSuckerDeploymentConfig {
9
+ JBSuckerDeployerConfig[] deployerConfigurations;
10
+ bytes32 salt;
11
+ }