marmot

Marmot docs

20 pages, from the idea to the error codes

Concepts

Passkey guardian

How a phone unlock becomes an on-chain veto.

What a passkey is

A passkey is a key pair your device makes for a website. The private half never leaves the device (or your synced keychain) and is unlocked with Face ID, a fingerprint or the device PIN. Technically it is a WebAuthn credential on the P-256 curve.

Why it works on Robinhood Chain

Verifying a P-256 signature in plain Solidity is expensive (hundreds of thousands of gas or more). The chain offers it as a precompile at address 0x100. We tested it live on chain 4663: a valid signature returns 1, anything else returns nothing. That makes a veto cost about 87,000 gas.

The flow

  1. The Guardian page asks your browser to create a passkey for the site's domain. We keep only its public point (x, y).
  2. The vault is created with that point and a hash of the domain (rpIdHash).
  3. To refuse announcement n, the browser asks your device to sign a challenge: the EIP-712 digest Veto(id, epoch) for this vault.
  4. The browser returns authenticatorData, clientDataJSON and an ECDSA signature (r, s).
  5. Anyone submits vetoWithSig(id, abi.encode(Auth)). The vault checks, in order: the domain hash, the "user present" and "user verified" flags, that the type is webauthn.get, that the challenge in the client data is exactly this digest, and the P-256 signature.
struct Auth {
  bytes   authenticatorData;
  string  clientDataJSON;
  uint256 challengeIndex;   // where "challenge":" starts in clientDataJSON
  uint256 typeIndex;        // where "type":"webauthn.get" starts
  uint256 r;
  uint256 s;
}

Bound to a domain

A passkey only signs for the website it was created on. A copy of the site on another domain cannot ask your device for this passkey, and a signature from another domain is refused by the vault. The flip side: choose the domain before you create a guardian passkey and do not move the site.

User verification is mandatory

The vault refuses a signature unless the device reports that the person was verified (Face ID, fingerprint, PIN), not merely present. A stolen unlocked phone still needs the biometric or PIN to whistle.

Backup and loss

  • Passkeys sync through iCloud Keychain or Google Password Manager. Check that yours does before trusting it.
  • If you lose the guardian passkey, the vault keeps working but nobody can refuse anything. Announce a new guardian, wait, execute. Until then you are protected only by luck.
  • For large amounts consider an ERC-1271 guardian, such as a Safe with two of three signers.

Relaying

The signature is bound to a specific vault, announcement and epoch, so a relayer can do nothing with it except submit the veto you meant. If a relayer ignores it, submit it yourself with the CLI (marmot relay) or from your wallet on the Lookout page.