Goals
- Preserve the user-facing model where contract source declares portable
intents and
--targetchooses the concrete chain route at compile time. - Represent exported entrypoints, state, and transitions without EVM/Solana/Move ABI details.
- Record target-resolved capability calls as typed effects so targets can reject unsupported operations before lowering.
- Carry enough metadata for artifact emission and cross-target scenario tests.
Non-goals (v0)
- Full Lean/LCNF preservation — only the contract-relevant subset.
- Automatic account/object inference for Solana or Move.
- Implicitly emulating target-specific semantics when a target cannot route an intent safely.
- Runtime proof transport to target chains — proofs are checked in Lean before codegen.
Layering
CapabilityPlan before
lowering. Target Extension SDKs may expose chain-specific operations such as
Solana PDA/CPI or Move resource primitives, but those extensions still lower
through capability ids and target metadata rather than adding chain-only
constructors to the portable IR.
IR Units (v0 sketch)
Module
name: package/module identifierentrypoints: exported handlersstate: declared persistent state slotstypes: portable structs/enums used by the module
Entrypoint
name: logical method name (e.g.increment,get)tag: optional dispatch tag for non-EVM targetsparams: portable values plus target-resolved account/resource bindings when the selected adapter requires explicit metadataeffects: ordered target-resolved capability callsreturns: portable return type or unit
State
id: stable state variable namekind:scalar|map|account_owned|object(target lowering hints)type: portable type reference
Effect (target-resolved capability call)
capability: id from capability-registry.mdargs: portable operandssource: optional Lean source span for diagnostics
Expression Surface
The current executable IR inProofForge/IR/Contract.lean includes a compact
expression set for target-source backends:
- literals:
U32,U64/Felt, Bool, and fixed four-limb Hash literals - local variables, fixed-array literals/indexing, struct literals, and field access
- numeric operations:
+,-,*,/,%,** - bitwise operations and shifts:
&,|,^,<<,>> - casts between supported scalar value types
- comparisons and boolean composition
- dynamic Hash value construction from four Felt limbs
- hash intrinsics: one-to-one and two-to-one hash operations
- effect expressions for storage reads, map reads, array reads, storage-path reads, and context reads
+=, -=, *=, /=, %=,
|=, &=, ^=, <<=, >>=), statement effects, assertions, if/else,
bounded for, and explicit return. Statement effects include storage writes
and storage-reference compound assignment effects for scalar storage and
generic storage paths.
Each target backend is responsible for either lowering each node it accepts or
rejecting it before source generation with an explicit diagnostic.
Relationship to LCNF
Target IR Subsets
Each target accepts a subset of IR. Unsupported constructs fail at capability check time with target id and capability id.| Restriction | Solana | Move (Aptos/Sui) | Psy DPN |
|---|---|---|---|
| Implicit contract storage | Rejected — use explicit accounts | Rejected — use resources/objects | Allowed only through explicit Psy storage/sourcegen mapping |
| Higher-order functions | Restricted runtime subset TBD | Rejected in v0 | Rejected in v0 |
| Arbitrary heap objects | Runtime size TBD | Rejected | Rejected |
| Closures | TBD with sBPF spike | Rejected | Rejected |
| Unbounded loops | TBD with sBPF spike | Rejected in v0 | Rejected; require circuit-friendly bounded shape |
Counter IR Example (v0)
Logical module for the shared scenario:storage.scalar to slot storage; Solana maps to account data;
CosmWasm maps to string-keyed KV; Aptos maps to an account resource field.
Phase 1 Acceptance Criteria
- IR node types documented in Lean (
ProofForge/IR/or equivalent). - Counter module expressible in IR without EVM-specific opcodes.
- EVM backend can lower Counter IR to Yul (directly or via existing EmitYul path with a thin adapter).
- Capability checker rejects at least one unsupported capability per non-EVM target with a clear diagnostic.
- EVM portable IR bytecode metadata records
irVersion: portable-ir-v0inproof-forge-artifact.json.
Open Questions
- How much of LCNF to reuse vs. a fresh contract IR AST?
- Should account schemas live in IR or in target sidecar manifests?
- IR versioning strategy when capabilities expand.