_useAllowanceOf
Contract: JBPayoutRedemptionPaymentTerminal
- Step by step
 - Code
 - Errors
 - Events
 - Bug bounty
 
Allows a project to send funds from its overflow up to the preconfigured allowance.
Only a project's owner or a designated operator can use its allowance.
Incurs the protocol fee.
Definition
function _useAllowanceOf(
  uint256 _projectId,
  uint256 _amount,
  uint256 _currency,
  uint256 _minReturnedTokens,
  address payable _beneficiary,
  string memory _memo
) private returns (uint256 netDistributedAmount) { ... }
- Arguments:
_projectIdis the ID of the project to use the allowance of._amountis the amount of terminal tokens to use from this project's current allowance, as a fixed point number with the same amount of decimals as this terminal._currencyis the expected currency of the amount being distributed. Must match the project's current funding cycle's overflow allowance currency._minReturnedTokensis the minimum number of tokens that the_amountshould be valued at in terms of this terminal's currency, as a fixed point number with the same amount of decimals as this terminal._beneficiaryis the address to send the funds to.
 - The function is private to this contract.
 - The function returns the amount of tokens that was distributed to the beneficiary, as a fixed point number with the same amount of decimals as the terminal.
 
Body
- 
Record the use of the allowed funds.
// Record the use of the allowance.
(JBFundingCycle memory _fundingCycle, uint256 _distributedAmount) = store.recordUsedAllowanceOf(
_projectId,
_amount,
_currency
);Internal references:
External references:
 - 
Make sure the distributed amount is at least as much as the specified minimum.
// The amount being withdrawn must be at least as much as was expected.
if (_distributedAmount < _minReturnedTokens) revert INADEQUATE_DISTRIBUTION_AMOUNT(); - 
The following scoped block is a bit of a hack to prevent a "Stack too deep" error.
// Scoped section prevents stack too deep. `_fee`, `_projectOwner`, `_feeDiscount`, and `_netAmount` only used within scope.
{ ... }- 
Get a reference to the fee.
// Get a reference to the fee amount that was paid.
uint256 _feeAmount; - 
Get a reference to the project owner, who will be the beneficiary of the paid fee.
// Get a reference to the project owner, which will receive tokens from paying the platform fee.
address _projectOwner = projects.ownerOf(_projectId);Internal references:
External references:
 - 
Get a reference to the discount that'll be used when applying the fee. If the fee is 0, set the discount to be 100% to simplify subsequent calculations. No fee is the same as a full discount.
// Get the amount of discount that should be applied to any fees taken.
// 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 = fee == 0 || isFeelessAddress[msg.sender]
? JBConstants.MAX_FEE_DISCOUNT
: _currentFeeDiscount(_projectId);Library references:
JBConstants.MAX_FEE_DISCOUNT(...)
Internal references:
 - 
Take the fee if needed.
// Take a fee from the `_distributedAmount`, if needed.
_feeAmount = _feeDiscount == JBConstants.MAX_FEE_DISCOUNT
? 0
: _takeFeeFrom(_projectId, _fundingCycle, _distributedAmount, _projectOwner, _feeDiscount);Library references:
JBConstants.MAX_FEE_DISCOUNT(...)
Internal references:
 - 
Send the net amount to the beneficiary if needed.
unchecked {
// The net amount is the withdrawn amount without the fee.
netDistributedAmount = _distributedAmount - _fee;
}
// Transfer any remaining balance to the beneficiary.
if (netDistributedAmount > 0)
_transferFrom(address(this), _beneficiary, _netAmount);Virtual references:
 
 - 
 - 
Emit a
UseAllowanceevent with the relevant parameters.emit UseAllowance(
_fundingCycle.configuration,
_fundingCycle.number,
_projectId,
_beneficiary,
_amount,
_distributedAmount,
netDistributedAmount,
_memo,
msg.sender
);Event references:
 
/**
  @notice
  Allows a project to send funds from its overflow up to the preconfigured allowance.
  @dev
  Only a project's owner or a designated operator can use its allowance.
  @dev
  Incurs the protocol fee.
  @param _projectId The ID of the project to use the allowance of.
  @param _amount The amount of terminal tokens to use from this project's current allowance, as a fixed point number with the same amount of decimals as this terminal.
  @param _currency The expected currency of the amount being distributed. Must match the project's current funding cycle's overflow allowance currency.
  @param _minReturnedTokens The minimum number of tokens that the `_amount` should be valued at in terms of this terminal's currency, as a fixed point number with the same amount of decimals as this terminal.
  @param _beneficiary The address to send the funds to.
  @param _memo A memo to pass along to the emitted event.
  @return netDistributedAmount The amount of tokens that was distributed to the beneficiary, as a fixed point number with the same amount of decimals as the terminal.)
*/
function useAllowanceOf(
  uint256 _projectId,
  uint256 _amount,
  uint256 _currency,
  uint256 _minReturnedTokens,
  address payable _beneficiary,
  string memory _memo
) private returns (uint256 netDistributedAmount) {
  // Record the use of the allowance.
  (JBFundingCycle memory _fundingCycle, uint256 _distributedAmount) = store.recordUsedAllowanceOf(
      _projectId,
      _amount,
      _currency
    );
  // Define variables that will be needed outside the scoped section below.
  // Keep a reference to the fee amount that was paid.
  if (_distributedAmount < _minReturnedTokens) revert INADEQUATE_DISTRIBUTION_AMOUNT();
  // Scoped section prevents stack too deep. `_fee`, `_projectOwner`, `_feeDiscount`, and `_netAmount` only used within scope.
  {
    // Get a reference to the fee amount that was paid.
    uint256 _feeAmount;
    // 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.
    // 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 = fee == 0 || isFeelessAddress[msg.sender]
      ? JBConstants.MAX_FEE_DISCOUNT
      : _currentFeeDiscount(_projectId);
    // Take a fee from the `_distributedAmount`, if needed.
    _fee = _feeDiscount == JBConstants.MAX_FEE_DISCOUNT
      ? 0
      : _takeFeeFrom(_projectId, _fundingCycle, _distributedAmount, _projectOwner, _feeDiscount);
    unchecked {
      // The net amount is the withdrawn amount without the fee.
      netDistributedAmount = _distributedAmount - _fee;
    }
    // Transfer any remaining balance to the beneficiary.
    if (netDistributedAmount > 0)
      _transferFrom(address(this), _beneficiary, _netAmount);
  }
  emit UseAllowance(
    _fundingCycle.configuration,
    _fundingCycle.number,
    _projectId,
    _beneficiary,
    _amount,
    _distributedAmount,
    netDistributedAmount,
    _memo,
    msg.sender
  );
}
| String | Description | 
|---|---|
INADEQUATE_DISTRIBUTION_AMOUNT | Thrown if the amount being distributed is less than the specified minimum. | 
| Name | Data | 
|---|---|
UseAllowance | 
  | 
| Category | Description | Reward | 
|---|---|---|
| Optimization | Help make this operation more efficient. | 0.5ETH | 
| Low severity | Identify a vulnerability in this operation that could lead to an inconvenience for a user of the protocol or for a protocol developer. | 1ETH | 
| High severity | Identify a vulnerability in this operation that could lead to data corruption or loss of funds. | 5+ETH |