I should be clear that I’m not commenting on ETHGent itself here—I don’t yet understand it well enough to make a fair technical judgment. I’m responding specifically to the claim that the IC is unsuitable for DeFi because inter-canister calls can fail.
For context, I only joined the IC to escape from Ethereum. In my view, the main problem with native IC development has not been the execution model; it has been the lack of tooling that makes correct use of that model straightforward. With IcyDB and Canic, we believe we have bridged that gap.
The IC does have atomicity. The precise boundary is a message execution.
The IC documentation states that only one message execution runs at a time in a canister, and that execution is atomic and sequential. If it traps, its state changes are discarded. However, an inter-canister call splits an asynchronous method into multiple message executions. State before the call may already be committed, other messages may interleave while it is waiting, and a later callback cannot roll back an earlier execution. That means the IC does not provide a global ACID transaction spanning multiple canisters—but that is different from saying it is unsuitable for DeFi.
This is documented explicitly in Properties of Message Executions on ICP.
The appropriate architecture is therefore:
-
Keep tightly coupled financial invariants inside one atomic boundary. Balance changes, reserve accounting, authorization and solvency checks that must succeed together should execute synchronously within the same canister message execution.
-
Treat inter-canister effects as explicit settlement workflows rather than pretending they are part of one global transaction. Record intent before issuing an effect, give the operation a stable identity, make retries idempotent or deduplicated, reconcile the result from authoritative state, and only then advance dependent state.
This is not merely our interpretation. The IC’s security guidance for inter-canister calls explicitly recommends journaling: persist the intent before a fallible asynchronous task, record or recover its result, and block dependent work until the outcome is known. Its safe-retry guidance describes idempotent endpoints, sequence numbers, operation-ID deduplication, queryable results and two-step ledger transfers.
There are important qualifications. An individual inter-canister request is delivered at most once, but an application retry is a new request and must be deduplicated. A bounded-wait call can return SYS_UNKNOWN even if the callee applied the effect. Ledger deduplication is also commonly time-bounded, so sufficiently old ambiguous results may require reconciliation against ledger blocks. A safe workflow may remain pending or require manual recovery; safety does not automatically guarantee liveness.
IcyDB addresses the local atomicity side of this model. Its mutation path is explicitly synchronous—no await, yield or re-entrancy—and scoped to one registered store. It completes validation, constraint checking, index derivation and all other fallible work before opening the commit boundary. It then publishes a commit marker and mechanically applies the prepared mutation. If application is interrupted after marker publication, deterministic recovery completes the marker-described state before guarded reads or writes proceed.
The current structural batch can atomically combine inserts, updates, replacements and deletes across as many as 64 entities in that store. It does not claim cross-store, cross-canister or multi-message transactions; those limits are part of its documented contract. See the IcyDB atomicity model and transaction semantics.
Canic addresses the asynchronous workflow side. In its current Fleet workflow, every mutating action has retained intent before the platform call. A lost response is resolved through exact live-state reconciliation or an idempotent Ledger/drain operation identity before retrying. A successful call means “issued,” not automatically “applied”; the journal advances only after a typed status query proves the terminal state. If the result is absent, inconsistent or ambiguous, dependent destructive actions remain blocked.
That is not distributed rollback. It is durable, recoverable workflow consistency built from individually atomic transitions—and it follows the same journaling and reconciliation pattern recommended by the IC documentation. Canic’s current boundaries are documented in Fleet ensure and current status.
So I believe “inter-canister calls can fail, therefore the IC is unsuitable for DeFi” is a common misunderstanding. The IC is suitable for DeFi when applications are designed for its actual execution model: atomic local state transitions combined with explicit, idempotent and recoverable asynchronous settlement.
What has been missing is tooling that makes those patterns safe and convenient by default. That is the gap we believe IcyDB and Canic have now bridged.