An Anoma Resource Machine (ARM) application that lets an Anoma transaction trigger arbitrary EVM calls.
A GenericCall resource encodes one or more EVM calls. When the resource is
consumed/created, the protocol adapter forwards those calls to the on-chain
GenericCallForwarder contract, which executes them on the target EVM. The
resource logic is a RISC0 zero-knowledge circuit that proves the forwarded
calldata matches the resource's committed label_ref and value_ref.
A GenericCall resource is always ephemeral and binds two references:
label_ref = hash(forwarder_addr)— pins the resource to a specificGenericCallForwardercontract.value_ref = hash(abi_encode(calls))— pins the resource to the exact set of EVM calls ((address to, uint256 value, bytes data)[]).
When the resource is constrained, the circuit:
- Asserts the resource is ephemeral.
- Recomputes
label_refandvalue_reffrom the witness and checks them against the resource. - Computes the resource's nullifier (if consumed) or commitment (if created).
- Emits the ABI-encoded forwarder calldata as an external payload blob (with
DeletionCriterion::Immediately) for the protocol adapter to deliver to the forwarder contract.
| Crate | Description |
|---|---|
generic_call_witness |
no_std-friendly witness library: the GenericCall type and the LogicCircuit constraint logic that runs inside the zkVM guest. |
generic_call_library |
Host-side prover. Wraps the witness in GenericCallLogic (LogicProver) and embeds the compiled guest ELF and image ID. |
generic_call_circuit |
The RISC0 guest binary and integration tests. Building it produces the ELF and image ID consumed by generic_call_library. Excluded from the workspace. |
The workspace crates build with the standard toolchain:
cargo build --workspace --all-targetsThe circuit is a separate package (it needs the RISC0 toolchain) and is built and tested from its own directory:
cd generic_call_circuit
cargo build --all-targets
cargo test -- --nocapturegeneric_call_library embeds a prebuilt guest ELF
(generic_call_library/elf/generic-call-guest.bin) and its image ID
(GENERIC_CALL_ID). After changing the witness/circuit, rebuild the guest
reproducibly:
cargo risczero build --manifest-path generic_call_circuit/methods/guest/Cargo.tomlthen copy the resulting ELF into generic_call_library/elf/ and update
GENERIC_CALL_ID in generic_call_library/src/lib.rs
with the printed image ID. Rotating it requires a protocol-adapter
redeployment — see
generic_call_circuit/README.md.
The workspace crates (anoma-generic-call-witness, anoma-generic-call-library)
share the version in [workspace.package] (currently 2.0.0-rc.4). The circuit
crate is versioned independently (currently 1.0.0).
rc.4 bumps anoma-rm-risc0 / anoma-rm-risc0-gadgets to v2.0.0-rc.8.1
(rc.3 tracked v2.0.0-rc.8). This crate's own API is unchanged, but ARM types
(Resource, Digest, NullifierKey) appear in it, so a consumer has to move to
the same ARM version — and rc.8.1 renamed LogicInstance::root to
action_tree_root, which a consumer reading that field has to follow. The
upgrade also re-links the guest, so GENERIC_CALL_ID was rotated.
Our software undergoes regular audits:
-
Informal Systems
- Company Website: https://informal.systems
- Commit ID: 4d561b11846fce692df49dbb73a5def97939e236
- Started: 2026-06-15
- Finished: 2026-06-19
- Last revised: 2026-07-03
If you believe you've found a security issue, we encourage you to notify us via Email at security@anoma.foundation.
Please do not use the issue tracker for security issues. We welcome working with you to resolve the issue promptly.
GPL-3.0