Skip to content
The Stablecoin Sandwich

The Stablecoin Sandwich

How to Track a Payment Across Four Systems That Don’t Talk to Each Other

Where is Carlos’s $500 right now? He sent it to his mother Rosa in Guadalajara twenty minutes ago. It should be there by now. But his remittance company can’t tell you if it is, because the payment touched four different systems on the way, and none of them talk to each other.

LedgerReconciliationStablecoins

What is the Stablecoin Sandwich?

Carlos is a construction worker in Houston. Rosa is his mother in Guadalajara. The “stablecoin sandwich” is how the money moves from one to the other: fiat in, stablecoin across the border, fiat out.

Behind the scenes, the remittance provider orchestrates:

  1. USD deposit via ACH (Chase)
  2. USDC dispatched from pre-funded custody (Fireblocks → Bitso)
  3. USDC → MXN conversion (Bitso)
  4. MXN payout via bank transfer (Banorte)

Settlement that used to take 2–5 days through correspondent banking now happens in minutes. Capital that used to sit in nostro accounts gets freed up. The customer experience improves.

The back office is a different story.

The Tracking Problem

A single remittance touches four separate systems. None share a transaction ID. None know Carlos or Rosa. None can tell the full story of a single payment.

This is not just an operational headache. It is a compliance and fraud exposure. If you cannot reconstruct a payment’s full path in real time, you cannot flag suspicious patterns, prove chain of custody to regulators, or respond to disputes without days of manual work.

  • Chase sees a USD deposit from Carlos. It has no context that the money is a remittance bound for Mexico.
  • Fireblocks sees a USDC transfer between wallets. It tracks custody, not your payment lifecycle.
  • Bitso sees a USDC/MXN trade. It tracks its order book, not your payment lifecycle.
  • Banorte sees a bank transfer to Rosa’s account. It does not know the transfer started as USD in Houston.

Each system has its own ledger, IDs, and timestamps. Operations ends up reconciling bank statements, custody reports, and exchange exports in a spreadsheet.

Basic questions become research projects:

  • Where is Carlos’s payment? Somewhere across four systems. Which one? Check the spreadsheet and hope it is current.
  • Did the USDC arrive before or after we sold it? This matters for compliance. Most teams will not have the necessary proof for an audit.
  • The payout failed. Do we still have the MXN? Probably. Where are they held? How long have they been stuck?
  • How much did we lose to FX slippage this month? Sum up the exchange reports, compare to quoted rates, and hope the timestamps align.

The stablecoin sandwich is faster. It is also more fragmented. Fragmentation turns reconciliation into ongoing work.

Why This Gets Worse at Scale

At 10 transactions a day, you can stitch things together manually. At 1,000 transactions a day (the US-Mexico corridor processes over $5 billion per month), you cannot.

Compliance holds pause some payments mid-flow while others complete. Your USDC inventory and MXN float are constantly in flux. Which funds are cleared? Which are frozen? External systems cannot tell you. Only your internal system can, if you have one.

Failed payouts strand money. A wrong account number means MXN sit in limbo. Without a ledger that tracks state per transaction, you end up searching logs to find where 8,600 MXN went.

FX timing mismatches eat margin. You quoted Carlos a rate of 16.80 MXN/USD. By the time compliance cleared and you executed, the market moved from 17.20 to 17.05. That delta is invisible unless you track quoted rate vs. execution rate per transaction.

Month-end reconciliation turns into forensic accounting. Your bank says you have X MXN. Bitso says you traded Y USDC. Fireblocks shows Z transfers. They should match. They often do not. Finding the discrepancy takes days.

What a Real Ledger Looks Like

A Postgres table with a status column and a balance field might get you through the first month. By month three, you are debugging phantom balances, writing migrations, and explaining to auditors why your transaction log contains UPDATE statements.

You need a purpose-built financial ledger, designed around constraints money imposes: every movement must balance, every entry is permanent, and every state transition is auditable.

