From 42fb2d5c57923c1ef6f11ae80d55afff1bce7399 Mon Sep 17 00:00:00 2001 From: mejango Date: Fri, 1 Sep 2023 09:56:33 -0400 Subject: [PATCH 1/2] removed fee gauge and fee discount --- .../JBPayoutRedemptionPaymentTerminal3_2.sol | 190 ++++++------------ .../IJBPayoutRedemptionPaymentTerminal3_2.sol | 5 +- contracts/libraries/JBFees3_2.sol | 27 +++ contracts/structs/JBFee3_2.sol | 11 + 4 files changed, 98 insertions(+), 135 deletions(-) create mode 100644 contracts/libraries/JBFees3_2.sol create mode 100644 contracts/structs/JBFee3_2.sol diff --git a/contracts/abstract/JBPayoutRedemptionPaymentTerminal3_2.sol b/contracts/abstract/JBPayoutRedemptionPaymentTerminal3_2.sol index d59bc6ef7..3a6766dda 100644 --- a/contracts/abstract/JBPayoutRedemptionPaymentTerminal3_2.sol +++ b/contracts/abstract/JBPayoutRedemptionPaymentTerminal3_2.sol @@ -5,13 +5,11 @@ import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol'; import {IERC165} from '@openzeppelin/contracts/utils/introspection/IERC165.sol'; import {ERC165Checker} from '@openzeppelin/contracts/utils/introspection/ERC165Checker.sol'; import {PRBMath} from '@paulrberg/contracts/math/PRBMath.sol'; -import {JBFeeType} from './../enums/JBFeeType.sol'; import {IJBAllowanceTerminal3_1} from './../interfaces/IJBAllowanceTerminal3_1.sol'; import {IJBController} from './../interfaces/IJBController.sol'; import {IJBDirectory} from './../interfaces/IJBDirectory.sol'; import {IJBPayoutRedemptionPaymentTerminal3_2} from './../interfaces/IJBPayoutRedemptionPaymentTerminal3_2.sol'; import {IJBSplitsStore} from './../interfaces/IJBSplitsStore.sol'; -import {IJBFeeGauge3_1} from './../interfaces/IJBFeeGauge3_1.sol'; import {IJBOperatable} from './../interfaces/IJBOperatable.sol'; import {IJBOperatorStore} from './../interfaces/IJBOperatorStore.sol'; import {IJBPaymentTerminal} from './../interfaces/IJBPaymentTerminal.sol'; @@ -23,14 +21,14 @@ import {IJBSingleTokenPaymentTerminalStore3_1_1} from './../interfaces/IJBSingle import {IJBSplitAllocator} from './../interfaces/IJBSplitAllocator.sol'; import {JBConstants} from './../libraries/JBConstants.sol'; import {JBCurrencies} from './../libraries/JBCurrencies.sol'; -import {JBFees} from './../libraries/JBFees.sol'; +import {JBFees3_2} from './../libraries/JBFees3_2.sol'; import {JBFixedPointNumber} from './../libraries/JBFixedPointNumber.sol'; import {JBFundingCycleMetadataResolver3_2} from './../libraries/JBFundingCycleMetadataResolver3_2.sol'; import {JBOperations} from './../libraries/JBOperations.sol'; import {JBTokens} from './../libraries/JBTokens.sol'; import {JBDidRedeemData3_1_1} from './../structs/JBDidRedeemData3_1_1.sol'; import {JBDidPayData3_1_1} from './../structs/JBDidPayData3_1_1.sol'; -import {JBFee} from './../structs/JBFee.sol'; +import {JBFee3_2} from './../structs/JBFee3_2.sol'; import {JBFundingCycle} from './../structs/JBFundingCycle.sol'; import {JBPayDelegateAllocation3_1_1} from './../structs/JBPayDelegateAllocation3_1_1.sol'; import {JBRedemptionDelegateAllocation3_1_1} from './../structs/JBRedemptionDelegateAllocation3_1_1.sol'; @@ -79,7 +77,7 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is /// @notice Fees that are being held to be processed later. /// @custom:param _projectId The ID of the project for which fees are being held. - mapping(uint256 => JBFee[]) internal _heldFeesOf; + mapping(uint256 => JBFee3_2[]) internal _heldFeesOf; //*********************************************************************// // ---------------- public immutable stored properties --------------- // @@ -111,9 +109,6 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is /// @dev Out of MAX_FEE (25_000_000 / 1_000_000_000) uint256 public override fee = 25_000_000; // 2.5% - /// @notice The data source that returns a discount to apply to a project's fee. - address public override feeGauge; - /// @notice Addresses that can be paid towards from this terminal without incurring a fee. /// @dev Only addresses that are considered to be contained within the ecosystem can be feeless. Funds sent outside the ecosystem may incur fees despite being stored as feeless. /// @custom:param _address The address that can be paid toward. @@ -155,7 +150,7 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is /// @notice The fees that are currently being held to be processed later for each project. /// @param _projectId The ID of the project for which fees are being held. /// @return An array of fees that are being held. - function heldFeesOf(uint256 _projectId) external view override returns (JBFee[] memory) { + function heldFeesOf(uint256 _projectId) external view override returns (JBFee3_2[] memory) { return _heldFeesOf[_projectId]; } @@ -462,7 +457,7 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is ) { // Get a reference to the project's held fees. - JBFee[] memory _heldFees = _heldFeesOf[_projectId]; + JBFee3_2[] memory _heldFees = _heldFeesOf[_projectId]; // Delete the held fees. delete _heldFeesOf[_projectId]; @@ -477,9 +472,7 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is for (uint256 _i; _i < _heldFeeLength; ) { // Get the fee amount. _amount = ( - _heldFees[_i].fee == 0 || _heldFees[_i].feeDiscount == JBConstants.MAX_FEE_DISCOUNT - ? 0 - : JBFees.feeIn(_heldFees[_i].amount, _heldFees[_i].fee, _heldFees[_i].feeDiscount) + _heldFees[_i].fee == 0 ? 0 : JBFees3_2.feeIn(_heldFees[_i].amount, _heldFees[_i].fee) ); // Process the fee. @@ -506,16 +499,6 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is emit SetFee(_fee, msg.sender); } - /// @notice Allows the fee gauge to be updated. - /// @dev Only the owner of this contract can change the fee gauge. - /// @param _feeGauge The new fee gauge. - function setFeeGauge(address _feeGauge) external virtual override onlyOwner { - // Store the new fee gauge. - feeGauge = _feeGauge; - - emit SetFeeGauge(_feeGauge, msg.sender); - } - /// @notice Sets whether projects operating on this terminal can pay towards the specified address without incurring a fee. /// @dev Only the owner of this contract can set addresses as feeless. /// @param _address The address that can be paid towards while still bypassing fees. @@ -625,14 +608,11 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is // Keep a reference to the funding cycle during which the redemption is being made. JBFundingCycle memory _fundingCycle; - // Scoped section prevents stack too deep. `_feeEligibleDistributionAmount`, `_feeDiscount` and `_feePercent` only used within scope. + // Scoped section prevents stack too deep. `_feeEligibleDistributionAmount` and `_feePercent` only used within scope. { // Keep a reference to the amount being reclaimed that should have fees withheld from. uint256 _feeEligibleDistributionAmount; - // Keep a reference to the amount of discount to apply to the fee. - uint256 _feeDiscount; - // Keep a reference to the fee. uint256 _feePercent = fee; @@ -655,12 +635,22 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is ); // Set the reference to the fee discount to apply. No fee if the beneficiary is feeless or if the redemption rate is at its max. +<<<<<<< Updated upstream _feeDiscount = isFeelessAddress[_beneficiary] || (_fundingCycle.redemptionRate() == JBConstants.MAX_REDEMPTION_RATE && _fundingCycle.ballotRedemptionRate() == JBConstants.MAX_REDEMPTION_RATE) || _feePercent == 0 ? JBConstants.MAX_FEE_DISCOUNT : _currentFeeDiscount(_projectId, JBFeeType.REDEMPTION); +======= + _feePercent = isFeelessAddress[_beneficiary] || + _fundingCycle.redemptionRate() == JBConstants.MAX_REDEMPTION_RATE || + _feePercent == 0 || + directory.primaryTerminalOf(_FEE_BENEFICIARY_PROJECT_ID, token) == + IJBPaymentTerminal(address(0)) + ? 0 + : _feePercent; +>>>>>>> Stashed changes // The amount being reclaimed must be at least as much as was expected. if (reclaimAmount < _minReturnedTokens) revert INADEQUATE_RECLAIM_AMOUNT(); @@ -706,7 +696,7 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is // Get the fee for the delegated amount. _delegatedAmountFee = _feePercent == 0 ? 0 - : JBFees.feeIn(_delegateAllocation.amount, _feePercent, _feeDiscount); + : JBFees3_2.feeIn(_delegateAllocation.amount, _feePercent); // Add the delegated amount to the amount eligible for having a fee taken. if (_delegatedAmountFee != 0) { @@ -745,9 +735,9 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is // Send the reclaimed funds to the beneficiary. if (reclaimAmount != 0) { // Get the fee for the reclaimed amount. - uint256 _reclaimAmountFee = _feeDiscount == JBConstants.MAX_FEE_DISCOUNT + uint256 _reclaimAmountFee = _feePercent == 0 ? 0 - : JBFees.feeIn(reclaimAmount, _feePercent, _feeDiscount); + : JBFees3_2.feeIn(reclaimAmount, _feePercent); if (_reclaimAmountFee != 0) { _feeEligibleDistributionAmount += reclaimAmount; @@ -760,14 +750,7 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is // Take the fee from all outbound reclaimations. _feeEligibleDistributionAmount != 0 - ? _takeFeeFrom( - _projectId, - false, - _feeEligibleDistributionAmount, - _feePercent, - _beneficiary, - _feeDiscount - ) + ? _takeFeeFrom(_projectId, false, _feeEligibleDistributionAmount, _feePercent, _beneficiary) : 0; } @@ -823,16 +806,15 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is // Keep a reference to the fee amount that was paid. uint256 _feeTaken; - // Scoped section prevents stack too deep. `_feePercent`, `_feeDiscount`, `_feeEligibleDistributionAmount`, and `_leftoverDistributionAmount` only used within scope. + // Scoped section prevents stack too deep. `_feeEligibleDistributionAmount` and `_leftoverDistributionAmount` only used within scope. { // Keep a reference to the fee. - uint256 _feePercent = fee; - - // Get the amount of discount that should be applied to any fees taken. // If the fee is zero, set the discount to 100% for convenience. - uint256 _feeDiscount = _feePercent == 0 - ? JBConstants.MAX_FEE_DISCOUNT - : _currentFeeDiscount(_projectId, JBFeeType.PAYOUT); + uint256 _feePercent = fee == 0 || + directory.primaryTerminalOf(_FEE_BENEFICIARY_PROJECT_ID, token) == + IJBPaymentTerminal(address(0)) + ? 0 + : fee; // The amount distributed that is eligible for incurring fees. uint256 _feeEligibleDistributionAmount; @@ -847,11 +829,10 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is _fundingCycle.configuration, payoutSplitsGroup, _distributedAmount, - _feePercent, - _feeDiscount + _feePercent ); - if (_feeDiscount != JBConstants.MAX_FEE_DISCOUNT) { + if (_feePercent != 0) { // Leftover distribution amount is also eligible for a fee since the funds are going out of the ecosystem to _beneficiary. unchecked { _feeEligibleDistributionAmount += _leftoverDistributionAmount; @@ -865,8 +846,7 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is _fundingCycle.shouldHoldFees(), _feeEligibleDistributionAmount, _feePercent, - _projectOwner, - _feeDiscount + _projectOwner ) : 0; @@ -875,11 +855,7 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is // Subtract the fee from the net leftover amount. netLeftoverDistributionAmount = _leftoverDistributionAmount - - ( - _feeDiscount == JBConstants.MAX_FEE_DISCOUNT - ? 0 - : JBFees.feeIn(_leftoverDistributionAmount, _feePercent, _feeDiscount) - ); + (_feePercent == 0 ? 0 : JBFees3_2.feeIn(_leftoverDistributionAmount, _feePercent)); // Transfer the amount to the project owner. _transferFrom(address(this), _projectOwner, netLeftoverDistributionAmount); @@ -933,33 +909,32 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is // The amount being withdrawn must be at least as much as was expected. if (_distributedAmount < _minReturnedTokens) revert INADEQUATE_DISTRIBUTION_AMOUNT(); - // Scoped section prevents stack too deep. `_fee`, `_projectOwner`, `_feeDiscount`, and `_netAmount` only used within scope. + // Scoped section prevents stack too deep. `_fee`, `_projectOwner` and `_netAmount` only used within scope. { // Keep a reference to the fee amount that was paid. uint256 _feeTaken; - // Keep a reference to the fee. - uint256 _feePercent = fee; - // Get a reference to the project owner, which will receive tokens from paying the platform fee. address _projectOwner = projects.ownerOf(_projectId); - // Get the amount of discount that should be applied to any fees taken. + // Keep a reference to the fee. // If the fee is zero or if the fee is being used by an address that doesn't incur fees, set the discount to 100% for convenience. - uint256 _feeDiscount = _feePercent == 0 || isFeelessAddress[msg.sender] - ? JBConstants.MAX_FEE_DISCOUNT - : _currentFeeDiscount(_projectId, JBFeeType.ALLOWANCE); + uint256 _feePercent = fee == 0 || + isFeelessAddress[msg.sender] || + directory.primaryTerminalOf(_FEE_BENEFICIARY_PROJECT_ID, token) == + IJBPaymentTerminal(address(0)) + ? 0 + : fee; // Take a fee from the `_distributedAmount`, if needed. - _feeTaken = _feeDiscount == JBConstants.MAX_FEE_DISCOUNT + _feeTaken = _feePercent == 0 ? 0 : _takeFeeFrom( _projectId, _fundingCycle.shouldHoldFees(), _distributedAmount, _feePercent, - _projectOwner, - _feeDiscount + _projectOwner ); unchecked { @@ -991,7 +966,6 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is /// @param _domain The domain of the splits to distribute the payout between. /// @param _group The group of the splits to distribute the payout between. /// @param _amount The total amount being distributed, as a fixed point number with the same number of decimals as this terminal. - /// @param _feeDiscount The amount of discount to apply to the fee, out of the MAX_FEE. /// @param _feePercent The percent of fees to take, out of MAX_FEE. /// @return If the leftover amount if the splits don't add up to 100%. /// @return feeEligibleDistributionAmount The total amount of distributions that are eligible to have fees taken from. @@ -1000,8 +974,7 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is uint256 _domain, uint256 _group, uint256 _amount, - uint256 _feePercent, - uint256 _feeDiscount + uint256 _feePercent ) internal returns (uint256, uint256 feeEligibleDistributionAmount) { // The total percentage available to split uint256 _leftoverPercentage = JBConstants.SPLITS_TOTAL_PERCENT; @@ -1026,8 +999,7 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is _projectId, _group, _payoutAmount, - _feePercent, - _feeDiscount + _feePercent ); // If the split allocator is set as feeless, this distribution is not eligible for a fee. @@ -1068,15 +1040,13 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is /// @param _split The split to distribute payouts to. /// @param _amount The total amount being distributed to the split, as a fixed point number with the same number of decimals as this terminal. /// @param _feePercent The percent of fees to take, out of MAX_FEE. - /// @param _feeDiscount The amount of discount to apply to the fee, out of the MAX_FEE. /// @return netPayoutAmount The amount sent to the split after subtracting fees. function _distributeToPayoutSplit( JBSplit memory _split, uint256 _projectId, uint256 _group, uint256 _amount, - uint256 _feePercent, - uint256 _feeDiscount + uint256 _feePercent ) internal returns (uint256 netPayoutAmount) { // By default, the net payout amount is the full amount. This will be adjusted if fees are taken. netPayoutAmount = _amount; @@ -1084,11 +1054,9 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is // If there's an allocator set, transfer to its `allocate` function. if (_split.allocator != IJBSplitAllocator(address(0))) { // This distribution is eligible for a fee since the funds are leaving this contract and the allocator isn't listed as feeless. - if ( - _feeDiscount != JBConstants.MAX_FEE_DISCOUNT && !isFeelessAddress[address(_split.allocator)] - ) { + if (_feePercent != 0 && !isFeelessAddress[address(_split.allocator)]) { unchecked { - netPayoutAmount -= JBFees.feeIn(_amount, _feePercent, _feeDiscount); + netPayoutAmount -= JBFees3_2.feeIn(_amount, _feePercent); } } @@ -1150,13 +1118,9 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is emit PayoutReverted(_projectId, _split, _amount, 'Terminal not found', msg.sender); } else { // This distribution is eligible for a fee since the funds are leaving this contract and the terminal isn't listed as feeless. - if ( - _terminal != this && - _feeDiscount != JBConstants.MAX_FEE_DISCOUNT && - !isFeelessAddress[address(_terminal)] - ) { + if (_terminal != this && _feePercent != 0 && !isFeelessAddress[address(_terminal)]) { unchecked { - netPayoutAmount -= JBFees.feeIn(_amount, _feePercent, _feeDiscount); + netPayoutAmount -= JBFees3_2.feeIn(_amount, _feePercent); } } @@ -1209,9 +1173,9 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is } else { // This distribution is eligible for a fee since the funds are leaving this contract and the beneficiary isn't listed as feeless. // Don't enforce feeless address for the beneficiary since the funds are leaving the ecosystem. - if (_feeDiscount != JBConstants.MAX_FEE_DISCOUNT) { + if (_feePercent != 0) { unchecked { - netPayoutAmount -= JBFees.feeIn(_amount, _feePercent, _feeDiscount); + netPayoutAmount -= JBFees3_2.feeIn(_amount, _feePercent); } } @@ -1230,25 +1194,21 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is /// @param _feePercent The percent of fees to take, out of MAX_FEE. /// @param _amount The amount of the fee to take, as a floating point number with 18 decimals. /// @param _beneficiary The address to mint the platforms tokens for. - /// @param _feeDiscount The amount of discount to apply to the fee, out of the MAX_FEE. /// @return feeAmount The amount of the fee taken. function _takeFeeFrom( uint256 _projectId, bool _shouldHoldFees, uint256 _amount, uint256 _feePercent, - address _beneficiary, - uint256 _feeDiscount + address _beneficiary ) internal returns (uint256 feeAmount) { - feeAmount = JBFees.feeIn(_amount, _feePercent, _feeDiscount); + feeAmount = JBFees3_2.feeIn(_amount, _feePercent); if (_shouldHoldFees) { // Store the held fee. - _heldFeesOf[_projectId].push( - JBFee(_amount, uint32(_feePercent), uint32(_feeDiscount), _beneficiary) - ); + _heldFeesOf[_projectId].push(JBFee3_2(_amount, uint32(_feePercent), _beneficiary)); - emit HoldFee(_projectId, _amount, _feePercent, _feeDiscount, _beneficiary, msg.sender); + emit HoldFee(_projectId, _amount, _feePercent, _beneficiary, msg.sender); } else { // Process the fee. _processFee(feeAmount, _beneficiary, _projectId); // Take the fee. @@ -1480,7 +1440,7 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is uint256 _amount ) internal returns (uint256 refundedFees) { // Get a reference to the project's held fees. - JBFee[] memory _heldFees = _heldFeesOf[_projectId]; + JBFee3_2[] memory _heldFees = _heldFeesOf[_projectId]; // Delete the current held fees. delete _heldFeesOf[_projectId]; @@ -1498,9 +1458,7 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is } else { // Notice here we take feeIn the stored .amount uint256 _feeAmount = ( - _heldFees[_i].fee == 0 || _heldFees[_i].feeDiscount == JBConstants.MAX_FEE_DISCOUNT - ? 0 - : JBFees.feeIn(_heldFees[_i].amount, _heldFees[_i].fee, _heldFees[_i].feeDiscount) + _heldFees[_i].fee == 0 ? 0 : JBFees3_2.feeIn(_heldFees[_i].amount, _heldFees[_i].fee) ); if (leftoverAmount >= _heldFees[_i].amount - _feeAmount) { @@ -1511,17 +1469,14 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is } else { // And here we overwrite with feeFrom the leftoverAmount _feeAmount = ( - _heldFees[_i].fee == 0 || _heldFees[_i].feeDiscount == JBConstants.MAX_FEE_DISCOUNT - ? 0 - : JBFees.feeFrom(leftoverAmount, _heldFees[_i].fee, _heldFees[_i].feeDiscount) + _heldFees[_i].fee == 0 ? 0 : JBFees3_2.feeFrom(leftoverAmount, _heldFees[_i].fee) ); unchecked { _heldFeesOf[_projectId].push( - JBFee( + JBFee3_2( _heldFees[_i].amount - (leftoverAmount + _feeAmount), _heldFees[_i].fee, - _heldFees[_i].feeDiscount, _heldFees[_i].beneficiary ) ); @@ -1538,33 +1493,4 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is emit RefundHeldFees(_projectId, _amount, refundedFees, leftoverAmount, msg.sender); } - - /// @notice Get the fee discount from the fee gauge for the specified project. - /// @param _projectId The ID of the project to get a fee discount for. - /// @param _feeType The type of fee the discount is being applied to. - /// @return feeDiscount The fee discount, which should be interpreted as a percentage out MAX_FEE_DISCOUNT. - function _currentFeeDiscount( - uint256 _projectId, - JBFeeType _feeType - ) internal view returns (uint256) { - // Can't take a fee if the protocol project doesn't have a terminal that accepts the token. - if ( - directory.primaryTerminalOf(_FEE_BENEFICIARY_PROJECT_ID, token) == - IJBPaymentTerminal(address(0)) - ) return JBConstants.MAX_FEE_DISCOUNT; - - // Get the fee discount. - if (feeGauge != address(0)) - // If the guage reverts, keep the discount at 0. - try IJBFeeGauge3_1(feeGauge).currentDiscountFor(_projectId, _feeType) returns ( - uint256 discount - ) { - // If the fee discount is greater than the max, we ignore the return value - if (discount <= JBConstants.MAX_FEE_DISCOUNT) return discount; - } catch { - return 0; - } - - return 0; - } } diff --git a/contracts/interfaces/IJBPayoutRedemptionPaymentTerminal3_2.sol b/contracts/interfaces/IJBPayoutRedemptionPaymentTerminal3_2.sol index 248091340..28db42023 100644 --- a/contracts/interfaces/IJBPayoutRedemptionPaymentTerminal3_2.sol +++ b/contracts/interfaces/IJBPayoutRedemptionPaymentTerminal3_2.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {JBFee} from './../structs/JBFee.sol'; +import {JBFee3_2} from './../structs/JBFee3_2.sol'; import {IJBAllowanceTerminal3_1} from './IJBAllowanceTerminal3_1.sol'; import {IJBDirectory} from './IJBDirectory.sol'; import {IJBFeeHoldingTerminal} from './IJBFeeHoldingTerminal.sol'; @@ -70,7 +70,6 @@ interface IJBPayoutRedemptionPaymentTerminal3_2 is uint256 indexed projectId, uint256 indexed amount, uint256 indexed fee, - uint256 feeDiscount, address beneficiary, address caller ); @@ -176,7 +175,7 @@ interface IJBPayoutRedemptionPaymentTerminal3_2 is function payoutSplitsGroup() external view returns (uint256); - function heldFeesOf(uint256 projectId) external view returns (JBFee[] memory); + function heldFeesOf(uint256 projectId) external view returns (JBFee3_2[] memory); function fee() external view returns (uint256); diff --git a/contracts/libraries/JBFees3_2.sol b/contracts/libraries/JBFees3_2.sol new file mode 100644 index 000000000..f4c81c94a --- /dev/null +++ b/contracts/libraries/JBFees3_2.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {PRBMath} from '@paulrberg/contracts/math/PRBMath.sol'; +import {JBConstants} from './../libraries/JBConstants.sol'; + +/// @notice Fee calculations. +library JBFees3_2 { + /// @notice Returns the fee included in the specified _amount for the specified project. + /// @param _amount The amount that the fee is based on, as a fixed point number with the same amount of decimals as this terminal. + /// @param _feePercent The percentage of the fee, out of MAX_FEE. + /// @return The amount of the fee, as a fixed point number with the same amount of decimals as this terminal. + function feeIn(uint256 _amount, uint256 _feePercent) internal pure returns (uint256) { + // The amount of tokens from the `_amount` to pay as a fee. If reverse, the fee taken from a payout of `_amount`. + return + _amount - PRBMath.mulDiv(_amount, JBConstants.MAX_FEE, _feePercent + JBConstants.MAX_FEE); + } + + /// @notice Returns the fee amount paid from a payouts of _amount for the specified project. + /// @param _amount The amount that the fee is based on, as a fixed point number with the same amount of decimals as this terminal. + /// @param _feePercent The percentage of the fee, out of MAX_FEE. + /// @return The amount of the fee, as a fixed point number with the same amount of decimals as this terminal. + function feeFrom(uint256 _amount, uint256 _feePercent) internal pure returns (uint256) { + // The amount of tokens from the `_amount` to pay as a fee. If reverse, the fee taken from a payout of `_amount`. + return PRBMath.mulDiv(_amount, _feePercent, JBConstants.MAX_FEE); + } +} diff --git a/contracts/structs/JBFee3_2.sol b/contracts/structs/JBFee3_2.sol new file mode 100644 index 000000000..14f570e92 --- /dev/null +++ b/contracts/structs/JBFee3_2.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @custom:member amount The total amount the fee was taken from, as a fixed point number with the same number of decimals as the terminal in which this struct was created. +/// @custom:member fee The percent of the fee, out of MAX_FEE. +/// @custom:member beneficiary The address that will receive the tokens that are minted as a result of the fee payment. +struct JBFee3_2 { + uint256 amount; + uint32 fee; + address beneficiary; +} From c50bdafbc41dd6e2b3e788afe59baa4e98d01bc8 Mon Sep 17 00:00:00 2001 From: mejango Date: Fri, 1 Sep 2023 09:59:36 -0400 Subject: [PATCH 2/2] - --- .../JBPayoutRedemptionPaymentTerminal3_2.sol | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/contracts/abstract/JBPayoutRedemptionPaymentTerminal3_2.sol b/contracts/abstract/JBPayoutRedemptionPaymentTerminal3_2.sol index 3a6766dda..5d2fb671a 100644 --- a/contracts/abstract/JBPayoutRedemptionPaymentTerminal3_2.sol +++ b/contracts/abstract/JBPayoutRedemptionPaymentTerminal3_2.sol @@ -614,7 +614,7 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is uint256 _feeEligibleDistributionAmount; // Keep a reference to the fee. - uint256 _feePercent = fee; + uint256 _feePercent; // Scoped section prevents stack too deep. `_delegateAllocations` only used within scope. { @@ -635,22 +635,13 @@ abstract contract JBPayoutRedemptionPaymentTerminal3_2 is ); // Set the reference to the fee discount to apply. No fee if the beneficiary is feeless or if the redemption rate is at its max. -<<<<<<< Updated upstream - _feeDiscount = isFeelessAddress[_beneficiary] || - (_fundingCycle.redemptionRate() == JBConstants.MAX_REDEMPTION_RATE && - _fundingCycle.ballotRedemptionRate() == JBConstants.MAX_REDEMPTION_RATE) || - _feePercent == 0 - ? JBConstants.MAX_FEE_DISCOUNT - : _currentFeeDiscount(_projectId, JBFeeType.REDEMPTION); -======= _feePercent = isFeelessAddress[_beneficiary] || _fundingCycle.redemptionRate() == JBConstants.MAX_REDEMPTION_RATE || - _feePercent == 0 || + fee == 0 || directory.primaryTerminalOf(_FEE_BENEFICIARY_PROJECT_ID, token) == IJBPaymentTerminal(address(0)) ? 0 - : _feePercent; ->>>>>>> Stashed changes + : fee; // The amount being reclaimed must be at least as much as was expected. if (reclaimAmount < _minReturnedTokens) revert INADEQUATE_RECLAIM_AMOUNT();