Executable formal model of the EVM and Yul in Lean 4.
Lean
97
499 commits
updated Nov 19, 2025
This repository contains a formal model of the EVM and Yul in Lean 4. Where applicable, the underlying EVM primops are used directly by the Yul model.
Everything here is work in progress and is subject to change therefore.
The Operation describing all of the primitive operations:
EvmYul/Operations.lean
The semantic function primCall associated with the ADT:
EvmYul/Yul/PrimOps.lean
The model of the EVM state EVM.State:
EvmYul/EVM/State.lean
The semantic function step:
EvmYul/EVM/Semantics.lean
The ADT Stmt mutually defined with Expr and FunctionDefinition describing Yul:
EvmYul/Yul/Ast.lean
The model of the Yul state YUL.State:
EvmYul/Yul/State.lean
The semantic function exec mutually defined with eval (and some misc. functions):
EvmYul/Yul/Interpreter.lean
A git submodule with EVM conformance tests is in:
EthereumTests/
The test running infrastructure can be found in:
Conform/
To execute conformance tests, make sure the EthereumTests directory is the appropriate git submodule and run:
lake test -- <NUM_THREADS> 2> out_discard.txt
where <NUM_THREADS> is the number of threads running conformance tests in parallel. Note that the default is 1.
We recommend redirecting stderr into a file to not pollute the output.
To execute the Yul semantics tests run:
lake exe yulSemanticsTests
These tests are defined in EvmYul/Yul/YulSemanticsTests/Main.lean.
SELFDESTRUCT of another contract.create or create2 because Yul code is not stored as bytecode, and so we cannot properly model create or create2 without some mechanism for correctly decompiling bytecode into Yul code, so we do not model this._ in the match statement in EVMYul/Semantics.lean and returns default.accountMap. See EvmYul/Yul/YulSemanticsTests/README.md for more information on how to include custom Solidity contracts in the modelled blockchain state.extcodesize and so generated Yul will not be able to call other contracts without removing or editing these extcodesize checks (manually).EvmYul/Yul/YulSemanticsTests.lean we manually changed let _1 := extcodesize( 2) to let _1 := 1 in fun_testStoreAndRetrieveExternal.EXTCODEHASH, EXTCODECOPY, CODECOPY, CODESIZE for similar reasons to not modelling EXTCODESIZE._ in the match statement in EVMYul/Semantics.lean and return default.SELFDESTRUCT is not implemented and the semantics for SELFDESTRUCT have limitations, such as not triggering the fallback function in a contract that is the recipient of the ether from the contract the self-destructs. We may remove the semantics for SELFDESTRUCT once its status changes from deprecated to not being supported.Lean
73.7%
Python
17.5%
Yul
7.0%
C
1.1%
Executable formal model of the EVM and Yul in Lean 4.
Lean
97
499 commits
updated Nov 19, 2025
This repository contains a formal model of the EVM and Yul in Lean 4. Where applicable, the underlying EVM primops are used directly by the Yul model.
Everything here is work in progress and is subject to change therefore.
The Operation describing all of the primitive operations:
EvmYul/Operations.lean
The semantic function primCall associated with the ADT:
EvmYul/Yul/PrimOps.lean
The model of the EVM state EVM.State:
EvmYul/EVM/State.lean
The semantic function step:
EvmYul/EVM/Semantics.lean
The ADT Stmt mutually defined with Expr and FunctionDefinition describing Yul:
EvmYul/Yul/Ast.lean
The model of the Yul state YUL.State:
EvmYul/Yul/State.lean
The semantic function exec mutually defined with eval (and some misc. functions):
EvmYul/Yul/Interpreter.lean
A git submodule with EVM conformance tests is in:
EthereumTests/
The test running infrastructure can be found in:
Conform/
To execute conformance tests, make sure the EthereumTests directory is the appropriate git submodule and run:
lake test -- <NUM_THREADS> 2> out_discard.txt
where <NUM_THREADS> is the number of threads running conformance tests in parallel. Note that the default is 1.
We recommend redirecting stderr into a file to not pollute the output.
To execute the Yul semantics tests run:
lake exe yulSemanticsTests
These tests are defined in EvmYul/Yul/YulSemanticsTests/Main.lean.
SELFDESTRUCT of another contract.create or create2 because Yul code is not stored as bytecode, and so we cannot properly model create or create2 without some mechanism for correctly decompiling bytecode into Yul code, so we do not model this._ in the match statement in EVMYul/Semantics.lean and returns default.accountMap. See EvmYul/Yul/YulSemanticsTests/README.md for more information on how to include custom Solidity contracts in the modelled blockchain state.extcodesize and so generated Yul will not be able to call other contracts without removing or editing these extcodesize checks (manually).EvmYul/Yul/YulSemanticsTests.lean we manually changed let _1 := extcodesize( 2) to let _1 := 1 in fun_testStoreAndRetrieveExternal.EXTCODEHASH, EXTCODECOPY, CODECOPY, CODESIZE for similar reasons to not modelling EXTCODESIZE._ in the match statement in EVMYul/Semantics.lean and return default.SELFDESTRUCT is not implemented and the semantics for SELFDESTRUCT have limitations, such as not triggering the fallback function in a contract that is the recipient of the ether from the contract the self-destructs. We may remove the semantics for SELFDESTRUCT once its status changes from deprecated to not being supported.Lean
73.7%
Python
17.5%
Yul
7.0%
C
1.1%