# Payy Markdown version of https://l2beat.com/privacy/projects/payy ## Summary **Warning:** The escrow was [drained](https://x.com/payy_link/status/2105047468639658317) on September 24, 2026, and the network has been halted since. Do not deposit funds. - Total Value Locked: $710.55 (-0.01% compared to seven days ago) - Live asset metrics: Not tracked. Onchain asset monitoring is not available for this project. - Tracked on: Ethereum - Attributes: ZK, Transfers, Any amount ### Risks - Privacy: Link privacy. Public observer: Link exposed (sentiment: bad); Chain analyst: Link exposed (sentiment: bad); Network observer: Link exposed (sentiment: bad); Privileged insider: Link exposed (sentiment: bad); Future adversary: Link exposed (sentiment: bad). - Trusted setup: 176 participants (sentiment: good). Aztec Ignition: Aztec Ignition is a trusted setup ceremony that was run by Aztec for KZG commitment over BN254 curve in 2019. It included 176 participants and was publicly open for participation. - Exit window: None (sentiment: bad). The PayyMultisig can instantly upgrade the RollupV1 contract, replace ZK verifiers and directly overwrite the state root, so users have no time to exit before a malicious change takes effect. This protocol fails the walkaway test: users cannot fully use it if every centralized participant disappears. Withdrawals must be included in a proven state update by the permissioned Payy operators. There is no mechanism for users to exit on Ethereum if the operators halt. - Reproducibility: Partially reproducible (sentiment: warning). The Payy app is closed source. The contracts, circuits and node are published without a license and can be built locally. Transaction data is not posted anywhere public, so the state cannot be rebuilt independently. ### About A shielded ledger L2 for USDC payments in a mobile app, with payment links and a card, that hides amounts but not which notes fund which. ### Links - Website: https://payy.network - Docs: https://docs.payy.network - Explorer: https://payy.network/explorer - Repository: https://github.com/polybase/payy - Social: https://x.com/payy_link - Contracts explorer (Disco): https://disco.l2beat.com/ui/p/payy ### Badges - Application-specific chain: This project is built to operate a specific application - Custom DA solution: This project is using a custom DA solution - Privacy: This project supports private transactions natively ## Protocol description Payy is a mobile app for USDC payments. The user deposits USDC, sends it to other users or as a payment link, and withdraws it to Ethereum or tops up the Payy card. Note amounts and owners stay hidden. Which notes fund which, and every deposit and withdrawal with its address and amount, are public. Users trust Payy, which runs the only validator, prover and node, delivers notes between users and holds the keys of link and ramp notes. The 2/4 multisig can upgrade the RollupV1 contract and overwrite its state root without delay. Leaving needs Payy: withdrawals settle only in its proven state updates, and transaction data lives only on its servers. ### Architecture Each balance is a set of notes. A note holds an amount of USDC and an owner key, and only its commitment enters the state tree. A transaction spends up to two notes, creates up to two and names the commitments it spends, since the circuits use no nullifiers. Payy's node serves every block with its proofs. Ethereum receives only state roots, deposits and withdrawals. ### Flow 1. **Deposit.** The app gives each wallet one fixed deposit address. You send USDC there, and Payy's relayer moves it into the RollupV1 contract with your signed authorization. Deposit address and amount are public. 2. **Send.** Your phone proves the transfer and submits it to Payy's node. The note reaches the recipient through Payy's registry, encrypted to the recipient's key, or as a payment link whose URL holds the note's secret. 3. **Withdraw.** You burn notes to an Ethereum address, which the next state update pays out. A whitelisted account may pay at once and get refunded at settlement. Recipient and amount are public. Card top-ups are withdrawals to the card issuer's contract. ### Keys The app is closed source, so how it creates and backs up keys is unverified. Payy's backend keeps wallet backups, and its diagnostics reports have a required field for the recovery phrase. ### App The ratings assume the Payy mobile app, which is closed source and talks only to Payy's servers. The [repository](https://github.com/polybase/payy) publishes the contracts, circuits, node and backend interfaces. Its open TypeScript client knows only Payy's testnet. ### Compliance KYC is required for the Payy card and fiat ramps, not for transfers. Payy's backend can block a wallet or an IP address from its services, and its validator can refuse any transaction. The protocol has no view key. ### Fees The RollupV1 contract charges no fee. Payy pays the gas of deposits and settlement. ## Privacy **What the protocol promises:** Hides note amounts and owners. Which notes fund which, and every deposit and withdrawal, are public. Ethereum is public by default. Each protocol is rated on its main privacy promise, like hiding who paid, who received, how much, or which deposit became which withdrawal. Against each adversary, the colour says whether it holds for a careful user with the app's own settings: green yes, yellow only with significant extra work, red no. Fields marked at risk stay private only under the condition in their note. ### Public observer Link exposed (sentiment: bad) **Who:** Everyone with a block explorer and some basic tools. Sees every public onchain event, but does no correlation beyond following links. Examples: A curious counterparty, an employer, a journalist. Every transaction names the notes it spends and creates, so which notes fund which is public. Empty padding notes have a zero commitment, so single-input and single-output transactions are recognizable. Each deposit or withdrawal shows address and amount and points at one node of that graph. The per-transaction proofs use a flavor its authors document as not zero-knowledge, and how much of a note it leaks is not established. **Inside** - Sender: private. The owner key is hidden, but the spent note is a public graph node. - Recipient: private. Recipient and change outputs are indistinguishable. - Amount: at risk. Protected by a proof flavor documented to leak witness data. - Asset: exposed - Link: exposed **Sources** - [Spend graph explorer built from Payy blocks (by L2BEAT)](https://sekuba.github.io/payy-graph/) - [UTXO circuit: spent and created commitments are public, no nullifier](https://github.com/polybase/payy/blob/2f95947f12981a838f6f0c9dddace825bf835502/noir/utxo/src/main.nr#L9-L15) - [Client proofs use the non-ZK Honk flavor](https://github.com/polybase/payy/blob/2f95947f12981a838f6f0c9dddace825bf835502/pkg/barretenberg-rs/src/binding.rs#L109-L118) - [Honk docs: the base flavor leaks witness information](https://github.com/AztecProtocol/aztec-packages/blob/58bf73a289f7da78c8920c9c73604a8e5d105025/barretenberg/cpp/src/barretenberg/ultra_honk/README.md#zero-knowledge) ### Chain analyst Link exposed (sentiment: bad) **Who:** Scrapes all public data and correlates it: timing, amounts, gas and wallet fingerprints, address clusters. Examples: Chain analytics firms, ZachXBT, data brokers. Along a path without splits or merges, the deposit and withdrawal amounts fix every amount in between. Each wallet has one fixed deposit address, so all its deposits link to each other and to whoever funded them. **Inside, compared with a public observer** - Sender: at risk. Nodes are labelled by their terminal deposit and withdrawal addresses. - Recipient: at risk - Amount: at risk. Inferable along a linear path from a deposit to a withdrawal. **Sources** - [Public block API](https://validators.mainnet.payy.network/v0/blocks) - [One deposit address stored per wallet](https://github.com/polybase/payy/blob/2f95947f12981a838f6f0c9dddace825bf835502/pkg/database/src/schema.rs#L464-L481) - [Deposit relayed from the deposit address with a signed USDC authorization](https://github.com/polybase/payy/blob/2f95947f12981a838f6f0c9dddace825bf835502/pkg/guild-interface/src/mint.rs#L56-L90) - [Wallet FAQ: the deposit address forwards to the bridge](https://docs.payy.network/payy-wallet/payy-wallet-faq) ### Network observer Link exposed (sentiment: bad) **Who:** Sits between the user and the services and sees traffic only: ISPs, VPNs, Tor exits, public RPCs and relayers. Learns IP addresses, timing, fingerprints and ciphertext. Services the operator runs count as the insider. Examples: Infura or Alchemy, a Tornado relayer, a wallet vendor selling telemetry, Google captcha or analytics in the dapp frontend. The Payy app is closed source and no open client works on mainnet, so what it sends to third parties is up to Payy and can change at any time. The payment-link website loads a third-party analytics script that records the page URL, which holds the link's redeem secret. **Inside, compared with a public observer** - Sender: unverifiable - Recipient: unverifiable - Amount: at risk. A link opened in a browser hands its redeem secret to the analytics provider. **Sources** - [The repository publishes only type bindings of the app](https://github.com/polybase/payy/blob/2f95947f12981a838f6f0c9dddace825bf835502/app/packages/payy/src) - [The open TypeScript client knows only dev and testnet](https://github.com/polybase/payy/blob/2f95947f12981a838f6f0c9dddace825bf835502/app/packages/payy-client/src/network.ts#L6-L17) - [Analytics with default settings on the link website](https://github.com/polybase/payy/blob/2f95947f12981a838f6f0c9dddace825bf835502/app/packages/link/src/config/posthog.ts#L10-L18) - [Send links carry the secret in the URL fragment](https://github.com/polybase/payy/blob/2f95947f12981a838f6f0c9dddace825bf835502/pkg/parse-link/src/lib.rs#L50-L56) ### Privileged insider Link exposed (sentiment: bad) **Who:** Holds an operator role, custodies funds, receives keys or plaintext by design, or delivers the client: upgrade admin, custodian, view key holder, enclave operator, association set provider, hosted prover, registry, frontend host. Examples: A compliance backdoor key, a DAO with an upgrade key, a KMS committee, an ASP operator, a custodial bridge. One company runs the only validator and prover, the node, the note registry, the deposit relayer and the KYC checks. Its backend ties each session to a wallet address and keeps, per wallet, the deposit address, KYC record, country, IP country and the commitment and owner of every note the app reports. For payment links and fiat ramps it holds the notes' private keys and can read and spend them. Its registry sees which wallet delivers a note to which recipient key, and in which block. **Inside, compared with a public observer** - Sender: exposed - Recipient: exposed - Amount: at risk. The backend holds the keys of link and ramp notes. **Sources** - [setRoot, provers, validators, burn substitutors](https://l2beat.com/privacy/projects/payy#RollupV1) - [Session bound to a wallet address by signature](https://github.com/polybase/payy/blob/2f95947f12981a838f6f0c9dddace825bf835502/pkg/guild-interface/src/auth.rs#L1-L16) - [Link and ramp notes are created with their private key on the backend](https://github.com/polybase/payy/blob/2f95947f12981a838f6f0c9dddace825bf835502/pkg/guild-interface/src/notes/create.rs#L36-L45) - [Wallet table: deposit address, KYC, country, IP country](https://github.com/polybase/payy/blob/2f95947f12981a838f6f0c9dddace825bf835502/pkg/database/src/schema.rs#L464-L481) ### Future adversary Link exposed (sentiment: bad) **Who:** Harvest now, decrypt later. Holds every byte ever written onchain plus any retained logs, and breaks all public-key cryptography, by quantum computer or new mathematics: elliptic curves, pairings, RSA, lattices and isogenies. Hashes, Poseidon included, and symmetric ciphers survive. Examples: An intelligence agency archiving chain data today, then anyone once a break is public. The per-transaction proofs are public and not zero-knowledge, and the commitments inside them rest on elliptic curves. Registry ciphertexts use elliptic-curve key exchange. If the operator retains them, whoever breaks elliptic-curve cryptography opens every note delivered through it. **Inside, compared with a public observer** - Sender: at risk. Only if Payy retains the registry, whose ciphertexts are not on Ethereum. - Recipient: at risk - Amount: at risk. Public proofs are not zero-knowledge, and retained registry ciphertexts open. **Sources** - [Registry encryption (X25519-XSalsa20-Poly1305)](https://github.com/polybase/payy/blob/2f95947f12981a838f6f0c9dddace825bf835502/pkg/encrypt/src/asymmetric.rs#L80-L81) - [Client proofs use the non-ZK Honk flavor](https://github.com/polybase/payy/blob/2f95947f12981a838f6f0c9dddace825bf835502/pkg/barretenberg-rs/src/binding.rs#L109-L118) - [Honk docs: ZK flavors add masking the base flavor lacks](https://github.com/AztecProtocol/aztec-packages/blob/58bf73a289f7da78c8920c9c73604a8e5d105025/barretenberg/cpp/src/barretenberg/ultra_honk/README.md#zero-knowledge) - [Onchain verifier (ZK flavor)](https://l2beat.com/privacy/projects/payy#HonkVerifier) ## Value Locked The interactive value chart is shown on [the HTML page](https://l2beat.com/privacy/projects/payy#privacy-tvl). ## Milestones & Incidents - 2026-09-24 (incident): [Escrow drained, network halted](https://x.com/payy_link/status/2105047468639658317). Two state updates pay out almost all escrowed USDC for an invalid burn. Payy halts the network. - 2026-06-10 (incident): [Critical circuit vulnerability disclosed](https://github.com/polybase/payy/security/advisories/GHSA-fhxc-63vg-9gwr). An aggregation circuit bug allowed forged burn messages, was patched by the team. - 2026-02-19: [Payy Network is live on Ethereum](https://payy.network/blog/payy-network-is-live-on-ethereum). Payy launches its network on Ethereum, migrating from its previous deployment on Polygon. ## Risk summary ### Funds can be stolen if 1. the verifier or the circuits accept an invalid withdrawal. 2. the PayyMultisig upgrades the RollupV1 contract or overwrites the state root, which takes effect without delay. ### Funds can be lost if 1. a user loses the note data or the keys required to spend their notes. 2. the offchain transaction data becomes unavailable, as data availability is not verified on Ethereum. 3. the operators stop including withdrawals in proven state updates, as there is no forced exit mechanism. ### Privacy can be lost if 1. anyone with Payy's block data follows which notes fund which, from a deposit address to a withdrawal address (see public observer). 2. a path without splits or merges reveals every amount between a deposit and a withdrawal (see chain analyst). 3. the closed-source Payy app sends user data to third parties, which Payy can change at any time (see network observer). 4. Payy's backend, which ties each wallet to its KYC record, deposit address and notes, leaks or uses this data (see privileged insider). 5. the public per-transaction proofs, which are not zero-knowledge, or retained registry ciphertexts are opened in the future (see future adversary). ## Upgrades & Governance All privileged functions are ultimately controlled by the PayyMultisig (2/4). It owns the ProxyAdmin, which can instantly upgrade the RollupV1 proxy, and it is the owner of the RollupV1 contract, allowing it to manage provers, validators, ZK verifiers, supported tokens and burn substitutors, and to directly overwrite the state root via setRoot(). There is no timelock or exit window on any of these actions. ## Trusted setup Risk levels follow the [Trusted Setups Risk Framework](https://forum.l2beat.com/t/the-trusted-setups-framework-for-zk-catalog/381). Yellow (medium risk): all contributions are published and the final output can be verified, the ceremony client is open source, there were at least 30 contributions, participation was open to the public and announced, and participants are publicly identified. Green (lowest risk): everything required for yellow, with at least 150 contributions. Red (highest risk): at least one requirement for yellow is not met. N/A: the proof system needs no trusted setup. ### Aztec Ignition - Risk: green (lowest risk) - Proof systems: UltraHonk (Plonk) Aztec Ignition is a trusted setup ceremony for KZG commitments over BN254 curve that was run by Aztec for KZG commitment over BN254 curve in 2019. It included 176 participants and was publicly open for participation. - Github repo to download and verify the ceremony artifacts: [https://github.com/AztecProtocol/ignition-verification](https://github.com/AztecProtocol/ignition-verification). - Github repo with instructions for ceremony participants: [https://github.com/AztecProtocol/Setup](https://github.com/AztecProtocol/Setup). - Ceremony announcement with a call to participate: [https://aztec.network/blog/announcing-ignition](https://aztec.network/blog/announcing-ignition). ## Updates Each date links the update on the HTML page, which also shows its contract diffs. ### [2026-10-13 13:09 UTC](https://l2beat.com/privacy/projects/payy?update=f0bef495) (high severity, 3 changes) New 7702-delegation for on the Payy ms members. ### [2026-08-25 10:47 UTC](https://l2beat.com/privacy/projects/payy?update=706e79b8) (4 changes) Discovery rerun on the same block number with only config-related changes. ## Permissions Explore these contracts and permissions in Disco, L2BEAT's contract explorer: https://disco.l2beat.com/ui/p/payy ### Ethereum #### Actors ##### PayyMultisig Addresses: [0x230Dfb03F078B0d5E705F4624fCC915f3126B40f](https://etherscan.io/address/0x230Dfb03F078B0d5E705F4624fCC915f3126B40f) A Multisig with 2/4 threshold. - Can upgrade **with no delay** - RollupV1 [via: ProxyAdmin] - Can interact with RollupV1 - can manage provers, validators, ZK verifiers, supported tokens and burn substitutors, and can overwrite the current state root via setRoot() Participants (4): [0x54e22ad93DE7Dad5C83e9b1caC257F3aB384b02c](https://etherscan.io/address/0x54e22ad93DE7Dad5C83e9b1caC257F3aB384b02c), [0x111e5feA3D613EB866fd41B30c8257C930180428](https://etherscan.io/address/0x111e5feA3D613EB866fd41B30c8257C930180428), [0xCa1Df6eDf8adaCA00FC24DBD919578dD2e9EcBb6](https://etherscan.io/address/0xCa1Df6eDf8adaCA00FC24DBD919578dD2e9EcBb6), [0xAF657A8Fa036bcc99AC3cCd5b7fFa4AaddFBE501](https://etherscan.io/address/0xAF657A8Fa036bcc99AC3cCd5b7fFa4AaddFBE501) ##### EOA 1 Addresses: [0x41582701CB3117680687Df80bD5a2ca971bDA964](https://etherscan.io/address/0x41582701CB3117680687Df80bD5a2ca971bDA964) - Can interact with RollupV1 - can sign state updates as a validator. Signatures from more than 2/3 of the current validator set are required for each update ##### EOA 2 Addresses: [0x5343B904Bf837Befb2f5A256B0CD5fbF30503D38](https://etherscan.io/address/0x5343B904Bf837Befb2f5A256B0CD5fbF30503D38) - Can interact with RollupV1 - can submit state updates (new state roots) via verifyRollup(), providing an aggregated ZK proof and validator signatures ## Smart contracts Explore these contracts and permissions in Disco, L2BEAT's contract explorer: https://disco.l2beat.com/ui/p/payy ### Ethereum #### HonkVerifier Addresses: [0x14DACD534ddc676601B27f41Eb541a7951524a2F](https://etherscan.io/address/0x14DACD534ddc676601B27f41Eb541a7951524a2F#code) UltraHonk proof verifier generated with Aztec's Barretenberg from Payy's final aggregation Noir circuit. It verifies the aggregated validity proof of each state update submitted to the Rollup contract. #### RollupV1 (escrow) Addresses: [0x367C1eAF14AA06b78ce76bd0243297de79d85270](https://etherscan.io/address/0x367C1eAF14AA06b78ce76bd0243297de79d85270#code), [0x7d8837b547F4FEa0053571CB149e845FC58e9B2D](https://etherscan.io/address/0x7d8837b547F4FEa0053571CB149e845FC58e9B2D#code) (Implementation (Upgradable)), [0xfE455baCAF1968F1Ae6a322b8Ffbe56840e2f590](https://etherscan.io/address/0xfE455baCAF1968F1Ae6a322b8Ffbe56840e2f590#code) (Admin) **Past upgrades** (Count of upgrades: No upgrades, Last upgrade: N/A, Avg upgrade interval: N/A) - 2026-02-17 10:32 UTC, deployment of [RollupV1](https://etherscan.io/address/0x367C1eAF14AA06b78ce76bd0243297de79d85270#code): transaction [0x8d002955fe594ded0ee57519c15a7c9dcf52e759be1fdd628eaf810dc2558abd](https://etherscan.io/tx/0x8d002955fe594ded0ee57519c15a7c9dcf52e759be1fdd628eaf810dc2558abd), implementations: [0x7d8837b547F4FEa0053571CB149e845FC58e9B2D](https://etherscan.io/address/0x7d8837b547F4FEa0053571CB149e845FC58e9B2D#code) Main contract of the Payy ZK rollup. It stores the state root, escrows USDC backing the notes on the rollup, processes deposits (mints) and withdrawals (burns), and accepts state updates that must include an aggregated ZK proof and signatures from more than 2/3 of the current validator set. - Roles: - **admin**: ProxyAdmin; ultimately PayyMultisig - **getValidatorSets**: EOA 1 - **initialProver**: EOA 2 - **owner**: PayyMultisig All supported tokens in this escrow are included in the value secured calculation. Can be upgraded by: PayyMultisig with no delay #### ProxyAdmin Addresses: [0xfE455baCAF1968F1Ae6a322b8Ffbe56840e2f590](https://etherscan.io/address/0xfE455baCAF1968F1Ae6a322b8Ffbe56840e2f590#code) - Roles: - **owner**: PayyMultisig The current deployment carries some associated risks: - Funds can be stolen if a contract receives a malicious code upgrade. There is no delay on code upgrades (CRITICAL).