Contracts Overview
NiceTry's onchain footprint is deliberately small: a stateless verifier, an ERC-4337 account, and a deterministic factory. Each FORS+C account is a minimal proxy that stores one signer commitment and rotates it on every UserOp.
Contract map
| Contract | File | Role |
|---|---|---|
ForsVerifier | src/Verifiers/ForsVerifier.sol | Stateless FORS+C verifier: recover(sig, digest) → address |
SimpleAccount | src/SimpleAccount.sol | ERC-4337 account; verifies + rotates owner on every UserOp |
SimpleAccountFactory | src/SimpleAccountFactory.sol | CREATE2 factory deploying account clones |
InitialSignerCommitment | src/InitialSignerCommitment.sol | Domain separators for salts and activation leaves |
ISignatureVerifier | src/Interfaces/ISignatureVerifier.sol | Verifier interface (lets the account stay scheme-agnostic) |
FrameAccount | src/FrameAccount.sol | EIP-8141 frame-native variant of the same rule |
How they fit together
SimpleAccountFactory --(CREATE2 clone)--> SimpleAccount (EIP-1167 proxy)
|
| validateUserOp
v
ISignatureVerifier.recover() -> ForsVerifier
|
v
compare to owner, rotate to nextOwnerThe account talks to the verifier only through ISignatureVerifier, so the signing scheme is a pluggable dependency rather than hard-wired logic:
interface ISignatureVerifier {
/// @return signer The recovered signer address, or address(0) on failure.
function recover(bytes calldata sig, bytes32 digest) external view returns (address signer);
}The ForsVerifier is immutable and shared: one deployment serves every account, and the account holds it in an immutable VERIFIER set at construction.
Conventions shared across the contracts
- EntryPoint: the canonical ERC-4337 EntryPoint v0.7, identical-address across mainnet, Sepolia, and major rollups.
- Rotation at validation time: the owner commitment advances inside
validateUserOp, so a key is retired even if the inner call reverts. See Standards → ERC-4337. - The
nextOwnerlives in calldata: every UserOp'scallDataends withbytes20(nextOwner), so the signeduserOpHashcommits to the next signer. - Deterministic addresses: verifier, factory, and account implementation are deployed via CREATE2 so they share addresses across chains.
- Toolchain:
solc 0.8.30, optimizer on,via-irenabled;account-abstraction, OpenZeppelin, and Solady as dependencies.
ERC-7579 module variant
For the legacy schemes, the rotation-validation logic is also packaged as ERC-7579 validator modules (KernelRotatingECDSAValidator, KernelRotatingWOTSValidator), so it can run inside an existing modular account (e.g. Kernel, Nexus) without deploying a new one. Module state is keyed by account address as the outermost mapping key to satisfy ERC-7562 storage rules. The ERC-7579 interfaces and mock-account integrations live under other-implementations/kernel/.
A FORS+C validator module is not implemented yet: today the FORS+C path ships only as the standalone SimpleAccount.