- Total Prize Pool: $18,000 in USDC
- HM awards: up to $14,400 in USDC
- If no valid Highs or Mediums are found, the HM pool is $0
- QA awards: $600 in USDC
- Judge awards: $2,500 in USDC
- Scout awards: $500 in USDC
- HM awards: up to $14,400 in USDC
- Read our guidelines for more details
- Starts November 25, 2025 20:00 UTC
- Ends December 1, 2025 20:00 UTC
- A coded, runnable PoC is required for all High/Medium submissions to this audit.
- This repo includes a basic template to run the test suite.
- PoCs must use the test suite provided in this repo.
- Your submission will be marked as Insufficient if the POC is not runnable and working with the provided test suite.
- Exception: PoC is optional (though recommended) for wardens with signal ≥ 0.68.
- Judging phase risk adjustments (upgrades/downgrades):
- High- or Medium-risk submissions downgraded by the judge to Low-risk (QA) will be ineligible for awards.
- Upgrading a Low-risk finding from a QA report to a Medium- or High-risk finding is not supported.
- As such, wardens are encouraged to select the appropriate risk level carefully during the submission phase.
V12 is Zellic's in-house AI auditing tool. It is the only autonomous Solidity auditor that reliably finds Highs and Criticals. All issues found by V12 will be judged as out of scope and ineligible for awards.
V12 findings can be viewed here.
Anything included in this section is considered a publicly known issue and is therefore ineligible for awards.
Merkl operates as a centralized solution. Therefore, any issues related to the contract owner's administrative access should be considered out of scope. Additionally, the following assumptions underpin the system's security model:
- The dispute resolution mechanism functions as intended
- Active monitoring bots continuously verify reward distributions through Merkl
We acknowledge a known risk: When users designate a smart contract as their reward recipient and pass data to it, their rewards are potentially vulnerable if:
- The recipient contract is misconfigured or malicious
- The user submits incorrect parameters (such as executing a swap without slippage protection)
In such cases, the recipient contract could redirect or capture the user's rewards.
Merkl is a DeFi incentive platform that connects liquidity providers with protocols looking to boost activity and engagement.
-
For Protocols: Launch, manage, and customize growth campaigns to attract liquidity, track user engagement, and distribute incentives without the usual operational burden.
-
For Users: Earn rewards or points by participating in incentive campaigns.
At its core, Merkl operates on an offchain engine that processes both onchain and offchain data to compute rewards and points for campaigns.
- Previous audits: https://code4rena.com/reports/2023-06-angle
- Documentation: https://docs.merkl.xyz
- Website: https://merkl.xyz/
- X/Twitter: https://x.com/merkl_xyz
| File | nSLOC |
|---|---|
| contracts/DistributionCreator.sol | 333 |
| contracts/Distributor.sol | 271 |
| Totals | 604 |
For a machine-readable version, see scope.txt
For a machine-readable version, see out_of_scope.txt
Primary Security Concerns:
Can an address exploit or access funds pre-deposited by another address without authorization?
Do rewards consistently reach their intended recipient through all claim paths (the claimant's address, a recipient specified in the call parameters, or a user-defined default recipient)?
Any scenario enabling unauthorized assumption of user roles or theft of funds constitutes a valid issue, including:
- Pre-deposited funds in the distributionCreator contract
- Idle funds in the distributor contract
The Guardian role must not have the ability to steal user funds or perform actions that result in fund reallocation.
Once rewards are earned and recorded in a Merkle root, they are immutably assigned to the recipient. These rewards cannot be revoked or redirected within the current Merkle root, except through:
- An explicit reallocation by authorized parties
- Token recovery executed by the admin address
Campaign creators retain full control over:
- End-to-end campaign management
- Their pre-deposited funds
- The ability to recover ownership of their funds at any time
- They can revoke any role or allowance they give at anytime
The contracts include three main trusted roles:
| Role | Description |
|---|---|
| Governor | - Operated via multisignature wallet - Possesses administrative rights over the distribution contracts and creator |
| Guardian | - May be held by EOAs - Responsible for operational tasks such as whitelisting of tokens and toggling operator permissions |
| Updater Address | - Authorized to update Merkle roots - May be EOAs as a dispute period exists as a safeguard to prevent malicious root updates before they are finalized |
The repository utilizes the foundry (forge) toolkit to compile its contracts, and contains several dependencies through foundry that will be automatically installed whenever a forge command is issued.
The compilation instructions were evaluated with the following toolkit versions:
- forge:
1.4.4-stable - NodeJS:
12.13.0(any should work)
After installing all npm dependencies through the npm i command, the traditional forge build command will install the foundry-specific dependencies and build the project:
forge buildThe following command can be issued to execute all tests within the repository:
forge testThe project is composed of two core contracts; a DistributionCreator and a Distribution contract.
The C4PoC.t.sol file contained within the test/c4 subpath will setup a DistributionCreator that permits wardens to demonstrate vulnerabilities pertaining to both the creator and its distribution instances.
For a submission to be considered valid, the test case should execute successfully via the following command:
forge test --match-test submissionValidityPoCs meant to demonstrate a reverting transaction must utilize the special expect utility functions forge exposes. Failure to do so may result in an invalidation of the submission.
All PoCs must adhere to the following guidelines:
- The PoC should execute successfully
- The PoC must not mock any contract-initiated calls
- The PoC must not utilize any mock contracts in place of actual in-scope implementations
Employees of Merkl and employees' family members are ineligible to participate in this audit.
Code4rena's rules cannot be overridden by the contents of this README. In case of doubt, please check with C4 staff.