Create Your Campaign from a Smart Contract
Automate recurring Merkl campaigns by deploying a middleman contract that hardcodes the parameters and only takes the amount each cycle
If you run recurring campaigns — weekly liquidity incentives, biweekly emissions, monthly rewards — you don't want a human (or a multisig) clicking through Merkl Studio every cycle. The clean institutional pattern is to deploy a middleman smart contract that hardcodes every campaign parameter on deployment and exposes a single function to launch the next campaign with an amount.
From then on, your weekly operation is reduced to two steps:
- Transfer the reward tokens to the middleman.
- Have a bot call the middleman with the amount.
The middleman handles the approval, calls Merkl's DistributionCreator, and creates the campaign with the pre-set rules. No multisig signing, no parameter drift between cycles, no human in the loop, and no risk that the wrong campaign config gets pushed.
Recommended template
We recommend using the StandardMiddleman contract:
It's audited (alongside the rest of the Merkl contracts) and supports the full set of Merkl campaign features.
How it works
The contract holds three pieces of state:
defaultParams— the fullCampaignParametersstruct used for every campaign created through it (campaign type, target pool, duration, hooks, blacklist/whitelist, etc.).executors— an allowlist of addresses authorized to trigger campaign creation (e.g. your bot's hot wallet, or your gauge contract).startTimestampOffset— how far in the past the campaign should start, useful for retroactive distributions.
The runtime entrypoint is a single function:
function notifyReward(uint256 amount) external;
When called by an authorized executor, it:
- Verifies the caller is in
executors. - Approves the
DistributionCreatorforamountof the reward token (idempotent — handled internally). - Calls
DistributionCreator.createCampaign(params)withdefaultParams, the suppliedamount, andblock.timestamp - startTimestampOffsetas the start time.
That's it. The campaign launches with the exact parameters baked in at deployment.
One-time setup
Performed by the contract owner:
- Deploy
StandardMiddlemanwith the MerklDistributionCreatoraddress. - Configure the campaign template via
setDefaultParameters(...)— this is where you bake in the pool, the duration, the customization hooks, and any other Merkl options for your recurring campaigns. - Whitelist the bot wallet (or the calling contract) via
setExecutor(...).
After this, the contract is ready. The owner can update parameters or rotate executors at any time, and recoverToken(...) is available as an emergency escape hatch.
Recurring operation
Every cycle (e.g. each Monday):
- Transfer the cycle's reward budget to the middleman.
- Bot calls
notifyReward(amount).
A new Merkl campaign is created with the hardcoded rules and the amount you just funded. Nothing else changes between cycles unless the owner explicitly updates the parameters.
Use cases
Recurring institutional emissions
A foundation, treasury, or protocol DAO that pays out weekly liquidity incentives can deploy one middleman per pool (or one shared middleman with a more advanced parameter mapping) and cut the operational burden to "send tokens, run bot." Every campaign is verifiably identical to the previous one — auditable, reproducible, no human discretion required.
Onchain gauge systems
Many protocols rely on gauge systems where users vote onchain to determine reward allocations. The middleman pattern slots in naturally: the gauge calls the middleman's notifyReward(amount) function (the standard interface gauge systems already use), and the middleman creates the corresponding Merkl campaign.
This combines Merkl's flexibility (campaign types, hooks, customization options, reporting) with the trustlessness of a fully onchain emission flow.
Several teams have shipped variations of this pattern:
If your gauge system calls a different function signature than notifyReward(uint256), you'll want a thin wrapper or a forked middleman with the matching interface — the rest of the logic stays the same.
Prerequisites
You'll need the campaign parameters in the format expected by DistributionCreator.createCampaign(...) — the same CampaignParameters struct used when creating campaigns from a multisig.
The easiest way to get the right payload is to:
- Walk through the campaign in Merkl Studio using our campaign creation guide, or programmatically via the API guide.
- Copy the JSON payload Studio produces for multisig flows — it maps directly to the struct fields you'll pass to
setDefaultParameters(...).
See Campaign Configuration for the full field reference.
Need help?
If your setup needs custom parameter logic (per-pool allocation, dynamic durations, multiple reward tokens), reach out to the Merkl team — we can help you adapt the template or design a fit-for-purpose middleman.