Skip to main content


Contract: JBETHERC20ProjectPayer

Interface: IJBProjectPayer

Make a payment to the specified project.


function pay(
uint256 _projectId,
address _token,
uint256 _amount,
address _beneficiary,
uint256 _minReturnedTokens,
bool _preferClaimedTokens,
string calldata _memo,
bytes calldata _metadata
) public payable virtual { ... }
  • Arguments:
    • _projectId is the ID of the project that is being paid.
    • _token is the token being paid in.
    • _amount is the amount of tokens being paid, as a fixed point number. If the token is ETH, this is ignored and msg.value is used in its place.
    • _decimals is the number of decimals in the _amount fixed point number. If the token is ETH, this is ignored and 18 is used in its place, which corresponds to the amount of decimals expected in msg.value.
    • _beneficiary is the address who will receive tokens from the payment.
    • _minReturnedTokens is the minimum number of project tokens expected in return, as a fixed point number with 18 decimals.
    • _preferClaimedTokens is a flag indicating whether the request prefers to mint project tokens into the beneficiaries wallet rather than leaving them unclaimed. This is only possible if the project has an attached token contract. Leaving them unclaimed saves gas.
    • _memo is a memo to pass along to the emitted event, and passed along the the funding cycle's data source and delegate. A data source can alter the memo before emitting in the event and forwarding to the delegate.
    • _metadata are bytes to send along to the data source, delegate, and emitted event, if provided.
  • The function can be accessed externally by anyone, or internally from this contract or one that inherits it.
  • The function can be overriden by inheriting contracts.
  • The function overrides a function definition from the IJBProjectPayer interface.
  • The function doesn't return anything.


  1. If the token isn't ETH, make sure ETH wasn't sent to the function, then transfer the amount of tokens from the message sender to this contract. If the token is ETH, override the specified amount and decimals values with with amount of ETH sent to the function, which is denoted as a fixed point number with 18 decimals.

    // ETH shouldn't be sent if the token isn't ETH.
    if (address(_token) != JBTokens.ETH) {
    if (msg.value > 0) revert NO_MSG_VALUE_ALLOWED();

    // Get a reference to the balance before receiving tokens.
    uint256 _balanceBefore = IERC20(_token).balanceOf(address(this));

    // Transfer tokens to this contract from the msg sender.
    IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);

    // The amount should reflect the change in balance.
    _amount = IERC20(_token).balanceOf(address(this)) - _balanceBefore;
    } else {
    // If ETH is being paid, set the amount to the message value, and decimals to 18.
    _amount = msg.value;
    _decimals = 18;

    Library references:

    External references:

  2. Make the payment.


    Internal references: