Keeping Rewards Campaigns Fair

Every Rewards Campaign is a finite pool of rewards distributed across a much larger pool of participants. If we get the distribution wrong, two things happen at once: builders doing genuine work get diluted, and the people optimising for the metric instead of the mission take the difference home. That's the worst possible outcome for an ecosystem reward, so we spend a lot of time making sure it doesn't happen.

This post is about how we approach that problem. We're not going to publish specific thresholds, weightings, or the precise combinations of signals that trigger a review — disclosing those would just turn this into a checklist for the people we're trying to keep out. What we can share is the philosophy and the categories of behaviour we look at, so the rest of the community understands the bar we hold every project to.

Why this has to be automated (mostly)

A Rewards Campaign cycle can have hundreds or thousands of enrolled projects. No human reviewer can fairly evaluate that volume in a single campaign period, and even if they could, "fair" stops meaning very much when the rules are applied case-by-case. Consistency requires automation: every project gets scored by the same calculation, against the same metrics, on the same timeline.

That said, the automation isn't the whole story. Scores produce a ranked list. Before rewards are finalised, we run a separate analysis pass that looks for patterns — behaviours that score well on the surface but don't look like real work when you check the underlying activity. Projects that trip enough of these patterns get reported and reviewed manually before any reward leaves the system.

We treat that second pass as a guardrail, not a punishment. The goal is to make sure the reward goes to the builder who actually did the work, not to the person who was best at making their activity look like work.

The kinds of things we look for

These are the broad categories. Each one has multiple specific checks underneath it, and a single signal almost never gets a project reported on its own — what matters is the combination, and how it correlates with everything else the project shipped.

"Activity" with nothing underneath it

The clearest farming pattern is when a metric goes up but the artefact behind it is hollow. A package that exists only as a name. A repository with a green commit graph but no actual code change in the commits. A smart contract that compiled and deployed but does nothing meaningful. The calculation already filters a lot of these at the source — trivial contracts don't earn onchain points, stub packages don't earn npm points — but we keep looking past the gate because the borderline cases are where the sophisticated farming happens.

Distribution patterns that don't match real usage

Real software has bursty, uneven, organic usage. Downloads cluster around releases. Commits cluster around the days people actually worked. Onchain calls come from many different wallets, with varying gas costs, at varying times. When we see the opposite of that — perfectly uniform daily numbers, all activity concentrated into a single day, transactions that all originate from the same wallet — it's almost always a script, not a userbase.

Effort that doesn't match outcome

A high score driven by a small number of commits. Many transactions that generate zero fees, suggesting the project is calling itself. New contract deployments that nobody (including the deployer) ever interacts with again. These are all cases where the surface metric tells one story and the underlying detail tells another. We give the underlying detail more weight.

Timing that lines up too neatly with the campaign

Projects created days before the campaign window opens. GitHub accounts created weeks before the project was registered. We don't flag these on their own — new builders are welcome and a lot of great projects start fresh — but combined with any of the patterns above, the timing becomes a meaningful signal that the work was assembled for the campaign rather than reflected by it.

Reuse across projects

A single creator submitting multiple projects is fine. A single creator submitting multiple projects that all share the same smart contract, or that all show the same farming pattern, or that all rely on the same hollow package, is not — it's the same project filed three times to get three rewards. When we find one project from a creator showing clear patterns, we review the rest of their portfolio in the same pass. If the patterns repeat, they're not coincidences.

Why we don't tell people exactly why they were flagged

We get asked this often, and the answer is uncomfortable but honest: every detail we publish becomes a thing the next bad actor knows to avoid. The detection only works as long as the people we're detecting don't have a printout of exactly how we detect them. That isn't unique to us — every fraud, spam, and abuse system in the industry works this way for the same reason.

What this means for builders shipping in good faith

If you're building something real, you have nothing to manage around here. The patterns above describe what scripted, hollow, or duplicate work looks like — and real work doesn't look like that, even when it's small. A few honest commits, a contract that does something, a package somebody actually uses: that's the whole bar. The system is designed to reward that, and to make sure the pool doesn't get drained by the people trying to imitate it.

We'd rather be the platform where the bar is fair than the platform where the bar is easy. The two are not the same thing, and we know which one matters for the long-term health of the ecosystem.