Advanced Reward Claiming

Learn how to claim on behalf of your users, to redirect where rewards are sent, and more.

circle-info

Rewards on Merkl do not increase block by block, but can be claimed at a frequency which depends on the chain. You can check the claim frequency on the Status pagearrow-up-right.

Operator System: Delegating Claim Rights

By default, rewards can only be claimed by the address that earned them. However, Merkl provides a flexible operator system that allows a third party to claim rewards on behalf of another address, while the rewards are still sent to the original address that earned them.

How regular operators work:

The address that earned rewards can approve an operator to claim on its behalf by calling the function toggleOperator on the distributor smart contractarrow-up-right. When the operator claims on behalf of the address that earned rewards, the rewards are still sent to the original address that earned them, the operator only facilitates the transaction.

If an address calls toggleOperator with address(0), then anyone can claim on its behalf without requiring individual operator approvals.

Admin rights to claim for everyone:

In some cases, certain addresses may be granted admin rights that allow them to claim rewards on behalf of all users without requiring individual operator approvals. These admin rights are granted on a case-by-case basis and enable streamlined reward distribution for specific use cases, such as protocol-level reward forwarding or automated claim processes.

Claiming from a multisig

When claiming rewards from a multisig address, we recommend delegating the claim process to an operator. This is because Merkl reward proofs are only valid for on average four hours (varies depending on the chain). If you fail to gather the necessary signatures and execute the claim transaction before a Merkle root is updated, your claim transaction will fail.

Claiming as an operator

Once an address has approved you as an operator by calling toggleOperator on the distributor smart contractarrow-up-right, you can claim rewards on behalf of that address directly from the Merkl frontend.

How to claim via the frontend

  1. Navigate to the user's dashboard: Go to https://app.merkl.xyz/users/[ADDRESS] where [ADDRESS] is the wallet address for which you want to claim rewards.

  2. Enable Operator mode: On the right side of the dashboard, you'll find a button with three vertical dots (⋮). Click on it and select "Operator mode (advanced)" to enable it.

    circle-exclamation
  3. Connect your operator wallet: Connect the wallet that has been toggled as an operator for the address you're claiming on behalf of.

  4. Claim the rewards: Once connected, you'll see the rewards available for the address. However, the claim button will only appear if you are a valid operator for that specific chain. When you click claim, the rewards will be sent to the original address that earned them, not to your operator address.

circle-exclamation
circle-info

If you need to claim rewards programmatically or via the API instead of the frontend, see the Integrating User Rewards section in the integration guide, which explains how to retrieve Merkle proofs from the API and build claim transactions.

Claim Recipient System

The claim recipient system allows protocols to redirect where claimed rewards are sent, instead of always sending them to the address that earned them.

Function: setClaimRecipient()

Signature:

Parameters:

  • recipient: Address that will receive the claimed tokens. Use address(0) to remove the custom recipient (revert to default)

  • token: Token for which to set the recipient. Use address(0) to set a global recipient that applies to all tokens without a specific recipient

Access: Callable by any address (sets recipient for msg.sender)

How it works:

  • Sets a custom recipient for claims

  • Setting recipient = address(0) removes the custom recipient for that token

  • When token = address(0), it sets claimRecipient[user][address(0)] as a global fallback

Priority order when claiming:

When claiming rewards, the system follows this priority order:

  1. Token-specific recipient: claimRecipient[user][token] (if set and not address(0))

  2. Global recipient: claimRecipient[user][address(0)] (if set)

  3. Default: User's own address

Token-specific recipients take precedence over the global recipient.

Examples:

Example flow:

Use cases:

  • Routing rewards to smart contracts that cannot directly claim

  • Redirecting rewards to user-controlled addresses

  • Protocol-level reward forwarding mechanisms

Claim Callback System (Automatic Actions)

The claimWithRecipient() function supports passing arbitrary data (bytes) to recipient contracts, enabling automatic actions like swaps via aggregators when rewards are claimed.

How it works

When you call claimWithRecipient() with non-empty datas, the system:

  1. Transfers tokens to the recipient address

  2. Automatically calls onClaim() on the recipient contract (if it implements IClaimRecipient)

  3. Passes the custom data to the callback, allowing the recipient to perform actions like swaps, deposits, or conversions

Function: claimWithRecipient()

Signature:

Parameters:

  • datas: Array of arbitrary bytes data, one per claim. This data is passed to the recipient's onClaim() callback.

IClaimRecipient Interface

Recipient contracts must implement this interface:

The callback must return CALLBACK_SUCCESS (keccak256("IClaimRecipient.onClaim")) or the claim will revert.

Important notes:

  • If data.length == 0, no callback is made (standard transfer only)

  • If the callback reverts, the token transfer still occurred (uses try/catch)

  • The datas array must have the same length as other arrays

  • Data encoding is flexible - you can encode any parameters your recipient contract needs

Use cases

  • Automatic swaps: Swap rewards immediately via DEX aggregators (1inch, 0x, etc.)

  • Auto-deposits: Deposit rewards into liquidity pools or yield farms

  • Token conversions: Convert rewards to a different token automatically

  • Complex routing: Perform multiple actions based on encoded data

Example: Automatic Swap

Support for address(0) as Wildcard

The Distributor contract uses address(0) as a wildcard parameter in several functions, representing "all tokens" or "default".

Where address(0) is used:

  1. setClaimRecipient(recipient, address(0))

    • Sets a global recipient that applies to all tokens without specific recipients

How it works:

  • When address(0) is used as the token parameter, it acts as a fallback/default

  • This simplifies operations that need to work across multiple tokens

  • Token-specific recipients take precedence over the global recipient (see priority order above)

Address Remapping

If a smart contract can't claim rewards directly, ask the Merkl team to remap those rewards to a claimable wallet by reaching out on Discordarrow-up-right with the campaign ID, source address, and destination address. The full walkthrough lives in the Reward Forwarding guide.

Last updated