Skip to content

Commit

Permalink
Merge pull request #158 from Bananapus/adjust/redemption-hook-values
Browse files Browse the repository at this point in the history
adjust redemption hook values
  • Loading branch information
mejango authored Jun 25, 2024
2 parents 867b9a8 + 086ffb8 commit 7da1b2a
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 81 deletions.
2 changes: 1 addition & 1 deletion lib/sphinx
Submodule sphinx updated 73 files
+1 −4 .circleci/config.yml
+24 −9 .github/workflows/docker-image.yml
+1 −7 README.md
+0 −57 docs/breaking/registration.md
+30 −32 docs/cli-existing-project.md
+13 −10 docs/cli-quickstart.md
+107 −8 ops/ci-builder/Dockerfile
+8 −0 ops/ci-builder/check-changed.sh
+1 −1 package.json
+0 −45 packages/contracts/CHANGELOG.md
+9 −8 packages/contracts/contracts/foundry/Sphinx.sol
+7 −61 packages/contracts/contracts/foundry/SphinxConstants.sol
+3 −34 packages/contracts/contracts/foundry/SphinxPluginTypes.sol
+99 −93 packages/contracts/contracts/foundry/SphinxUtils.sol
+2 −2 packages/contracts/package.json
+0 −30 packages/contracts/sphinx.lock
+0 −147 packages/contracts/src/addresses.ts
+14 −334 packages/contracts/src/networks.ts
+22 −0 packages/contracts/src/utils.ts
+1 −1 packages/contracts/src/version.ts
+1 −1 packages/contracts/test/ManagedService.t.sol
+15 −9 packages/contracts/test/ScriptConfiguration.t.sol
+13 −7 packages/contracts/test/Sphinx.t.sol
+7 −8 packages/contracts/test/SphinxTestUtils.sol
+51 −5 packages/contracts/test/SphinxUtils.t.sol
+21 −0 packages/contracts/test/issues/CHU572.s.sol
+4 −1 packages/contracts/test/issues/CHU663.s.sol
+23 −0 packages/contracts/test/issues/CHU663/CHU663.s.sol
+0 −38 packages/contracts/test/mocha/address.spec.ts
+35 −0 packages/contracts/test/mocha/utils.spec.ts
+0 −62 packages/core/CHANGELOG.md
+3 −3 packages/core/package.json
+3 −8 packages/core/src/actions/execute.ts
+8 −3 packages/core/src/actions/types.ts
+7 −6 packages/core/src/artifacts.ts
+5 −8 packages/core/src/config/types.ts
+1 −2 packages/core/src/languages/solidity/types.ts
+0 −25 packages/core/src/networks.ts
+0 −18 packages/core/src/types.ts
+64 −52 packages/core/src/utils.ts
+7 −17 packages/core/test/convert.spec.ts
+0 −13 packages/demo/CHANGELOG.md
+5 −5 packages/demo/package.json
+0 −18 packages/demo/sphinx.lock
+2 −2 packages/demo/test/Solc.spec.ts
+16 −22 packages/demo/test/init.spec.ts
+0 −83 packages/plugins/CHANGELOG.md
+5 −1 packages/plugins/contracts/test/script/Cases.s.sol
+4 −0 packages/plugins/contracts/test/script/Empty.s.sol
+5 −1 packages/plugins/contracts/test/script/Large.s.sol
+5 −1 packages/plugins/contracts/test/script/PartiallyEmpty.s.sol
+5 −1 packages/plugins/contracts/test/script/RevertDuringSimulation.s.sol
+15 −3 packages/plugins/contracts/test/script/Simple.s.sol
+4 −1 packages/plugins/contracts/test/script/issues/CHU676.s.sol
+0 −4 packages/plugins/foundry.toml
+5 −6 packages/plugins/package.json
+7 −3 packages/plugins/script/Sample.s.sol
+0 −12 packages/plugins/script/write-version.ts
+0 −18 packages/plugins/sphinx.lock
+6 −10 packages/plugins/src/cli/propose/index.ts
+5 −30 packages/plugins/src/cli/setup.ts
+0 −1 packages/plugins/src/cli/version.ts
+4 −1 packages/plugins/src/foundry/decode.ts
+30 −35 packages/plugins/src/foundry/utils/index.ts
+8 −6 packages/plugins/src/sample-project/index.ts
+11 −4 packages/plugins/src/sample-project/sample-contracts.ts
+1 −2 packages/plugins/src/sample-project/sample-foundry-config.ts
+2 −5 packages/plugins/test/mocha/artifacts.spec.ts
+2 −2 packages/plugins/test/mocha/cli/deploy.spec.ts
+11 −7 packages/plugins/test/mocha/cli/propose.spec.ts
+133 −2 packages/plugins/test/mocha/common.ts
+1 −32 packages/plugins/test/mocha/foundry/utils.spec.ts
+2 −4 packages/plugins/test/mocha/simulate.spec.ts
119 changes: 39 additions & 80 deletions src/JBTerminalStore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {IJBTerminal} from "./interfaces/IJBTerminal.sol";
import {IJBTerminalStore} from "./interfaces/IJBTerminalStore.sol";
import {JBConstants} from "./libraries/JBConstants.sol";
import {JBFixedPointNumber} from "./libraries/JBFixedPointNumber.sol";
import {JBRedemptions} from "./libraries/JBRedemptions.sol";
import {JBRulesetMetadataResolver} from "./libraries/JBRulesetMetadataResolver.sol";
import {JBAccountingContext} from "./structs/JBAccountingContext.sol";
import {JBBeforePayRecordedContext} from "./structs/JBBeforePayRecordedContext.sol";
Expand Down Expand Up @@ -169,29 +170,27 @@ contract JBTerminalStore is ReentrancyGuard, IJBTerminalStore {
return _currentTotalSurplusOf(projectId, decimals, currency);
}

/// @notice The surplus amount that can currently be reclaimed from a terminal by redeeming the specified number of
/// tokens, based on the total token supply and current surplus.
/// @dev The returned amount in terms of the specified terminal's currency.
/// @notice Returns the number of surplus terminal tokens that would be reclaimed from a terminal by redeeming a
/// given number of tokens, based on the total token supply and total surplus.
/// @dev The returned amount in terms of the specified `terminal`'s base currency.
/// @dev The returned amount is represented as a fixed point number with the same amount of decimals as the
/// specified terminal.
/// @param terminal The terminal the redeemable amount would come from.
/// @param projectId The ID of the project to get the redeemable surplus amount for.
/// @param accountingContexts The accounting contexts of tokens whose balances should contribute to the surplus
/// being reclaimed from.
/// @param terminal The terminal that would be redeemed from. If `useTotalSurplus` is true, this is ignored.
/// @param projectId The ID of the project whose tokens would be redeemed.
/// @param accountingContexts The accounting contexts of the surplus terminal tokens that would be reclaimed
/// @param decimals The number of decimals to include in the resulting fixed point number.
/// @param currency The currency that the resulting number will be in terms of.
/// @param tokenCount The number of tokens to make the calculation with, as a fixed point number with 18 decimals.
/// @param useTotalSurplus A flag indicating whether the surplus used in the calculation should be summed from all
/// of the project's terminals. If false, surplus should be limited to the amount in the specified `terminal`.
/// @return The amount of surplus tokens that can be reclaimed by redeeming `tokenCount` tokens as a fixed point
/// number with the specified number of decimals.
/// @param tokensRedeemed The number of tokens that would be redeemed, as a fixed point number with 18 decimals.
/// @param useTotalSurplus Whether the total surplus should be summed across all of the project's terminals. If
/// false, only the `terminal`'s surplus is used.
/// @return The amount of surplus terminal tokens that would be reclaimed by redeeming `tokensRedeemed` tokens.
function currentReclaimableSurplusOf(
address terminal,
uint256 projectId,
JBAccountingContext[] calldata accountingContexts,
uint256 decimals,
uint256 currency,
uint256 tokenCount,
uint256 tokensRedeemed,
bool useTotalSurplus
)
external
Expand All @@ -203,43 +202,43 @@ contract JBTerminalStore is ReentrancyGuard, IJBTerminalStore {
JBRuleset memory ruleset = RULESETS.currentOf(projectId);

// Get the current surplus amount.
// Use the project's total surplus across all of its terminals if the flag species specifies so. Otherwise, use
// the surplus local to the specified terminal.
// If `useTotalSurplus` is true, use the total surplus across all terminals. Otherwise, get the `terminal`'s
// surplus.
uint256 currentSurplus = useTotalSurplus
? _currentTotalSurplusOf(projectId, decimals, currency)
: _surplusFrom(terminal, projectId, accountingContexts, ruleset, decimals, currency);

// If there's no surplus, there's no reclaimable surplus.
// If there's no surplus, nothing can be reclaimed.
if (currentSurplus == 0) return 0;

// Get the number of outstanding tokens the project has.
// Get the project token's total supply.
uint256 totalSupply =
IJBController(address(DIRECTORY.controllerOf(projectId))).totalTokenSupplyWithReservedTokensOf(projectId);

// Can't redeem more tokens that is in the supply.
if (tokenCount > totalSupply) return 0;
// Can't redeem more tokens than are in the total supply.
if (tokensRedeemed > totalSupply) return 0;

// Return the reclaimable surplus amount.
return _reclaimableSurplusFrom({
// Return the amount of surplus terminal tokens that would be reclaimed.
return JBRedemptions.reclaimFrom({
surplus: currentSurplus,
tokenCount: tokenCount,
tokensRedeemed: tokensRedeemed,
totalSupply: totalSupply,
redemptionRate: ruleset.redemptionRate()
});
}

/// @notice The current amount of surplus tokens from a terminal that can be reclaimed by redeeming the specified
/// number of tokens, based on the specified total token supply and surplus amounts.
/// @param projectId The ID of the project to get the reclaimable surplus amount for.
/// @param tokenCount The number of tokens to make the calculation with, as a fixed point number with 18 decimals.
/// @param totalSupply The total number of tokens to make the calculation with, as a fixed point number with 18
/// @notice Returns the number of surplus terminal tokens that would be reclaimed by redeeming a given project's
/// tokens based on its current ruleset and the given total project token supply and total terminal token surplus.
/// @param projectId The ID of the project whose project tokens would be redeemed.
/// @param tokensRedeemed The number of project tokens that would be redeemed, as a fixed point number with 18
/// decimals.
/// @param surplus The surplus amount to make the calculation with, as a fixed point number.
/// @return The surplus token amount that can be reclaimed, as a fixed point number with the same number of decimals
/// as the provided `surplus`.
/// @param totalSupply The total project token supply, as a fixed point number with 18 decimals.
/// @param surplus The total terminal token surplus amount, as a fixed point number.
/// @return The number of surplus terminal tokens that would be reclaimed, as a fixed point number with the same
/// number of decimals as the provided `surplus`.
function currentReclaimableSurplusOf(
uint256 projectId,
uint256 tokenCount,
uint256 tokensRedeemed,
uint256 totalSupply,
uint256 surplus
)
Expand All @@ -248,19 +247,19 @@ contract JBTerminalStore is ReentrancyGuard, IJBTerminalStore {
override
returns (uint256)
{
// If there's no surplus, there's no reclaimable surplus.
// If there's no surplus, nothing can be reclaimed.
if (surplus == 0) return 0;

// Can't redeem more tokens than is in the supply.
if (tokenCount > totalSupply) return 0;
// Can't redeem more tokens than are in the total supply.
if (tokensRedeemed > totalSupply) return 0;

// Get a reference to the project's current ruleset.
JBRuleset memory ruleset = RULESETS.currentOf(projectId);

// Return the reclaimable surplus amount.
return _reclaimableSurplusFrom({
// Return the amount of surplus terminal tokens that would be reclaimed.
return JBRedemptions.reclaimFrom({
surplus: surplus,
tokenCount: tokenCount,
tokensRedeemed: tokensRedeemed,
totalSupply: totalSupply,
redemptionRate: ruleset.redemptionRate()
});
Expand Down Expand Up @@ -493,15 +492,15 @@ contract JBTerminalStore is ReentrancyGuard, IJBTerminalStore {

if (currentSurplus != 0) {
// Calculate reclaim amount using the current surplus amount.
reclaimAmount = _reclaimableSurplusFrom({
reclaimAmount = JBRedemptions.reclaimFrom({
surplus: currentSurplus,
tokenCount: redeemCount,
tokensRedeemed: redeemCount,
totalSupply: totalSupply,
redemptionRate: redemptionRate
});
}

// Keep a reference to the amount that should be subtracted from the project's balance.
// Keep a reference to the amount that should be added to the project's balance.
uint256 balanceDiff = reclaimAmount;

// Ensure that the specifications have valid amounts.
Expand Down Expand Up @@ -735,46 +734,6 @@ contract JBTerminalStore is ReentrancyGuard, IJBTerminalStore {
// --------------------- internal helper functions ------------------- //
//*********************************************************************//

/// @notice The amount of surplus which is available for reclaiming via redemption given the number of tokens being
/// redeemed, the total supply, the current surplus, and the current ruleset.
/// @param surplus The surplus amount to make the calculation with.
/// @param tokenCount The number of tokens to make the calculation with, as a fixed point number with 18 decimals.
/// @param totalSupply The total supply of tokens to make the calculation with, as a fixed point number with 18
/// decimals.
/// @param redemptionRate The redemption rate with which the reclaimable surplus is being calculated.
/// @return The amount of surplus tokens that can be reclaimed.
function _reclaimableSurplusFrom(
uint256 surplus,
uint256 tokenCount,
uint256 totalSupply,
uint256 redemptionRate
)
internal
pure
returns (uint256)
{
// If the redemption rate is 0, nothing is claimable.
if (redemptionRate == 0) return 0;

// If the amount being redeemed is the total supply, return the rest of the surplus.
if (tokenCount == totalSupply) return surplus;

// Get a reference to the linear proportion.
uint256 base = mulDiv(surplus, tokenCount, totalSupply);

// These conditions are all part of the same curve. Edge conditions are separated because fewer operation are
// necessary.
if (redemptionRate == JBConstants.MAX_REDEMPTION_RATE) {
return base;
}

return mulDiv(
base,
redemptionRate + mulDiv(tokenCount, JBConstants.MAX_REDEMPTION_RATE - redemptionRate, totalSupply),
JBConstants.MAX_REDEMPTION_RATE
);
}

/// @notice Gets a project's surplus amount in a terminal as measured by a given ruleset, across multiple accounting
/// contexts.
/// @dev This amount changes as the value of the balance changes in relation to the currency being used to measure
Expand Down
48 changes: 48 additions & 0 deletions src/libraries/JBRedemptionFormula.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import {mulDiv} from "@prb/math/src/Common.sol";

import {JBConstants} from "./JBConstants.sol";

library JBRedemptionFormula {
/// @notice The amount of surplus which is available for reclaiming via redemption given the number of tokens being
/// redeemed, the total supply, the current surplus, and the current ruleset.
/// @param surplus The surplus amount to make the calculation with.
/// @param tokenCount The number of tokens to make the calculation with, as a fixed point number with 18 decimals.
/// @param totalSupply The total supply of tokens to make the calculation with, as a fixed point number with 18
/// decimals.
/// @param redemptionRate The redemption rate with which the reclaimable surplus is being calculated.
/// @return The amount of surplus tokens that can be reclaimed.
function reclaimableSurplusFrom(
uint256 surplus,
uint256 tokenCount,
uint256 totalSupply,
uint256 redemptionRate
)
internal
pure
returns (uint256)
{
// If the redemption rate is 0, nothing is claimable.
if (redemptionRate == 0) return 0;

// If the amount being redeemed is the total supply, return the rest of the surplus.
if (tokenCount == totalSupply) return surplus;

// Get a reference to the linear proportion.
uint256 base = mulDiv(surplus, tokenCount, totalSupply);

// These conditions are all part of the same curve. Edge conditions are separated because fewer operation are
// necessary.
if (redemptionRate == JBConstants.MAX_REDEMPTION_RATE) {
return base;
}

return mulDiv(
base,
redemptionRate + mulDiv(tokenCount, JBConstants.MAX_REDEMPTION_RATE - redemptionRate, totalSupply),
JBConstants.MAX_REDEMPTION_RATE
);
}
}
48 changes: 48 additions & 0 deletions src/libraries/JBRedemptions.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import {mulDiv} from "@prb/math/src/Common.sol";

import {JBConstants} from "./JBConstants.sol";

/// @notice Redemption calculations.
library JBRedemptions {
/// @notice Returns the amount of surplus terminal tokens which can be reclaimed based on the total surplus, the
/// number of tokens being redeemed, the total token supply, and the ruleset's redemption rate.
/// @param surplus The total amount of surplus terminal tokens.
/// @param tokensRedeemed The number of tokens being redeemed, as a fixed point number with 18 decimals.
/// @param totalSupply The total token supply, as a fixed point number with 18 decimals.
/// @param redemptionRate The current ruleset's redemption rate.
/// @return The amount of surplus tokens that can be reclaimed.
function reclaimFrom(
uint256 surplus,
uint256 tokensRedeemed,
uint256 totalSupply,
uint256 redemptionRate
)
internal
pure
returns (uint256)
{
// If the redemption rate is 0, no surplus can be reclaimed.
if (redemptionRate == 0) return 0;

// If the total supply is being redeemed, return the entire surplus.
if (tokensRedeemed == totalSupply) return surplus;

// Get a reference to the linear proportion.
uint256 base = mulDiv(surplus, tokensRedeemed, totalSupply);

// These conditions are all part of the same curve.
// Edge conditions are separated to minimize the operations performed in those cases.
if (redemptionRate == JBConstants.MAX_REDEMPTION_RATE) {
return base;
}

return mulDiv(
base,
redemptionRate + mulDiv(tokensRedeemed, JBConstants.MAX_REDEMPTION_RATE - redemptionRate, totalSupply),
JBConstants.MAX_REDEMPTION_RATE
);
}
}

0 comments on commit 7da1b2a

Please sign in to comment.