Reserve Validation
Purpose
Reserve validation compares the EMI's fiat reserves against on-chain token supply to confirm that every outstanding token is backed 1:1 by EUR. It runs automated checks, requires Treasury review. Successful validation can be published as verified supply figures to the public API with a Supply Multisig co-sign. This is the primary control for MiCA Art. 36 (reserve of assets) and Art. 30 (ongoing disclosure to holders).
Who Can Trigger
Treasury Officer. Each run creates an independent validation record.
Trigger
Treasury Officer clicks "Start Validation" in the backoffice and provides the fiat balance. This is the trigger — the process begins here.
What happens before (reserve management, issuance, redemption) and what happens after an end state is reached (remediation follow-up, regulatory reporting) is outside this process.
Schedule
The cadence is policy-driven and tracks supply-changing activity, not a fixed calendar:
- Weekly at launch. MiCA Art. 30 requires updates at least monthly, and weekly is a conservative starting point while volume is low.
- Daily or monthly later. Depending on mint/redemption activity and operational burden.
- Event-driven runs always allowed. Treasury Officer can start an out-of-cadence validation at any time (e.g. after a large mint or burn) and choose whether to publish it.
- The validation should run in the morning before any supply-changing activity — the finality lag (~30 min) between the fiat timestamp and the on-chain snapshot is only negligible if nothing is moving in between.
- Weekends and holidays create gaps. Mints and burns require human operators and don't run continuously, but the chain does — so the public API shows older data between runs.
Overview
- Treasury Officer provides the fiat reserve balance with a timestamp and proof
- System pulls on-chain supply data at the last finalized block before the fiat balance timestamp
- System runs automated checks against fiat and on-chain data
- Treasury Officer reviews results and, if proposing publication, provides the reserve-location note
- Supply Multisig (2-of-3) co-signs the publication decision
- System publishes verified supply figures to the public API
If any step fails or is rejected, the record is closed as closed_failed. Treasury Officer investigates and triggers a new validation run.
Constraints
- MiCA Art. 36 — reserve of assets: the reserve's aggregate value must be at least equal to the claims of holders. Total token supply must never exceed fiat reserves — a validation failure on the fiat backing check is a potential breach.
- MiCA Art. 30 — ongoing disclosure: the issuer must publicly disclose the amount of tokens in circulation and the value and composition of the reserve, updated at least monthly. The publication step fulfils this obligation. Art. 30 is Title III (asset-referenced tokens); it applies to significant e-money tokens via Art. 58.
- Dual sign-off on publication: automated checks alone are insufficient. Treasury Officer proposes publication after manual review, and the Supply Multisig (2-of-3) co-signs — the same pool that signs mints, so the same two-person rule applies to the act of publishing supply figures.
- Only co-signed validations are published: the public API only receives data from validations where all automated checks passed, Treasury Officer approved, and the Supply Multisig co-sign completed. No unconfirmed data, no partial results, and no failure states are ever pushed to the public API.
- On-chain data must be L1-finalized: the validation only uses on-chain data from blocks included in an L1 batch posted to Ethereum. Unconfirmed L2 data is never used.
Steps
The following describes the happy path. Any step can result in failure or rejection → closed_failed.
Step 1 — Provide Fiat Balance
Owner: Treasury Officer · Status: new → awaiting_on_chain_data
- Treasury Officer enters the fiat reserve balance with a timestamp (
fiat_timestamp) and proof (e.g., bank statement screenshot). Thefiat_timestamprecords when the balance was observed. - The timestamp can be any point from the last published validation up to now.
Step 2 — Pull On-Chain Supply
Owner: System · Status: awaiting_on_chain_data → awaiting_checks
- Select the highest finalized block on Base with timestamp ≤
fiat_timestampas the reference block. - Query on-chain data to retrieve: public supply, encrypted supply (FHE-decrypted), and all mint/burn transactions since the last published validation, all as of that block.
- Depends on the decryption service (see Infrastructure).
- The first validation is seeded with zero values at the token contract deployment block — there is no previous publication to reference.
Step 3 — Run Automated Checks
Owner: System · Status: awaiting_checks → awaiting_review
- Execute validation checks against the fiat and on-chain data.
| Check | Rule |
|---|---|
| Fiat backing | total_supply ≤ fiat_balance |
| Internal consistency | public_supply + encrypted_supply == total_supply |
| Net change | prev_total + Σ(mints) − Σ(burns) == current_total |
| Mint/burn reconciliation | Every on-chain mint and burn exists as a record in the backoffice |
Step 4 — Manual Review
Owner: Treasury Officer · Status: awaiting_review
- Treasury Officer reviews the fiat balance against on-chain supply figures, check results, and mint/burn activity since the last published validation.
- Mint/burn vs. fiat transfer matching is not automated — the backoffice does not have access to bank records. This reconciliation happens here.
- Over-collateralization (fiat > supply) is expected in some cases — e.g., fiat received for mints not yet processed on-chain. Treasury Officer assesses whether the surplus is explained.
- Any inconsistencies caught by automated checks or spotted during review are for Treasury Officer to investigate and escalate as needed.
- To propose publication, Treasury Officer provides the reserve-location note — free-form text describing where the reserves are held (e.g., safeguarding account bank name, account reference, any split across accounts). This is saved with the validation record and published alongside the supply figures, fulfilling the "composition of the reserve" half of MiCA Art. 30. Required only for publication; no structured schema.
- Propose publication to move to Step 5 (Supply Multisig co-sign), or close this run.
- Close without publishing →
closed_not_published. Used for out-of-cadence validations that don't need publication (e.g. an intra-period sanity check after a large mint). No reserve-location note needed.
Step 5 — Supply Multisig Co-Sign
Owner: Supply Signers (2-of-3) · Status: awaiting_cosign
- The proposed publication (fiat balance, fiat timestamp, reserve-location note, on-chain figures, check results, mint/burn reconciliation since the last published validation) is presented to the Supply Signer pool — the same 2-of-3 that signs mints.
- Treasury Officer's Step 4 review is not a signature. Two distinct Supply Signers must co-sign on top of the review. If Treasury Officer is a Supply Signer, they may count as one of the two; the second must be a different Supply Signer.
- Each signer independently reviews the case file before signing. Each signer is individually accountable for the publication.
- Co-sign complete → proceeds to Step 6 (publication).
- Reject →
closed_failed. Treasury Officer investigates and triggers a new validation.
Step 6 — Publish Supply
Owner: System · Status: awaiting_publication → closed_published
- Submit verified supply figures (including the reserve-location note) to the Reserve Publication Service, which updates the public API.
- If publication fails after retries, the record stays in
awaiting_publicationuntil resolved manually. The previously published figures remain on the public API.
End States
| Status | Description |
|---|---|
closed_published | All checks passed, Treasury Officer approved, Supply Multisig co-signed, supply figures published. |
closed_not_published | Validation passed review but the co-sign step chose not to publish. Record retained for audit trail. |
closed_failed | Validation failed automated checks, was rejected at review, or was rejected at Supply Multisig co-sign. |
Infrastructure
The backoffice requires access to FHE-encrypted on-chain data:
- mint/burn transaction amounts
- encrypted token supply
Viewing keys are available via a dedicated decryption service — the backoffice never holds key material directly. If the decryption service is unavailable, the on-chain pull (Step 2) fails.
Publishing to Website
MiCA Art. 30 requires public disclosure. The backoffice writes each closed_published validation to a Reserve Publication Service, which feeds a public website showing the latest data point.
- Key (Art. 30): total supply, fiat balance, reserve-location note, validation date, pass/fail.
- Secondary (expandable): public vs. encrypted split, block number/timestamp, validation ID.
- Download CSV — button exports the current data point as one row.
SLAs
| Parameter | Value |
|---|---|
| End-to-end (happy path) | ~20 minutes. Automation < 1 min; the rest is manual review + co-sign. |
| Co-sign window (Supply Multisig) | TBD |
| Resolution of failed validation | TBD |
Open Decisions
| Decision | Notes |
|---|---|
| Fiat input method | Manual entry vs. bank API callback vs. both. Bank API would reduce manual effort but adds an integration dependency. |
| On-chain data staleness threshold | How recent must the block timestamp be to be considered valid? Affects whether a delayed chain or indexer triggers a failure. |
| Published data on public website | Suggested: block number, block timestamp, public supply, encrypted supply, total supply, reserve-location note, and a pass/fail indicator for reserve backing. Exact payload and format TBD. |
| Proof of encrypted supply | The decryption service returns plaintext values, but there is no independent proof that the decrypted values are correct. A ZK proof that the decrypted supply matches the on-chain ciphertext would remove trust in the decryption service. |
| Shielded pool reconciliation | When shielded pools are introduced, the validation must decrypt and reconcile shielded supply and shielded mint/burns as well. |
Alternatives Considered
No human review (fully automated publish): if all automated checks pass, publish immediately without human review. Rejected because automated checks cannot catch all anomalies — unusual mint patterns or context that requires human judgment. The review step adds latency but is the primary control against publishing incorrect supply figures.
Treasury provides fiat balance for a specific finalized block: instead of providing a fiat balance with a free-form timestamp (which the system then maps to the nearest finalized block, introducing a ~30 min timing gap), Treasury Officer would provide the fiat balance as of a specific finalized block's timestamp. This eliminates the finality lag problem entirely — both sides of the comparison use the exact same point in time. Rejected because Treasury Officer would need to have access to bank data with the granularity needed to produce a balance for an arbitrary timestamp in the past.