@rev-net/core-v6 0.0.47 → 0.0.48
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/CHANGELOG.md +5 -17
- package/README.md +4 -12
- package/package.json +2 -2
- package/references/operations.md +0 -8
- package/references/runtime.md +0 -10
- package/script/Deploy.s.sol +0 -22
- package/src/REVDeployer.sol +2 -3
- package/src/REVOwner.sol +5 -14
- package/src/interfaces/IREVOwner.sol +0 -5
- package/src/REVHiddenTokens.sol +0 -169
- package/src/interfaces/IREVHiddenTokens.sol +0 -71
package/CHANGELOG.md
CHANGED
|
@@ -9,11 +9,9 @@ This file describes the verified change from `revnet-core-v5` to the current `re
|
|
|
9
9
|
- `REVDeployer`
|
|
10
10
|
- `REVOwner`
|
|
11
11
|
- `REVLoans`
|
|
12
|
-
- `REVHiddenTokens`
|
|
13
12
|
- `IREVDeployer`
|
|
14
13
|
- `IREVOwner`
|
|
15
14
|
- `IREVLoans`
|
|
16
|
-
- `IREVHiddenTokens`
|
|
17
15
|
|
|
18
16
|
## Summary
|
|
19
17
|
|
|
@@ -23,15 +21,12 @@ This file describes the verified change from `revnet-core-v5` to the current `re
|
|
|
23
21
|
- The v6 test tree is substantially broader than the v5 tree, with dedicated regression, fork, attack, and invariant coverage for loans, cash-outs, split weights, and lifecycle edges.
|
|
24
22
|
- The repo moved from the v5 `0.8.23` baseline to `0.8.28`.
|
|
25
23
|
|
|
26
|
-
## Operator delegation
|
|
24
|
+
## Operator delegation
|
|
27
25
|
|
|
28
|
-
- Added
|
|
29
|
-
- `
|
|
30
|
-
- `
|
|
31
|
-
- `
|
|
32
|
-
- `REPAY_LOAN` (38) — repay a loan on behalf of a loan owner via `REVLoans.repayLoan`
|
|
33
|
-
- `REVEAL_TOKENS` (39) — legacy permission id; hidden-token reveal no longer depends on it
|
|
34
|
-
- `REVHiddenTokens` now inherits `JBPermissioned` and accepts a `holder` parameter on `hideTokensOf` and `revealTokensOf`. Hiding is available to an operator-managed holder allowlist, and also to the project owner or any operator with `HIDE_TOKENS`. Revealing is holder-only and does not require special permission.
|
|
26
|
+
- Added new `JBPermissionIds` for operator delegation in `@bananapus/permission-ids-v6`:
|
|
27
|
+
- `OPEN_LOAN` — open a loan on behalf of a token holder via `REVLoans.borrowFrom`
|
|
28
|
+
- `REALLOCATE_LOAN` — reallocate loan collateral on behalf of a loan owner via `REVLoans.reallocateCollateralFromLoan`
|
|
29
|
+
- `REPAY_LOAN` — repay a loan on behalf of a loan owner via `REVLoans.repayLoan`
|
|
35
30
|
- `REVLoans.borrowFrom` now accepts a `holder` parameter. The loan NFT is minted to `holder`, and collateral is burned from `holder`. An operator with `OPEN_LOAN` permission can borrow on behalf of a holder.
|
|
36
31
|
- `REVLoans.repayLoan` now allows permissioned operators with `REPAY_LOAN` to repay on behalf of the loan NFT owner. Replacement loans are minted to the original loan owner.
|
|
37
32
|
- `REVLoans.reallocateCollateralFromLoan` now allows permissioned operators with `REALLOCATE_LOAN` to reallocate on behalf of the loan NFT owner. Returned collateral and replacement loans go to the original loan owner.
|
|
@@ -39,11 +34,6 @@ This file describes the verified change from `revnet-core-v5` to the current `re
|
|
|
39
34
|
|
|
40
35
|
### Breaking ABI changes from delegation
|
|
41
36
|
|
|
42
|
-
- `IREVHiddenTokens.hideTokensOf` signature changed: added `address holder` parameter
|
|
43
|
-
- `IREVHiddenTokens.revealTokensOf` signature changed: added `address holder` parameter
|
|
44
|
-
- `IREVHiddenTokens.setTokenHidingAllowedFor` added for operator-managed holder allowlisting
|
|
45
|
-
- `IREVHiddenTokens.HideTokens` event: added `address holder` field
|
|
46
|
-
- `IREVHiddenTokens.RevealTokens` event: added `address holder` field
|
|
47
37
|
- `IREVLoans.borrowFrom` signature changed: added `address holder` as last parameter
|
|
48
38
|
|
|
49
39
|
## Verified deltas
|
|
@@ -52,8 +42,6 @@ This file describes the verified change from `revnet-core-v5` to the current `re
|
|
|
52
42
|
- `IREVDeployer.deployFor(...)` now has overloads that return `(uint256, IJB721TiersHook)`.
|
|
53
43
|
- `IREVDeployer.BUYBACK_HOOK()`, `LOANS()`, and `OWNER()` are explicit v6 surface area.
|
|
54
44
|
- `IREVOwner` is a new interface and runtime counterpart to the deployer.
|
|
55
|
-
- `IREVHiddenTokens` is a new interface for temporary token hiding (burn to exclude from live totalSupply, re-mint on reveal).
|
|
56
|
-
- `REVHiddenTokens` is a new standalone contract that lets holders temporarily hide tokens from visible/governance supply while `REVOwner` and `REVLoans` keep hidden balances in economic denominators.
|
|
57
45
|
- The old caller-supplied `REVBuybackHookConfig` path is no longer part of the deployer interface.
|
|
58
46
|
|
|
59
47
|
## Breaking ABI changes
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Revnet Core
|
|
2
2
|
|
|
3
|
-
`@rev-net/core-v6` deploys and operates Revnets: Juicebox project shapes with staged economics, optional tiered NFTs, cross-chain support, buyback integration,
|
|
3
|
+
`@rev-net/core-v6` deploys and operates Revnets: Juicebox project shapes with staged economics, optional tiered NFTs, cross-chain support, buyback integration, and token-collateralized loans.
|
|
4
4
|
|
|
5
5
|
Docs: <https://docs.juicebox.money>
|
|
6
6
|
Architecture: [ARCHITECTURE.md](./ARCHITECTURE.md)
|
|
@@ -19,8 +19,6 @@ This package provides:
|
|
|
19
19
|
- a deployer that launches Revnets and stores their long-lived configuration
|
|
20
20
|
- a runtime hook that mediates pay, cash-out, mint-permission, and delayed-cash-out behavior
|
|
21
21
|
- a loan system that burns token collateral on borrow and remints on repayment
|
|
22
|
-
- a hidden-token system that temporarily removes tokens from visible supply while preserving economic claim
|
|
23
|
-
denominators
|
|
24
22
|
|
|
25
23
|
It also composes with the 721 hook stack, buyback hook, router terminal, Croptop, and suckers where needed.
|
|
26
24
|
|
|
@@ -33,14 +31,12 @@ Use this repo when the product is a treasury-backed network with encoded stage t
|
|
|
33
31
|
| `REVDeployer` | Launches and configures Revnets, stages, split operators, and optional auxiliary features. |
|
|
34
32
|
| `REVOwner` | Runtime data-hook and cash-out-hook surface used by active Revnets. |
|
|
35
33
|
| `REVLoans` | Loan surface that lets users borrow against Revnet tokens with burned collateral and NFT loan positions. |
|
|
36
|
-
| `REVHiddenTokens` | Lets token holders temporarily hide tokens from visible/governance supply until reveal, while cash-out and loan denominators still count hidden supply. |
|
|
37
|
-
|
|
38
34
|
## Mental Model
|
|
39
35
|
|
|
40
36
|
Read the package in two halves:
|
|
41
37
|
|
|
42
38
|
1. deployment-time shape: `REVDeployer` decides what the network will be allowed to do
|
|
43
|
-
2. runtime enforcement: `REVOwner
|
|
39
|
+
2. runtime enforcement: `REVOwner` and `REVLoans` decide how that shape behaves over time
|
|
44
40
|
|
|
45
41
|
Most mistakes come from assuming a deploy-time parameter can be changed later or that a runtime hook is only advisory.
|
|
46
42
|
|
|
@@ -49,8 +45,7 @@ Most mistakes come from assuming a deploy-time parameter can be changed later or
|
|
|
49
45
|
1. `src/REVDeployer.sol`
|
|
50
46
|
2. `src/REVOwner.sol`
|
|
51
47
|
3. `src/REVLoans.sol`
|
|
52
|
-
4.
|
|
53
|
-
5. the integrated hook or bridge repo used by the deployment
|
|
48
|
+
4. the integrated hook or bridge repo used by the deployment
|
|
54
49
|
|
|
55
50
|
## Integration Traps
|
|
56
51
|
|
|
@@ -64,8 +59,6 @@ Most mistakes come from assuming a deploy-time parameter can be changed later or
|
|
|
64
59
|
- deployment-time configuration and operator envelope live in `REVDeployer`
|
|
65
60
|
- runtime pay and cash-out behavior live in `REVOwner`
|
|
66
61
|
- loan positions and loan-specific state live in `REVLoans`
|
|
67
|
-
- hidden-token state lives in `REVHiddenTokens`
|
|
68
|
-
|
|
69
62
|
## High-Signal Tests
|
|
70
63
|
|
|
71
64
|
1. `test/REVLifecycle.t.sol`
|
|
@@ -104,7 +97,6 @@ src/
|
|
|
104
97
|
REVDeployer.sol
|
|
105
98
|
REVOwner.sol
|
|
106
99
|
REVLoans.sol
|
|
107
|
-
REVHiddenTokens.sol
|
|
108
100
|
interfaces/
|
|
109
101
|
structs/
|
|
110
102
|
test/
|
|
@@ -124,5 +116,5 @@ script/
|
|
|
124
116
|
## For AI Agents
|
|
125
117
|
|
|
126
118
|
- Describe Revnets as treasury-backed Juicebox project shapes with encoded stage transitions, not as simple presets.
|
|
127
|
-
- Read `REVDeployer`, `REVOwner`,
|
|
119
|
+
- Read `REVDeployer`, `REVOwner`, and `REVLoans` together before answering economic or admin-surface questions.
|
|
128
120
|
- If a deployment enables buybacks, 721 hooks, or suckers, inspect those sibling repos before making definitive claims.
|
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.48",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"@bananapus/buyback-hook-v6": "^0.0.39",
|
|
31
31
|
"@bananapus/core-v6": "^0.0.44",
|
|
32
32
|
"@bananapus/ownable-v6": "^0.0.24",
|
|
33
|
-
"@bananapus/permission-ids-v6": "^0.0.
|
|
33
|
+
"@bananapus/permission-ids-v6": "^0.0.24",
|
|
34
34
|
"@bananapus/router-terminal-v6": "^0.0.37",
|
|
35
35
|
"@bananapus/suckers-v6": "^0.0.37",
|
|
36
36
|
"@croptop/core-v6": "^0.0.42",
|
package/references/operations.md
CHANGED
|
@@ -143,8 +143,6 @@ Use this file when you need revnet-specific risks, state reads, constants, or ex
|
|
|
143
143
|
19. **39.16% cash-out tax crossover.** Below ~39% cash-out tax, cashing out is more capital-efficient than borrowing. Above ~39%, loans become more efficient because they preserve upside while providing liquidity. Based on CryptoEconLab academic research. Design implication: revnets intended for active token trading should consider this threshold when setting `cashOutTaxRate`.
|
|
144
144
|
20. **REVDeployer always deploys a 721 hook** via `HOOK_DEPLOYER.deployHookFor` — even if `baseline721HookConfiguration` has empty tiers. This is correct by design: it lets the split operator add and sell NFTs later without migration. Non-revnet projects should follow the same pattern by using `JB721TiersHookProjectDeployer.launchProjectFor` (or `JBOmnichainDeployer.launchProjectFor`) instead of bare `launchProjectFor`.
|
|
145
145
|
21. **REVOwner deployer binding is precomputed.** REVOwner records the account that created it as an internal one-time binder. That account must call `setDeployer(precomputedRevDeployerAddress)` exactly once before the canonical REVDeployer is deployed. This avoids an ambient public initializer while keeping the circular dependency manageable. If `setDeployer(...)` is never called, all DEPLOYER-gated runtime configuration breaks.
|
|
146
|
-
22. **Hidden tokens are economic, not cosmetic.** Hiding burns visible tokens and lowers visible/governance supply until reveal. Cash-out and loan denominators still include hidden balances because they are recoverable claims.
|
|
147
|
-
|
|
148
146
|
### NATIVE_TOKEN Accounting on Non-ETH Chains
|
|
149
147
|
|
|
150
148
|
When deploying to a chain where the native token is NOT ETH (Celo, Polygon), the terminal must NOT use `JBConstants.NATIVE_TOKEN` as its accounting context. `NATIVE_TOKEN` represents whatever is native on that chain, but `baseCurrency=1` (ETH) assumes ETH-denominated value.
|
|
@@ -199,12 +197,6 @@ Quick-reference for common read operations. All functions are `view`/`pure` and
|
|
|
199
197
|
|------|------|---------|
|
|
200
198
|
| Remaining auto-issuance for beneficiary | `REVDeployer.amountToAutoIssue(revnetId, stageId, beneficiary)` | `uint256` (0 if already claimed) |
|
|
201
199
|
|
|
202
|
-
### Hidden Tokens
|
|
203
|
-
|
|
204
|
-
| What | Call | Returns |
|
|
205
|
-
|------|------|---------|
|
|
206
|
-
| Hidden balance for holder | `REVHiddenTokens.hiddenBalanceOf(holder, revnetId)` | `uint256` |
|
|
207
|
-
|
|
208
200
|
### Loans
|
|
209
201
|
|
|
210
202
|
| What | Call | Returns |
|
package/references/runtime.md
CHANGED
|
@@ -13,7 +13,6 @@ Deploy and manage Revnets -- autonomous, unowned Juicebox projects with staged i
|
|
|
13
13
|
| `REVDeployer` | Deploys revnets, permanently owns the project NFT. Manages stages, splits, auto-issuance, buyback hooks, suckers, split operators, and configuration state storage. Exposes `OWNER()` view returning the REVOwner address. Calls DEPLOYER-restricted setters on REVOwner during deployment to store `cashOutDelayOf` and `tiered721HookOf`. |
|
|
14
14
|
| `REVOwner` | Runtime hook contract for all revnets. Implements `IJBRulesetDataHook` + `IJBCashOutHook`. Set as the `dataHook` in each revnet's ruleset metadata. Handles pay hooks, cash-out hooks, mint permissions, and sucker verification. Stores `cashOutDelayOf` and `tiered721HookOf` mappings (set by REVDeployer via DEPLOYER-restricted setters `setCashOutDelayOf()` and `setTiered721HookOf()`). |
|
|
15
15
|
| `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). |
|
|
16
|
-
| `REVHiddenTokens` | Burns tokens into a hidden balance and can later re-mint them. This is a supply-management primitive, not just a wallet convenience feature. |
|
|
17
16
|
|
|
18
17
|
## Key Functions
|
|
19
18
|
|
|
@@ -67,8 +66,6 @@ Deploy and manage Revnets -- autonomous, unowned Juicebox projects with staged i
|
|
|
67
66
|
| `REVLoans.loanOf(loanId)` | Returns the full `REVLoan` struct for a loan. |
|
|
68
67
|
| `REVLoans.loanSourcesOf(revnetId)` | Returns all `(terminal, token)` pairs used for loans by a revnet. |
|
|
69
68
|
| `REVLoans.revnetIdOfLoanWith(loanId)` | Decode the revnet ID from a loan ID (`loanId / 1_000_000_000_000`). |
|
|
70
|
-
| `REVHiddenTokens.hiddenBalanceOf(holder, revnetId)` | Returns how many tokens a holder has hidden from visible supply. |
|
|
71
|
-
|
|
72
69
|
## Integration Points
|
|
73
70
|
|
|
74
71
|
| Dependency | Import | Used For |
|
|
@@ -98,10 +95,3 @@ Deploy and manage Revnets -- autonomous, unowned Juicebox projects with staged i
|
|
|
98
95
|
| `REV721TiersHookFlags` | `noNewTiersWithReserves`, `noNewTiersWithVotes`, `noNewTiersWithOwnerMinting`, `preventOverspending` | Same as `JB721TiersHookFlags` minus `issueTokensForSplits`. Revnets do their own weight adjustment for splits. |
|
|
99
96
|
| `REVCroptopAllowedPost` | `category` (uint24), `minimumPrice` (uint104), `minimumTotalSupply` (uint32), `maximumTotalSupply` (uint32), `allowedAddresses[]` | Croptop posting criteria |
|
|
100
97
|
| `REVSuckerDeploymentConfig` | `deployerConfigurations[]`, `salt` | Cross-chain sucker deployment |
|
|
101
|
-
### Hidden Tokens
|
|
102
|
-
|
|
103
|
-
| Function | Permissions | What it does |
|
|
104
|
-
|----------|------------|-------------|
|
|
105
|
-
| `REVHiddenTokens.hideTokensOf(revnetId, tokenCount, holder)` | Holder only. The holder must either be allowlisted or personally hold `HIDE_TOKENS`. | Burns visible tokens, increases hidden balance, and lowers visible supply. Cash-out and loan denominators still include the hidden balance while it is revealable. |
|
|
106
|
-
| `REVHiddenTokens.revealTokensOf(revnetId, tokenCount, holder)` | Holder only | Re-mints previously hidden tokens back to the holder and reduces hidden balance. |
|
|
107
|
-
| `REVHiddenTokens.setTokenHidingAllowedFor(revnetId, holder, isAllowed)` | Operator with `HIDE_TOKENS` | Allows or revokes a holder's ability to hide their own tokens. |
|
package/script/Deploy.s.sol
CHANGED
|
@@ -37,7 +37,6 @@ import {REVConfig} from "../src/structs/REVConfig.sol";
|
|
|
37
37
|
import {REVDescription} from "../src/structs/REVDescription.sol";
|
|
38
38
|
import {REVStageConfig} from "../src/structs/REVStageConfig.sol";
|
|
39
39
|
import {REVSuckerDeploymentConfig} from "../src/structs/REVSuckerDeploymentConfig.sol";
|
|
40
|
-
import {REVHiddenTokens} from "./../src/REVHiddenTokens.sol";
|
|
41
40
|
import {REVLoans} from "./../src/REVLoans.sol";
|
|
42
41
|
import {REVDeploy721TiersHookConfig} from "../src/structs/REVDeploy721TiersHookConfig.sol";
|
|
43
42
|
import {REVCroptopAllowedPost} from "../src/structs/REVCroptopAllowedPost.sol";
|
|
@@ -94,8 +93,6 @@ contract DeployScript is Script, Sphinx {
|
|
|
94
93
|
// forge-lint: disable-next-line(mixed-case-variable)
|
|
95
94
|
bytes32 REVLOANS_SALT = "_REV_LOANS_SALT_V6_";
|
|
96
95
|
// forge-lint: disable-next-line(mixed-case-variable)
|
|
97
|
-
bytes32 REVHIDDENTOKENS_SALT = "_REV_HIDDEN_TOKENS_SALT_V6_";
|
|
98
|
-
// forge-lint: disable-next-line(mixed-case-variable)
|
|
99
96
|
bytes32 REVOWNER_SALT = "_REV_OWNER_SALT_V6_";
|
|
100
97
|
// forge-lint: disable-next-line(mixed-case-variable)
|
|
101
98
|
address LOANS_OWNER;
|
|
@@ -376,13 +373,10 @@ contract DeployScript is Script, Sphinx {
|
|
|
376
373
|
|
|
377
374
|
// Try to find an existing deployment by checking all project IDs that have already been created.
|
|
378
375
|
bool _revloansExists;
|
|
379
|
-
bool _revHiddenTokensExists;
|
|
380
376
|
bool _revOwnerExists;
|
|
381
377
|
bool _revDeployerExists;
|
|
382
378
|
// The address of the previously deployed REVLoans, if found.
|
|
383
379
|
address _existingRevloansAddr;
|
|
384
|
-
// The address of the previously deployed REVHiddenTokens, if found.
|
|
385
|
-
address _existingHiddenTokensAddr;
|
|
386
380
|
// The address of the previously deployed REVOwner, if found.
|
|
387
381
|
address _existingOwnerAddr;
|
|
388
382
|
// The address of the previously deployed REVDeployer, if found.
|
|
@@ -407,13 +401,6 @@ contract DeployScript is Script, Sphinx {
|
|
|
407
401
|
_existingRevloansAddr = _candidateRevloansAddr;
|
|
408
402
|
_revloansExists = true;
|
|
409
403
|
|
|
410
|
-
// Also predict and verify the hidden tokens contract.
|
|
411
|
-
(_existingHiddenTokensAddr, _revHiddenTokensExists) = _isDeployed({
|
|
412
|
-
salt: REVHIDDENTOKENS_SALT,
|
|
413
|
-
creationCode: type(REVHiddenTokens).creationCode,
|
|
414
|
-
arguments: abi.encode(core.controller, TRUSTED_FORWARDER)
|
|
415
|
-
});
|
|
416
|
-
|
|
417
404
|
// Also predict and verify the owner.
|
|
418
405
|
(_existingOwnerAddr, _revOwnerExists) = _isDeployed({
|
|
419
406
|
salt: REVOWNER_SALT,
|
|
@@ -424,7 +411,6 @@ contract DeployScript is Script, Sphinx {
|
|
|
424
411
|
_candidateId,
|
|
425
412
|
suckers.registry,
|
|
426
413
|
_candidateRevloansAddr,
|
|
427
|
-
_existingHiddenTokensAddr,
|
|
428
414
|
msg.sender
|
|
429
415
|
)
|
|
430
416
|
});
|
|
@@ -483,13 +469,6 @@ contract DeployScript is Script, Sphinx {
|
|
|
483
469
|
trustedForwarder: TRUSTED_FORWARDER
|
|
484
470
|
});
|
|
485
471
|
|
|
486
|
-
// Deploy REVHiddenTokens — allows revnet holders to temporarily hide tokens from totalSupply.
|
|
487
|
-
REVHiddenTokens revHiddenTokens = _revHiddenTokensExists
|
|
488
|
-
? REVHiddenTokens(_existingHiddenTokensAddr)
|
|
489
|
-
: new REVHiddenTokens{salt: REVHIDDENTOKENS_SALT}({
|
|
490
|
-
controller: core.controller, trustedForwarder: TRUSTED_FORWARDER
|
|
491
|
-
});
|
|
492
|
-
|
|
493
472
|
// Deploy REVOwner — the runtime data hook that handles pay and cash out callbacks.
|
|
494
473
|
REVOwner revOwner = _revOwnerExists
|
|
495
474
|
? REVOwner(_existingOwnerAddr)
|
|
@@ -499,7 +478,6 @@ contract DeployScript is Script, Sphinx {
|
|
|
499
478
|
feeRevnetId: FEE_PROJECT_ID,
|
|
500
479
|
suckerRegistry: suckers.registry,
|
|
501
480
|
loans: revloans,
|
|
502
|
-
hiddenTokens: revHiddenTokens,
|
|
503
481
|
deployerBinder: msg.sender
|
|
504
482
|
});
|
|
505
483
|
|
package/src/REVDeployer.sol
CHANGED
|
@@ -372,7 +372,7 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IERC721Receiver {
|
|
|
372
372
|
uint256[] memory customSplitOperatorPermissionIndexes = _extraOperatorPermissions[revnetId];
|
|
373
373
|
|
|
374
374
|
// Make the array that merges the default and custom operator permissions.
|
|
375
|
-
allOperatorPermissions = new uint256[](
|
|
375
|
+
allOperatorPermissions = new uint256[](9 + customSplitOperatorPermissionIndexes.length);
|
|
376
376
|
allOperatorPermissions[0] = JBPermissionIds.SET_SPLIT_GROUPS;
|
|
377
377
|
allOperatorPermissions[1] = JBPermissionIds.SET_BUYBACK_POOL;
|
|
378
378
|
allOperatorPermissions[2] = JBPermissionIds.SET_BUYBACK_TWAP;
|
|
@@ -382,11 +382,10 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IERC721Receiver {
|
|
|
382
382
|
allOperatorPermissions[6] = JBPermissionIds.SET_ROUTER_TERMINAL;
|
|
383
383
|
allOperatorPermissions[7] = JBPermissionIds.SET_TOKEN_METADATA;
|
|
384
384
|
allOperatorPermissions[8] = JBPermissionIds.SIGN_FOR_ERC20;
|
|
385
|
-
allOperatorPermissions[9] = JBPermissionIds.HIDE_TOKENS;
|
|
386
385
|
|
|
387
386
|
// Copy the custom permissions into the array.
|
|
388
387
|
for (uint256 i; i < customSplitOperatorPermissionIndexes.length;) {
|
|
389
|
-
allOperatorPermissions[
|
|
388
|
+
allOperatorPermissions[9 + i] = customSplitOperatorPermissionIndexes[i];
|
|
390
389
|
unchecked {
|
|
391
390
|
++i;
|
|
392
391
|
}
|
package/src/REVOwner.sol
CHANGED
|
@@ -24,7 +24,6 @@ import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol
|
|
|
24
24
|
import {mulDiv} from "@prb/math/src/Common.sol";
|
|
25
25
|
|
|
26
26
|
import {IREVDeployer} from "./interfaces/IREVDeployer.sol";
|
|
27
|
-
import {IREVHiddenTokens} from "./interfaces/IREVHiddenTokens.sol";
|
|
28
27
|
import {IREVLoans} from "./interfaces/IREVLoans.sol";
|
|
29
28
|
import {REVLoanSource} from "./structs/REVLoanSource.sol";
|
|
30
29
|
|
|
@@ -69,9 +68,6 @@ contract REVOwner is IJBRulesetDataHook, IJBCashOutHook, IJBPeerChainAdjustedAcc
|
|
|
69
68
|
/// @notice The Juicebox project ID of the revnet that receives cash out fees.
|
|
70
69
|
uint256 public immutable FEE_REVNET_ID;
|
|
71
70
|
|
|
72
|
-
/// @notice The hidden tokens contract used by all revnets.
|
|
73
|
-
IREVHiddenTokens public immutable HIDDEN_TOKENS;
|
|
74
|
-
|
|
75
71
|
/// @notice The loan contract used by all revnets.
|
|
76
72
|
IREVLoans public immutable LOANS;
|
|
77
73
|
|
|
@@ -111,7 +107,6 @@ contract REVOwner is IJBRulesetDataHook, IJBCashOutHook, IJBPeerChainAdjustedAcc
|
|
|
111
107
|
/// @param feeRevnetId The Juicebox project ID of the fee revnet.
|
|
112
108
|
/// @param suckerRegistry The sucker registry.
|
|
113
109
|
/// @param loans The loan contract.
|
|
114
|
-
/// @param hiddenTokens The hidden tokens contract.
|
|
115
110
|
/// @param deployerBinder The account allowed to bind the canonical deployer via `setDeployer`. Passed explicitly
|
|
116
111
|
/// because CREATE2 deployments set `msg.sender` to the factory, not the intended operator.
|
|
117
112
|
constructor(
|
|
@@ -120,7 +115,6 @@ contract REVOwner is IJBRulesetDataHook, IJBCashOutHook, IJBPeerChainAdjustedAcc
|
|
|
120
115
|
uint256 feeRevnetId,
|
|
121
116
|
IJBSuckerRegistry suckerRegistry,
|
|
122
117
|
IREVLoans loans,
|
|
123
|
-
IREVHiddenTokens hiddenTokens,
|
|
124
118
|
address deployerBinder
|
|
125
119
|
) {
|
|
126
120
|
BUYBACK_HOOK = buybackHook;
|
|
@@ -128,7 +122,6 @@ contract REVOwner is IJBRulesetDataHook, IJBCashOutHook, IJBPeerChainAdjustedAcc
|
|
|
128
122
|
FEE_REVNET_ID = feeRevnetId;
|
|
129
123
|
SUCKER_REGISTRY = suckerRegistry;
|
|
130
124
|
LOANS = loans;
|
|
131
|
-
HIDDEN_TOKENS = hiddenTokens;
|
|
132
125
|
_DEPLOYER_BINDER = deployerBinder;
|
|
133
126
|
}
|
|
134
127
|
|
|
@@ -359,8 +352,8 @@ contract REVOwner is IJBRulesetDataHook, IJBCashOutHook, IJBPeerChainAdjustedAcc
|
|
|
359
352
|
}
|
|
360
353
|
|
|
361
354
|
/// @notice Returns whether an address may mint a revnet's tokens on-demand. Grants permission to: the loans
|
|
362
|
-
/// contract (re-mints collateral on repayment),
|
|
363
|
-
///
|
|
355
|
+
/// contract (re-mints collateral on repayment), buyback hook and its delegates (mints tokens from pool swaps),
|
|
356
|
+
/// and suckers (mints bridged tokens on the destination chain).
|
|
364
357
|
/// @dev Part of `IJBRulesetDataHook`.
|
|
365
358
|
/// @param revnetId The ID of the revnet to check.
|
|
366
359
|
/// @param ruleset The ruleset to check against.
|
|
@@ -376,16 +369,14 @@ contract REVOwner is IJBRulesetDataHook, IJBCashOutHook, IJBPeerChainAdjustedAcc
|
|
|
376
369
|
override
|
|
377
370
|
returns (bool)
|
|
378
371
|
{
|
|
379
|
-
// The loans contract,
|
|
380
|
-
|
|
381
|
-
return addr == address(LOANS) || addr == address(HIDDEN_TOKENS) || addr == address(BUYBACK_HOOK)
|
|
372
|
+
// The loans contract, buyback hook (and its delegates), and suckers are allowed to mint the revnet's tokens.
|
|
373
|
+
return addr == address(LOANS) || addr == address(BUYBACK_HOOK)
|
|
382
374
|
|| BUYBACK_HOOK.hasMintPermissionFor({projectId: revnetId, ruleset: ruleset, addr: addr})
|
|
383
375
|
|| _isSuckerOf({revnetId: revnetId, addr: addr});
|
|
384
376
|
}
|
|
385
377
|
|
|
386
378
|
/// @notice Additional revnet accounts that peer-chain snapshots should include.
|
|
387
|
-
/// @dev
|
|
388
|
-
/// changing loan or cash-out math for other holders. Outstanding loan debt is counted as both surplus and balance:
|
|
379
|
+
/// @dev Outstanding loan debt is counted as both surplus and balance:
|
|
389
380
|
/// it is value owed back to this chain's revnet and should travel to peer snapshots with the collateral supply.
|
|
390
381
|
/// @param revnetId The ID of the revnet to snapshot.
|
|
391
382
|
/// @param decimals The decimals to use for the returned surplus.
|
|
@@ -2,14 +2,9 @@
|
|
|
2
2
|
pragma solidity ^0.8.0;
|
|
3
3
|
|
|
4
4
|
import {IREVDeployer} from "./IREVDeployer.sol";
|
|
5
|
-
import {IREVHiddenTokens} from "./IREVHiddenTokens.sol";
|
|
6
5
|
|
|
7
6
|
/// @notice Interface for the REVOwner contract that handles runtime data hook and cash out hook behavior for revnets.
|
|
8
7
|
interface IREVOwner {
|
|
9
|
-
/// @notice The hidden tokens contract used by the revnet owner hook.
|
|
10
|
-
/// @return The hidden tokens contract.
|
|
11
|
-
function HIDDEN_TOKENS() external view returns (IREVHiddenTokens);
|
|
12
|
-
|
|
13
8
|
/// @notice The timestamp of when cashouts will become available to a specific revnet's participants.
|
|
14
9
|
/// @param revnetId The ID of the revnet.
|
|
15
10
|
/// @return The cash out delay timestamp.
|
package/src/REVHiddenTokens.sol
DELETED
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
pragma solidity 0.8.28;
|
|
3
|
-
|
|
4
|
-
import {IJBController} from "@bananapus/core-v6/src/interfaces/IJBController.sol";
|
|
5
|
-
import {IJBPermissioned} from "@bananapus/core-v6/src/interfaces/IJBPermissioned.sol";
|
|
6
|
-
import {IJBPermissions} from "@bananapus/core-v6/src/interfaces/IJBPermissions.sol";
|
|
7
|
-
import {IJBProjects} from "@bananapus/core-v6/src/interfaces/IJBProjects.sol";
|
|
8
|
-
import {JBPermissioned} from "@bananapus/core-v6/src/abstract/JBPermissioned.sol";
|
|
9
|
-
import {JBPermissionIds} from "@bananapus/permission-ids-v6/src/JBPermissionIds.sol";
|
|
10
|
-
import {ERC2771Context} from "@openzeppelin/contracts/metatx/ERC2771Context.sol";
|
|
11
|
-
import {Context} from "@openzeppelin/contracts/utils/Context.sol";
|
|
12
|
-
|
|
13
|
-
import {IREVHiddenTokens} from "./interfaces/IREVHiddenTokens.sol";
|
|
14
|
-
|
|
15
|
-
/// @notice Allows authorized operators to hide (burn) revnet tokens on behalf of holders, excluding them from
|
|
16
|
-
/// governance weight. Hidden tokens are burned from live circulating supply, but `REVOwner` and `REVLoans` add the
|
|
17
|
-
/// hidden supply back into their economic denominators while those tokens remain revealable.
|
|
18
|
-
/// Hidden tokens can be revealed (re-minted) at any time.
|
|
19
|
-
contract REVHiddenTokens is ERC2771Context, JBPermissioned, IREVHiddenTokens {
|
|
20
|
-
//*********************************************************************//
|
|
21
|
-
// --------------------------- custom errors ------------------------- //
|
|
22
|
-
//*********************************************************************//
|
|
23
|
-
|
|
24
|
-
error REVHiddenTokens_InsufficientHiddenBalance(uint256 hiddenBalance, uint256 requested);
|
|
25
|
-
error REVHiddenTokens_Unauthorized(uint256 revnetId, address caller);
|
|
26
|
-
|
|
27
|
-
//*********************************************************************//
|
|
28
|
-
// --------------- public immutable stored properties ---------------- //
|
|
29
|
-
//*********************************************************************//
|
|
30
|
-
|
|
31
|
-
/// @notice The controller that manages revnets using this contract.
|
|
32
|
-
IJBController public immutable override CONTROLLER;
|
|
33
|
-
|
|
34
|
-
/// @notice The projects contract used to resolve revnet owners.
|
|
35
|
-
IJBProjects public immutable PROJECTS;
|
|
36
|
-
|
|
37
|
-
//*********************************************************************//
|
|
38
|
-
// --------------------- public stored properties -------------------- //
|
|
39
|
-
//*********************************************************************//
|
|
40
|
-
|
|
41
|
-
/// @notice The number of tokens a holder has hidden for a given revnet.
|
|
42
|
-
/// @custom:param holder The address of the token holder.
|
|
43
|
-
/// @custom:param revnetId The ID of the revnet.
|
|
44
|
-
mapping(address holder => mapping(uint256 revnetId => uint256 count)) public override hiddenBalanceOf;
|
|
45
|
-
|
|
46
|
-
/// @notice The total number of hidden tokens for a revnet.
|
|
47
|
-
/// @custom:param revnetId The ID of the revnet.
|
|
48
|
-
mapping(uint256 revnetId => uint256 count) public override totalHiddenOf;
|
|
49
|
-
|
|
50
|
-
/// @notice Whether a holder is allowed to hide their own tokens.
|
|
51
|
-
/// @custom:param holder The holder to check.
|
|
52
|
-
/// @custom:param revnetId The ID of the revnet.
|
|
53
|
-
mapping(address holder => mapping(uint256 revnetId => bool isAllowed)) public override tokenHidingIsAllowedFor;
|
|
54
|
-
|
|
55
|
-
//*********************************************************************//
|
|
56
|
-
// -------------------------- constructor ---------------------------- //
|
|
57
|
-
//*********************************************************************//
|
|
58
|
-
|
|
59
|
-
/// @param controller The controller that manages revnets.
|
|
60
|
-
/// @param trustedForwarder The trusted forwarder for ERC-2771 meta-transactions.
|
|
61
|
-
constructor(
|
|
62
|
-
IJBController controller,
|
|
63
|
-
address trustedForwarder
|
|
64
|
-
)
|
|
65
|
-
ERC2771Context(trustedForwarder)
|
|
66
|
-
JBPermissioned(IJBPermissioned(address(controller)).PERMISSIONS())
|
|
67
|
-
{
|
|
68
|
-
CONTROLLER = controller;
|
|
69
|
-
PROJECTS = controller.PROJECTS();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/// @notice Hide tokens by burning them and tracking them for later reveal.
|
|
73
|
-
/// @dev The caller must be the holder. Hiding is allowed for holders on the operator-managed allowlist,
|
|
74
|
-
/// and also for holders who are themselves the project owner or an operator with `HIDE_TOKENS`.
|
|
75
|
-
/// @dev The holder must have granted BURN_TOKENS permission to this contract.
|
|
76
|
-
/// @param revnetId The ID of the revnet whose tokens to hide.
|
|
77
|
-
/// @param tokenCount The number of tokens to hide.
|
|
78
|
-
/// @param holder The address whose tokens to hide.
|
|
79
|
-
function hideTokensOf(uint256 revnetId, uint256 tokenCount, address holder) external override {
|
|
80
|
-
address caller = _msgSender();
|
|
81
|
-
if (caller != holder) revert REVHiddenTokens_Unauthorized(revnetId, caller);
|
|
82
|
-
|
|
83
|
-
bool isAllowlistedHolder = tokenHidingIsAllowedFor[holder][revnetId];
|
|
84
|
-
bool isPermissionedOperator =
|
|
85
|
-
_hasPermissionFrom(caller, PROJECTS.ownerOf(revnetId), revnetId, JBPermissionIds.HIDE_TOKENS);
|
|
86
|
-
|
|
87
|
-
if (!isAllowlistedHolder && !isPermissionedOperator) {
|
|
88
|
-
revert REVHiddenTokens_Unauthorized({revnetId: revnetId, caller: caller});
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Increment the holder's hidden balance.
|
|
92
|
-
hiddenBalanceOf[holder][revnetId] += tokenCount;
|
|
93
|
-
|
|
94
|
-
// Increment the revnet's total hidden count.
|
|
95
|
-
totalHiddenOf[revnetId] += tokenCount;
|
|
96
|
-
|
|
97
|
-
// Burn the tokens from the holder. The holder must have granted BURN_TOKENS permission.
|
|
98
|
-
CONTROLLER.burnTokensOf({holder: holder, projectId: revnetId, tokenCount: tokenCount, memo: ""});
|
|
99
|
-
|
|
100
|
-
emit HideTokens({revnetId: revnetId, tokenCount: tokenCount, holder: holder, caller: _msgSender()});
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/// @notice Reveal previously hidden tokens by re-minting them.
|
|
104
|
-
/// @dev Any holder can reveal their own hidden tokens without special permissions.
|
|
105
|
-
/// Revealed tokens always return to the holder.
|
|
106
|
-
/// @param revnetId The ID of the revnet whose tokens to reveal.
|
|
107
|
-
/// @param tokenCount The number of tokens to reveal.
|
|
108
|
-
/// @param holder The address whose hidden balance to decrement.
|
|
109
|
-
function revealTokensOf(uint256 revnetId, uint256 tokenCount, address holder) external override {
|
|
110
|
-
address caller = _msgSender();
|
|
111
|
-
if (caller != holder) revert REVHiddenTokens_Unauthorized(revnetId, caller);
|
|
112
|
-
|
|
113
|
-
uint256 hidden = hiddenBalanceOf[holder][revnetId];
|
|
114
|
-
|
|
115
|
-
// Make sure the holder has enough hidden tokens.
|
|
116
|
-
if (hidden < tokenCount) {
|
|
117
|
-
revert REVHiddenTokens_InsufficientHiddenBalance({hiddenBalance: hidden, requested: tokenCount});
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Decrement the holder's hidden balance.
|
|
121
|
-
hiddenBalanceOf[holder][revnetId] = hidden - tokenCount;
|
|
122
|
-
|
|
123
|
-
// Decrement the revnet's total hidden count.
|
|
124
|
-
totalHiddenOf[revnetId] -= tokenCount;
|
|
125
|
-
|
|
126
|
-
// Mint the tokens to the beneficiary without applying the reserved percent.
|
|
127
|
-
CONTROLLER.mintTokensOf({
|
|
128
|
-
projectId: revnetId, tokenCount: tokenCount, beneficiary: holder, memo: "", useReservedPercent: false
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
emit RevealTokens({revnetId: revnetId, tokenCount: tokenCount, holder: holder, caller: _msgSender()});
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/// @notice Allow or disallow a holder to hide their own tokens.
|
|
135
|
-
/// @dev The caller must have `HIDE_TOKENS` permission for the revnet.
|
|
136
|
-
/// @param revnetId The ID of the revnet.
|
|
137
|
-
/// @param holder The holder to update.
|
|
138
|
-
/// @param isAllowed Whether the holder should be allowed.
|
|
139
|
-
function setTokenHidingAllowedFor(uint256 revnetId, address holder, bool isAllowed) external override {
|
|
140
|
-
_requirePermissionFrom({
|
|
141
|
-
account: PROJECTS.ownerOf(revnetId), projectId: revnetId, permissionId: JBPermissionIds.HIDE_TOKENS
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
tokenHidingIsAllowedFor[holder][revnetId] = isAllowed;
|
|
145
|
-
|
|
146
|
-
emit SetTokenHidingAllowed({revnetId: revnetId, holder: holder, isAllowed: isAllowed});
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
//*********************************************************************//
|
|
150
|
-
// ------------------------ internal overrides ----------------------- //
|
|
151
|
-
//*********************************************************************//
|
|
152
|
-
|
|
153
|
-
/// @dev Resolve the `_msgSender` conflict between `ERC2771Context` and `Context` (from `JBPermissioned`).
|
|
154
|
-
/// Prefer the ERC2771 version.
|
|
155
|
-
function _msgSender() internal view override(ERC2771Context, Context) returns (address) {
|
|
156
|
-
return ERC2771Context._msgSender();
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/// @dev Resolve the `_msgData` conflict between `ERC2771Context` and `Context` (from `JBPermissioned`).
|
|
160
|
-
/// Prefer the ERC2771 version.
|
|
161
|
-
function _msgData() internal view override(ERC2771Context, Context) returns (bytes calldata) {
|
|
162
|
-
return ERC2771Context._msgData();
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/// @dev Resolve the `_contextSuffixLength` conflict between `ERC2771Context` and `Context`.
|
|
166
|
-
function _contextSuffixLength() internal view override(ERC2771Context, Context) returns (uint256) {
|
|
167
|
-
return ERC2771Context._contextSuffixLength();
|
|
168
|
-
}
|
|
169
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
pragma solidity ^0.8.0;
|
|
3
|
-
|
|
4
|
-
import {IJBController} from "@bananapus/core-v6/src/interfaces/IJBController.sol";
|
|
5
|
-
|
|
6
|
-
/// @notice Manages hiding (burning) and revealing (re-minting) revnet tokens to exclude them from live totalSupply.
|
|
7
|
-
/// @dev Hidden balances are an operator-controlled security handle. They remain revealable, but cash-out and loan
|
|
8
|
-
/// accounting intentionally excludes `totalHiddenOf` so hidden inventory cannot dilute other holders' access to
|
|
9
|
-
/// revnet capital.
|
|
10
|
-
interface IREVHiddenTokens {
|
|
11
|
-
/// @notice Emitted when a holder is allowed or disallowed to hide their own tokens.
|
|
12
|
-
/// @param revnetId The ID of the revnet.
|
|
13
|
-
/// @param holder The holder to allow or disallow.
|
|
14
|
-
/// @param isAllowed Whether the holder is allowed.
|
|
15
|
-
event SetTokenHidingAllowed(uint256 indexed revnetId, address indexed holder, bool isAllowed);
|
|
16
|
-
|
|
17
|
-
/// @notice Emitted when tokens are hidden (burned and tracked for later reveal).
|
|
18
|
-
/// @param revnetId The ID of the revnet whose tokens were hidden.
|
|
19
|
-
/// @param tokenCount The number of tokens hidden.
|
|
20
|
-
/// @param holder The address whose tokens were hidden.
|
|
21
|
-
/// @param caller The address that hid the tokens.
|
|
22
|
-
event HideTokens(uint256 indexed revnetId, uint256 tokenCount, address holder, address caller);
|
|
23
|
-
|
|
24
|
-
/// @notice Emitted when previously hidden tokens are revealed (re-minted).
|
|
25
|
-
/// @param revnetId The ID of the revnet whose tokens are revealed.
|
|
26
|
-
/// @param tokenCount The number of tokens revealed.
|
|
27
|
-
/// @param holder The address whose hidden balance is decremented.
|
|
28
|
-
/// @param caller The address that revealed the tokens.
|
|
29
|
-
event RevealTokens(uint256 indexed revnetId, uint256 tokenCount, address holder, address caller);
|
|
30
|
-
|
|
31
|
-
/// @notice The controller that manages revnets using this contract.
|
|
32
|
-
/// @return The controller contract.
|
|
33
|
-
function CONTROLLER() external view returns (IJBController);
|
|
34
|
-
|
|
35
|
-
/// @notice The number of tokens a holder has hidden for a given revnet.
|
|
36
|
-
/// @param holder The address of the token holder.
|
|
37
|
-
/// @param revnetId The ID of the revnet.
|
|
38
|
-
/// @return The number of hidden tokens.
|
|
39
|
-
function hiddenBalanceOf(address holder, uint256 revnetId) external view returns (uint256);
|
|
40
|
-
|
|
41
|
-
/// @notice The total number of hidden tokens for a revnet.
|
|
42
|
-
/// @param revnetId The ID of the revnet.
|
|
43
|
-
/// @return The total hidden token count.
|
|
44
|
-
function totalHiddenOf(uint256 revnetId) external view returns (uint256);
|
|
45
|
-
|
|
46
|
-
/// @notice Whether a holder is allowed to hide their own tokens.
|
|
47
|
-
/// @param holder The holder to check.
|
|
48
|
-
/// @param revnetId The ID of the revnet.
|
|
49
|
-
/// @return Whether the holder is allowed.
|
|
50
|
-
function tokenHidingIsAllowedFor(address holder, uint256 revnetId) external view returns (bool);
|
|
51
|
-
|
|
52
|
-
/// @notice Hide tokens by burning them and tracking them for later reveal.
|
|
53
|
-
/// @dev The holder must have granted BURN_TOKENS permission to this contract.
|
|
54
|
-
/// @param revnetId The ID of the revnet whose tokens to hide.
|
|
55
|
-
/// @param tokenCount The number of tokens to hide.
|
|
56
|
-
/// @param holder The address whose tokens to hide.
|
|
57
|
-
function hideTokensOf(uint256 revnetId, uint256 tokenCount, address holder) external;
|
|
58
|
-
|
|
59
|
-
/// @notice Reveal previously hidden tokens by re-minting them.
|
|
60
|
-
/// @param revnetId The ID of the revnet whose tokens to reveal.
|
|
61
|
-
/// @param tokenCount The number of tokens to reveal.
|
|
62
|
-
/// @param holder The address whose hidden balance to decrement.
|
|
63
|
-
function revealTokensOf(uint256 revnetId, uint256 tokenCount, address holder) external;
|
|
64
|
-
|
|
65
|
-
/// @notice Allow or disallow a holder to hide their own tokens.
|
|
66
|
-
/// @dev The caller must have `HIDE_TOKENS` permission for the revnet.
|
|
67
|
-
/// @param revnetId The ID of the revnet.
|
|
68
|
-
/// @param holder The holder to update.
|
|
69
|
-
/// @param isAllowed Whether the holder should be allowed.
|
|
70
|
-
function setTokenHidingAllowedFor(uint256 revnetId, address holder, bool isAllowed) external;
|
|
71
|
-
}
|