MultisigPE

TEE-powered policy engine that scores smart contract risk and dynamically sets multisig thresholds

MultisigPE

Created At

ETHGlobal Cannes 2026

Winner of

Flare Network

Flare - Bonus Track: Best Smart Account App

Project Description

Organizations managing on-chain treasuries face a fundamental tension: security requires multiple signers, but requiring maximum approvals for every transaction creates operational friction. A $5 transfer to a verified Uniswap contract shouldn't need the same approval process as a $500K interaction with an unverified contract deployed ten minutes ago. This project builds a policy engine where an organization defines transaction policies on-chain through a unanimous governance multisig. Each policy specifies conditions (target addresses, function selectors, value thresholds, time windows), allow/deny lists, per-transaction and daily USD limits, whether the target must be a verified contract, whether it must appear in the ERC-7730 clear signing registry, and its own dedicated set of signers. All policies are fully public, anyone can read the conditions and verify the organization's rules.

When a transaction is proposed, the details are ECIES-encrypted and submitted to a Flare TEE (Trusted Execution Environment) running inside Intel TDX hardware. Inside the enclave, the engine decrypts the proposal, fetches the current policies from the on-chain registry, and runs a simulation against every matching policy. The simulation evaluates ten risk factors: allowlist/denylist membership, contract verification status via block explorer APIs, presence in the Ledger ERC-7730 clear signing registry, transaction value converted to USD through Flare's FTSO oracle price feeds, cumulative daily volume against per-policy limits, bytecode analysis for proxy patterns and dangerous opcodes, contract age, transaction history, and calldata complexity. Each factor produces a weighted sub-score that rolls into a composite risk score from 0 to 100. If multiple policies match a single transaction, the one producing the highest risk score is selected, ensuring the most conservative policy always applies. The risk score maps linearly to a signer threshold within that policy's signer set: low risk requires one signer, high risk requires all of them.

The TEE returns an attested policy decision containing the matched policy ID, risk score, a bitmap showing which checks passed or failed, the required signers, and their addresses — but never the transaction target, calldata, or value. These inputs remain private during the evaluation window, preventing front-running. The multisig wallet contract verifies the TEE attestation and posts an audit receipt to an append-only on-chain log before allowing execution. Auditors can cross-reference the public policy definitions with the check bitmaps to verify the organization followed its own rules, without seeing what specific transactions were evaluated. Built on the Flare TEE extension architecture using the FCE scaffold, deployed and tested on Coston2.

How it's Made

The system is built on three layers: on-chain governance contracts, a TEE off-chain simulation engine, and a client-side encryption pipeline, all stitched together through Flare's TEE extension infrastructure. On-chain layer (Solidity, Foundry): Five contracts deployed to Coston2. GovernanceMultisig enforces unanimous approval for policy mutations where every signer must call approve() before execute() will succeed, which prevents any single compromised key from altering organizational rules. PolicyRegistry stores the full policy definitions with nested structs (Conditions, Limits) including dynamic arrays for allowlists, denylists, target addresses, and function selectors. All read functions are public with no access modifier so anyone can audit the policy set. AuditLog is an append-only contract, this is the core of the audit trail design, giving auditors granular compliance visibility without revealing transaction details. MultisigWallet ties it all together by requiring a TEE-attested evaluation before accepting signer approvals, and it posts the audit receipt atomically during the submitEvaluation call. InstructionSender is the standard Flare TEE entry point using TeeExtensionRegistry and TeeMachineRegistry. TEE layer (FCE-extension-scaffold, Go/Python/TypeScript): The extension runs inside a Docker container alongside the TEE node binary (built from flare-foundation/tee-node), communicating over localhost. The handler receives the encrypted proposal, calls the TEE node's /decrypt endpoint (base64-encoded ECIES), then ABI-decodes the plaintext into an EvaluateRequest. The ERC-7730 clear signing registry check queries the LedgerHQ/clear-signing-erc7730-registry on GitHub. The registry stores JSON descriptors organized by entity, where each file contains context.contract.deployments[] with chain IDs and addresses. For MVP, we use the GitHub code search API to check if the target address appears anywhere in the registry directory. For production, the plan is to clone the registry at startup and build an in-memory address set, refreshed hourly. Contract verification uses the Coston2 block explorer API (module=contract, action=getabi) — if the ABI is available, the contract source is verified and published. All external checks (explorer API, GitHub API, FTSO oracle) are wrapped in a fail-open error handler. If any HTTP call times out or returns an error, that check's bitmap bit is set to 1 (pass) and its weight is excluded from the composite score, the remaining checks' weights are redistributed proportionally. This prevents external service outages from causing false-positive maximum-risk lockouts on every transaction. The scoring engine computes a weighted composite across all ten checks, then applies the policy's riskWeight amplifier (1–10 scale, translating to a 1.0x–1.9x multiplier). Hard penalty floors are enforced: a denylist hit forces the score to at least 90 regardless of other factors, and a per-transaction limit breach forces at least 80. When multiple policies match a single transaction, each is scored independently and the highest-risk result is selected which ensures the most conservative applicable policy always governs. Daily volume tracking is per-policy, not global. The TEE state maintains a map from policy ID to DailyVolume (date string + cumulative USD amount), rolled at UTC midnight. This means a high-frequency trading policy consuming its $50K daily limit doesn't eat into a treasury policy's separate $10K daily limit. Client-side encryption: Before submitting, the user fetches the TEE's secp256k1 public key from the proxy (/info endpoint), ABI-encodes the EvaluateRequest (target, calldata, value, sender, nonce), ECIES-encrypts it, and passes the ciphertext bytes directly to InstructionSender.sendEvaluate(). The encrypted payload is visible on-chain but unreadable — the TEE decrypts inside the enclave, so transaction details remain private during the evaluation window until the multisig eventually executes the transaction (which is inherently public on EVM). Flare-specific integrations that made this viable: The TEE extension framework (ext-proxy + TEE node + redis) handles all the infrastructure for attestation, instruction routing, and result submission, so the custom code only implements business logic. The ContractRegistry pattern means the extension doesn't hardcode any contract addresses except the registry itself, which is stable across all networks.

background image mobile

Join the mailing list

Get the latest news and updates

MultisigPE | ETHGlobal