Hierarchical Accounts

Instead of flat tables, structure accounts as hierarchical paths that encode meaning. The key choice is to put the user first, then provider and purpose. One prefix query can then return everything about a customer across systems:

  • users:carlos:bitso:custody (Carlos’s stablecoins at Bitso)
  • users:carlos:bitso:compliance (Carlos’s funds held for review)
  • users:carlos:banorte:payout (Carlos’s MXN after FX conversion, earmarked for payout)
  • users:carlos:banorte:RMT-001:pending (payout in flight for one remittance)
  • users:carlos:banorte:RMT-001:holding (stuck funds from a failed payout)
  • banks:banorte:pool (company pre-funded MXN pool)

Notice that the currency is not encoded in the account name. A well-designed ledger is multi-asset: each account can hold balances in any currency, and the asset type is tracked at the transaction level.

The user-first naming pattern is the key advantage. Query users:carlos: and you get every account holding Carlos’s funds in any currency, across all providers. Drill down with users:carlos:banorte: to isolate the Banorte positions. The RMT-001:pending and RMT-001:holding accounts are per-transaction sub-accounts, created for each remittance. New states become deeper nodes in the tree, not schema migrations.

Platform-level accounts like banks:banorte:pool and treasury:fireblocks:pool stay infrastructure-scoped to company capital, not customer funds.

One Transaction, One Timeline

Carlos sends $500 to Rosa. The ledger records each step, with a remittance_id in metadata linking entries into one timeline. For clarity, we focus on the Bitso-to-Banorte leg: compliance, conversion, and payout.

Step 1: USDC Arrives at Carlos’s Custody Account

Cross-border settlement completes when stablecoins land at Bitso, in a per-customer account that records whose money this is.

SourceDestinationAmountReference
treasury:fireblocks:poolusers:carlos:bitso:custody500 USDCRMT-001

Step 2: Compliance Flags the Transaction

The payment needs enhanced due diligence. Move funds to a per-customer compliance hold account until review completes.

SourceDestinationAmountReference
users:carlos:bitso:custodyusers:carlos:bitso:compliance500 USDCRMT-001

Step 3: Compliance Clears

Two hours later, the review completes. Funds return to Carlos’s custody account.

SourceDestinationAmountReference
users:carlos:bitso:complianceusers:carlos:bitso:custody500 USDCRMT-001

Step 4: Convert USDC to MXN

Sell 500 USDC on Bitso at 17.20 MXN/USD, yielding 8,600 MXN. Carlos was quoted 16.80, so Rosa receives 8,400 MXN. The 200 MXN spread is FX revenue.

SourceDestinationAmountReference
users:carlos:bitso:custodyworld500 USDCRMT-001
worldusers:carlos:banorte:payout8,400 MXNRMT-001
worldplatform:revenue:fx200 MXNRMT-001
Why this matters: The ledger records the conversion economics as one atomic entry. 500 USDC leaves custody. 8,400 MXN lands in a per-customer payout account. The spread posts to revenue.
In a double-entry ledger, world is the universal counterparty representing external systems. When money enters the system, world is the source. When money leaves the system, world is the destination.

Step 5: Initiate Bank Transfer

Move MXN from Carlos’s payout account to a pending account while the bank transfer to Rosa is in flight.

SourceDestinationAmountReference
users:carlos:banorte:payoutusers:carlos:banorte:RMT-001:pending8,400 MXNRMT-001

Step 6: Payout Fails

Rosa’s account number was entered incorrectly. Move funds to a holding account until Carlos can correct the details.

SourceDestinationAmountReference
users:carlos:banorte:RMT-001:pendingusers:carlos:banorte:RMT-001:holding8,400 MXNRMT-001

