@rev-net/core-v6 0.0.11 → 0.0.12
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 +7 -7
- package/ARCHITECTURE.md +11 -11
- package/README.md +7 -4
- package/RISKS.md +2 -2
- package/SKILLS.md +8 -10
- package/STYLE_GUIDE.md +14 -1
- package/package.json +9 -9
- package/script/Deploy.s.sol +85 -35
- package/script/helpers/RevnetCoreDeploymentLib.sol +12 -5
- package/src/REVDeployer.sol +121 -129
- package/src/REVLoans.sol +14 -13
- package/src/interfaces/IREVDeployer.sol +25 -22
- package/src/structs/REVDeploy721TiersHookConfig.sol +12 -14
- package/test/REV.integrations.t.sol +17 -8
- package/test/REVAutoIssuanceFuzz.t.sol +9 -4
- package/test/REVDeployerRegressions.t.sol +13 -6
- package/test/REVInvincibility.t.sol +26 -12
- package/test/REVLifecycle.t.sol +9 -4
- package/test/REVLoans.invariants.t.sol +13 -6
- package/test/REVLoansAttacks.t.sol +12 -5
- package/test/REVLoansFeeRecovery.t.sol +12 -5
- package/test/REVLoansFindings.t.sol +16 -7
- package/test/REVLoansRegressions.t.sol +9 -4
- package/test/REVLoansSourced.t.sol +24 -11
- package/test/REVLoansUnSourced.t.sol +13 -6
- package/test/TestBurnHeldTokens.t.sol +16 -7
- package/test/TestCEIPattern.t.sol +12 -5
- package/test/TestCashOutCallerValidation.t.sol +12 -5
- package/test/TestConversionDocumentation.t.sol +25 -9
- package/test/TestCrossSourceReallocation.t.sol +12 -5
- package/test/TestEmptyBuybackSpecs.t.sol +23 -8
- package/test/TestFlashLoanSurplus.t.sol +12 -5
- package/test/TestHookArrayOOB.t.sol +19 -10
- package/test/TestLiquidationBehavior.t.sol +12 -5
- package/test/TestLowFindings.t.sol +16 -7
- package/test/TestMixedFixes.t.sol +16 -7
- package/test/TestSplitWeightAdjustment.t.sol +29 -12
- package/test/TestSplitWeightE2E.t.sol +24 -16
- package/test/TestSplitWeightFork.t.sol +20 -14
- package/test/TestStageTransitionBorrowable.t.sol +15 -5
- package/test/TestSwapTerminalPermission.t.sol +15 -5
- package/test/TestUint112Overflow.t.sol +12 -5
- package/test/TestZeroRepayment.t.sol +12 -5
- package/test/fork/ForkTestBase.sol +20 -14
- package/test/fork/TestCashOutFork.t.sol +8 -2
- package/test/fork/TestLoanCrossRulesetFork.t.sol +8 -2
- package/test/helpers/REVEmpty721Config.sol +45 -0
- package/test/regression/TestCumulativeLoanCounter.t.sol +12 -5
- package/test/regression/TestLiquidateGapHandling.t.sol +12 -5
package/ADMINISTRATION.md
CHANGED
|
@@ -35,8 +35,7 @@ Admin privileges and their scope in revnet-core-v6. Revnets are designed to be a
|
|
|
35
35
|
|
|
36
36
|
| Function | Required Role | Permission ID | What It Does |
|
|
37
37
|
|----------|--------------|---------------|-------------|
|
|
38
|
-
| `deployFor()` | Anyone (new revnet) or Juicebox project owner (existing project) | None | Deploys a new revnet or irreversibly converts an existing Juicebox project into a revnet. |
|
|
39
|
-
| `deployWith721sFor()` | Anyone (new revnet) or Juicebox project owner (existing project) | None | Same as `deployFor()` but also deploys a tiered ERC-721 hook and optional croptop posting rules. |
|
|
38
|
+
| `deployFor()` | Anyone (new revnet) or Juicebox project owner (existing project) | None | Deploys a new revnet or irreversibly converts an existing Juicebox project into a revnet. Both variants deploy a tiered ERC-721 hook: the 4-arg variant deploys a default empty hook; the 6-arg variant deploys a hook with pre-configured tiers and optional croptop posting rules. |
|
|
40
39
|
| `deploySuckersFor()` | Split Operator | Checked via `_checkIfIsSplitOperatorOf()` | Deploys new cross-chain suckers for an existing revnet. Also requires the current ruleset's `extraMetadata` bit 2 to be set (allows deploying suckers). |
|
|
41
40
|
| `setSplitOperatorOf()` | Split Operator | Checked via `_checkIfIsSplitOperatorOf()` | Replaces the current split operator with a new address. Revokes all operator permissions from the caller and grants them to the new address. |
|
|
42
41
|
| `autoIssueFor()` | Anyone | None | Mints pre-configured auto-issuance tokens for a beneficiary once the relevant stage has started. Amounts are set at deployment and can only be claimed once. |
|
|
@@ -57,15 +56,16 @@ The split operator receives the following Juicebox permission IDs, scoped to its
|
|
|
57
56
|
| `SUCKER_SAFETY` | Manage sucker safety settings (e.g., emergency hatch). |
|
|
58
57
|
| `SET_BUYBACK_HOOK` | Configure the buyback hook. |
|
|
59
58
|
| `SET_ROUTER_TERMINAL` | Set the router terminal. |
|
|
59
|
+
| `SET_TOKEN_METADATA` | Update the revnet token's name and symbol. |
|
|
60
60
|
|
|
61
61
|
Optional 721 permissions (granted only if enabled at deployment via `REVDeploy721TiersHookConfig`):
|
|
62
62
|
|
|
63
63
|
| Permission ID | Deployment Flag | What It Allows |
|
|
64
64
|
|---------------|----------------|----------------|
|
|
65
|
-
| `ADJUST_721_TIERS` | `
|
|
66
|
-
| `SET_721_METADATA` | `
|
|
67
|
-
| `MINT_721` | `
|
|
68
|
-
| `SET_721_DISCOUNT_PERCENT` | `
|
|
65
|
+
| `ADJUST_721_TIERS` | `preventSplitOperatorAdjustingTiers` | Add or remove ERC-721 tiers. Allowed unless prevented. |
|
|
66
|
+
| `SET_721_METADATA` | `preventSplitOperatorUpdatingMetadata` | Update ERC-721 tier metadata. Allowed unless prevented. |
|
|
67
|
+
| `MINT_721` | `preventSplitOperatorMinting` | Mint ERC-721s without payment from tiers with `allowOwnerMint`. Allowed unless prevented. |
|
|
68
|
+
| `SET_721_DISCOUNT_PERCENT` | `preventSplitOperatorIncreasingDiscountPercent` | Increase the discount percentage of a tier. Allowed unless prevented. |
|
|
69
69
|
|
|
70
70
|
### REVLoans
|
|
71
71
|
|
|
@@ -112,7 +112,7 @@ The `REVLoans` contract has minimal admin surface by design:
|
|
|
112
112
|
|
|
113
113
|
The following parameters are set at deployment and can never be changed:
|
|
114
114
|
|
|
115
|
-
### REVDeployer (per-revnet, set at `deployFor`
|
|
115
|
+
### REVDeployer (per-revnet, set at `deployFor` time)
|
|
116
116
|
- Stage schedule (start times, issuance rates, cut frequencies, cut percentages)
|
|
117
117
|
- Cash-out tax rates per stage
|
|
118
118
|
- Split percentages per stage
|
package/ARCHITECTURE.md
CHANGED
|
@@ -9,7 +9,7 @@ Autonomous revenue networks ("revnets") built on Juicebox V6. REVDeployer create
|
|
|
9
9
|
```
|
|
10
10
|
src/
|
|
11
11
|
├── REVDeployer.sol — Deploys revnets: stages → rulesets, data hook, buyback, suckers, 721 tiers
|
|
12
|
-
├── REVLoans.sol — Borrow against
|
|
12
|
+
├── REVLoans.sol — Borrow against burned revnet tokens (10-year max, permissionless liquidation)
|
|
13
13
|
├── interfaces/
|
|
14
14
|
│ ├── IREVDeployer.sol
|
|
15
15
|
│ └── IREVLoans.sol
|
|
@@ -28,7 +28,7 @@ Deployer → REVDeployer.deployFor()
|
|
|
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
|
-
→ Deploy 721
|
|
31
|
+
→ Deploy tiered ERC-721 hook (always — empty by default, pre-configured if specified)
|
|
32
32
|
→ Compute matching hash for cross-chain deployment verification
|
|
33
33
|
```
|
|
34
34
|
|
|
@@ -47,18 +47,18 @@ Cash Out → REVDeployer.beforeCashOutRecordedWith()
|
|
|
47
47
|
### Loan Flow
|
|
48
48
|
```
|
|
49
49
|
Borrower → REVLoans.borrowFrom()
|
|
50
|
-
→
|
|
50
|
+
→ Burn borrower's revnet tokens as collateral
|
|
51
51
|
→ Calculate max borrow based on bonding curve value
|
|
52
|
-
→
|
|
53
|
-
→
|
|
52
|
+
→ Pull funds from treasury via USE_ALLOWANCE
|
|
53
|
+
→ Mint loan ERC-721 NFT to borrower
|
|
54
54
|
|
|
55
55
|
Repay → REVLoans.repayLoan()
|
|
56
|
-
→ Accept repayment (principal +
|
|
57
|
-
→
|
|
56
|
+
→ Accept repayment (principal + prepaid fee)
|
|
57
|
+
→ Re-mint collateral tokens to borrower
|
|
58
58
|
|
|
59
|
-
Liquidate → REVLoans.
|
|
60
|
-
→ After
|
|
61
|
-
→
|
|
59
|
+
Liquidate → REVLoans.liquidateExpiredLoansFrom()
|
|
60
|
+
→ After 10-year term, anyone can liquidate
|
|
61
|
+
→ Collateral permanently destroyed (was burned at borrow time)
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
## Extension Points
|
|
@@ -84,4 +84,4 @@ Liquidate → REVLoans.liquidateLoan()
|
|
|
84
84
|
- Stages are immutable after deployment — no owner can change ruleset parameters
|
|
85
85
|
- Matching hash ensures cross-chain deployments have identical economic parameters
|
|
86
86
|
- REVDeployer is the data hook for all revnets it deploys — centralizes behavioral control
|
|
87
|
-
- Loans use bonding curve value, not market price —
|
|
87
|
+
- Loans use bonding curve value, not market price — independent of external DEX pricing
|
package/README.md
CHANGED
|
@@ -54,8 +54,10 @@ Revnets are autonomous Juicebox projects with predetermined economic stages. Eac
|
|
|
54
54
|
|
|
55
55
|
### Deployer Variants
|
|
56
56
|
|
|
57
|
-
-
|
|
58
|
-
|
|
57
|
+
Every revnet gets a tiered ERC-721 hook deployed automatically — even if no tiers are configured at launch. This lets the split operator add and sell NFTs later without migration.
|
|
58
|
+
|
|
59
|
+
- **Basic revnet** -- `deployFor` with stage configurations mapped to Juicebox rulesets and an empty 721 hook.
|
|
60
|
+
- **Tiered 721 revnet** -- `deployFor` adds a tiered 721 pay hook with pre-configured tiers that mint NFTs as people pay.
|
|
59
61
|
- **Croptop revnet** -- A tiered 721 revnet with Croptop posting criteria, allowing the public to post content.
|
|
60
62
|
|
|
61
63
|
## Architecture
|
|
@@ -102,8 +104,8 @@ If `forge install` has issues, try `git submodule update --init --recursive`.
|
|
|
102
104
|
|
|
103
105
|
```
|
|
104
106
|
src/
|
|
105
|
-
REVDeployer.sol # Revnet deployer + data hook (~1,
|
|
106
|
-
REVLoans.sol # Token-collateralized lending (~1,
|
|
107
|
+
REVDeployer.sol # Revnet deployer + data hook (~1,287 lines)
|
|
108
|
+
REVLoans.sol # Token-collateralized lending (~1,359 lines)
|
|
107
109
|
interfaces/
|
|
108
110
|
IREVDeployer.sol # Deployer interface + events
|
|
109
111
|
IREVLoans.sol # Loans interface + events
|
|
@@ -159,6 +161,7 @@ The split operator has these default permissions:
|
|
|
159
161
|
| `SUCKER_SAFETY` | Emergency sucker functions |
|
|
160
162
|
| `SET_BUYBACK_HOOK` | Swap buyback hook |
|
|
161
163
|
| `SET_ROUTER_TERMINAL` | Swap terminal |
|
|
164
|
+
| `SET_TOKEN_METADATA` | Update token name and symbol |
|
|
162
165
|
|
|
163
166
|
Plus optional from 721 hook config: `ADJUST_721_TIERS`, `SET_721_METADATA`, `MINT_721`, `SET_721_DISCOUNT_PERCENT`.
|
|
164
167
|
|
package/RISKS.md
CHANGED
|
@@ -44,6 +44,6 @@ When a revnet expands to a chain where the native token is not ETH (e.g., Celo),
|
|
|
44
44
|
|
|
45
45
|
| Function | Protection | Risk |
|
|
46
46
|
|----------|-----------|------|
|
|
47
|
-
| `REVLoans.borrowFrom` | Collateral
|
|
48
|
-
| `REVLoans.repayLoan` | Loan state cleared BEFORE collateral
|
|
47
|
+
| `REVLoans.borrowFrom` | Collateral burned BEFORE funds transferred | LOW |
|
|
48
|
+
| `REVLoans.repayLoan` | Loan state cleared BEFORE collateral re-minted | LOW |
|
|
49
49
|
| `REVDeployer.beforePayRecordedWith` | View function, no state changes | NONE |
|
package/SKILLS.md
CHANGED
|
@@ -8,8 +8,8 @@ Deploy and manage Revnets -- autonomous, unowned Juicebox projects with staged i
|
|
|
8
8
|
|
|
9
9
|
| Contract | Role |
|
|
10
10
|
|----------|------|
|
|
11
|
-
| `REVDeployer` | Deploys revnets, permanently owns the project NFT, acts as data hook and cash-out hook. Manages stages, splits, auto-issuance, buyback hooks, 721 hooks, suckers, and split operators. (~1,
|
|
12
|
-
| `REVLoans` | Issues token-collateralized loans from revnet treasuries. Each loan is an ERC-721 NFT. Burns collateral on borrow, re-mints on repay. Charges tiered fees (REV protocol fee + source fee + prepaid fee). (~1,
|
|
11
|
+
| `REVDeployer` | Deploys revnets, permanently owns the project NFT, acts as data hook and cash-out hook. Manages stages, splits, auto-issuance, buyback hooks, 721 hooks, suckers, and split operators. (~1,287 lines) |
|
|
12
|
+
| `REVLoans` | Issues token-collateralized loans from revnet treasuries. Each loan is an ERC-721 NFT. Burns collateral on borrow, re-mints on repay. Charges tiered fees (REV protocol fee + source fee + prepaid fee). (~1,359 lines) |
|
|
13
13
|
|
|
14
14
|
## Key Functions
|
|
15
15
|
|
|
@@ -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, 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
|
|
21
|
-
| `REVDeployer.
|
|
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, loans permissions, and deploys a default empty tiered ERC-721 hook. |
|
|
21
|
+
| `REVDeployer.deployFor(revnetId, config, terminals, suckerConfig, hookConfig, allowedPosts)` | Same as `deployFor` but deploys a tiered ERC-721 hook with pre-configured tiers. 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
|
|
@@ -80,13 +80,13 @@ Deploy and manage Revnets -- autonomous, unowned Juicebox projects with staged i
|
|
|
80
80
|
|
|
81
81
|
| Struct | Key Fields | Used In |
|
|
82
82
|
|--------|------------|---------|
|
|
83
|
-
| `REVConfig` | `description` (REVDescription), `baseCurrency`, `splitOperator`, `stageConfigurations[]
|
|
83
|
+
| `REVConfig` | `description` (REVDescription), `baseCurrency`, `splitOperator`, `stageConfigurations[]` | `deployFor` |
|
|
84
84
|
| `REVStageConfig` | `startsAtOrAfter` (uint48), `initialIssuance` (uint112), `issuanceCutFrequency` (uint32), `issuanceCutPercent` (uint32), `cashOutTaxRate` (uint16), `splitPercent` (uint16), `splits[]`, `autoIssuances[]`, `extraMetadata` (uint16) | Translated into `JBRulesetConfig` |
|
|
85
85
|
| `REVDescription` | `name`, `ticker`, `uri`, `salt` | ERC-20 token deployment and project metadata |
|
|
86
86
|
| `REVAutoIssuance` | `chainId` (uint32), `count` (uint104), `beneficiary` | Per-stage cross-chain token auto-minting |
|
|
87
87
|
| `REVLoan` | `amount` (uint112), `collateral` (uint112), `createdAt` (uint48), `prepaidFeePercent` (uint16), `prepaidDuration` (uint32), `source` (REVLoanSource) | Per-loan state in `REVLoans` |
|
|
88
88
|
| `REVLoanSource` | `token`, `terminal` (IJBPayoutTerminal) | Identifies which terminal and token a loan draws from |
|
|
89
|
-
| `REVDeploy721TiersHookConfig` | `baseline721HookConfiguration` (REVBaseline721HookConfig), `salt`, `
|
|
89
|
+
| `REVDeploy721TiersHookConfig` | `baseline721HookConfiguration` (REVBaseline721HookConfig), `salt`, `preventSplitOperatorAdjustingTiers`, `preventSplitOperatorUpdatingMetadata`, `preventSplitOperatorMinting`, `preventSplitOperatorIncreasingDiscountPercent` | 721 hook deployment with operator permissions (preventive flags — `false` = allowed). Uses `REVBaseline721HookConfig` (not `JBDeploy721TiersHookConfig`) to omit `issueTokensForSplits` — revnets always force it to `false`. |
|
|
90
90
|
| `REVBaseline721HookConfig` | `name`, `symbol`, `baseUri`, `tokenUriResolver`, `contractUri`, `tiersConfig`, `reserveBeneficiary`, `flags` (REV721TiersHookFlags) | Same as `JBDeploy721TiersHookConfig` but uses `REV721TiersHookFlags` which omits `issueTokensForSplits`. |
|
|
91
91
|
| `REV721TiersHookFlags` | `noNewTiersWithReserves`, `noNewTiersWithVotes`, `noNewTiersWithOwnerMinting`, `preventOverspending` | Same as `JB721TiersHookFlags` minus `issueTokensForSplits`. Revnets do their own weight adjustment for splits. |
|
|
92
92
|
| `REVCroptopAllowedPost` | `category` (uint24), `minimumPrice` (uint104), `minimumTotalSupply` (uint32), `maximumTotalSupply` (uint32), `allowedAddresses[]` | Croptop posting criteria |
|
|
@@ -212,11 +212,9 @@ REVConfig memory config = REVConfig({
|
|
|
212
212
|
uri: "ipfs://...",
|
|
213
213
|
salt: bytes32(0)
|
|
214
214
|
}),
|
|
215
|
-
baseCurrency: 1, //
|
|
215
|
+
baseCurrency: 1, // ETH
|
|
216
216
|
splitOperator: msg.sender,
|
|
217
|
-
stageConfigurations: stages
|
|
218
|
-
loanSources: new REVLoanSource[](0),
|
|
219
|
-
loans: address(0) // No loans contract
|
|
217
|
+
stageConfigurations: stages
|
|
220
218
|
});
|
|
221
219
|
|
|
222
220
|
deployer.deployFor({
|
package/STYLE_GUIDE.md
CHANGED
|
@@ -253,9 +253,12 @@ uint256 public constant MAX_RESERVED_PERCENT = 10_000;
|
|
|
253
253
|
|
|
254
254
|
## Function Calls
|
|
255
255
|
|
|
256
|
-
Use named
|
|
256
|
+
Use named arguments for all function calls with 2 or more arguments — in both `src/` and `script/`:
|
|
257
257
|
|
|
258
258
|
```solidity
|
|
259
|
+
// Good — named arguments
|
|
260
|
+
token.mint({account: beneficiary, amount: count});
|
|
261
|
+
_transferOwnership({newOwner: address(0), projectId: 0});
|
|
259
262
|
PERMISSIONS.hasPermission({
|
|
260
263
|
operator: sender,
|
|
261
264
|
account: account,
|
|
@@ -264,8 +267,18 @@ PERMISSIONS.hasPermission({
|
|
|
264
267
|
includeRoot: true,
|
|
265
268
|
includeWildcardProjectId: true
|
|
266
269
|
});
|
|
270
|
+
|
|
271
|
+
// Bad — positional arguments with 2+ args
|
|
272
|
+
token.mint(beneficiary, count);
|
|
273
|
+
_transferOwnership(address(0), 0);
|
|
267
274
|
```
|
|
268
275
|
|
|
276
|
+
Single-argument calls use positional style: `_burn(amount)`.
|
|
277
|
+
|
|
278
|
+
This also applies to constructor calls, struct literals, and inherited/library calls (e.g., OZ `_mint`, `_safeMint`, `safeTransfer`, `allowance`, `Clones.cloneDeterministic`).
|
|
279
|
+
|
|
280
|
+
Named argument keys must use **camelCase** — never underscores. If a function's parameter names use underscores, rename them to camelCase first.
|
|
281
|
+
|
|
269
282
|
## Multiline Signatures
|
|
270
283
|
|
|
271
284
|
```solidity
|
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.12",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -20,14 +20,14 @@
|
|
|
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/ownable-v6": "^0.0.
|
|
27
|
-
"@bananapus/permission-ids-v6": "^0.0.
|
|
28
|
-
"@bananapus/router-terminal-v6": "^0.0.
|
|
29
|
-
"@bananapus/suckers-v6": "^0.0.
|
|
30
|
-
"@croptop/core-v6": "^0.0.
|
|
23
|
+
"@bananapus/721-hook-v6": "^0.0.16",
|
|
24
|
+
"@bananapus/buyback-hook-v6": "^0.0.12",
|
|
25
|
+
"@bananapus/core-v6": "^0.0.16",
|
|
26
|
+
"@bananapus/ownable-v6": "^0.0.9",
|
|
27
|
+
"@bananapus/permission-ids-v6": "^0.0.9",
|
|
28
|
+
"@bananapus/router-terminal-v6": "^0.0.11",
|
|
29
|
+
"@bananapus/suckers-v6": "^0.0.10",
|
|
30
|
+
"@croptop/core-v6": "^0.0.15",
|
|
31
31
|
"@openzeppelin/contracts": "^5.6.1",
|
|
32
32
|
"@uniswap/v4-core": "^1.0.2",
|
|
33
33
|
"@uniswap/v4-periphery": "^1.0.3"
|
package/script/Deploy.s.sol
CHANGED
|
@@ -31,11 +31,21 @@ import {REVDescription} from "../src/structs/REVDescription.sol";
|
|
|
31
31
|
import {REVStageConfig} from "../src/structs/REVStageConfig.sol";
|
|
32
32
|
import {REVSuckerDeploymentConfig} from "../src/structs/REVSuckerDeploymentConfig.sol";
|
|
33
33
|
import {REVLoans, IREVLoans} from "./../src/REVLoans.sol";
|
|
34
|
+
import {REVDeploy721TiersHookConfig} from "../src/structs/REVDeploy721TiersHookConfig.sol";
|
|
35
|
+
import {REVCroptopAllowedPost} from "../src/structs/REVCroptopAllowedPost.sol";
|
|
36
|
+
import {IJB721TokenUriResolver} from "@bananapus/721-hook-v6/src/interfaces/IJB721TokenUriResolver.sol";
|
|
37
|
+
import {IJBPrices} from "@bananapus/core-v6/src/interfaces/IJBPrices.sol";
|
|
38
|
+
import {JB721InitTiersConfig} from "@bananapus/721-hook-v6/src/structs/JB721InitTiersConfig.sol";
|
|
39
|
+
import {JB721TierConfig} from "@bananapus/721-hook-v6/src/structs/JB721TierConfig.sol";
|
|
40
|
+
import {REVBaseline721HookConfig} from "../src/structs/REVBaseline721HookConfig.sol";
|
|
41
|
+
import {REV721TiersHookFlags} from "../src/structs/REV721TiersHookFlags.sol";
|
|
34
42
|
|
|
35
43
|
struct FeeProjectConfig {
|
|
36
44
|
REVConfig configuration;
|
|
37
45
|
JBTerminalConfig[] terminalConfigurations;
|
|
38
46
|
REVSuckerDeploymentConfig suckerDeploymentConfiguration;
|
|
47
|
+
REVDeploy721TiersHookConfig tiered721HookConfiguration;
|
|
48
|
+
REVCroptopAllowedPost[] allowedPosts;
|
|
39
49
|
}
|
|
40
50
|
|
|
41
51
|
contract DeployScript is Script, Sphinx {
|
|
@@ -90,32 +100,43 @@ contract DeployScript is Script, Sphinx {
|
|
|
90
100
|
// Get the deployment addresses for the nana CORE for this chain.
|
|
91
101
|
// We want to do this outside of the `sphinx` modifier.
|
|
92
102
|
core = CoreDeploymentLib.getDeployment(
|
|
93
|
-
vm.envOr(
|
|
103
|
+
vm.envOr({
|
|
104
|
+
name: "NANA_CORE_DEPLOYMENT_PATH", defaultValue: string("node_modules/@bananapus/core-v6/deployments/")
|
|
105
|
+
})
|
|
94
106
|
);
|
|
95
107
|
// Get the deployment addresses for the suckers contracts for this chain.
|
|
96
108
|
suckers = SuckerDeploymentLib.getDeployment(
|
|
97
|
-
vm.envOr(
|
|
109
|
+
vm.envOr({
|
|
110
|
+
name: "NANA_SUCKERS_DEPLOYMENT_PATH",
|
|
111
|
+
defaultValue: string("node_modules/@bananapus/suckers-v6/deployments/")
|
|
112
|
+
})
|
|
98
113
|
);
|
|
99
114
|
// Get the deployment addresses for the 721 hook contracts for this chain.
|
|
100
115
|
croptop = CroptopDeploymentLib.getDeployment(
|
|
101
|
-
vm.envOr(
|
|
116
|
+
vm.envOr({
|
|
117
|
+
name: "CROPTOP_CORE_DEPLOYMENT_PATH", defaultValue: string("node_modules/@croptop/core-v6/deployments/")
|
|
118
|
+
})
|
|
102
119
|
);
|
|
103
120
|
// Get the deployment addresses for the 721 hook contracts for this chain.
|
|
104
121
|
hook = Hook721DeploymentLib.getDeployment(
|
|
105
|
-
vm.envOr(
|
|
122
|
+
vm.envOr({
|
|
123
|
+
name: "NANA_721_DEPLOYMENT_PATH",
|
|
124
|
+
defaultValue: string("node_modules/@bananapus/721-hook-v6/deployments/")
|
|
125
|
+
})
|
|
106
126
|
);
|
|
107
127
|
// Get the deployment addresses for the router terminal contracts for this chain.
|
|
108
128
|
routerTerminal = RouterTerminalDeploymentLib.getDeployment(
|
|
109
|
-
vm.envOr(
|
|
110
|
-
"NANA_ROUTER_TERMINAL_DEPLOYMENT_PATH",
|
|
111
|
-
string("node_modules/@bananapus/router-terminal-v6/deployments/")
|
|
112
|
-
)
|
|
129
|
+
vm.envOr({
|
|
130
|
+
name: "NANA_ROUTER_TERMINAL_DEPLOYMENT_PATH",
|
|
131
|
+
defaultValue: string("node_modules/@bananapus/router-terminal-v6/deployments/")
|
|
132
|
+
})
|
|
113
133
|
);
|
|
114
134
|
// Get the deployment addresses for the 721 hook contracts for this chain.
|
|
115
135
|
buybackHook = BuybackDeploymentLib.getDeployment(
|
|
116
|
-
vm.envOr(
|
|
117
|
-
"NANA_BUYBACK_HOOK_DEPLOYMENT_PATH",
|
|
118
|
-
|
|
136
|
+
vm.envOr({
|
|
137
|
+
name: "NANA_BUYBACK_HOOK_DEPLOYMENT_PATH",
|
|
138
|
+
defaultValue: string("node_modules/@bananapus/buyback-hook-v6/deployments/")
|
|
139
|
+
})
|
|
119
140
|
);
|
|
120
141
|
|
|
121
142
|
// We use the same trusted forwarder and permit2 as the core deployment.
|
|
@@ -210,7 +231,7 @@ contract DeployScript is Script, Sphinx {
|
|
|
210
231
|
|
|
211
232
|
// The project's revnet configuration
|
|
212
233
|
REVConfig memory revnetConfiguration = REVConfig({
|
|
213
|
-
description: REVDescription(NAME, SYMBOL, PROJECT_URI, ERC20_SALT),
|
|
234
|
+
description: REVDescription({name: NAME, ticker: SYMBOL, uri: PROJECT_URI, salt: ERC20_SALT}),
|
|
214
235
|
baseCurrency: ETH_CURRENCY,
|
|
215
236
|
splitOperator: OPERATOR,
|
|
216
237
|
stageConfigurations: stageConfigurations
|
|
@@ -262,7 +283,32 @@ contract DeployScript is Script, Sphinx {
|
|
|
262
283
|
return FeeProjectConfig({
|
|
263
284
|
configuration: revnetConfiguration,
|
|
264
285
|
terminalConfigurations: terminalConfigurations,
|
|
265
|
-
suckerDeploymentConfiguration: suckerDeploymentConfiguration
|
|
286
|
+
suckerDeploymentConfiguration: suckerDeploymentConfiguration,
|
|
287
|
+
tiered721HookConfiguration: REVDeploy721TiersHookConfig({
|
|
288
|
+
baseline721HookConfiguration: REVBaseline721HookConfig({
|
|
289
|
+
name: "",
|
|
290
|
+
symbol: "",
|
|
291
|
+
baseUri: "",
|
|
292
|
+
tokenUriResolver: IJB721TokenUriResolver(address(0)),
|
|
293
|
+
contractUri: "",
|
|
294
|
+
tiersConfig: JB721InitTiersConfig({
|
|
295
|
+
tiers: new JB721TierConfig[](0), currency: ETH_CURRENCY, decimals: 18
|
|
296
|
+
}),
|
|
297
|
+
reserveBeneficiary: address(0),
|
|
298
|
+
flags: REV721TiersHookFlags({
|
|
299
|
+
noNewTiersWithReserves: false,
|
|
300
|
+
noNewTiersWithVotes: false,
|
|
301
|
+
noNewTiersWithOwnerMinting: false,
|
|
302
|
+
preventOverspending: false
|
|
303
|
+
})
|
|
304
|
+
}),
|
|
305
|
+
salt: bytes32(0),
|
|
306
|
+
preventSplitOperatorAdjustingTiers: false,
|
|
307
|
+
preventSplitOperatorUpdatingMetadata: false,
|
|
308
|
+
preventSplitOperatorMinting: false,
|
|
309
|
+
preventSplitOperatorIncreasingDiscountPercent: false
|
|
310
|
+
}),
|
|
311
|
+
allowedPosts: new REVCroptopAllowedPost[](0)
|
|
266
312
|
});
|
|
267
313
|
}
|
|
268
314
|
|
|
@@ -271,11 +317,13 @@ contract DeployScript is Script, Sphinx {
|
|
|
271
317
|
uint256 FEE_PROJECT_ID = core.projects.createFor(safeAddress());
|
|
272
318
|
|
|
273
319
|
// Deploy REVLoans first — it only depends on the controller.
|
|
274
|
-
(address _revloansAddr, bool _revloansIsDeployed) = _isDeployed(
|
|
275
|
-
REVLOANS_SALT,
|
|
276
|
-
type(REVLoans).creationCode,
|
|
277
|
-
abi.encode(
|
|
278
|
-
|
|
320
|
+
(address _revloansAddr, bool _revloansIsDeployed) = _isDeployed({
|
|
321
|
+
salt: REVLOANS_SALT,
|
|
322
|
+
creationCode: type(REVLoans).creationCode,
|
|
323
|
+
arguments: abi.encode(
|
|
324
|
+
core.controller, core.projects, FEE_PROJECT_ID, LOANS_OWNER, PERMIT2, TRUSTED_FORWARDER
|
|
325
|
+
)
|
|
326
|
+
});
|
|
279
327
|
REVLoans revloans = _revloansIsDeployed
|
|
280
328
|
? REVLoans(payable(_revloansAddr))
|
|
281
329
|
: new REVLoans{salt: REVLOANS_SALT}({
|
|
@@ -288,10 +336,10 @@ contract DeployScript is Script, Sphinx {
|
|
|
288
336
|
});
|
|
289
337
|
|
|
290
338
|
// Deploy REVDeployer with the REVLoans and buyback hook addresses.
|
|
291
|
-
(address _deployerAddr, bool _deployerIsDeployed) = _isDeployed(
|
|
292
|
-
DEPLOYER_SALT,
|
|
293
|
-
type(REVDeployer).creationCode,
|
|
294
|
-
abi.encode(
|
|
339
|
+
(address _deployerAddr, bool _deployerIsDeployed) = _isDeployed({
|
|
340
|
+
salt: DEPLOYER_SALT,
|
|
341
|
+
creationCode: type(REVDeployer).creationCode,
|
|
342
|
+
arguments: abi.encode(
|
|
295
343
|
core.controller,
|
|
296
344
|
suckers.registry,
|
|
297
345
|
FEE_PROJECT_ID,
|
|
@@ -301,22 +349,22 @@ contract DeployScript is Script, Sphinx {
|
|
|
301
349
|
address(revloans),
|
|
302
350
|
TRUSTED_FORWARDER
|
|
303
351
|
)
|
|
304
|
-
);
|
|
352
|
+
});
|
|
305
353
|
REVDeployer _basicDeployer = _deployerIsDeployed
|
|
306
354
|
? REVDeployer(payable(_deployerAddr))
|
|
307
|
-
: new REVDeployer{salt: DEPLOYER_SALT}(
|
|
308
|
-
core.controller,
|
|
309
|
-
suckers.registry,
|
|
310
|
-
FEE_PROJECT_ID,
|
|
311
|
-
hook.hook_deployer,
|
|
312
|
-
croptop.publisher,
|
|
313
|
-
IJBBuybackHookRegistry(address(buybackHook.registry)),
|
|
314
|
-
address(revloans),
|
|
315
|
-
TRUSTED_FORWARDER
|
|
316
|
-
);
|
|
355
|
+
: new REVDeployer{salt: DEPLOYER_SALT}({
|
|
356
|
+
controller: core.controller,
|
|
357
|
+
suckerRegistry: suckers.registry,
|
|
358
|
+
feeRevnetId: FEE_PROJECT_ID,
|
|
359
|
+
hookDeployer: hook.hook_deployer,
|
|
360
|
+
publisher: croptop.publisher,
|
|
361
|
+
buybackHook: IJBBuybackHookRegistry(address(buybackHook.registry)),
|
|
362
|
+
loans: address(revloans),
|
|
363
|
+
trustedForwarder: TRUSTED_FORWARDER
|
|
364
|
+
});
|
|
317
365
|
|
|
318
366
|
// Approve the basic deployer to configure the project.
|
|
319
|
-
core.projects.approve(address(_basicDeployer), FEE_PROJECT_ID);
|
|
367
|
+
core.projects.approve({to: address(_basicDeployer), tokenId: FEE_PROJECT_ID});
|
|
320
368
|
|
|
321
369
|
// Build the config.
|
|
322
370
|
FeeProjectConfig memory feeProjectConfig = getFeeProjectConfig();
|
|
@@ -326,7 +374,9 @@ contract DeployScript is Script, Sphinx {
|
|
|
326
374
|
revnetId: FEE_PROJECT_ID,
|
|
327
375
|
configuration: feeProjectConfig.configuration,
|
|
328
376
|
terminalConfigurations: feeProjectConfig.terminalConfigurations,
|
|
329
|
-
suckerDeploymentConfiguration: feeProjectConfig.suckerDeploymentConfiguration
|
|
377
|
+
suckerDeploymentConfiguration: feeProjectConfig.suckerDeploymentConfiguration,
|
|
378
|
+
tiered721HookConfiguration: feeProjectConfig.tiered721HookConfiguration,
|
|
379
|
+
allowedPosts: feeProjectConfig.allowedPosts
|
|
330
380
|
});
|
|
331
381
|
}
|
|
332
382
|
|
|
@@ -29,7 +29,7 @@ library RevnetCoreDeploymentLib {
|
|
|
29
29
|
|
|
30
30
|
for (uint256 _i; _i < networks.length; _i++) {
|
|
31
31
|
if (networks[_i].chainId == chainId) {
|
|
32
|
-
return getDeployment(path, networks[_i].name);
|
|
32
|
+
return getDeployment({path: path, network_name: networks[_i].name});
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -44,10 +44,17 @@ library RevnetCoreDeploymentLib {
|
|
|
44
44
|
view
|
|
45
45
|
returns (RevnetCoreDeployment memory deployment)
|
|
46
46
|
{
|
|
47
|
-
deployment.basic_deployer =
|
|
48
|
-
|
|
47
|
+
deployment.basic_deployer = IREVDeployer(
|
|
48
|
+
_getDeploymentAddress({
|
|
49
|
+
path: path, project_name: "revnet-core-v6", network_name: network_name, contractName: "REVDeployer"
|
|
50
|
+
})
|
|
51
|
+
);
|
|
49
52
|
|
|
50
|
-
deployment.loans = IREVLoans(
|
|
53
|
+
deployment.loans = IREVLoans(
|
|
54
|
+
_getDeploymentAddress({
|
|
55
|
+
path: path, project_name: "revnet-core-v6", network_name: network_name, contractName: "REVLoans"
|
|
56
|
+
})
|
|
57
|
+
);
|
|
51
58
|
}
|
|
52
59
|
|
|
53
60
|
/// @notice Get the address of a contract that was deployed by the Deploy script.
|
|
@@ -67,6 +74,6 @@ library RevnetCoreDeploymentLib {
|
|
|
67
74
|
{
|
|
68
75
|
string memory deploymentJson =
|
|
69
76
|
vm.readFile(string.concat(path, project_name, "/", network_name, "/", contractName, ".json"));
|
|
70
|
-
return stdJson.readAddress(deploymentJson, ".address");
|
|
77
|
+
return stdJson.readAddress({json: deploymentJson, key: ".address"});
|
|
71
78
|
}
|
|
72
79
|
}
|