@rev-net/core-v6 0.0.44 → 0.0.46

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rev-net/core-v6",
3
- "version": "0.0.44",
3
+ "version": "0.0.46",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,14 +26,14 @@
26
26
  "artifacts": "source ./.env && npx sphinx artifacts --org-id 'ea165b21-7cdc-4d7b-be59-ecdd4c26bee4' --project-name 'revnet-core-v6'"
27
27
  },
28
28
  "dependencies": {
29
- "@bananapus/721-hook-v6": "0.0.43",
30
- "@bananapus/buyback-hook-v6": "0.0.37",
31
- "@bananapus/core-v6": "0.0.42",
32
- "@bananapus/ownable-v6": "0.0.24",
33
- "@bananapus/permission-ids-v6": "0.0.22",
34
- "@bananapus/router-terminal-v6": "0.0.36",
35
- "@bananapus/suckers-v6": "0.0.33",
36
- "@croptop/core-v6": "0.0.39",
29
+ "@bananapus/721-hook-v6": "^0.0.47",
30
+ "@bananapus/buyback-hook-v6": "^0.0.39",
31
+ "@bananapus/core-v6": "^0.0.44",
32
+ "@bananapus/ownable-v6": "^0.0.24",
33
+ "@bananapus/permission-ids-v6": "^0.0.23",
34
+ "@bananapus/router-terminal-v6": "^0.0.37",
35
+ "@bananapus/suckers-v6": "^0.0.37",
36
+ "@croptop/core-v6": "^0.0.42",
37
37
  "@openzeppelin/contracts": "5.6.1",
38
38
  "@uniswap/permit2": "github:Uniswap/permit2#cc56ad0f3439c502c246fc5cfcc3db92bb8b7219"
39
39
  },
@@ -266,6 +266,7 @@ REVConfig memory config = REVConfig({
266
266
  }),
267
267
  baseCurrency: 1, // ETH
268
268
  splitOperator: msg.sender,
269
+ scopeCashOutsToLocalBalances: false,
269
270
  stageConfigurations: stages
270
271
  });
271
272
 
@@ -271,6 +271,7 @@ contract DeployScript is Script, Sphinx {
271
271
  description: REVDescription({name: NAME, ticker: SYMBOL, uri: PROJECT_URI, salt: ERC20_SALT}),
272
272
  baseCurrency: ETH_CURRENCY,
273
273
  splitOperator: OPERATOR,
274
+ scopeCashOutsToLocalBalances: false,
274
275
  stageConfigurations: stageConfigurations
275
276
  });
276
277
 
@@ -497,7 +498,8 @@ contract DeployScript is Script, Sphinx {
497
498
  feeRevnetId: FEE_PROJECT_ID,
498
499
  suckerRegistry: suckers.registry,
499
500
  loans: revloans,
500
- hiddenTokens: revHiddenTokens
501
+ hiddenTokens: revHiddenTokens,
502
+ deployerBinder: msg.sender
501
503
  });
502
504
 
503
505
  // Deploy REVDeployer with the REVLoans, buyback hook, and REVOwner addresses.
