Skip to main content

recordDistributionFor

Contract: JBSingleTokenPaymentTerminalStore

Interface: IJBSingleTokenPaymentTerminalStore

Records newly distributed funds for a project.

The msg.sender must be an IJBSingleTokenPaymentTerminal.

Definition​

function recordDistributionFor(
uint256 _projectId,
uint256 _amount,
uint256 _currency
)
external
override
nonReentrant
returns (JBFundingCycle memory fundingCycle, uint256 distributedAmount) { ... }
  • Arguments:
    • _projectId is the ID of the project that is having funds distributed.
    • _amount is the amount to use from the distribution limit, as a fixed point number.
    • _currency is the currency of the _amount. This must match the project's current funding cycle's currency.
  • The resulting function overrides a function definition from the JBSingleTokenPaymentTerminalStore interface.
  • The function returns:
    • fundingCycle is the funding cycle during which the withdrawal was made.
    • distributedAmount is the amount of terminal tokens distributed, as a fixed point number with the same amount of decimals as its relative terminal.

Body​

  1. Get a reference to the project's current funding cycle.

    // Get a reference to the project's current funding cycle.
    fundingCycle = fundingCycleStore.currentOf(_projectId);

    External references:

  2. Make sure the current funding cycle doesn't have distributions paused.

    // The funding cycle must not be configured to have distributions paused.
    if (fundingCycle.distributionsPaused()) revert FUNDING_CYCLE_DISTRIBUTION_PAUSED();

    Library references:

  3. Calculate the new total amount that has been distributed during this funding cycle by adding the amount being distributed to the used distribution limit.

    // The new total amount that has been distributed during this funding cycle.
    uint256 _newUsedDistributionLimitOf = usedDistributionLimitOf[
    IJBSingleTokenPaymentTerminal(msg.sender)
    ][_projectId][fundingCycle.number] + _amount;

    Internal references:

  4. Get a reference to the currrent distribution limit of the project during the current funding cycle, and the currency the distribution limit is in terms of.

    // Amount must be within what is still distributable.
    (uint256 _distributionLimitOf, uint256 _distributionLimitCurrencyOf) = IJBController(
    directory.controllerOf(_projectId)
    ).distributionLimitOf(
    _projectId,
    fundingCycle.configuration,
    IJBSingleTokenPaymentTerminal(msg.sender),
    IJBSingleTokenPaymentTerminal(msg.sender).token()
    );

    External references:

  5. Make sure the new total amount distributed will be at most the distribution limit.

    // Make sure the new used amount is within the distribution limit.
    if (_newUsedDistributionLimitOf > _distributionLimitOf || _distributionLimitOf == 0)
    revert DISTRIBUTION_AMOUNT_LIMIT_REACHED();
  6. Make the sure the provided currency matches the expected currency for the distribution limit.

    // Make sure the currencies match.
    if (_currency != _distributionLimitCurrencyOf) revert CURRENCY_MISMATCH();
  7. Get a reference to the terminal's currency.

    // Get a reference to the terminal's currency.
    uint256 _balanceCurrency = IJBSingleTokenPaymentTerminal(msg.sender).currency();
  8. Calculate how much of the balance will be used. If the currency of the distribution limit and the balance are the same, no price conversion is necessary. Otherwise, convert the distribution limit currency to that of the balance.

    // Convert the amount to the balance's currency.
    distributedAmount = (_currency == _balanceCurrency) ? _amount : PRBMath
    .mulDiv(
    _amount,
    10**_MAX_FIXED_POINT_FIDELITY, // Use _MAX_FIXED_POINT_FIDELITY to keep as much of the `_amount.value`'s fidelity as possible when converting.
    prices.priceFor(_currency, _balanceCurrency, _MAX_FIXED_POINT_FIDELITY)
    );

    Library references:

    Internal references:

    External references:

  9. Make sure the project has access to the amount being distributed.

    // The amount being distributed must be available.
    if (distributedAmount > balanceOf[IJBSingleTokenPaymentTerminal(msg.sender)][_projectId])
    revert INADEQUATE_PAYMENT_TERMINAL_STORE_BALANCE();

    Internal references:

  10. Store the new used distributed amount.

    // Store the new amount.
    usedDistributionLimitOf[IJBSingleTokenPaymentTerminal(msg.sender)][_projectId][
    fundingCycle.number
    ] = _newUsedDistributionLimitOf;

    Internal references:

  11. Store the decremented balance.

    // Removed the distributed funds from the project's token balance.
    unchecked {
    balanceOf[IJBSingleTokenPaymentTerminal(msg.sender)][_projectId] =
    balanceOf[IJBSingleTokenPaymentTerminal(msg.sender)][_projectId] -
    distributedAmount;
    }

    Internal references: