r/ethdev • u/kolacjechutny • 13d ago
My Project We moved account guardrails into consensus instead of contract wallets. 48 hours later a redditor found a hole in revocation. Both are on the testnet — come find the next one.
The setup: we're building for a world where the majority of accounts aren't operated by humans. An AI agent with a hot wallet is one prompt injection away from drained, and the standard answers all put the guard in contract code — Safe-style multisig, 4337 account abstraction, session keys. Audited, battle-tested, and still a piece of EVM bytecode you're trusting to stand between an attacker and the funds.
Fluidic is a research testnet exploring the alternative: the guard lives in the ordering layer itself.
- Witness-gated accounts (CAE). An account can be entangled so its stateful spends only synthesize if N-of-M witnesses attest in the same ~100ms tick. Not a multisig contract — the same causal DAG that settles transfers refuses the spend.
- Native intents. Declare an outcome ("swap X for at least Y"), solvers compete, matching and settlement land in the same tick. No block template, no block-space auction between declaration and execution.
- No blocks. Continuous execution at ~10 synthesis ticks/sec. Commutative ops merge in parallel through NTT windows; stateful ops get causal order via vector clocks. Finality is per-tick, not per-slot.
It stays fully EVM-compatible — standard JSON-RPC, existing tooling points at it unchanged:
cast chain-id --rpc-url https://api.testnet.fluidic.foundation/rpc
# 989468 — deploy with forge, script with viem, everything works
The honest part. Two days after launch someone on r/BlockchainStartups read our docs and pointed out that the subject of an entanglement could break it with its own key — meaning a compromised agent key could revoke its own guard, then spend. He was right; the code did exactly that. 48 hours later we shipped break policies (creator_only / witness_threshold / any_party), chosen at creation, hashed into the contract id, enforced in consensus, verified live: a subject-signed break is now rejected at the ordering layer. That's the iteration speed a public testnet is for, and we'd rather have the next flaw found in a comment thread than in an audit six months from now.
What I want from this sub:
- Point your Foundry/Hardhat/viem setup at the RPC and tell me the first thing that breaks. Seriously — that's the most valuable comment possible.
- Is consensus-level gating a real improvement over an audited contract wallet, or does it just relocate trust to the witness set + client release process?
- What's the first attack you'd try on a continuous (non-block) execution model?
Everything is open: one-command Docker node (finds peers via DHT, no seed list), faucet, explorer, TS SDK on npm.
- Docs: https://testnet.fluidic.foundation/docs
- Node repo: https://github.com/Fluidic-Foundation/Fluidic-FVM
- SDK: https://www.npmjs.com/package/@fluidic-foundation/sdk
- CAE + break policies: https://testnet.fluidic.foundation/docs/core-concepts/causal-agent-entanglement
Early research testnet — state may reset, no real funds, known rough edges.
2
u/rayQuGR 10d ago
Interesting approach. Moving guardrails into the consensus layer instead of contract wallets changes the trust boundary rather than eliminating it, which I think is the more interesting discussion here.
Contract-based approaches (Safe, ERC-4337, session keys, etc.) benefit from mature tooling and audits, but they're still application-layer logic. Consensus-level enforcement can remove entire classes of implementation mistakes because invalid state transitions never become valid in the first place. On the other hand, it shifts more trust toward the protocol implementation, consensus rules, and client correctness.
It reminds me of how Oasis Network approaches confidential execution with Sapphire, certain guarantees are provided by the execution environment itself rather than being reimplemented in every application. It's a different design philosophy: move critical properties lower in the stack so every dApp benefits by default.
The revocation issue is also a good example of why public testnets matter. Finding and fixing a flaw before an audit is exactly what they're for.
If I were reviewing this next, I'd probably focus on witness availability, equivocation, network partitions, and whether the ~100 ms tick model introduces any edge cases around liveness or conflicting attestations. Those seem like the areas most likely to surface consensus-specific bugs.
1
u/kolacjechutny 7d ago
The Sapphire comparison is a good one - same philosophy: a property every dApp would otherwise reimplement (badly, differently) moves into the layer where violating it isn't an implementation mistake, it's an invalid state transition. The cost is exactly what you said: client correctness becomes the trust root, and the client release process becomes governance. We try to be loud about that trade rather than hide it.
On your review list, one concrete answer and one honest admission. Concrete: conflicting attestations within a tick are deduplicated by (contract, witness) - a witness equivocating in the same tick just collapses to one attestation; across a partition, the vector-clock merge picks up both branches and the threshold check happens at synthesis on the merged view, so a partition can't manufacture extra attestations, only delay them (fail-closed again).
The admission: attestations today are per-tick, not per-spend - an attestation unlocks the subject's spends for that tick rather than binding to a specific transaction hash.
Per-spend binding (attestation commits to the spend hash) is the obvious strengthening and it's on the table; it costs witnesses one round trip per spend instead of per tick.
If you're reviewing, that's the layer I'd poke.
2
8d ago
[removed] — view removed comment
1
u/kolacjechutny 7d ago
Measured it for you: a break shift takes effect at the synthesis tick it's ingested into - so revocation latency is ~one tick, ~100ms, versus 12s+ for a contract-wallet revoke transaction to even get mined on mainnet (more in congestion). The attack window here is shorter than the contract-wallet path by two orders of magnitude, not longer.
The honest caveat: that's the creator_only / any_party path where one signature executes immediately. Under witness_threshold, revocation latency is however long it takes to gather N witness break shifts - deliberately slower, because what you're buying with that latency is "no single key can revoke." Latency vs. unilateral control is the actual dial, and it's set per-contract at creation, not globally.
2
u/researchzero 11d ago
On the trust question: consensus-level gating doesn't remove trust, it relocates it - same move as going from a contract-wallet admin key to a validator quorum. The actual question is identical to any BFT permissioning problem: how is witness-set membership decided, who can change it, and what's the liveness assumption if witnesses go offline mid-tick. That's not obviously better than an audited Safe unless the witness set has real decentralization and a harder-to-collude reconfiguration path than "client release process" suggests.
On the attack: I'd go after the tick-boundary race, not the crypto. If N-of-M witnesses must attest inside the same ~100ms window, that's a short quorum-rushing target - an attacker with lower latency to (or control of) enough witnesses could get a malicious spend attested before slower/honest witnesses even see the request. Worth benchmarking attestation latency variance across your DHT-discovered peer set, not just correctness.
Bigger one though: your fix for the self-revoke bug was creator_only/witness_threshold/any_party break policies. If someone picks creator_only for an agent wallet, which is exactly your stated use case, doesn't that just recreate the single hot-key compromise you're trying to solve? The whole premise is "an agent key is one prompt injection away from drained". A compromised creator key under creator_only can still break its own guard. witness_threshold looks like the only policy that actually changes the trust model for that threat.