AdAura
Marketing agents that evolve, capped on-chain
Created on 20th September 2026
•
AdAura
Marketing agents that evolve, capped on-chain
The problem AdAura solves
The guess that costs money
When someone wants to sell something, they have to guess the marketing strategy: platform, audience, tone, format, call to action, bid aggressiveness, frequency. That guess costs real money and is almost never measured properly.
In our strategy space there are 40,500 possible combinations. Nobody has the budget to test them one by one.
What Darwin Agents does
You load a product and a budget. The system creates a population of autonomous agents, each with:
- a distinct strategy (its genome: platform, audience, format, tone, CTA, bid aggressiveness, frequency)
- its own Ethereum wallet
- a budget the contract will not let it exceed
Agents spend to win conversions. Every few cycles there is a generational cut:
- the ones losing money shut down
- the profitable ones reproduce with a small, observable mutation
- the child inherits part of the parent's unspent budget
Nobody tells the system which strategy works. It discovers it by paying to be wrong a few times.
Why Ethereum, and not a database
This is the question a judge should ask, so here is the answer up front.
An agent's budget is not a number in a prompt. It is a state variable, and exceeding it makes the transaction revert.
AgentTreasury.spend() checks four independent ceilings before moving a single token:
| Ceiling | What it prevents |
|---|---|
allowance | An agent spending more than it was assigned in its entire life |
epochCap | An agent burning its whole budget in one day |
globalCap | The whole population exceeding the campaign limit |
| real liquidity | Promising money the treasury does not hold |
There is a test that builds 4 agents with $140 of nominal allowance against a $50 ceiling and verifies that not one cent escapes.
The full evolutionary tree is reconstructible from events alone — AgentRegistered and AgentReproduced carry the parent and the genome hash. An indexer never has to trust our database.
The human always keeps the switch: setPaused() freezes the entire population, and withdraw() recovers whatever the agents did not burn.
Live on HashKey Chain Testnet (chainId 133)
AgentTreasury | 0x87017Fdeb14140043dfE323a48e26c4be0169bE4 |
MockUSD | 0x9b5d391F1fed4D4C18ae5ce221476d60a8C96b93 |
Testnet on purpose: MockUSD has an open faucet and the contract is not audited. No real money is used.
What is real and what is simulated
We put this in the pitch rather than hiding it:
| Contract, wallets, agent signatures, enforced ceiling | real, on-chain |
| Ad copy written by Claude | real |
| Profit / ROI / selection math | real |
| Ad delivery, clicks, conversions | simulated — the UI says so |
| Login, hosting, posting to real networks | does not exist |
The verification that matters
npm run sim runs the evolution headless, then brute-forces the global optimum across all 40,500 strategies to compare against what the population found on its own. If the population does not improve, the script exits with code 1. The project refuses to pretend it works.
Challenges I ran into
1. Proving the population actually learns, instead of claiming it
The easiest way to fake an "evolutionary" system is to show a rising fitness curve and let people assume it means something. A population can improve and still be far worse than a strategy you could have found by hand.
So we made the project argue against itself. scripts/sim.ts runs the evolution headless and then brute-forces all 40,500 strategy combinations to compute the true global optimum, and compares the population's result against it. If the population does not improve, the script exits with code 1.
This caught real bugs. Early on, selection pressure was too aggressive: the population converged fast onto a local optimum and stopped exploring. The fix was adding immigration — injecting fresh random genomes each generation — so the population keeps sampling the space it has not seen. We verify convergence across 5 different seeds so we are not reporting one lucky run.
2. Which spending ceiling actually bites first
We wanted a live demo where an agent tries to overspend and the chain rejects it. The first attempt failed to revert at all, and the reason was an assumption about which of the four ceilings would trigger.
epochCap is derived as perAgent / 12, which makes the daily ceiling far tighter than the lifetime allowance. An agent hits EpochCapExceeded long before it can ever hit AllowanceExceeded. Once we understood the ordering, the demo became deterministic: the overspend attempt reliably reverts with EpochCapExceeded, and the lifetime and campaign-wide ceilings are covered by contract tests instead of the live path.
3. Making each agent genuinely sign its own transaction
It would have been much easier to have one operator wallet send every transaction on behalf of the agents. That would also have made the whole premise a lie — an agent with no wallet is not an economic actor.
Each agent derives its own HD wallet and signs its own spend(). Getting there meant solving gas: a freshly derived wallet holds no native token and cannot sign anything, so the operator has to drip gas to each new wallet before its first transaction.
We verified this independently rather than trusting our own UI — cast receipt on the resulting transaction confirms the from address is the agent's wallet, not the operator's.
4. A first-run failure that looked like a broken demo
The on-chain flow needs two clicks: the first run registers the agent on-chain, and only then can it spend. During testing this looked exactly like a bug, and it is the kind of thing that derails a live demo in front of judges. We documented it explicitly rather than papering over it.
5. Keeping the honest line between real and simulated
The hardest non-technical decision. Ad delivery, clicks and conversions are simulated — we did not integrate a real ad network. The temptation is to blur that.
Instead we labelled it in the UI itself and put the real-vs-simulated table in the README and the pitch. The on-chain enforcement, the agent signatures and the selection math are real; the ad marketplace is not. A judge should not have to dig to find that out.
Tracks Applied (3)