With this structure, each question has a direct, auditable answer:

  • Where is Carlos’s $500? Query remittance_id=RMT-001. Last entry: users:carlos:banorte:RMT-001:holding. It is 8,400 MXN waiting for corrected details.
  • Compliance timing? Held at 2:04pm, cleared at 4:15pm. Two hours, eleven minutes.
  • FX revenue? Quoted 16.80, executed at 17.20. The 200 MXN spread posted to platform:revenue:fx. If execution had slipped to 17.05 instead of 17.20, the delta would flow to platform:expenses:fx_slippage.
  • Where is Carlos’s money across all systems? Query users:carlos:. You can see each of his accounts, and their contents regardless of currency or where it is held.
  • Month-end reconciliation? Sum users:carlos:bitso: and compare to Bitso's custody report. Sum banks:banorte:pool plus users:carlos:banorte: and compare to Banorte's statement. That’s it.

Step 7: Carlos Corrects the Account Number, Rosa Gets Paid

Carlos provides the correct account details. The payout retries and succeeds:

SourceDestinationAmountReference
users:carlos:banorte:RMT-001:holdingworld8,400 MXNRMT-001

Rosa has her money. The holding and pending sub-accounts for RMT-001 are zeroed. The full lifecycle, from USD deposit to MXN payout, is recorded on one timeline, so you can see precisely what happened and when.

Why Most Teams Don’t Build This

Building a ledger on Postgres is straightforward. Building one that handles the stablecoin sandwich correctly is difficult.

Double-entry enforcement: Every movement needs a source and destination. Money cannot appear from nowhere. Many homegrown systems skip this, then spend months debugging balance mismatches that an enforced ledger would have rejected on day one.

Immutability: You must never be able to delete or edit transactions. Failed payouts require reversals, not row deletions. This is something that auditors care deeply about.

Hierarchical queries: Summing all accounts matching users:carlos: across providers sounds simple until you are writing recursive queries at 2am.

Multi-system sync: Chase, Fireblocks, Bitso, and Banorte all have different APIs, formats, and latencies. Keeping them aligned without drift is ongoing work.

Compliance state machine: Payments move through holds, reviews, partial completion, failures, and retries. Each transition needs to be atomic and auditable.

Teams start with spreadsheets. They graduate to a Postgres table. They bolt on features for months. At some point they realize they have built a ledger, and now they carry the burden of maintaining it.

How Formance Solves This

If you're reading this and it sounds like your last six months, you're not alone. Most teams we talk to hit this wall somewhere between the second corridor and the first audit.

Formance is a programmable ledger designed to solve this problem: Tracking money across fragmented systems with one source of truth.

Hierarchical accounts out of the box. You can create users:carlos:bitso:custody by referencing it in a transaction, with no migration required. Query users:carlos: to see every position across all providers, or drill into users:carlos:banorte: for just the Banorte leg.

Double-entry enforced. Every transaction must balance. The system rejects anything that does not.

Immutable by design. The ledger uses an append-only log. You make reversals, not edits or deletions. Every state change is traceable back to the original entry.

Numscript for complex flows. Formance includes a domain-specific language for complex, multi-step transactions that execute atomically, with metadata attached for audit.

send [USDC/6 500000000] (
  source = @users:carlos:bitso:custody
  destination = @world
)

send [MXN/2 840000] (
  source = @world
  destination = @users:carlos:banorte:payout
)

send [MXN/2 20000] (
  source = @world
  destination = @platform:revenue:fx
)

set_tx_meta("type", "FX_CONVERSION")
set_tx_meta("remittance_id", "RMT-001")
set_tx_meta("quoted_rate", "16.80")
set_tx_meta("execution_rate", "17.20")

Reconciliation built in. Formance can ingest external data, compare it to internal ledger state, and surface drift before it becomes a month-end exercise. And where there is drift, Formance can help you understand the source.

The stablecoin sandwich represents a better way to move money across borders. Formance gives you a ledger that can tell the whole story of each payment.

Formance

Try the Interactive Demo

Explore an end-to-end demo of the scenario described above in your browser. See how a ledger-centric approach makes money movement auditable, explainable, and easier to operate.

Related Articles