The ERC20 Variable Criteria Incentive is a protocol incentive that allows for a variable distribution of native and ERC-20 assets, with each claim amount being determined dynamically at claim time depending on a value extracted from a provided transaction.

On Boost creation, a predetermined amount of the specified asset is transferred into this incentive from the associated budget.

The Boost V2 Docs are under active development and will be subject to changes.

Key Features

  • Supports native assets as well as any ERC20
  • Rewards dynamic at claim time, depending on the value of a field extracted from a transaction log or function argument.

Unlike budgets, allowlists, and validators, incentives cannot be re-used between multiple Boosts.

Create a new ERC20VariableCriteriaIncentive

Get an existing ERC20VariableCriteriaIncentive

Setting Up Incentive Criteria

The incentive criteria determines how the reward amount is extracted from transaction data. You can configure it to read values from either contract events or function calls.

Criteria Configuration

The criteria object requires four fields:

  • criteriaType: Either SignatureType.EVENT for event logs or SignatureType.FUNC for function calls
  • signature: The event or function signature to match against
  • fieldIndex: Which parameter in the event/function to extract the value from (0-based index)
  • targetContract: The contract address to watch for the event/function

You can use the @boostxyz/signatures package to get pre-defined event signatures instead of using raw hex values. For example: import { selectors } from '@boostxyz/signatures/events'

Example: Event-based Criteria

Here’s an example setting up criteria to extract an amount from a Transfer event:

import { selectors } from '@boostxyz/signatures/events'
import { SignatureType } from '@boostxyz/sdk'

const criteria = {
  criteriaType: SignatureType.EVENT,
  // Use pre-defined signature for Transfer(address,address,uint256)
  signature: selectors['Transfer(address indexed,address indexed,uint256)'],
  fieldIndex: 2, // Extract amount from the third parameter
  targetContract: '0xTokenContract' // Contract to watch for events
}

Example: Function-based Criteria

Here’s an example setting up criteria to extract an amount from a mint function:

import { selectors } from '@boostxyz/signatures/functions'
import { SignatureType } from '@boostxyz/sdk/claiming'

const criteria = {
  criteriaType: SignatureType.FUNC,
  // Use pre-defined signature for mint(uint256)
  signature: selectors['mint(uint256)'],
  fieldIndex: 0, // Extract amount from the first parameter (quantity)
  targetContract: '0xNFTContract' // Contract to watch for function calls
}

The extracted value will be used to calculate the reward amount, which is then capped by the maxReward parameter if necessary.

Sign a claim amount

// Get the index of the incentive to claim
const incentiveIndex = boost.incentives.findIndex(incentive => incentive instanceof ERC20VariableCriteriaIncentive)

// build claim data, signing a variable amount for the incentive
const allClaimData = boost.incentives.map(incentive => {
  if (incentive instanceof ERC20VariableCriteriaIncentive || incentive instanceof ERC20VariableCriteriaIncentive) {
    const rewardAmount = parseEther("1");
    return incentive.buildClaimData(rewardAmount);
  } else {
    return ''
  }
})

// Sign a valid transaction with the variable reward amount
const { data } = await axios.get('/signatures', {
  params: {
    boostId: `${chainId}:${boost.id}`,
    txHash,
    claimData: allClaimData.join(',')
  }
});

// claim the ERC20VariableCriteriaIncentive
const { signature, incentiveId, claimant } = data.at(incentiveIndex);
await core.claimIncentive(
  boost.id,
  incentiveId,
  claimant,
  signature,
);