As of 14 Oct 2026, Zircuit has 4 audit reports by 1 security firm on Trustblock; the latest is by Quantstamp, dated 7 Sep 2026. Those reports list no open critical findings.
Record last updated . It holds audits and findings, contracts and incidents up to Oct 2026. Statuses are the security firms’ own. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| Zircuit Finance - Merkle Distributor | Security firm: Quantstamp | Date: | Scope: Not recorded. See the report | No open critical findings | Open · certificate.quantstamp.com |
| Zircuit Finance - Circle CCTP Adapter | Security firm: Quantstamp | Date: | Scope: Not recorded. See the report | No open critical findings | Open · certificate.quantstamp.com |
| Zircuit ZRC | Security firm: Quantstamp | Date: | Scope: Files named in the report | No open critical findings | Open · certificate.quantstamp.com |
| Zircuit - L2 Upgradeable Contract | Security firm: Quantstamp | Date: | Scope: Repository at commit e76f03c | No open critical findings | Open · certificate.quantstamp.com |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 0 | 0 |
| Medium | 0 | 0 | 0 |
| Low | 0 | 3 | 3 |
`CircleCCTPAdapter` maintains a bijection between chain identifiers and Circle CCTP domains through the `chainIdToConfig` and `domainToChainId` mappings, and signals every lifecycle change on a single event, `CCTPPeerSet(uint256 indexed chainId, uint32 indexed domain, address indexed adapter)`. Off-chain indexers, monitoring tooling, and any downstream subgraph rely on this event to mirror peer state. On additions the event carries the real domain and adapter values; on removals the current implementation emits `CCTPPeerSet(chainId, 0, address(0))` to encode "cleared". However, `0` is the canonical Circle CCTP v2 domain identifier for Ethereum mainnet — a legitimate value that may be registered as a peer at any time. Emitting `0` in the `indexed domain` topic as a removal sentinel is indistinguishable on-chain from an event describing a peer whose domain is Ethereum. Indexers that filter on `domain = 0` to track Ethereum-related peer changes will falsely match every `removePeer` emission, and indexers that reconstruct history by pairing set with remove will lose the original domain of the peer being removed because the topic overwrites it with a value that looks like an Ethereum registration. This could cause off-chain systems to misclassify peer removals as Ethereum peer registrations, corrupt historical peer state reconstructions, and complicate observability once Ethereum is legitimately registered. There is no on-chain fund impact, but the ambiguity is avoidable and undermines the otherwise clean event-based audit trail the contract provides.
Open the report`CircleCCTPAdapter` has no function to recover ERC20 tokens that land in the contract outside of the normal `receiveFunds` flow. In practice, USDC cannot get stuck via the protocol path — `messageTransmitter.receiveMessage()` and the subsequent transfer to the router are atomic, so any failure rolls back the mint entirely. However, if USDC or any other ERC20 is sent directly to this contract address by mistake (e.g. a user error, a failed airdrop, or dust from an unrelated interaction), it is permanently unrecoverable. Every other adapter in this package ( `OFTBridgeAdapter`, `ProtoCCTPGatewayAdapter`, `ArbitrumAdapterL1`, and `ArbitrumAdapterL2`) has a `RESCUE_ROLE`-gated recovery mechanism.
Open the report`CircleCCTPAdapter.receiveFunds()` authenticates an inbound CCTP v2 message by forwarding it to `messageTransmitter.receiveMessage()` and then hands it to `_parseReceivedMessage()`. The parser reads fields from the 228-byte `BurnMessageV2` body, `mintRecipient`, `amount`, `feeExecuted`, `messageSender`, and the trailing `hookData`, and compares each against state maintained by the adapter (the `domainToChainId` mapping, the stored peer adapter for the resolved source chain, and `address(this)`). These three body-level comparisons are the adapter's entire authorization model for inbound messages. The parsed `destAddress` and `extraData` are then passed to `router.handleReceivedFunds`, which gates the final destination through `Factory.isAuthorizedBridgeAddress()`. However, Circle's `MessageTransmitterV2.sendMessage()` is a permissionless entry point that produces valid, attestable messages whose body is entirely attacker-controlled bytes. The adapter never inspects the 148-byte message header, in particular the `sender` field (which for a genuine burn message equals the source-chain `TokenMessengerV2`) and the `recipient` field (which equals the destination-chain `TokenMessengerV2`). An attacker on a registered peer chain can therefore craft a message whose body is byte-compatible with `_parseReceivedMessage()` (correct `mintRecipient`, `messageSender` equal to the registered peer adapter, any chosen `amount`, any `feeExecuted`, any `destAddress` encoded in the hook data) have Circle attest it, and submit it via `receiveFunds` on the adapter. Circle dispatches the hook payload to an attacker-chosen no-op handler, so no USDC is minted to the adapter, yet the body-level checks all pass because the attacker wrote the bytes the parser expects. This could allow any USDC residing in the adapter — operational dust, accidental transfers, or balances introduced by a future refactor — to be routed to a vault of the attacker's choosing through `router.handleReceivedFunds()`. In the current integration, the destination is constrained to addresses that `Factory.isAuthorizedBridgeAddress()` has whitelisted, so the funds end up in a Zircuit-authorized vault rather than an attacker-controlled wallet; the attacker gains nothing and the worst case is a bounded shift of residual balance between authorized cluster vaults. The residual business impact is therefore informational, but the adapter has no defense-in-depth for future integrations that may permit non-cluster destinations or for scenarios in which the adapter accrues a non-trivial balance.
Open the reportThe reports name a repository or files. Open a report to see its scope.
Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.
Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.
<head><script src="https://widget.trustblock.run/project-widget.min.js" defer></script></head><body><divdata-tb-project-widgetdata-tb-project-slug="zircuit"></div></body>
Paste the code where the label should appear. It uses no API credit and updates by itself.
Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.
Tell us