Skip to content

Commit

Permalink
Merge pull request #234 from Bananapus/jango/fee-always-from
Browse files Browse the repository at this point in the history
Jango/fee always from
  • Loading branch information
mejango authored Jan 19, 2025
2 parents 734cd71 + 599ee12 commit a817c4f
Show file tree
Hide file tree
Showing 14 changed files with 93 additions and 112 deletions.
27 changes: 14 additions & 13 deletions src/JBMultiTerminal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
// This payout is eligible for a fee since the funds are leaving this contract and the split hook isn't a
// feeless address.
if (!_isFeeless(address(split.hook))) {
netPayoutAmount -= JBFees.feeAmountIn({amount: amount, feePercent: FEE});
netPayoutAmount -= JBFees.feeAmountFrom({amountBeforeFee: amount, feePercent: FEE});
}

// Create the context to send to the split hook.
Expand Down Expand Up @@ -585,7 +585,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
// This payout is eligible for a fee if the funds are leaving this contract and the receiving terminal isn't
// a feelss address.
if (terminal != this && !_isFeeless(address(terminal))) {
netPayoutAmount -= JBFees.feeAmountIn({amount: amount, feePercent: FEE});
netPayoutAmount -= JBFees.feeAmountFrom({amountBeforeFee: amount, feePercent: FEE});
}

// Send the `projectId` in the metadata as a referral.
Expand Down Expand Up @@ -622,7 +622,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
// This payout is eligible for a fee since the funds are leaving this contract and the recipient isn't a
// feeless address.
if (!_isFeeless(recipient)) {
netPayoutAmount -= JBFees.feeAmountIn({amount: amount, feePercent: FEE});
netPayoutAmount -= JBFees.feeAmountFrom({amountBeforeFee: amount, feePercent: FEE});
}

// If there's a beneficiary, send the funds directly to the beneficiary. Otherwise send to the
Expand Down Expand Up @@ -830,7 +830,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
_processFee({
projectId: projectId,
token: token,
amount: JBFees.feeAmountIn({amount: heldFee.amount, feePercent: FEE}),
amount: JBFees.feeAmountFrom({amountBeforeFee: heldFee.amount, feePercent: FEE}),
beneficiary: heldFee.beneficiary,
feeTerminal: feeTerminal,
wasHeld: true
Expand Down Expand Up @@ -1129,7 +1129,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
if (!_isFeeless(beneficiary) && cashOutTaxRate != 0) {
amountEligibleForFees += reclaimAmount;
// Subtract the fee for the reclaimed amount.
reclaimAmount -= JBFees.feeAmountIn({amount: reclaimAmount, feePercent: FEE});
reclaimAmount -= JBFees.feeAmountFrom({amountBeforeFee: reclaimAmount, feePercent: FEE});
}

// Subtract the fee from the reclaim amount.
Expand Down Expand Up @@ -1401,7 +1401,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
// Get the fee for the specified amount.
uint256 specificationAmountFee = _isFeeless(address(specification.hook))
? 0
: JBFees.feeAmountIn({amount: specification.amount, feePercent: FEE});
: JBFees.feeAmountFrom({amountBeforeFee: specification.amount, feePercent: FEE});

// Add the specification's amount to the amount eligible for fees.
if (specificationAmountFee != 0) {
Expand Down Expand Up @@ -1637,8 +1637,8 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
if (leftoverAmount == 0) {
break;
} else {
// Notice here we take `feeAmountIn` on the stored `.amount`.
uint256 feeAmount = JBFees.feeAmountIn({amount: heldFee.amount, feePercent: FEE});
// Notice here we take `feeAmountFrom` on the stored `.amount`.
uint256 feeAmount = JBFees.feeAmountFrom({amountBeforeFee: heldFee.amount, feePercent: FEE});

// Keep a reference to the amount from which the fee was taken.
uint256 amountPaidOut = heldFee.amount - feeAmount;
Expand All @@ -1652,8 +1652,8 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
// Move the start index forward to the held fee after the current one.
newStartIndex = startIndex + i + 1;
} else {
// And here we overwrite with `feeAmountFrom` the `leftoverAmount`
feeAmount = JBFees.feeAmountFrom({amount: leftoverAmount, feePercent: FEE});
// And here we overwrite with `feeAmountResultingIn` the `leftoverAmount`
feeAmount = JBFees.feeAmountResultingIn({amountAfterFee: leftoverAmount, feePercent: FEE});

// Get fee from `leftoverAmount`.
unchecked {
Expand Down Expand Up @@ -1740,8 +1740,9 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
// Send any leftover funds to the project owner and update the fee tracking accordingly.
if (leftoverPayoutAmount != 0) {
// Keep a reference to the fee for the leftover payout amount.
uint256 fee =
_isFeeless(projectOwner) ? 0 : JBFees.feeAmountIn({amount: leftoverPayoutAmount, feePercent: FEE});
uint256 fee = _isFeeless(projectOwner)
? 0
: JBFees.feeAmountFrom({amountBeforeFee: leftoverPayoutAmount, feePercent: FEE});

// Transfer the amount to the project owner.
try this.executeTransferTo({addr: projectOwner, token: token, amount: leftoverPayoutAmount - fee}) {
Expand Down Expand Up @@ -1915,7 +1916,7 @@ contract JBMultiTerminal is JBPermissioned, ERC2771Context, IJBMultiTerminal {
returns (uint256 feeAmount)
{
// Get a reference to the fee amount.
feeAmount = JBFees.feeAmountIn({amount: amount, feePercent: FEE});
feeAmount = JBFees.feeAmountFrom({amountBeforeFee: amount, feePercent: FEE});

if (shouldHoldFees) {
// Store the held fee.
Expand Down
18 changes: 8 additions & 10 deletions src/libraries/JBFees.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,27 @@ import {JBConstants} from "./../libraries/JBConstants.sol";

/// @notice Fee calculations.
library JBFees {
/// @notice Returns the amount of tokens to pay as a fee out of the specified `amount`.
/// @dev The resulting fee will be `feePercent` of the REMAINING `amount` after subtracting the fee, not the full
/// `amount`.
/// @param amount The amount that the fee is based on, as a fixed point number.
/// @notice Returns the amount of tokens to pay as a fee relative to the specified `amount`.
/// @param amountAfterFee The amount that the fee is based on, as a fixed point number.
/// @param feePercent The fee percent, out of `JBConstants.MAX_FEE`.
/// @return The amount of tokens to pay as a fee, as a fixed point number with the same number of decimals as the
/// provided `amount`.
function feeAmountIn(uint256 amount, uint256 feePercent) internal pure returns (uint256) {
function feeAmountResultingIn(uint256 amountAfterFee, 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 - mulDiv(amount, JBConstants.MAX_FEE, feePercent + JBConstants.MAX_FEE);
return mulDiv(amountAfterFee, JBConstants.MAX_FEE, JBConstants.MAX_FEE - feePercent) - amountAfterFee;
}

/// @notice Returns the fee that would have been paid based on an `amount` which has already had the fee subtracted
/// from it.
/// @dev The resulting fee will be `feePercent` of the full `amount`.
/// @param amount The amount that the fee is based on, as a fixed point number with the same amount of decimals as
/// @param amountBeforeFee 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 fee percent, out of `JBConstants.MAX_FEE`.
/// @return The amount of the fee, as a fixed point number with the same amount of decimals as this terminal.
function feeAmountFrom(uint256 amount, uint256 feePercent) internal pure returns (uint256) {
function feeAmountFrom(uint256 amountBeforeFee, 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 mulDiv(amount, feePercent, JBConstants.MAX_FEE);
return mulDiv(amountBeforeFee, feePercent, JBConstants.MAX_FEE);
}
}
Loading

0 comments on commit a817c4f

Please sign in to comment.