Measuring Where Intent Gets Lost in Agentic Smart Contract Synthesis
Organizations: Columbia University New York, NY, USA · IBM T.J. Watson Research Center Yorktown Heights, NY, USA
Abstract
AI agents can now write software from a plain-English description, but code that runs is not the same as code that does what was asked. This gap matters most for smart contracts, the programs behind Web3 applications that move money on a blockchain and cannot be fixed once deployed. We ask how to check whether an AI-written contract behaves as it should, and where the requested behavior gets lost. We design an evaluation built on execution rather than opinion. We replay the same transactions on an AI-written contract and on the original it should reproduce and measure how often they agree. We test every grading tool on planted mistakes, compare against an answer key written without the description, and audit our own scorer until known wrong answers cannot pass. Common methods, such as AI judges and standard analysis tools, miss obvious mistakes, and scoring choices matter too. Checking only the functions every system includes hid about half the difference between pipelines. We then propose an elicitation-first architecture. Before writing code, the agent asks the client a short checklist of questions, checks the contract against an independently written executable answer key, and returns disagreements to the client instead of silently rewriting code. Asking first matters far more than reviewing or patching afterwards, across three AI models, while automated security fixes often break requested behavior. A few well-chosen questions recover much of what a short description omits, and their value can be estimated without the original contract. To our knowledge, this is the first study in smart contract synthesis to gather missing requirements before generation and check the result against an independently written executable model. The lessons extend to any setting where AI agents turn requests into programs. We release our tools, 600 tasks and all results.
Figures & tables
| Instrument | Caught | False alarms |
|---|---|---|
| Slither (static analysis) | 1.5% [0.5, 4.3] | n/a |
| LLM judge reading the code | 65.0% | 80% |
| Black-box LLM tester | 17.5% | 40% |
| LLM judge with executable proof | 30.0% | 40% |
| Reference model, with description | 94.3% | 14.4% |
| Reference model, function names only | 87.5% | 18.7% |
| Txn | Pass | Build | Func. | Obs. | |
|---|---|---|---|---|---|
| One-shot generation | 53.9 | 2.6 | 95.2 | 75.5 | 75.6 |
| Original pipeline | 39.3 | 1.2 | 79.2 | 58.7 | 67.1 |
| Elicitation-first, before triage | 72.2 | 17.2 | 97.0 | 84.7 | 77.7 |
| Elicitation-first, full | 72.9 | 19.6 | 97.0 | 84.7 | 77.7 |
| Conclusion | Checks that support it |
|---|---|
| Information is lost before code | fresh transaction sequences; five transaction-generator variants; three rulebook writer families; generated contracts as well as rulebooks; descriptions without factual errors; three generator families |
| Stages after writing add at most about one point | no detectable gain from extractor, critic, reviewer, ensemble, voting, proof-gated judging or rulebook repair; triage detectable but small and provisional |
| Security rewriting breaks requirements | 94 contracts; LLM classification of selected changes; holds on contracts without any selected justified fix |
| Elicitation-first beats the original | 96 and 499 contracts; four contract types; equal-information factorial; shared, adapted and exact scoring; failures counted or excluded; near-duplicates excluded |
| Few questions recover much of the gain | cross-fitted ordering; four adaptive agents; a label-free separation score; which questions matter depends on description errors |
| Instrument fixes do not drive results | runner fix moved no catch rate by more than 0.6 points; exact replay preserved every ranking |
Appendix figures & tables6 assets
Supplementary material from the paper’s appendix.
Appendix
| Module | Role |
|---|---|
| harness.py | deploy at the declared compiler version, run steps with callers, ether and time travel |
| runner_state.py , model_runner3.py | sandboxed reference-model execution with revert rollback and per-sequence reset |
| idea8_specific.py | transaction generator, seed pool, contract-specific mutation operators |
| rbeval.py | strict side-picking, right-side rate, bootstrap over contracts |
| fidelity.py , rescore.py | fidelity with exact replay, saved compile repairs, real-defect analysis |
| exp*.py , tests/ | one script per experiment with its criteria; known-answer tests |
| Experiment | Criterion | Outcome | Value |
|---|---|---|---|
| Slither on guard removal § | detection below 25% | met | 1.5% |
| Conventional over-permission § | violation rate at least 5% | not met | 0.2% |
| Tester versus judge § | tester at least judge plus 15 | not met | 17.5 vs 65.0 |
| Proof-gated judge § | recall at least 50% | not met | 30% |
| Implementation voting § | majority above mean single | not met | 80.5 vs 80.9 |
| Disagreement-guided clarification § | over none, over random | not met |
| Setting | Value |
|---|---|
| Sequences per contract, steps | 60, 8 |
| Callers | owner (deployer), two other accounts |
| Numeric arguments | 0, 1, 100, 999, 1000, 1001, seeded values |
| Seed pool | contract literals and getter values , at most 16 |
| Time steps | 15% of steps, 1 hour to 366 days |
| Clock | fixed start, one second per block |
| Agent | Questions | Fidelity | Most frequent first question |
|---|---|---|---|
| Picks three | 3.0 | 67.2% | roles (56 of 93) |
| Picks and stops | 4.7 | 70.6% | roles (46 of 93) |
| Picks, stops, own questions | 6.6 | 77.7% | roles (44 of 93) |
| Judge only stops | 10.0 | 73.1% | never stopped early |
| All ten questions | 10 | 76.0% |
Agentic Code Generation
Agentic code generation uses AI agents to plan, write, test, and revise executable programs with tools and feedback.
See all 130 papers