Skip to content

Commit fb05cc3

Browse files
committed
fix: remove ~90 lines of dead code from Conversions.lean
Remove 13 unused definitions that had no external call sites: - isValidAddress, isValidAddress_normalized (address predicates) - addressToNat_injective_valid (redundant with stronger axiom #2) - natToUint256, natToUint256_uint256ToNat (unused round-trip) - contractStateToIRState_storage (non-simp duplicate) - storage_preservation (duplicate of contractStateToIRState_storage) - sender_preservation (never referenced) - SelectorMap, SelectorMap.lookup, simpleStorageSelectorMap (unused helpers) Update AXIOMS.md and TRUST_ASSUMPTIONS.md to note the derived theorem was removed as dead code. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 771c9e0 commit fb05cc3

3 files changed

Lines changed: 2 additions & 91 deletions

File tree

AXIOMS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ theorem addressToNat_injective_valid :
143143
fun _ _ h_eq => addressToNat_injective _ _ h_eq
144144
```
145145

146-
**Impact**: Reduced axiom count from 5 to 4 with zero changes to proof structure (the axiom had no call sites).
146+
**Impact**: Reduced axiom count from 5 to 4 with zero changes to proof structure (the axiom had no call sites). The derived theorem was later removed as dead code (no call sites in any proof file).
147147

148148
---
149149

Compiler/Proofs/IRGeneration/Conversions.lean

Lines changed: 0 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,6 @@ open Verity.Proofs.Stdlib.SpecInterpreter
2525

2626
/-! ## Address Encoding -/
2727

28-
/-- Predicate for valid Ethereum addresses
29-
30-
We treat valid addresses as 20-byte hex strings:
31-
- Prefixed with "0x"
32-
- Exactly 40 hex characters after the prefix
33-
- All characters are valid hex digits
34-
- Normalized to lowercase (to make encoding injective)
35-
36-
This matches the production address encoding used by `Compiler.Hex.addressToNat`.
37-
-/
38-
def isValidAddress (addr : Address) : Prop :=
39-
addr.startsWith "0x"
40-
addr.length = 42
41-
(∀ c ∈ (addr.drop 2).data, (hexCharToNat? c).isSome) ∧
42-
addr = normalizeAddress addr
43-
44-
/-- Valid addresses are already normalized to lowercase. -/
45-
theorem isValidAddress_normalized {addr : Address} (h : isValidAddress addr) :
46-
addr = normalizeAddress addr := by
47-
exact h.2.2.2
48-
4928
/-- Convert Address (String) to Nat for IR execution
5029
5130
We use the production encoding:
@@ -69,37 +48,11 @@ def addressKeyMap (addrs : List Address) : List (Nat × Address) :=
6948
def addressFromNat (addrs : List Address) (key : Nat) : Option Address :=
7049
(addressKeyMap addrs).lookup key
7150

72-
/-- For valid Ethereum addresses, addressToNat is injective.
73-
74-
This was previously an axiom but is now derived from the stronger
75-
`addressToNat_injective` (which holds for all addresses, not just valid ones).
76-
See AXIOMS.md for the remaining axioms.
77-
-/
78-
theorem addressToNat_injective_valid :
79-
∀ {a b : Address}, isValidAddress a → isValidAddress b → addressToNat a = addressToNat b → a = b :=
80-
fun _ _ h_eq => Verity.Proofs.Stdlib.Automation.addressToNat_injective _ _ h_eq
81-
8251
/-! ## Uint256 Conversion -/
8352

8453
/-- Extract Nat value from Uint256 -/
8554
def uint256ToNat (u : Uint256) : Nat := u.val
8655

87-
/-- Construct Uint256 from Nat (with modular reduction) -/
88-
def natToUint256 (n : Nat) : Uint256 :=
89-
⟨n % (2^256), by
90-
have : 2^256 > 0 := by omega
91-
exact Nat.mod_lt n this⟩
92-
93-
/-- Round-trip property: natToUint256 (uint256ToNat u) = u -/
94-
theorem natToUint256_uint256ToNat (u : Uint256) :
95-
natToUint256 (uint256ToNat u) = u := by
96-
unfold natToUint256 uint256ToNat
97-
ext
98-
simp
99-
-- u.val < 2^256, so u.val % 2^256 = u.val
100-
have h_bound : u.val < 2^256 := u.isLt
101-
exact Nat.mod_eq_of_lt h_bound
102-
10356
/-! ## State Conversion -/
10457

10558
/-- Convert ContractState to IRState for IR execution
@@ -153,12 +106,6 @@ def specStorageToIRState (storage : SpecStorage) (sender : Address) : IRState :=
153106
(specStorageToIRState storage sender).memory offset = 0 := by
154107
rfl
155108

156-
/-- Storage conversion preserves slot values -/
157-
theorem contractStateToIRState_storage (addrs : List Address) (state : ContractState) (slot : Nat) :
158-
(contractStateToIRState addrs state).storage slot = uint256ToNat (state.storage slot) := by
159-
unfold contractStateToIRState
160-
rfl
161-
162109
@[simp] theorem contractStateToIRState_memory (addrs : List Address) (state : ContractState) (offset : Nat) :
163110
(contractStateToIRState addrs state).memory offset = 0 := by
164111
unfold contractStateToIRState
@@ -197,41 +144,6 @@ def resultsMatch (usesMapping : Bool) (addrs : List Address) (irResult : IRResul
197144
irResult.finalMappings baseSlot (addressToNat addr) =
198145
specResult.finalStorage.getMapping baseSlot (addressToNat addr))
199146

200-
/-! ## Helper: Function Selector Lookup -/
201-
202-
structure SelectorMap where
203-
/-- Map function names to their selectors -/
204-
selectors : List (String × Nat)
205-
206-
def SelectorMap.lookup (map : SelectorMap) (name : String) : Option Nat :=
207-
map.selectors.find? (·.1 == name) |>.map (·.2)
208-
209-
/-! ## Conversion Properties -/
210-
211-
/-- Storage preservation: Converting state and extracting storage preserves values -/
212-
theorem storage_preservation (addrs : List Address) (s : ContractState) (slot : Nat) :
213-
(contractStateToIRState addrs s).storage slot = uint256ToNat (s.storage slot) := by
214-
unfold contractStateToIRState uint256ToNat
215-
rfl
216-
217-
/-- Sender preservation: Converting state preserves sender -/
218-
theorem sender_preservation (addrs : List Address) (s : ContractState) :
219-
(contractStateToIRState addrs s).sender = addressToNat (s.sender) := by
220-
unfold contractStateToIRState
221-
rfl
222-
223-
/-! ## Example: SimpleStorage Conversions -/
224-
225-
/-- For SimpleStorage, we only use slot 0 and have two functions -/
226-
def simpleStorageSelectorMap : SelectorMap :=
227-
{ selectors := [
228-
("store", 0x6057361d),
229-
("retrieve", 0x2e64cec1)
230-
] }
231-
232-
example : simpleStorageSelectorMap.lookup "store" = some 0x6057361d := by rfl
233-
example : simpleStorageSelectorMap.lookup "retrieve" = some 0x2e64cec1 := by rfl
234-
235147
/-! ## Notes on Conversion Soundness
236148
237149
The conversion layer makes several simplifying assumptions:
@@ -244,7 +156,6 @@ The conversion layer makes several simplifying assumptions:
244156
2. **Uint256 conversion**: Direct value extraction is sound because:
245157
- Uint256.val already represents the mathematical value
246158
- IR arithmetic uses mod 2^256, matching Uint256 semantics
247-
- Round-trip property proven (natToUint256 ∘ uint256ToNat = id)
248159
249160
3. **Mapping conversion**: We decode Nat keys using an explicit address table, which is sufficient because:
250161
- IR only stores/loads using Nat keys

TRUST_ASSUMPTIONS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ abbrev Address := String
457457
One axiom depends on address injectivity:
458458
- `addressToNat_injective` (Automation.lean): Claims `addressToNat a = addressToNat b → a = b`
459459

460-
Note: `addressToNat_injective_valid` (Conversions.lean) was previously an axiom but is now a derived theorem that requires an `isValidAddress` pre-condition.
460+
Note: `addressToNat_injective_valid` was previously an axiom but was eliminated as a derived theorem (see AXIOMS.md). The derived theorem was later removed as dead code.
461461

462462
Since `Address = String`, any string can be used as an address. The axiom `addressToNat_injective` (without validity check) is technically unsound for arbitrary strings — `addressToNat "0xFF"` might equal `addressToNat "0xff"` while the strings are different.
463463

0 commit comments

Comments
 (0)