lfglabs-dev / lfglabs-dev/verity
Macro-emit reentrancy adversary holes and entrypoint registry (single-source rely-guarantee models)
Nobody has claimed this yet.
- Dominant language
- Lean
- Stars
- 148
- Forks
- 20
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 29
Description
Problem
The rely-guarantee reentrancy framework (Verity/Core/Reentrancy.lean, worked example in Contracts/ReentrancyRelyGuarantee/Contract.lean) is sound, but using it today requires writing the contract twice:
- the executable EDSL contract (
verity_contract), and - a hand-written abstract model where every function that opens a reentrancy window is re-expressed with an adversary hole (
adv : ContractState → ContractState) placed at the external call site, plus a hand-maintainedentrypointsregistry in theReentrancySpec.
This duplication is also the source of two of the three author obligations recorded in TRUST_ASSUMPTIONS.md (§ Reentrancy Rely-Guarantee Framework):
- Registry completeness —
entrypointsmust list every state-mutating public function; omitting one makesschedule_preservesquantify over the wrong adversary. - Hole placement fidelity — the
advhole must sit exactly where the real external call happens; today this correspondence is reviewed, not checked.
The hook for fixing this already exists: Env.reenter : ContractState → ContractState := id is declared in Verity/Core/Semantics.lean:24, but it is not wired into the external-call semantics or the elaborator — its declaration is currently its only reference.
Goal: write once
Make the verity_contract macro the single source of truth:
- Wire
Env.reenterinto the semantics of external calls (externalCallBind/ the call lowering path), so that elaborated function bodies are automatically parameterized by the reentry hook at every real call site — i.e. the macro emits thereentrantCall env.reenterform instead of the author writing a parallel model. - Emit the
entrypointsregistry automatically from the contract's actual public surface (non-view, state-mutating, externally dispatchable functions), soReentrancySpec.entrypointscannot silently under-approximate. - Keep the default
reenter := idso executable behavior and all existing proofs are unchanged when no adversary is instantiated. - Update
TRUST_ASSUMPTIONS.md: registry completeness and hole placement move from author obligations to macro-guaranteed properties (invariant adequacy remains the author's). - Port
Contracts/ReentrancyRelyGuaranteeto consume the emitted form and delete the hand-written model.
Why priority
Until this lands, every rely-guarantee proof rests on the honor system for hole placement and registry completeness — precisely the parts a reviewer is worst at checking. Automating both closes the gap between "the theorem is kernel-checked" and "the theorem is about the contract you actually deployed", and removes the double-write cost that makes the framework expensive to adopt.
References
Verity/Core/Reentrancy.lean—reentrantCall,ReentrancySpec,schedule_preservesVerity/Core/Invariant.lean—Preserves,runSeq,runSeq_preservesVerity/Core/Semantics.lean:24— the unwiredEnv.reenterhookTRUST_ASSUMPTIONS.md— § Reentrancy Rely-Guarantee Framework (three author obligations)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with Env.reenter in Verity/Core/Semantics.lean and trace externalCallBind or the call-lowering path, then read Verity/Core/Reentrancy.lean and the Contracts/ReentrancyRelyGuarantee example. Done means the macro emits reentry hooks and the public entrypoint registry, the example uses the emitted form, and TRUST_ASSUMPTIONS.md reflects the changed obligations.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100