@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.
- package/LICENSE +21 -0
- package/README.md +65 -0
- package/REVNET_SECURITY_CHECKLIST.md +164 -0
- package/SECURITY.md +68 -0
- package/SKILLS.md +166 -0
- package/deployments/revnet-core-v5/arbitrum/REVDeployer.json +2821 -0
- package/deployments/revnet-core-v5/arbitrum/REVLoans.json +2260 -0
- package/deployments/revnet-core-v5/arbitrum_sepolia/REVDeployer.json +2821 -0
- package/deployments/revnet-core-v5/arbitrum_sepolia/REVLoans.json +2260 -0
- package/deployments/revnet-core-v5/base/REVDeployer.json +2825 -0
- package/deployments/revnet-core-v5/base/REVLoans.json +2264 -0
- package/deployments/revnet-core-v5/base_sepolia/REVDeployer.json +2825 -0
- package/deployments/revnet-core-v5/base_sepolia/REVLoans.json +2264 -0
- package/deployments/revnet-core-v5/ethereum/REVDeployer.json +2825 -0
- package/deployments/revnet-core-v5/ethereum/REVLoans.json +2264 -0
- package/deployments/revnet-core-v5/optimism/REVDeployer.json +2821 -0
- package/deployments/revnet-core-v5/optimism/REVLoans.json +2260 -0
- package/deployments/revnet-core-v5/optimism_sepolia/REVDeployer.json +2825 -0
- package/deployments/revnet-core-v5/optimism_sepolia/REVLoans.json +2264 -0
- package/deployments/revnet-core-v5/sepolia/REVDeployer.json +2825 -0
- package/deployments/revnet-core-v5/sepolia/REVLoans.json +2264 -0
- package/docs/book.css +13 -0
- package/docs/book.toml +13 -0
- package/docs/solidity.min.js +74 -0
- package/docs/src/README.md +88 -0
- package/docs/src/SUMMARY.md +20 -0
- package/docs/src/src/README.md +7 -0
- package/docs/src/src/REVDeployer.sol/contract.REVDeployer.md +968 -0
- package/docs/src/src/REVLoans.sol/contract.REVLoans.md +1047 -0
- package/docs/src/src/interfaces/IREVDeployer.sol/interface.IREVDeployer.md +243 -0
- package/docs/src/src/interfaces/IREVLoans.sol/interface.IREVLoans.md +296 -0
- package/docs/src/src/interfaces/README.md +5 -0
- package/docs/src/src/structs/README.md +14 -0
- package/docs/src/src/structs/REVAutoIssuance.sol/struct.REVAutoIssuance.md +19 -0
- package/docs/src/src/structs/REVBuybackHookConfig.sol/struct.REVBuybackHookConfig.md +19 -0
- package/docs/src/src/structs/REVBuybackPoolConfig.sol/struct.REVBuybackPoolConfig.md +21 -0
- package/docs/src/src/structs/REVConfig.sol/struct.REVConfig.md +35 -0
- package/docs/src/src/structs/REVCroptopAllowedPost.sol/struct.REVCroptopAllowedPost.md +28 -0
- package/docs/src/src/structs/REVDeploy721TiersHookConfig.sol/struct.REVDeploy721TiersHookConfig.md +34 -0
- package/docs/src/src/structs/REVDescription.sol/struct.REVDescription.md +23 -0
- package/docs/src/src/structs/REVLoan.sol/struct.REVLoan.md +28 -0
- package/docs/src/src/structs/REVLoanSource.sol/struct.REVLoanSource.md +16 -0
- package/docs/src/src/structs/REVStageConfig.sol/struct.REVStageConfig.md +44 -0
- package/docs/src/src/structs/REVSuckerDeploymentConfig.sol/struct.REVSuckerDeploymentConfig.md +16 -0
- package/foundry.lock +11 -0
- package/foundry.toml +23 -0
- package/package.json +31 -0
- package/remappings.txt +1 -0
- package/script/Deploy.s.sol +350 -0
- package/script/helpers/RevnetCoreDeploymentLib.sol +72 -0
- package/slither-ci.config.json +10 -0
- package/sphinx.lock +507 -0
- package/src/REVDeployer.sol +1257 -0
- package/src/REVLoans.sol +1333 -0
- package/src/interfaces/IREVDeployer.sol +198 -0
- package/src/interfaces/IREVLoans.sol +241 -0
- package/src/structs/REVAutoIssuance.sol +11 -0
- package/src/structs/REVConfig.sol +17 -0
- package/src/structs/REVCroptopAllowedPost.sol +20 -0
- package/src/structs/REVDeploy721TiersHookConfig.sol +25 -0
- package/src/structs/REVDescription.sol +14 -0
- package/src/structs/REVLoan.sol +19 -0
- package/src/structs/REVLoanSource.sol +11 -0
- package/src/structs/REVStageConfig.sol +34 -0
- package/src/structs/REVSuckerDeploymentConfig.sol +11 -0
- package/test/REV.integrations.t.sol +420 -0
- package/test/REVAutoIssuanceFuzz.t.sol +276 -0
- package/test/REVDeployerAuditRegressions.t.sol +328 -0
- package/test/REVInvincibility.t.sol +1275 -0
- package/test/REVInvincibilityHandler.sol +357 -0
- package/test/REVLifecycle.t.sol +364 -0
- package/test/REVLoans.invariants.t.sol +642 -0
- package/test/REVLoansAttacks.t.sol +739 -0
- package/test/REVLoansAuditRegressions.t.sol +314 -0
- package/test/REVLoansFeeRecovery.t.sol +704 -0
- package/test/REVLoansSourced.t.sol +1732 -0
- package/test/REVLoansUnSourced.t.sol +331 -0
- package/test/TestPR09_ConversionDocumentation.t.sol +304 -0
- package/test/TestPR10_LiquidationBehavior.t.sol +340 -0
- package/test/TestPR11_LowFindings.t.sol +571 -0
- package/test/TestPR12_FlashLoanSurplus.t.sol +305 -0
- package/test/TestPR13_CrossSourceReallocation.t.sol +302 -0
- package/test/TestPR15_CashOutCallerValidation.t.sol +320 -0
- package/test/TestPR16_ZeroRepayment.t.sol +297 -0
- package/test/TestPR21_Uint112Overflow.t.sol +251 -0
- package/test/TestPR22_HookArrayOOB.t.sol +221 -0
- package/test/TestPR26_BurnHeldTokens.t.sol +331 -0
- package/test/TestPR27_CEIPattern.t.sol +448 -0
- package/test/TestPR29_SwapTerminalPermission.t.sol +206 -0
- package/test/TestPR32_MixedFixes.t.sol +529 -0
- package/test/helpers/MaliciousContracts.sol +233 -0
- package/test/mock/MockBuybackDataHook.sol +61 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.23;
|
|
3
|
+
|
|
4
|
+
import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
|
|
5
|
+
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
|
|
6
|
+
import {JBConstants} from "@bananapus/core-v6/src/libraries/JBConstants.sol";
|
|
7
|
+
import {JBAccountingContext} from "@bananapus/core-v6/src/structs/JBAccountingContext.sol";
|
|
8
|
+
import {IJBTerminal} from "@bananapus/core-v6/src/interfaces/IJBTerminal.sol";
|
|
9
|
+
import {IJBPayoutTerminal} from "@bananapus/core-v6/src/interfaces/IJBPayoutTerminal.sol";
|
|
10
|
+
import {IREVLoans} from "../../src/interfaces/IREVLoans.sol";
|
|
11
|
+
import {REVLoanSource} from "../../src/structs/REVLoanSource.sol";
|
|
12
|
+
|
|
13
|
+
/// @notice A terminal that reverts on both pay() and addToBalanceOf().
|
|
14
|
+
/// @dev Used to prove H-2: if the fee terminal breaks, cash-outs brick because
|
|
15
|
+
/// afterCashOutRecordedWith's fallback addToBalanceOf also reverts.
|
|
16
|
+
contract BrokenFeeTerminal is ERC165, IJBPayoutTerminal {
|
|
17
|
+
bool public payReverts = true;
|
|
18
|
+
bool public addToBalanceReverts = true;
|
|
19
|
+
|
|
20
|
+
function setPayReverts(bool _reverts) external {
|
|
21
|
+
payReverts = _reverts;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function setAddToBalanceReverts(bool _reverts) external {
|
|
25
|
+
addToBalanceReverts = _reverts;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function pay(
|
|
29
|
+
uint256,
|
|
30
|
+
address,
|
|
31
|
+
uint256,
|
|
32
|
+
address,
|
|
33
|
+
uint256,
|
|
34
|
+
string calldata,
|
|
35
|
+
bytes calldata
|
|
36
|
+
)
|
|
37
|
+
external
|
|
38
|
+
payable
|
|
39
|
+
override
|
|
40
|
+
returns (uint256)
|
|
41
|
+
{
|
|
42
|
+
if (payReverts) revert("BrokenFeeTerminal: pay reverts");
|
|
43
|
+
return 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function addToBalanceOf(
|
|
47
|
+
uint256,
|
|
48
|
+
address,
|
|
49
|
+
uint256,
|
|
50
|
+
bool,
|
|
51
|
+
string calldata,
|
|
52
|
+
bytes calldata
|
|
53
|
+
)
|
|
54
|
+
external
|
|
55
|
+
payable
|
|
56
|
+
override
|
|
57
|
+
{
|
|
58
|
+
if (addToBalanceReverts) revert("BrokenFeeTerminal: addToBalance reverts");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function accountingContextForTokenOf(uint256, address) external pure override returns (JBAccountingContext memory) {
|
|
62
|
+
return JBAccountingContext({
|
|
63
|
+
token: JBConstants.NATIVE_TOKEN, decimals: 18, currency: uint32(uint160(JBConstants.NATIVE_TOKEN))
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function accountingContextsOf(uint256) external pure override returns (JBAccountingContext[] memory) {
|
|
68
|
+
return new JBAccountingContext[](0);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function addAccountingContextsFor(uint256, JBAccountingContext[] calldata) external override {}
|
|
72
|
+
|
|
73
|
+
function currentSurplusOf(
|
|
74
|
+
uint256,
|
|
75
|
+
JBAccountingContext[] memory,
|
|
76
|
+
uint256,
|
|
77
|
+
uint256
|
|
78
|
+
)
|
|
79
|
+
external
|
|
80
|
+
pure
|
|
81
|
+
override
|
|
82
|
+
returns (uint256)
|
|
83
|
+
{
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function migrateBalanceOf(uint256, address, IJBTerminal) external pure override returns (uint256) {
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function sendPayoutsOf(uint256, address, uint256, uint256, uint256) external pure override returns (uint256) {
|
|
92
|
+
return 0;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function useAllowanceOf(
|
|
96
|
+
uint256,
|
|
97
|
+
address,
|
|
98
|
+
uint256,
|
|
99
|
+
uint256,
|
|
100
|
+
uint256,
|
|
101
|
+
address payable,
|
|
102
|
+
address payable,
|
|
103
|
+
string calldata
|
|
104
|
+
)
|
|
105
|
+
external
|
|
106
|
+
pure
|
|
107
|
+
override
|
|
108
|
+
returns (uint256)
|
|
109
|
+
{
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function supportsInterface(bytes4 interfaceId) public view override(ERC165, IERC165) returns (bool) {
|
|
114
|
+
return interfaceId == type(IJBTerminal).interfaceId || interfaceId == type(IJBPayoutTerminal).interfaceId
|
|
115
|
+
|| super.supportsInterface(interfaceId);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
receive() external payable {}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/// @notice A terminal that attempts to addToBalance + borrow in a single tx.
|
|
122
|
+
/// @dev Used to prove M-11: flash loan surplus inflation via live surplus read.
|
|
123
|
+
contract SurplusInflator is ERC165, IJBPayoutTerminal {
|
|
124
|
+
IREVLoans public loans;
|
|
125
|
+
uint256 public revnetId;
|
|
126
|
+
IJBPayoutTerminal public realTerminal;
|
|
127
|
+
bool public shouldInflate;
|
|
128
|
+
|
|
129
|
+
function configure(IREVLoans _loans, uint256 _revnetId, IJBPayoutTerminal _realTerminal) external {
|
|
130
|
+
loans = _loans;
|
|
131
|
+
revnetId = _revnetId;
|
|
132
|
+
realTerminal = _realTerminal;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function setShouldInflate(bool _should) external {
|
|
136
|
+
shouldInflate = _should;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function pay(
|
|
140
|
+
uint256,
|
|
141
|
+
address,
|
|
142
|
+
uint256,
|
|
143
|
+
address,
|
|
144
|
+
uint256,
|
|
145
|
+
string calldata,
|
|
146
|
+
bytes calldata
|
|
147
|
+
)
|
|
148
|
+
external
|
|
149
|
+
payable
|
|
150
|
+
override
|
|
151
|
+
returns (uint256)
|
|
152
|
+
{
|
|
153
|
+
if (shouldInflate) {
|
|
154
|
+
shouldInflate = false;
|
|
155
|
+
// Try to borrow at the inflated surplus
|
|
156
|
+
REVLoanSource memory source = REVLoanSource({token: JBConstants.NATIVE_TOKEN, terminal: realTerminal});
|
|
157
|
+
try loans.borrowFrom(revnetId, source, 0, 1e18, payable(address(this)), 25) {} catch {}
|
|
158
|
+
}
|
|
159
|
+
return 0;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function addToBalanceOf(
|
|
163
|
+
uint256,
|
|
164
|
+
address,
|
|
165
|
+
uint256,
|
|
166
|
+
bool,
|
|
167
|
+
string calldata,
|
|
168
|
+
bytes calldata
|
|
169
|
+
)
|
|
170
|
+
external
|
|
171
|
+
payable
|
|
172
|
+
override
|
|
173
|
+
{}
|
|
174
|
+
|
|
175
|
+
function accountingContextForTokenOf(uint256, address) external pure override returns (JBAccountingContext memory) {
|
|
176
|
+
return JBAccountingContext({
|
|
177
|
+
token: JBConstants.NATIVE_TOKEN, decimals: 18, currency: uint32(uint160(JBConstants.NATIVE_TOKEN))
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function accountingContextsOf(uint256) external pure override returns (JBAccountingContext[] memory) {
|
|
182
|
+
return new JBAccountingContext[](0);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function addAccountingContextsFor(uint256, JBAccountingContext[] calldata) external override {}
|
|
186
|
+
|
|
187
|
+
function currentSurplusOf(
|
|
188
|
+
uint256,
|
|
189
|
+
JBAccountingContext[] memory,
|
|
190
|
+
uint256,
|
|
191
|
+
uint256
|
|
192
|
+
)
|
|
193
|
+
external
|
|
194
|
+
pure
|
|
195
|
+
override
|
|
196
|
+
returns (uint256)
|
|
197
|
+
{
|
|
198
|
+
return 0;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function migrateBalanceOf(uint256, address, IJBTerminal) external pure override returns (uint256) {
|
|
202
|
+
return 0;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function sendPayoutsOf(uint256, address, uint256, uint256, uint256) external pure override returns (uint256) {
|
|
206
|
+
return 0;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function useAllowanceOf(
|
|
210
|
+
uint256,
|
|
211
|
+
address,
|
|
212
|
+
uint256,
|
|
213
|
+
uint256,
|
|
214
|
+
uint256,
|
|
215
|
+
address payable,
|
|
216
|
+
address payable,
|
|
217
|
+
string calldata
|
|
218
|
+
)
|
|
219
|
+
external
|
|
220
|
+
pure
|
|
221
|
+
override
|
|
222
|
+
returns (uint256)
|
|
223
|
+
{
|
|
224
|
+
return 0;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function supportsInterface(bytes4 interfaceId) public view override(ERC165, IERC165) returns (bool) {
|
|
228
|
+
return interfaceId == type(IJBTerminal).interfaceId || interfaceId == type(IJBPayoutTerminal).interfaceId
|
|
229
|
+
|| super.supportsInterface(interfaceId);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
receive() external payable {}
|
|
233
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.23;
|
|
3
|
+
|
|
4
|
+
import {IJBRulesetDataHook} from "@bananapus/core-v6/src/interfaces/IJBRulesetDataHook.sol";
|
|
5
|
+
import {IJBPayHook} from "@bananapus/core-v6/src/interfaces/IJBPayHook.sol";
|
|
6
|
+
import {IJBBuybackHook} from "@bananapus/buyback-hook-v6/src/interfaces/IJBBuybackHook.sol";
|
|
7
|
+
import {JBBeforePayRecordedContext} from "@bananapus/core-v6/src/structs/JBBeforePayRecordedContext.sol";
|
|
8
|
+
import {JBBeforeCashOutRecordedContext} from "@bananapus/core-v6/src/structs/JBBeforeCashOutRecordedContext.sol";
|
|
9
|
+
import {JBPayHookSpecification} from "@bananapus/core-v6/src/structs/JBPayHookSpecification.sol";
|
|
10
|
+
import {JBCashOutHookSpecification} from "@bananapus/core-v6/src/structs/JBCashOutHookSpecification.sol";
|
|
11
|
+
import {JBAfterPayRecordedContext} from "@bananapus/core-v6/src/structs/JBAfterPayRecordedContext.sol";
|
|
12
|
+
import {JBRuleset} from "@bananapus/core-v6/src/structs/JBRuleset.sol";
|
|
13
|
+
import {IUniswapV3Pool} from "@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol";
|
|
14
|
+
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
|
|
15
|
+
|
|
16
|
+
/// @notice A minimal mock buyback data hook for tests. Returns the default weight and a no-op pay hook specification.
|
|
17
|
+
contract MockBuybackDataHook is IJBRulesetDataHook, IJBPayHook {
|
|
18
|
+
function beforePayRecordedWith(JBBeforePayRecordedContext calldata context)
|
|
19
|
+
external
|
|
20
|
+
view
|
|
21
|
+
override
|
|
22
|
+
returns (uint256 weight, JBPayHookSpecification[] memory hookSpecifications)
|
|
23
|
+
{
|
|
24
|
+
weight = context.weight;
|
|
25
|
+
hookSpecifications = new JBPayHookSpecification[](1);
|
|
26
|
+
hookSpecifications[0] = JBPayHookSpecification({hook: IJBPayHook(address(this)), amount: 0, metadata: ""});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function beforeCashOutRecordedWith(JBBeforeCashOutRecordedContext calldata context)
|
|
30
|
+
external
|
|
31
|
+
view
|
|
32
|
+
override
|
|
33
|
+
returns (
|
|
34
|
+
uint256 cashOutTaxRate,
|
|
35
|
+
uint256 cashOutCount,
|
|
36
|
+
uint256 totalSupply,
|
|
37
|
+
JBCashOutHookSpecification[] memory hookSpecifications
|
|
38
|
+
)
|
|
39
|
+
{
|
|
40
|
+
cashOutTaxRate = context.cashOutTaxRate;
|
|
41
|
+
cashOutCount = context.cashOutCount;
|
|
42
|
+
totalSupply = context.totalSupply;
|
|
43
|
+
hookSpecifications = new JBCashOutHookSpecification[](0);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function hasMintPermissionFor(uint256, JBRuleset calldata, address) external pure override returns (bool) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function afterPayRecordedWith(JBAfterPayRecordedContext calldata) external payable override {}
|
|
51
|
+
|
|
52
|
+
/// @notice No-op pool configuration for tests.
|
|
53
|
+
function setPoolFor(uint256, uint24, uint256, address) external pure returns (IUniswapV3Pool) {
|
|
54
|
+
return IUniswapV3Pool(address(0));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
|
|
58
|
+
return interfaceId == type(IJBRulesetDataHook).interfaceId || interfaceId == type(IJBPayHook).interfaceId
|
|
59
|
+
|| interfaceId == type(IERC165).interfaceId;
|
|
60
|
+
}
|
|
61
|
+
}
|