lfglabs-dev / lfglabs-dev/verity

Macro-emit reentrancy adversary holes and entrypoint registry (single-source rely-guarantee models)

Open
#2,094 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement lean P1: core language
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:

  1. the executable EDSL contract (verity_contract), and
  2. 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-maintained entrypoints registry in the ReentrancySpec.

This duplication is also the source of two of the three author obligations recorded in TRUST_ASSUMPTIONS.md (§ Reentrancy Rely-Guarantee Framework):

  • Registry completenessentrypoints must list every state-mutating public function; omitting one makes schedule_preserves quantify over the wrong adversary.
  • Hole placement fidelity — the adv hole 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.reenter into 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 the reentrantCall env.reenter form instead of the author writing a parallel model.
  • Emit the entrypoints registry automatically from the contract's actual public surface (non-view, state-mutating, externally dispatchable functions), so ReentrancySpec.entrypoints cannot silently under-approximate.
  • Keep the default reenter := id so 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/ReentrancyRelyGuarantee to 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.leanreentrantCall, ReentrancySpec, schedule_preserves
  • Verity/Core/Invariant.leanPreserves, runSeq, runSeq_preserves
  • Verity/Core/Semantics.lean:24 — the unwired Env.reenter hook
  • TRUST_ASSUMPTIONS.md — § Reentrancy Rely-Guarantee Framework (three author obligations)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.