article

Merces as a Monad Private Settlement domain

7 min read

Institutions have been trying to get private execution onchain for years, and have mostly ended up with permissioned ledgers. A chain per consortium, bespoke bridges to everything outside it, and liquidity split across all of them.

Category Labs has published its synopsis of Monad Private Settlement, which takes a different route. A private execution domain is registered through a hub contract on the Monad L1, with no fork and no protocol change. Whoever creates the domain sets its validators, its access rules, its jurisdiction, which L1 tokens it can hold, and the cryptographic technique those validators run: TEE, zkVM or MPC.

That last choice is where this gets concrete for us. Merces is TACEO’s privacy layer for onchain finance and it is built on MPC, which makes a Merces domain one of the three instantiations the model describes. The synopsis describes the model. It doesn’t include a deployment.

So we built one. Over the past three weeks we built a prototype of Merces running as a Private Settlement domain, with deposits, transfers and withdrawals working end to end. This post is what that took: what we reused, what we had to build ourselves, and what it would change compared with the Merces deployment we already run on Monad mainnet.

What we built

Merces is TACEO’s privacy layer for onchain finance. It runs on Monad mainnet today as an ordinary EVM deployment. The prototype discussed in this post runs Merces instead as a Private Settlement domain, using Category Labs’ domain framework as it stands and changing as little of it as possible.

Three flows work end to end: deposits from the L1 into the domain, transfers inside the domain, and withdrawals back out to the L1. The demo is at monad-psd.merces-demo.taceo.io, running against a Monad deployment and the MPC nodes, with the values shown coming from live chain state.

The live prototype. Open it in a new tab for the full-size view.

The Merces MPC network is three parties running replicated secret sharing in the honest-majority semi-honest setting. When a domain creator picks MPC as the technique, that network is what they are nominating as the validator set.

What we reused, and what we put in front of it

Most of the plumbing came from Category Labs’ framework unchanged. The Hub and Bridge contracts handle sequencing, messaging and token handling. Deposits, transfers and withdrawals map onto those primitives directly: our events become L1 to domain messages, our MPC settlement calls become domain to L1 state updates, and token handling moves into the bridge.

What we had to add comes from one mismatch. The framework assumes a domain is a full EVM chain, with authorization by signatures inside the domain and standard JSON-RPC on the outside. A Merces domain has no contracts, logs or events in that sense. Authorization happens on the L1, and its RPCs return shares rather than values, under access control.

So users cannot talk to the Hub directly. We put a proxy contract in front of it that checks user intent first and only then emits the message, and alongside it we deployed the pieces with no equivalent in the framework: the identity and user group registries, and the verifiers. Domain blocks are derived one per finalized L1 block, from the messages recorded on the L1.

Withdrawals use the framework’s flow as is: the withdrawals from each block are committed as a Merkle root alongside the state update, and claimed from the L1 bridge with an inclusion proof.

The traffic went both ways. The framework’s messaging and block-building design was worked through with Merces as the non-EVM case, and the approach the Hub ended up taking, a pending queue of messages on the L1, is close to the one Merces already used.

How it would differ from our mainnet deployment

Merces on Monad mainnet is a normal EVM deployment. We bring our own entry points, our own messaging, and our own bridging. It works, and it is how Merces runs on every chain we are on.

As a domain, the L1 would provide sequencing, messaging and token bridging, so we would no longer have to run our own. The domain would be registered with an explicit validator set, access rules, jurisdiction, attestation policy, and the set of L1 tokens it can hold, so the configuration an institution cares about would be declared onchain rather than agreed with us offchain.

The larger change would be what sits next to it. Two Merces domains on the same L1 could settle against each other without a bridge between them, and the same would hold between a Merces domain and any other domain on Monad. Our deployments today are one per chain, and anything crossing between them is a bridging problem. That is the part we cannot build on our own.

What would not change is the privacy model. Merces keeps amounts and accounts private in its fully private mode. Privacy here comes from the MPC protocol, so running inside a domain would not strengthen them, and the domain framework would not weaken them.

What is still open

This was built against an early preview of the framework, so some of the integration is provisional. Three things are open:

What private state is for

The flows in the prototype are deliberately plain: move value in, move it around, move it out. The reason to care is what private state allows once it is there.

Merces keeps state that several parties update and none of them can read. That is different from a private chain, where the transactions are private but the parties transacting are visible, and different again from a per-user notes model, where each user holds their own state and anything shared needs a coordinator who sees it in the clear.

Harder things sit on the same primitive. An order book where positions and sizes stay private from everyone including the operator. A register several institutions write to without seeing each other’s entries. A matching or auction process where the inputs stay private and only the outcome settles. These are shared-state problems, which is why they have been hard to put onchain privately.

With a domain, that private state would sit right next to the L1. Two institutions each running their own domain could settle against each other with neither the counterparties nor the amounts public, and the settlement would land on the same chain as everything else. Regulators and auditors would get scoped access to what they are entitled to see, after the fact, without that access being open to anyone else.

That is what we are building toward next: a fully private RFQ setup for OTC trades between two Private Settlement domains, with the quotes, the counterparties and the size of the trade all kept private.


Try the prototype: monad-psd.merces-demo.taceo.io

Documentation and client SDKs: docs.taceo.io

Talk to us about integrating Merces: [email protected]