
Portcullis
A security firewall that authenticates cross-chain settlement messages before value moves.
Demo
About
Portcullis protects inbound cross-chain settlements at the receiving contract. Before an adapter transfers a token, PortcullisGuard verifies the signing authority, token and recipient allowlists, value bounds, replay protection, nonce order, per-source rate limits, and volume or policy conditions. Invalid messages are rejected before receiver state changes. The circuit breaker only latches on authenticated anomalies: a rate-limit breach, a volume spike, or an explicit policy denial. The project runs across Arc testnet, ENSv2 identity on Sepolia, Chainlink CRE private policy checks, and a Graph subgraph for inspection history and configuration.
How it's made
Portcullis is built in Solidity 0.8.36 with Foundry, Solady OwnableRoles, and OpenZeppelin. PortcullisGuard keeps the settlement state, while the inlined PortcullisChecks library evaluates six checks before an adapter can transfer value. The message digest binds block.chainid, the guard address, and the settlement payload; an ECDSA signature from the resolved authority proves the sender. EnsIdentityRegistry resolves guardian-allowlisted ENS names through ENSv2’s UniversalResolverV2. A Chainlink CRE Confidential Workflow runs policy checks in a TEE and reports ALLOW, DENY, or MANUAL_REVIEW to CrePolicyConsumer. The Graph indexes guard and receiver events for the static Next.js guardian dashboard, built with viem and Privy. The project also includes Foundry unit, fuzz, invariant, and exploit-replay tests.