@rev-net/core-v6 0.0.9 → 0.0.11
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/ARCHITECTURE.md +1 -1
- package/README.md +4 -4
- package/SKILLS.md +2 -8
- package/STYLE_GUIDE.md +127 -51
- package/docs/src/README.md +2 -2
- package/foundry.toml +3 -0
- package/package.json +12 -9
- package/remappings.txt +1 -1
- package/script/Deploy.s.sol +1 -1
- package/script/helpers/RevnetCoreDeploymentLib.sol +1 -1
- package/src/REVDeployer.sol +30 -26
- package/src/REVLoans.sol +1 -0
- package/test/{REVDeployerAuditRegressions.t.sol → REVDeployerRegressions.t.sol} +1 -1
- package/test/REVInvincibility.t.sol +15 -19
- package/test/REVLifecycle.t.sol +0 -1
- package/test/REVLoansAttacks.t.sol +3 -7
- package/test/REVLoansFeeRecovery.t.sol +0 -2
- package/test/{REVLoans_AuditFindings.t.sol → REVLoansFindings.t.sol} +6 -6
- package/test/{REVLoansAuditRegressions.t.sol → REVLoansRegressions.t.sol} +2 -2
- package/test/REVLoansSourced.t.sol +3 -1
- package/test/{TestPR26_BurnHeldTokens.t.sol → TestBurnHeldTokens.t.sol} +1 -1
- package/test/{TestPR27_CEIPattern.t.sol → TestCEIPattern.t.sol} +3 -3
- package/test/{TestPR15_CashOutCallerValidation.t.sol → TestCashOutCallerValidation.t.sol} +1 -3
- package/test/{TestPR09_ConversionDocumentation.t.sol → TestConversionDocumentation.t.sol} +1 -1
- package/test/{TestPR13_CrossSourceReallocation.t.sol → TestCrossSourceReallocation.t.sol} +1 -1
- package/test/{TestPR12_FlashLoanSurplus.t.sol → TestFlashLoanSurplus.t.sol} +1 -1
- package/test/{TestPR22_HookArrayOOB.t.sol → TestHookArrayOOB.t.sol} +1 -1
- package/test/{TestPR10_LiquidationBehavior.t.sol → TestLiquidationBehavior.t.sol} +4 -4
- package/test/{TestPR11_LowFindings.t.sol → TestLowFindings.t.sol} +1 -1
- package/test/{TestPR32_MixedFixes.t.sol → TestMixedFixes.t.sol} +1 -1
- package/test/TestSplitWeightFork.t.sol +118 -159
- package/test/{TestPR29_SwapTerminalPermission.t.sol → TestSwapTerminalPermission.t.sol} +1 -1
- package/test/{TestPR21_Uint112Overflow.t.sol → TestUint112Overflow.t.sol} +4 -4
- package/test/{TestPR16_ZeroRepayment.t.sol → TestZeroRepayment.t.sol} +4 -6
- package/test/fork/ForkTestBase.sol +83 -51
- package/test/fork/TestCashOutFork.t.sol +12 -11
- package/test/fork/TestLoanBorrowFork.t.sol +10 -12
- package/test/fork/TestLoanCrossRulesetFork.t.sol +300 -0
- package/test/fork/TestLoanLiquidationFork.t.sol +13 -8
- package/test/fork/TestLoanReallocateFork.t.sol +21 -12
- package/test/fork/TestLoanRepayFork.t.sol +17 -14
- package/test/fork/TestSplitWeightFork.t.sol +34 -34
- package/test/mock/MockBuybackDataHook.sol +4 -7
- package/test/mock/MockBuybackDataHookMintPath.sol +5 -8
- package/test/regression/{TestI20_CumulativeLoanCounter.t.sol → TestCumulativeLoanCounter.t.sol} +4 -4
- package/test/regression/{TestL27_LiquidateGapHandling.t.sol → TestLiquidateGapHandling.t.sol} +3 -3
package/ARCHITECTURE.md
CHANGED
|
@@ -26,7 +26,7 @@ Deployer → REVDeployer.deployFor()
|
|
|
26
26
|
→ Each stage: duration, weight, cashOutTaxRate, splits
|
|
27
27
|
→ Auto-issuance: pre-mint tokens to specified beneficiaries per chain
|
|
28
28
|
→ Set REVDeployer as data hook (controls pay + cashout behavior)
|
|
29
|
-
→
|
|
29
|
+
→ Initialize buyback pools at 1:1 price, configure buyback hook
|
|
30
30
|
→ Deploy suckers for cross-chain operation
|
|
31
31
|
→ Deploy 721 tiers if specified
|
|
32
32
|
→ Compute matching hash for cross-chain deployment verification
|
package/README.md
CHANGED
|
@@ -16,9 +16,9 @@ Revnets are autonomous Juicebox projects with predetermined economic stages. Eac
|
|
|
16
16
|
|
|
17
17
|
```
|
|
18
18
|
1. Deploy revnet with stage configurations
|
|
19
|
-
→ REVDeployer.deployFor(revnetId=0, config, terminals,
|
|
19
|
+
→ REVDeployer.deployFor(revnetId=0, config, terminals, suckerConfig)
|
|
20
20
|
→ Creates Juicebox project owned by REVDeployer (permanently)
|
|
21
|
-
→ Deploys ERC-20 token,
|
|
21
|
+
→ Deploys ERC-20 token, initializes buyback pools at 1:1 price, deploys suckers
|
|
22
22
|
|
|
|
23
23
|
2. Stage 1 begins (startsAtOrAfter or block.timestamp)
|
|
24
24
|
→ Tokens issued at initialIssuance rate per unit of base currency
|
|
@@ -125,13 +125,13 @@ test/
|
|
|
125
125
|
REVAutoIssuanceFuzz.t.sol # Auto-issuance fuzz tests
|
|
126
126
|
REVInvincibility.t.sol # Economic property fuzzing
|
|
127
127
|
REVInvincibilityHandler.sol # Fuzz handler
|
|
128
|
-
|
|
128
|
+
REVDeployerRegressions.t.sol # Deployer regressions
|
|
129
129
|
REVLoansSourced.t.sol # Multi-source loan tests
|
|
130
130
|
REVLoansUnSourced.t.sol # Loan error cases
|
|
131
131
|
REVLoansFeeRecovery.t.sol # Fee calculation tests
|
|
132
132
|
REVLoansAttacks.t.sol # Flash loan, reentrancy scenarios
|
|
133
133
|
REVLoans.invariants.t.sol # Loan fuzzing invariants
|
|
134
|
-
|
|
134
|
+
REVLoansRegressions.t.sol # Loan regressions
|
|
135
135
|
TestPR09-32_*.t.sol # Per-PR regression tests
|
|
136
136
|
helpers/
|
|
137
137
|
MaliciousContracts.sol # Attack contract mocks
|
package/SKILLS.md
CHANGED
|
@@ -17,8 +17,8 @@ Deploy and manage Revnets -- autonomous, unowned Juicebox projects with staged i
|
|
|
17
17
|
|
|
18
18
|
| Function | What it does |
|
|
19
19
|
|----------|-------------|
|
|
20
|
-
| `REVDeployer.deployFor(revnetId, config, terminals,
|
|
21
|
-
| `REVDeployer.deployWith721sFor(revnetId, config, terminals,
|
|
20
|
+
| `REVDeployer.deployFor(revnetId, config, terminals, suckerConfig)` | Deploy a new revnet (`revnetId=0`) or convert an existing Juicebox project. Encodes stage configs into rulesets, deploys ERC-20 token, initializes buyback pool at 1:1 price, sets up split operator, suckers, and loans permissions. |
|
|
21
|
+
| `REVDeployer.deployWith721sFor(revnetId, config, terminals, suckerConfig, hookConfig, allowedPosts)` | Same as `deployFor` but also deploys a tiered ERC-721 hook. Optionally configures Croptop posting criteria and grants publisher permission to add tiers. |
|
|
22
22
|
| `REVDeployer.deploySuckersFor(revnetId, suckerConfig)` | Deploy new cross-chain suckers post-launch. Split operator only. Validates ruleset allows sucker deployment (bit 2 of `extraMetadata`). Uses stored config hash for cross-chain matching. |
|
|
23
23
|
|
|
24
24
|
### Data Hooks
|
|
@@ -187,7 +187,6 @@ JBAccountingContext({
|
|
|
187
187
|
import {REVConfig} from "@rev-net/core-v6/src/structs/REVConfig.sol";
|
|
188
188
|
import {REVStageConfig} from "@rev-net/core-v6/src/structs/REVStageConfig.sol";
|
|
189
189
|
import {REVDescription} from "@rev-net/core-v6/src/structs/REVDescription.sol";
|
|
190
|
-
import {REVBuybackHookConfig} from "@rev-net/core-v6/src/structs/REVBuybackHookConfig.sol";
|
|
191
190
|
import {REVSuckerDeploymentConfig} from "@rev-net/core-v6/src/structs/REVSuckerDeploymentConfig.sol";
|
|
192
191
|
import {IREVDeployer} from "@rev-net/core-v6/src/interfaces/IREVDeployer.sol";
|
|
193
192
|
|
|
@@ -224,11 +223,6 @@ deployer.deployFor({
|
|
|
224
223
|
revnetId: 0, // 0 = deploy new
|
|
225
224
|
configuration: config,
|
|
226
225
|
terminalConfigurations: terminals,
|
|
227
|
-
buybackHookConfiguration: REVBuybackHookConfig({
|
|
228
|
-
dataHook: IJBRulesetDataHook(address(0)),
|
|
229
|
-
hookToConfigure: IJBBuybackHook(address(0)),
|
|
230
|
-
poolConfigurations: new REVBuybackPoolConfig[](0)
|
|
231
|
-
}),
|
|
232
226
|
suckerDeploymentConfiguration: REVSuckerDeploymentConfig({
|
|
233
227
|
deployerConfigurations: new JBSuckerDeployerConfig[](0),
|
|
234
228
|
salt: bytes32(0)
|
package/STYLE_GUIDE.md
CHANGED
|
@@ -17,8 +17,6 @@ src/
|
|
|
17
17
|
|
|
18
18
|
One contract/interface/struct/enum per file. Name the file after the type it contains.
|
|
19
19
|
|
|
20
|
-
**Structs, enums, libraries, and interfaces always go in their subdirectories** (`src/structs/`, `src/enums/`, `src/libraries/`, `src/interfaces/`) — never inline in contract files or placed in `src/` root. This keeps type definitions discoverable and import paths consistent across repos.
|
|
21
|
-
|
|
22
20
|
## Pragma Versions
|
|
23
21
|
|
|
24
22
|
```solidity
|
|
@@ -106,14 +104,6 @@ contract JBExample is JBPermissioned, IJBExample {
|
|
|
106
104
|
// -------------------------- constructor ---------------------------- //
|
|
107
105
|
//*********************************************************************//
|
|
108
106
|
|
|
109
|
-
//*********************************************************************//
|
|
110
|
-
// ---------------------- receive / fallback ------------------------- //
|
|
111
|
-
//*********************************************************************//
|
|
112
|
-
|
|
113
|
-
//*********************************************************************//
|
|
114
|
-
// --------------------------- modifiers ----------------------------- //
|
|
115
|
-
//*********************************************************************//
|
|
116
|
-
|
|
117
107
|
//*********************************************************************//
|
|
118
108
|
// ---------------------- external transactions ---------------------- //
|
|
119
109
|
//*********************************************************************//
|
|
@@ -141,28 +131,23 @@ contract JBExample is JBPermissioned, IJBExample {
|
|
|
141
131
|
```
|
|
142
132
|
|
|
143
133
|
**Section order:**
|
|
144
|
-
1.
|
|
145
|
-
2.
|
|
146
|
-
3.
|
|
147
|
-
4.
|
|
148
|
-
5.
|
|
149
|
-
6.
|
|
150
|
-
7.
|
|
151
|
-
8.
|
|
152
|
-
9.
|
|
153
|
-
10.
|
|
154
|
-
11.
|
|
155
|
-
12.
|
|
156
|
-
13.
|
|
157
|
-
14.
|
|
158
|
-
15. Internal helpers
|
|
159
|
-
16. Internal views
|
|
160
|
-
17. Private helpers
|
|
134
|
+
1. Custom errors
|
|
135
|
+
2. Public constants
|
|
136
|
+
3. Internal constants
|
|
137
|
+
4. Public immutable stored properties
|
|
138
|
+
5. Internal immutable stored properties
|
|
139
|
+
6. Public stored properties
|
|
140
|
+
7. Internal stored properties
|
|
141
|
+
8. Constructor
|
|
142
|
+
9. External transactions
|
|
143
|
+
10. External views
|
|
144
|
+
11. Public transactions
|
|
145
|
+
12. Internal helpers
|
|
146
|
+
13. Internal views
|
|
147
|
+
14. Private helpers
|
|
161
148
|
|
|
162
149
|
Functions are alphabetized within each section.
|
|
163
150
|
|
|
164
|
-
**Events:** Events are declared in interfaces only, never in implementation contracts. Implementations inherit events from their interface and emit them unqualified. This keeps the ABI definition in one place and allows tests to use interface-qualified event expectations (e.g., `emit IJBController.LaunchProject(...)`).
|
|
165
|
-
|
|
166
151
|
## Interface Structure
|
|
167
152
|
|
|
168
153
|
```solidity
|
|
@@ -334,9 +319,6 @@ optimizer_runs = 200
|
|
|
334
319
|
libs = ["node_modules", "lib"]
|
|
335
320
|
fs_permissions = [{ access = "read-write", path = "./"}]
|
|
336
321
|
|
|
337
|
-
[profile.ci_sizes]
|
|
338
|
-
optimizer_runs = 200
|
|
339
|
-
|
|
340
322
|
[fuzz]
|
|
341
323
|
runs = 4096
|
|
342
324
|
|
|
@@ -351,13 +333,13 @@ multiline_func_header = "all"
|
|
|
351
333
|
wrap_comments = true
|
|
352
334
|
```
|
|
353
335
|
|
|
354
|
-
**
|
|
355
|
-
- `
|
|
356
|
-
- `via_ir = true` for repos hitting stack-too-deep (buyback-hook, banny-retail, univ4-lp-split-hook, deploy-all)
|
|
357
|
-
- `optimizer = false` only for deploy-all-v6 (stack-too-deep with optimization)
|
|
358
|
-
- `lint_on_build = false` for repos that depend on packages with test helpers using bare `src/` imports (solar linter can't resolve cross-package). Run `forge lint src/` explicitly.
|
|
336
|
+
**Optional sections (add only when needed):**
|
|
337
|
+
- `[rpc_endpoints]` — repos with fork tests. Maps named endpoints to env vars (e.g. `ethereum = "${RPC_ETHEREUM_MAINNET}"`).
|
|
359
338
|
|
|
360
|
-
|
|
339
|
+
**Common variations:**
|
|
340
|
+
- `via_ir = true` when hitting stack-too-deep
|
|
341
|
+
- `optimizer = false` when optimization causes stack-too-deep
|
|
342
|
+
- `optimizer_runs` reduced when deep struct nesting causes stack-too-deep at 200 runs
|
|
361
343
|
|
|
362
344
|
### CI Workflows
|
|
363
345
|
|
|
@@ -390,7 +372,7 @@ jobs:
|
|
|
390
372
|
env:
|
|
391
373
|
RPC_ETHEREUM_MAINNET: ${{ secrets.RPC_ETHEREUM_MAINNET }}
|
|
392
374
|
- name: Check contract sizes
|
|
393
|
-
run:
|
|
375
|
+
run: forge build --sizes --skip "*/test/**" --skip "*/script/**" --skip SphinxUtils
|
|
394
376
|
```
|
|
395
377
|
|
|
396
378
|
**lint.yml:**
|
|
@@ -412,6 +394,55 @@ jobs:
|
|
|
412
394
|
run: forge fmt --check
|
|
413
395
|
```
|
|
414
396
|
|
|
397
|
+
**slither.yml** (repos with `src/` contracts only):
|
|
398
|
+
```yaml
|
|
399
|
+
name: slither
|
|
400
|
+
on:
|
|
401
|
+
pull_request:
|
|
402
|
+
branches:
|
|
403
|
+
- main
|
|
404
|
+
push:
|
|
405
|
+
branches:
|
|
406
|
+
- main
|
|
407
|
+
jobs:
|
|
408
|
+
analyze:
|
|
409
|
+
runs-on: ubuntu-latest
|
|
410
|
+
steps:
|
|
411
|
+
- uses: actions/checkout@v4
|
|
412
|
+
with:
|
|
413
|
+
submodules: recursive
|
|
414
|
+
- uses: actions/setup-node@v4
|
|
415
|
+
with:
|
|
416
|
+
node-version: latest
|
|
417
|
+
- name: Install npm dependencies
|
|
418
|
+
run: npm install --omit=dev
|
|
419
|
+
- name: Install Foundry
|
|
420
|
+
uses: foundry-rs/foundry-toolchain@v1
|
|
421
|
+
- name: Run slither
|
|
422
|
+
uses: crytic/slither-action@v0.3.1
|
|
423
|
+
with:
|
|
424
|
+
slither-config: slither-ci.config.json
|
|
425
|
+
fail-on: medium
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
**slither-ci.config.json:**
|
|
429
|
+
```json
|
|
430
|
+
{
|
|
431
|
+
"detectors_to_exclude": "timestamp,uninitialized-local,naming-convention,solc-version,shadowing-local",
|
|
432
|
+
"exclude_informational": true,
|
|
433
|
+
"exclude_low": false,
|
|
434
|
+
"exclude_medium": false,
|
|
435
|
+
"exclude_high": false,
|
|
436
|
+
"disable_color": false,
|
|
437
|
+
"filter_paths": "(mocks/|test/|node_modules/|lib/)",
|
|
438
|
+
"legacy_ast": false
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
**Variations:**
|
|
443
|
+
- Deployer-only repos (no `src/`, only `script/`) skip slither entirely — the action's internal `forge build` skips `test/` and `script/` by default, leaving nothing to compile.
|
|
444
|
+
- Use inline `// slither-disable-next-line <detector>` to suppress known false positives rather than adding to `detectors_to_exclude` in the config. The comment must be on the line immediately before the flagged expression.
|
|
445
|
+
|
|
415
446
|
### package.json
|
|
416
447
|
|
|
417
448
|
```json
|
|
@@ -436,13 +467,62 @@ jobs:
|
|
|
436
467
|
|
|
437
468
|
### remappings.txt
|
|
438
469
|
|
|
439
|
-
Every repo has a `remappings.txt
|
|
470
|
+
Every repo has a `remappings.txt` as the **single source of truth** for import remappings. Never add remappings to `foundry.toml`.
|
|
471
|
+
|
|
472
|
+
**Principle:** Import paths in Solidity source must match npm package names exactly. With `libs = ["node_modules", "lib"]`, Foundry auto-resolves `@scope/package/path/File.sol` → `node_modules/@scope/package/path/File.sol`. No remapping needed for packages installed as real directories.
|
|
473
|
+
|
|
474
|
+
**Note:** Auto-resolution does **not** work for symlinked packages (e.g. npm workspace links). Workspace repos like `deploy-all-v6` and `nana-cli-v6` need explicit `@scope/package/=node_modules/@scope/package/` remappings for each symlinked dependency.
|
|
475
|
+
|
|
476
|
+
**Minimal content** (most repos):
|
|
477
|
+
|
|
478
|
+
```
|
|
479
|
+
forge-std/=lib/forge-std/src/
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
Only add extra remappings for:
|
|
483
|
+
- **`forge-std`** — always needed (git submodule with `src/` subdirectory)
|
|
484
|
+
- **Repo-specific `lib/` submodules** that have no npm package (e.g., `hookmate/=lib/hookmate/src/`)
|
|
485
|
+
- **Symlinked npm packages** — need explicit `@scope/package/=node_modules/@scope/package/` entries
|
|
486
|
+
- **Nested transitive deps** — e.g., `@chainlink/contracts-ccip/` nested inside `@bananapus/suckers-v6/node_modules/`
|
|
487
|
+
|
|
488
|
+
**Never add remappings for:**
|
|
489
|
+
- npm packages that match their import path and are installed as real directories — they auto-resolve
|
|
490
|
+
- Short-form aliases (e.g., `@bananapus/core/` → `@bananapus/core-v6/src/`) — fix the import instead
|
|
491
|
+
- Packages available via npm that are also git submodules — remove the submodule, use npm
|
|
492
|
+
|
|
493
|
+
**Import path convention:**
|
|
494
|
+
|
|
495
|
+
| Package | Import path | Resolves to |
|
|
496
|
+
|---------|------------|-------------|
|
|
497
|
+
| `@bananapus/core-v6` | `@bananapus/core-v6/src/libraries/JBConstants.sol` | `node_modules/@bananapus/core-v6/src/...` |
|
|
498
|
+
| `@openzeppelin/contracts` | `@openzeppelin/contracts/token/ERC20/IERC20.sol` | `node_modules/@openzeppelin/contracts/...` |
|
|
499
|
+
| `@uniswap/v4-core` | `@uniswap/v4-core/src/interfaces/IPoolManager.sol` | `node_modules/@uniswap/v4-core/src/...` |
|
|
440
500
|
|
|
501
|
+
### Linting
|
|
502
|
+
|
|
503
|
+
Solar (Foundry's built-in linter) runs automatically during `forge build`. It scans all `.sol` files in `libs` directories, including `node_modules`.
|
|
504
|
+
|
|
505
|
+
**All test helpers must use relative imports** (e.g. `../../src/structs/JBRuleset.sol`), not bare `src/` imports. This ensures solar can resolve paths when the helper is consumed via npm in downstream repos.
|
|
506
|
+
|
|
507
|
+
### Fork Tests
|
|
508
|
+
|
|
509
|
+
Fork tests use named RPC endpoints defined in `[rpc_endpoints]` of `foundry.toml`. No skip guards — fork tests should hard-fail if the RPC endpoint is unavailable, making CI failures explicit.
|
|
510
|
+
|
|
511
|
+
```solidity
|
|
512
|
+
function setUp() public {
|
|
513
|
+
vm.createSelectFork("ethereum");
|
|
514
|
+
// ... setup code
|
|
515
|
+
}
|
|
441
516
|
```
|
|
442
|
-
|
|
517
|
+
|
|
518
|
+
The endpoint name (e.g. `"ethereum"`) maps to an env var via `foundry.toml`:
|
|
519
|
+
|
|
520
|
+
```toml
|
|
521
|
+
[rpc_endpoints]
|
|
522
|
+
ethereum = "${RPC_ETHEREUM_MAINNET}"
|
|
443
523
|
```
|
|
444
524
|
|
|
445
|
-
|
|
525
|
+
For multi-chain fork tests, add all needed endpoints.
|
|
446
526
|
|
|
447
527
|
### Formatting
|
|
448
528
|
|
|
@@ -453,15 +533,6 @@ Run `forge fmt` before committing. The `[fmt]` config in `foundry.toml` enforces
|
|
|
453
533
|
|
|
454
534
|
CI checks formatting via `forge fmt --check`.
|
|
455
535
|
|
|
456
|
-
### CI Secrets
|
|
457
|
-
|
|
458
|
-
| Secret | Purpose |
|
|
459
|
-
|--------|--------|
|
|
460
|
-
| `NPM_TOKEN` | npm publish access (used by `publish.yml`) |
|
|
461
|
-
| `RPC_ETHEREUM_MAINNET` | Ethereum mainnet RPC URL for fork tests (used by `test.yml`) |
|
|
462
|
-
|
|
463
|
-
Fork tests require `RPC_ETHEREUM_MAINNET` — they fail if it's missing.
|
|
464
|
-
|
|
465
536
|
### Branching
|
|
466
537
|
|
|
467
538
|
- `main` is the primary branch
|
|
@@ -480,3 +551,8 @@ Fork tests require `RPC_ETHEREUM_MAINNET` — they fail if it's missing.
|
|
|
480
551
|
### Contract Size Checks
|
|
481
552
|
|
|
482
553
|
CI runs `forge build --sizes` to catch contracts approaching the 24KB limit.
|
|
554
|
+
|
|
555
|
+
## Repo-Specific Deviations
|
|
556
|
+
|
|
557
|
+
- **`optimizer_runs = 100`** — reduced for contract size compliance
|
|
558
|
+
- **`npm install --omit=dev && npm install @sphinx-labs/contracts` in CI** — test files import deployment helpers from dependencies (`SuckerDeploymentLib`, `CroptopDeploymentLib`) that use `@sphinx-labs` contracts. Installing just the contracts package avoids the full `@sphinx-labs/plugins` tree (445+ Solidity files) that would bloat compilation
|
package/docs/src/README.md
CHANGED
|
@@ -123,13 +123,13 @@ test/
|
|
|
123
123
|
REVAutoIssuanceFuzz.t.sol # Auto-issuance fuzz tests
|
|
124
124
|
REVInvincibility.t.sol # Economic property fuzzing
|
|
125
125
|
REVInvincibilityHandler.sol # Fuzz handler
|
|
126
|
-
|
|
126
|
+
REVDeployerRegressions.t.sol # Deployer regressions
|
|
127
127
|
REVLoansSourced.t.sol # Multi-source loan tests
|
|
128
128
|
REVLoansUnSourced.t.sol # Loan error cases
|
|
129
129
|
REVLoansFeeRecovery.t.sol # Fee calculation tests
|
|
130
130
|
REVLoansAttacks.t.sol # Flash loan, reentrancy scenarios
|
|
131
131
|
REVLoans.invariants.t.sol # Loan fuzzing invariants
|
|
132
|
-
|
|
132
|
+
REVLoansRegressions.t.sol # Loan regressions
|
|
133
133
|
TestPR09-32_*.t.sol # Per-PR regression tests
|
|
134
134
|
helpers/
|
|
135
135
|
MaliciousContracts.sol # Attack contract mocks
|
package/foundry.toml
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rev-net/core-v6",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -20,14 +20,17 @@
|
|
|
20
20
|
"artifacts": "source ./.env && npx sphinx artifacts --org-id 'ea165b21-7cdc-4d7b-be59-ecdd4c26bee4' --project-name 'revnet-core-v6'"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@bananapus/721-hook-v6": "^0.0.
|
|
24
|
-
"@bananapus/buyback-hook-v6": "^0.0.
|
|
25
|
-
"@bananapus/core-v6": "^0.0.
|
|
26
|
-
"@bananapus/
|
|
27
|
-
"@bananapus/
|
|
28
|
-
"@bananapus/
|
|
29
|
-
"@
|
|
30
|
-
"@
|
|
23
|
+
"@bananapus/721-hook-v6": "^0.0.15",
|
|
24
|
+
"@bananapus/buyback-hook-v6": "^0.0.11",
|
|
25
|
+
"@bananapus/core-v6": "^0.0.15",
|
|
26
|
+
"@bananapus/ownable-v6": "^0.0.8",
|
|
27
|
+
"@bananapus/permission-ids-v6": "^0.0.7",
|
|
28
|
+
"@bananapus/router-terminal-v6": "^0.0.10",
|
|
29
|
+
"@bananapus/suckers-v6": "^0.0.9",
|
|
30
|
+
"@croptop/core-v6": "^0.0.14",
|
|
31
|
+
"@openzeppelin/contracts": "^5.6.1",
|
|
32
|
+
"@uniswap/v4-core": "^1.0.2",
|
|
33
|
+
"@uniswap/v4-periphery": "^1.0.3"
|
|
31
34
|
},
|
|
32
35
|
"devDependencies": {
|
|
33
36
|
"@sphinx-labs/plugins": "^0.33.2"
|
package/remappings.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
forge-std/=lib/forge-std/src/
|
package/script/Deploy.s.sol
CHANGED
|
@@ -8,7 +8,7 @@ import "@bananapus/suckers-v6/script/helpers/SuckerDeploymentLib.sol";
|
|
|
8
8
|
import "@bananapus/router-terminal-v6/script/helpers/RouterTerminalDeploymentLib.sol";
|
|
9
9
|
import "@croptop/core-v6/script/helpers/CroptopDeploymentLib.sol";
|
|
10
10
|
|
|
11
|
-
import {Sphinx} from "@sphinx-labs/contracts/SphinxPlugin.sol";
|
|
11
|
+
import {Sphinx} from "@sphinx-labs/contracts/contracts/foundry/SphinxPlugin.sol";
|
|
12
12
|
import {Script} from "forge-std/Script.sol";
|
|
13
13
|
|
|
14
14
|
import {JBConstants} from "@bananapus/core-v6/src/libraries/JBConstants.sol";
|
|
@@ -3,7 +3,7 @@ pragma solidity 0.8.26;
|
|
|
3
3
|
|
|
4
4
|
import {stdJson} from "forge-std/Script.sol";
|
|
5
5
|
import {Vm} from "forge-std/Vm.sol";
|
|
6
|
-
import {SphinxConstants, NetworkInfo} from "@sphinx-labs/contracts/SphinxConstants.sol";
|
|
6
|
+
import {SphinxConstants, NetworkInfo} from "@sphinx-labs/contracts/contracts/foundry/SphinxConstants.sol";
|
|
7
7
|
|
|
8
8
|
import {IREVDeployer} from "./../../src/interfaces/IREVDeployer.sol";
|
|
9
9
|
import {IREVLoans} from "./../../src/interfaces/IREVLoans.sol";
|
package/src/REVDeployer.sol
CHANGED
|
@@ -99,8 +99,8 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
99
99
|
uint24 public constant DEFAULT_BUYBACK_POOL_FEE = 10_000;
|
|
100
100
|
|
|
101
101
|
/// @notice The default tick spacing used when auto-configuring buyback pools.
|
|
102
|
-
/// @dev
|
|
103
|
-
int24 public constant DEFAULT_BUYBACK_TICK_SPACING =
|
|
102
|
+
/// @dev 200 aligns with UniV4DeploymentSplitHook.TICK_SPACING so both target the same pool.
|
|
103
|
+
int24 public constant DEFAULT_BUYBACK_TICK_SPACING = 200;
|
|
104
104
|
|
|
105
105
|
/// @notice The default TWAP window used when auto-configuring buyback pools.
|
|
106
106
|
/// @dev 2 days provides robust manipulation resistance.
|
|
@@ -326,6 +326,7 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
326
326
|
bool usesTiered721Hook = address(tiered721Hook) != address(0);
|
|
327
327
|
if (usesTiered721Hook) {
|
|
328
328
|
JBPayHookSpecification[] memory specs;
|
|
329
|
+
// slither-disable-next-line unused-return
|
|
329
330
|
(, specs) = IJBRulesetDataHook(address(tiered721Hook)).beforePayRecordedWith(context);
|
|
330
331
|
// The 721 hook returns a single spec (itself) whose amount is the total split amount.
|
|
331
332
|
if (specs.length > 0) {
|
|
@@ -441,17 +442,14 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
441
442
|
return SUCKER_REGISTRY.isSuckerOf({projectId: revnetId, addr: addr});
|
|
442
443
|
}
|
|
443
444
|
|
|
444
|
-
/// @notice Initialize fund access limits for the loan contract
|
|
445
|
+
/// @notice Initialize fund access limits for the loan contract.
|
|
445
446
|
/// @dev Returns an unlimited surplus allowance for each terminal+token pair derived from the terminal
|
|
446
|
-
/// configurations.
|
|
447
|
-
/// @param revnetId The ID of the revnet to configure buyback pools for.
|
|
447
|
+
/// configurations.
|
|
448
448
|
/// @param terminalConfigurations The terminals to set up for the revnet. Used for payments and cash outs.
|
|
449
449
|
/// @return fundAccessLimitGroups The fund access limit groups for the loans.
|
|
450
|
-
function
|
|
451
|
-
uint256 revnetId,
|
|
452
|
-
JBTerminalConfig[] calldata terminalConfigurations
|
|
453
|
-
)
|
|
450
|
+
function _makeLoanFundAccessLimits(JBTerminalConfig[] calldata terminalConfigurations)
|
|
454
451
|
internal
|
|
452
|
+
pure
|
|
455
453
|
returns (JBFundAccessLimitGroup[] memory fundAccessLimitGroups)
|
|
456
454
|
{
|
|
457
455
|
// Count the total number of accounting contexts across all terminals.
|
|
@@ -463,7 +461,7 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
463
461
|
// Initialize the fund access limit groups.
|
|
464
462
|
fundAccessLimitGroups = new JBFundAccessLimitGroup[](count);
|
|
465
463
|
|
|
466
|
-
// Set up the fund access limits
|
|
464
|
+
// Set up the fund access limits.
|
|
467
465
|
uint256 index;
|
|
468
466
|
for (uint256 i; i < terminalConfigurations.length; i++) {
|
|
469
467
|
JBTerminalConfig calldata terminalConfiguration = terminalConfigurations[i];
|
|
@@ -481,30 +479,28 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
481
479
|
payoutLimits: new JBCurrencyAmount[](0),
|
|
482
480
|
surplusAllowances: loanAllowances
|
|
483
481
|
});
|
|
484
|
-
|
|
485
|
-
// Configure a buyback pool for this terminal token with default fee and TWAP window.
|
|
486
|
-
// slither-disable-next-line calls-loop
|
|
487
|
-
_trySetBuybackPoolFor(revnetId, accountingContext.token);
|
|
488
482
|
}
|
|
489
483
|
}
|
|
490
484
|
}
|
|
491
485
|
|
|
492
|
-
/// @notice Try to
|
|
493
|
-
/// pool
|
|
486
|
+
/// @notice Try to initialize a Uniswap V4 buyback pool for a terminal token at a generic 1:1 price.
|
|
487
|
+
/// @dev Called after the ERC-20 token is deployed so the pool can be initialized in the PoolManager.
|
|
488
|
+
/// Silently catches failures (e.g., if the pool is already initialized).
|
|
494
489
|
/// @param revnetId The ID of the revnet.
|
|
495
|
-
/// @param terminalToken The terminal token to
|
|
496
|
-
function
|
|
497
|
-
// Try to
|
|
490
|
+
/// @param terminalToken The terminal token to initialize a buyback pool for.
|
|
491
|
+
function _tryInitializeBuybackPoolFor(uint256 revnetId, address terminalToken) internal {
|
|
492
|
+
// Try to initialize the pool at a generic 1:1 sqrtPriceX96 and configure the buyback hook.
|
|
498
493
|
// The buyback hook constructs the PoolKey internally from the project token, terminal token, and pool params.
|
|
499
494
|
// slither-disable-next-line calls-loop
|
|
500
|
-
try BUYBACK_HOOK.
|
|
495
|
+
try BUYBACK_HOOK.initializePoolFor({
|
|
501
496
|
projectId: revnetId,
|
|
502
497
|
fee: DEFAULT_BUYBACK_POOL_FEE,
|
|
503
498
|
tickSpacing: DEFAULT_BUYBACK_TICK_SPACING,
|
|
504
499
|
twapWindow: DEFAULT_BUYBACK_TWAP_WINDOW,
|
|
505
|
-
terminalToken: terminalToken
|
|
500
|
+
terminalToken: terminalToken,
|
|
501
|
+
sqrtPriceX96: uint160(1 << 96)
|
|
506
502
|
}) {}
|
|
507
|
-
catch {} // Pool may
|
|
503
|
+
catch {} // Pool may already be initialized — that's OK.
|
|
508
504
|
}
|
|
509
505
|
|
|
510
506
|
/// @notice Make a ruleset configuration for a revnet's stage.
|
|
@@ -1063,6 +1059,15 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
1063
1059
|
salt: keccak256(abi.encode(configuration.description.salt, encodedConfigurationHash, _msgSender()))
|
|
1064
1060
|
});
|
|
1065
1061
|
|
|
1062
|
+
// Now that the ERC-20 exists, initialize buyback pools for each terminal token.
|
|
1063
|
+
for (uint256 i; i < terminalConfigurations.length; i++) {
|
|
1064
|
+
JBTerminalConfig calldata terminalConfiguration = terminalConfigurations[i];
|
|
1065
|
+
for (uint256 j; j < terminalConfiguration.accountingContextsToAccept.length; j++) {
|
|
1066
|
+
// slither-disable-next-line calls-loop
|
|
1067
|
+
_tryInitializeBuybackPoolFor(revnetId, terminalConfiguration.accountingContextsToAccept[j].token);
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1066
1071
|
// Give the split operator their permissions.
|
|
1067
1072
|
_setSplitOperatorOf({revnetId: revnetId, operator: configuration.splitOperator});
|
|
1068
1073
|
|
|
@@ -1153,10 +1158,9 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IJBRulesetDataHook, IJBCas
|
|
|
1153
1158
|
configuration.description.salt
|
|
1154
1159
|
);
|
|
1155
1160
|
|
|
1156
|
-
// Initialize fund access limit groups for the loan contract
|
|
1157
|
-
JBFundAccessLimitGroup[] memory fundAccessLimitGroups =
|
|
1158
|
-
|
|
1159
|
-
});
|
|
1161
|
+
// Initialize fund access limit groups for the loan contract.
|
|
1162
|
+
JBFundAccessLimitGroup[] memory fundAccessLimitGroups =
|
|
1163
|
+
_makeLoanFundAccessLimits({terminalConfigurations: terminalConfigurations});
|
|
1160
1164
|
|
|
1161
1165
|
// Iterate through each stage to set up its ruleset.
|
|
1162
1166
|
for (uint256 i; i < configuration.stageConfigurations.length; i++) {
|
package/src/REVLoans.sol
CHANGED
|
@@ -1206,6 +1206,7 @@ contract REVLoans is ERC721, ERC2771Context, Ownable, IREVLoans {
|
|
|
1206
1206
|
/// @param sourceFeeAmount The amount of the fee being taken from the revnet acting as the source of the loan.
|
|
1207
1207
|
/// @param collateralCountToReturn The amount of collateral being returned that the loan no longer requires.
|
|
1208
1208
|
/// @param beneficiary The address receiving the returned collateral and any tokens resulting from paying fees.
|
|
1209
|
+
// slither-disable-next-line reentrancy-eth,reentrancy-events
|
|
1209
1210
|
function _repayLoan(
|
|
1210
1211
|
uint256 loanId,
|
|
1211
1212
|
REVLoan storage loan,
|
|
@@ -29,7 +29,7 @@ import {JBAddressRegistry} from "@bananapus/address-registry-v6/src/JBAddressReg
|
|
|
29
29
|
import {IJBAddressRegistry} from "@bananapus/address-registry-v6/src/interfaces/IJBAddressRegistry.sol";
|
|
30
30
|
|
|
31
31
|
/// @notice Regression tests for REVDeployer.
|
|
32
|
-
contract
|
|
32
|
+
contract REVDeployerRegressions is TestBaseWorkflow {
|
|
33
33
|
using JBRulesetMetadataResolver for JBRuleset;
|
|
34
34
|
|
|
35
35
|
bytes32 REV_DEPLOYER_SALT = "REVDeployer";
|