@@ -316,11 +316,13 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IERC721Receiver {
316
316
 
317
317
  /// @notice Make a ruleset configuration for a revnet's stage.
318
318
  /// @param baseCurrency The base currency of the revnet.
319
+ /// @param scopeCashOutsToLocalBalances If true, cash-out calculations use only the local terminal's surplus.
319
320
  /// @param stageConfiguration The stage configuration to build a ruleset from.
320
321
  /// @param fundAccessLimitGroups The fund access limit groups to include in the ruleset.
321
322
  /// @return rulesetConfiguration The ruleset configuration.
322
323
  function _makeRulesetConfiguration(
323
324
  uint32 baseCurrency,
325
+ bool scopeCashOutsToLocalBalances,
324
326
  REVStageConfig calldata stageConfiguration,
325
327
  JBFundAccessLimitGroup[] memory fundAccessLimitGroups
326
328
  )
@@ -333,7 +335,7 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IERC721Receiver {
333
335
  metadata.reservedPercent = stageConfiguration.splitPercent;
334
336
  metadata.cashOutTaxRate = stageConfiguration.cashOutTaxRate;
335
337
  metadata.baseCurrency = baseCurrency;
336
- metadata.useTotalSurplusForCashOuts = true; // Use surplus from all terminals for cash outs.
338
+ metadata.scopeCashOutsToLocalBalances = scopeCashOutsToLocalBalances;
337
339
  metadata.allowOwnerMinting = true; // Allow this contract to auto-mint tokens as the revnet's owner.
338
340
  metadata.useDataHookForPay = true; // Call this contract's `beforePayRecordedWith(…)` callback on payments.
339
341
  metadata.useDataHookForCashOut = true; // Call this contract's `beforeCashOutRecordedWith(…)` callback on cash
@@ -940,6 +942,7 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IERC721Receiver {
940
942
  // Add the base configuration to the byte-encoded configuration.
941
943
  bytes memory encodedConfiguration = abi.encode(
942
944
  configuration.baseCurrency,
945
+ configuration.scopeCashOutsToLocalBalances,
943
946
  configuration.description.name,
944
947
  configuration.description.ticker,
945
948
  configuration.description.salt
@@ -1002,6 +1005,7 @@ contract REVDeployer is ERC2771Context, IREVDeployer, IERC721Receiver {
1002
1005
  // Set up the ruleset.
1003
1006
  rulesetConfigurations[i] = _makeRulesetConfiguration({
1004
1007
  baseCurrency: configuration.baseCurrency,
1008
+ scopeCashOutsToLocalBalances: configuration.scopeCashOutsToLocalBalances,
1005
1009
  stageConfiguration: stageConfiguration,
1006
1010
  fundAccessLimitGroups: fundAccessLimitGroups
1007
1011
  });
package/src/REVLoans.sol CHANGED
@@ -372,14 +372,19 @@ contract REVLoans is ERC721, ERC2771Context, JBPermissioned, Ownable, IREVLoans
372
372
  // for the same collateral changes. A lower cashOutTaxRate in a later stage means more borrowable value per
373
373
  // collateral. This is by design: loan value tracks the current bonding curve parameters, just as cash-out
374
374
  // value does. Borrowers benefit from decreasing tax rates and are constrained by increasing ones.
375
- // Add cross-chain remote values for proportional reclaim.
376
- uint256 omnichainSurplus = localSurplus
377
- + SUCKER_REGISTRY.remoteSurplusOf({projectId: revnetId, decimals: decimals, currency: currency});
378
- uint256 omnichainSupply = localSupply + SUCKER_REGISTRY.remoteTotalSupplyOf(revnetId);
375
+ // Start with local values. If the ruleset aggregates cross-chain state, add remote supply and surplus.
376
+ uint256 effectiveSurplus = localSurplus;
377
+ uint256 effectiveSupply = localSupply;
378
+ if (!currentStage.scopeCashOutsToLocalBalances()) {
379
+ effectiveSurplus += SUCKER_REGISTRY.remoteSurplusOf({
380
+ projectId: revnetId, decimals: decimals, currency: currency
381
+ });
382
+ effectiveSupply += SUCKER_REGISTRY.remoteTotalSupplyOf(revnetId);
383
+ }
379
384
  uint256 reclaimable = JBCashOuts.cashOutFrom({
380
- surplus: omnichainSurplus,
385
+ surplus: effectiveSurplus,
381
386
  cashOutCount: collateralCount,
382
- totalSupply: omnichainSupply,
387
+ totalSupply: effectiveSupply,
383
388
  cashOutTaxRate: currentStage.cashOutTaxRate()
384
389
  });
385
390
  // Cap at local surplus — can't borrow more than what this chain's terminals actually hold.
package/src/REVOwner.sol CHANGED
@@ -112,13 +112,16 @@ contract REVOwner is IJBRulesetDataHook, IJBCashOutHook, IJBPeerChainAdjustedAcc
112
112
  /// @param suckerRegistry The sucker registry.
113
113
  /// @param loans The loan contract.
114
114
  /// @param hiddenTokens The hidden tokens contract.
115
+ /// @param deployerBinder The account allowed to bind the canonical deployer via `setDeployer`. Passed explicitly
116
+ /// because CREATE2 deployments set `msg.sender` to the factory, not the intended operator.
115
117
  constructor(
116
118
  IJBBuybackHookRegistry buybackHook,
117
119
  IJBDirectory directory,
118
120
  uint256 feeRevnetId,
119
121
  IJBSuckerRegistry suckerRegistry,
120
122
  IREVLoans loans,
121
- IREVHiddenTokens hiddenTokens
123
+ IREVHiddenTokens hiddenTokens,
124
+ address deployerBinder
122
125
  ) {
123
126
  BUYBACK_HOOK = buybackHook;
124
127
  DIRECTORY = directory;
@@ -126,7 +129,7 @@ contract REVOwner is IJBRulesetDataHook, IJBCashOutHook, IJBPeerChainAdjustedAcc
126
129
  SUCKER_REGISTRY = suckerRegistry;
127
130
  LOANS = loans;
128
131
  HIDDEN_TOKENS = hiddenTokens;
129
- _DEPLOYER_BINDER = msg.sender;
132
+ _DEPLOYER_BINDER = deployerBinder;
130
133
  }
131
134
 
132
135
  //*********************************************************************//
@@ -190,15 +193,19 @@ contract REVOwner is IJBRulesetDataHook, IJBCashOutHook, IJBPeerChainAdjustedAcc
190
193
  // Get the terminal that will receive the cash out fee.
191
194
  IJBTerminal feeTerminal = DIRECTORY.primaryTerminalOf({projectId: FEE_REVNET_ID, token: context.surplus.token});
192
195
 
193
- // Compute the cross-chain total supply (local + remote peer chain supplies) for cross-chain-aware bonding
194
- // curve.
195
- totalSupply = context.totalSupply + totalCollateral + SUCKER_REGISTRY.remoteTotalSupplyOf(context.projectId);
196
- effectiveSurplusValue = context.surplus.value + totalBorrowed
197
- + SUCKER_REGISTRY.remoteSurplusOf({
196
+ // Start with local supply and surplus (including collateral and borrowed amounts).
197
+ totalSupply = context.totalSupply + totalCollateral;
198
+ effectiveSurplusValue = context.surplus.value + totalBorrowed;
199
+
200
+ // If the ruleset aggregates cross-chain state, add remote supply and surplus.
201
+ if (!context.scopeCashOutsToLocalBalances) {
202
+ totalSupply += SUCKER_REGISTRY.remoteTotalSupplyOf(context.projectId);
203
+ effectiveSurplusValue += SUCKER_REGISTRY.remoteSurplusOf({
198
204
  projectId: context.projectId,
199
205
  decimals: context.surplus.decimals,
200
206
  currency: uint256(context.surplus.currency)
201
207
  });
208
+ }
202
209
 
203
210
  // If there's no cash out tax (100% cash out tax rate), if there's no fee terminal, or if the beneficiary is
204
211
  // feeless (e.g. the router terminal routing value between projects), proxy to the buyback hook with our
@@ -11,10 +11,13 @@ import {REVStageConfig} from "./REVStageConfig.sol";
11
11
  /// @custom:member baseCurrency The currency that issuance pricing is denominated in (e.g. ETH or USD).
12
12
  /// @custom:member splitOperator The address that receives production splits and can reassign the operator role.
13
13
  /// Only the current operator can replace itself after deployment.
14
+ /// @custom:member scopeCashOutsToLocalBalances If true, cash-out calculations use only the local terminal's surplus.
15
+ /// When false, the bonding curve considers surplus from every terminal across all chains.
14
16
  /// @custom:member stageConfigurations The ordered stages that define how the revnet's tokenomics evolve over time.
15
17
  struct REVConfig {
16
18
  REVDescription description;
17
19
  uint32 baseCurrency;
18
20
  address splitOperator;
21
+ bool scopeCashOutsToLocalBalances;
19
22
  REVStageConfig[] stageConfigurations;
20
23
  }