Security posture
MLabChain is a reference testnet. It has not been audited, has not been fuzzed, and has not been subjected to adversarial testing at Internet scale. It is suitable for experimentation, for research, and for local runs on a single machine.
The project's security philosophy is to state every assumption explicitly, in the code, in the docs, and on this page. A reader should be able to look at any claim and find the mechanism that backs it, or find the acknowledgement that it is not backed at all.
Do not use MLabChain for anything of value
Do not store significant assets on it. Do not treat the wallet as secure storage. Do not present Mera as an investment. The project is a scientific research tool, and it should be evaluated as one.
What v0.3 defends against
Five categories of attack have explicit defences in the code.
1 · Transaction forgery
Every transaction carries an Ed25519 signature over a canonical message. The core checks that the sender address is derived from the included public key and that the signature verifies against the message. A transaction whose signature is invalid is rejected before it enters the mempool.
Multisig transactions require m valid signatures
from the declared key set, with the keys sorted canonically and
free of duplicates.
2 · Replay and stale nonces
Every account has a monotonic nonce. A transaction from an
account is valid only if its nonce equals
account.nonce + pending_count + 1. Signed
transactions cannot be replayed, even after the account has
submitted other pending transactions.
3 · Double-spend within the mempool
The mempool enforces per-sender balance reservation. When a sender submits a transfer, the amount and fee are reserved against the account balance for the lifetime of the pending transaction. A second transfer that would over-spend the unreserved balance is rejected.
4 · Tampering with the chain
Every block hash is recomputed during validation. Every Merkle root is recomputed over the block's transactions. Every producer signature is verified. Every cumulative work value is checked. If a single byte of any block is changed, validation fails at that block.
The database is also cross-checked against a fresh replay from
genesis. A hand-edited accounts row is detected by
comparing every account's balance, nonce, and authorization key
against the replay result.
5 · Supply-cap violations
Every reward and every faucet mint is checked against the
remaining supply before the state transition is applied. A
transaction that would push the total supply above
MAX_SUPPLY is rejected.
What v0.3 does not defend against
This is the more important list. Each entry is a real limitation, not a theoretical concern.
Fabricated ML metrics
The core validates that the reward is arithmetically consistent
with the submitted metrics. It does not validate that the
metrics are honest. A malicious submitter can sign an
ML_WORK transaction with a fabricated
nmse_scaled and receive the corresponding reward.
The only defence is the Python verify-ml audit,
which re-executes the training and compares. This is a
post-hoc audit performed by whoever wants to check, not a
consensus rule enforced by every node.
Wall-time fabrication
Wall time is recorded as an audit metric and is not a minting input. A miner can report any value without affecting issuance. The field's only use is as scientific provenance.
P2P denial of service
The wire protocol is line-based and unauthenticated. A peer can
spam TX|... or BLOCK|... messages at
line rate. There is no rate limiting, no peer scoring, no
connection quotas, and no message size limit on the server side
beyond the implicit limits of the operating system.
Eclipse attacks
There is no peer discovery and no anti-eclipse mechanism. A node connects only to peers that are manually configured. An attacker who controls all of a node's configured peers can lie about the chain tip and the cumulative work, and the node will not notice.
Sybil identities
Creating an address is free. An attacker can generate thousands of Ed25519 keypairs, register many challenges, and farm the maximum reward from each. The challenge bond and per-proposer limits are per-address, not per-entity. There is no proof of personhood, no staking requirement, and no account age rule.
Duplicate ML work
Two miners who train different models against the same challenge both get paid, subject to the marginal reward rule. There is no first-mover priority beyond the challenge's current best quality. The marginal reward rule reduces the payout for later submissions but does not eliminate it.
Withholding and selfish mining
A miner who finds a valid block can choose not to broadcast it. There is no mechanism that forces publication. This is standard for PoW chains; the mitigation is economic (a withheld block earns nothing) rather than cryptographic.
Key compromise
If an account's private key is compromised, an attacker can transfer the balance, rotate the key, and submit ML work in the account's name. The wallet file is encrypted with Scrypt + AES-GCM, which raises the cost of a brute-force attack against the password, but does not prevent a compromise from a keylogger or a compromised host.
Faucet abuse on devnet
On a devnet chain, the faucet can be called by any address for any amount up to the supply cap. This is intentional. On a mainnet chain the faucet is disabled at genesis and cannot be re-enabled.
Rollback after a 51% attack
The fork choice rule is highest cumulative work. An attacker with more than half the network's hashrate can build a longer chain that excludes a specific transaction, and the network will reorg to it. There is no economic finality. At the v0.3 difficulty levels, this is trivially achievable on a local testnet.
Bridge trust
The ERC-20 contract in contracts/MeraScientific.sol
grants a MINTER_ROLE to a single address. Whoever
holds that key can mint up to the cap at any time. This is a
full centralization of EVM-side issuance. It is not a trustless
bridge, and it does not pretend to be one.
Regulatory and legal exposure
A transferable token that people treat as having monetary value brings securities law, tax law, and anti-money-laundering rules in most jurisdictions. This codebase provides no compliance tooling. Any deployment that involves real money is a regulatory question before it is a technical one.
Cryptographic choices
Every primitive is standard, and every parameter is documented.
Hashing
SHA-256 throughout. Used for transaction IDs, block hashes, Merkle roots, address payloads, challenge manifests, dataset commitments, and artifact hashes. No novel hash construction is used anywhere.
Signatures
Ed25519 via OpenSSL's EVP_PKEY_ED25519. Chosen for
its small signatures (64 bytes), fast verification, and the
absence of parameter choices. The implementation rejects
non-canonical signatures by default.
Wallet encryption
Scrypt with parameters N=2^15, r=8, p=1, followed
by AES-256-GCM with a 12-byte nonce and a bound authentication
tag of MERA-WALLET-V2. The KDF parameters are
stored in the wallet file so they can be raised in a future
version without invalidating existing wallets.
Multisig
Ed25519 signatures from an m-of-n set. The keys
are sorted canonically before address derivation and before
verification. The threshold and key set are included in the
transaction and compared against the derived address.
Address checksums
Every address has an 8-character checksum suffix derived from
SHA256("MERA-ADDR-V3|" + prefix). A typo in the
payload portion of an address will not match the checksum, and
the core will reject the address. This prevents the most common
category of user error.
Known weaknesses in the reference implementation
These are specific bugs or design choices in the v0.3 code that a reader should know about. Some are being fixed in v0.3.1; others are noted for future work.
- Client-side reward estimate. The Python client computes a pessimistic reward estimate before calling the core. The estimate is not always correct — it uses the full quality against the baseline rather than the marginal delta against the challenge's current best. The core catches this and rejects, but the error message is confusing.
-
Wallet overwrite.
create-walletoverwrites an existing wallet file without a--forceflag or a confirmation prompt. Running it twice destroys the first wallet. -
Artifact existence.
verify-mlrecomputes the model hash from memory but does not check that the recorded artifact file still exists on disk. A user who deletes the model file after mining will still seeSTATUS: VERIFIED. -
Unused LSWU. The LSWU score is computed and
stored in every
ML_WORKtransaction, but no consensus rule consumes it and no command displays it in a structured way. It is audit-only, but the docs do not yet explain what an auditor would do with it. - Test coverage gaps. Multisig, key rotation, governance timelock, reorg, block relay, transaction relay, fee market, mempool quotas, schema migration, challenge budget exhaustion, duplicate claim, retargeting, and timestamp bounds are all implemented but not covered by tests in the v0.3.0 release.
- Windows and macOS CI. The GitHub Actions workflow builds and tests on Linux only. The Windows and macOS build paths exist but are not continuously tested.
Operational security
If you run a node, four practices matter.
1 · Use a dedicated password
The wallet password must be at least 10 characters and should
not be reused from any other system. Set
MERAWALLET_PASSWORD in a way that does not appear
in your shell history — a secrets manager, a temporary
environment, or an interactive prompt.
2 · Back up the wallet separately from the chain
The SQLite database and the wallet file are separate. A backup
of the database does not include the wallet, and a backup of the
wallet does not include the chain. Use
wallet-backup for the wallet and
backup for the chain, and store them in different
places.
3 · Do not expose the node to the public Internet
The P2P protocol has no authentication, no encryption, and no
rate limiting. A node listening on 0.0.0.0 is
reachable by anyone. Bind to 127.0.0.1 for local
testing and use a firewall or a VPN for anything else.
4 · Treat the chain file as public
Every transaction on the chain is readable by anyone with access to the database. Do not record anything in a note field that you would not want published. This is inherent to the design.
Production checklist
Before any deployment could honestly be called an audited mainnet, all of the following must be complete.
- Independent cryptographic audit of the C++ core.
- Independent consensus audit against the protocol specification.
- Fuzzing of all transaction and block parsers.
- Differential replay tests across platforms (Linux, macOS, Windows, ARM, x86_64).
- Deterministic build pipeline with signed releases.
- Peer discovery and anti-eclipse design.
- Rate limiting, peer scoring, and connection quotas.
- A chain checkpoint or finality strategy.
- Audited governance and multisig controls.
- Audited bridge, or removal of the bridge dependency.
- Economic simulation of fee burn and scientific issuance.
- Formal specification of the verifier bytecode or semantics for every paid ML class.
- zkML or equivalent verifiable-computation layer before paying arbitrary GPU or ML workloads.
- Legal review of the token's regulatory status in every jurisdiction where it will be offered or used.
The four research problems remain
Even after the checklist above, four problems cannot be resolved by engineering:
- General ML proofs (requires zkML or equivalent).
- Stochastic and GPU training verification.
- Permissionless P2P hardening at Internet scale.
- Trustless L1↔EVM bridging.
Take-away
v0.3 defends against transaction forgery, replay, double-spend within the mempool, chain tampering, and supply-cap violations. It does not defend against fabricated ML metrics, P2P denial of service, eclipse attacks, Sybil identities, key compromise, or bridge trust. Every one of these is stated in the docs and visible in the code.