Skip to content

Hackathon

DotFusion

Trustless ETH↔DOT atomic swaps between Ethereum and Polkadot using hash time-locked contracts, with Polkadot's XCM precompile propagating the secret across chains automatically.

Oct 20251st 1inch · 1st Polkadot · 1st BuidlGuidl · ETHRome 2025 (+ ENS honorable mention)Web3

DotFusion swaps ETH for DOT directly between Ethereum and Polkadot: two parties lock funds on their respective chains against the same hash, and either both claims succeed or both refunds do. There is no bridge contract holding the assets and no wrapped representation of either side.

Event
ETHRome 2025 (48h)
Result
1st 1inch · 1st Polkadot · 1st BuidlGuidl · ENS honorable mention
Role
Team lead
Networks
Ethereum Sepolia · Polkadot Paseo Asset Hub
Repository
VincenzoImp/dot-fusion
VincenzoImp/dot-fusionTrustless, secure, and fast token exchanges between Ethereum and Polkadot ecosystems.TypeScript

The problem

Almost every cross-chain transfer routes through a custodian: a bridge contract, a multisig, or a validator set that holds the real asset and issues a claim against it. That custody is where the value concentrates, and it is where the large losses have historically happened.

A hash time-locked contract removes the custodian, but it replaces it with a coordination burden. The party who claims first reveals a secret, and the counterparty has to notice that revelation on a different chain and act on it before their own lock expires. Classically that watching is the user’s problem, or a service’s.

What I built

Three contracts and a resolver. EthereumEscrow and PolkadotEscrow hold the two sides of a swap against the same hash; XCMBridge is the piece that makes the second half automatic.

When the secret is revealed on the Polkadot side, XCMBridge calls Polkadot’s XCM precompile at 0x…0804 with send(uint32 paraId, bytes xcmMessage, uint64 weight), encoding a Transact instruction that completes the swap on the destination chain. The counterparty does not have to be watching. If the XCM call fails the contract rolls back its own state – the secret is un-marked as processed and the pending message deleted – so a failed propagation leaves the swap claimable rather than half-finished.

Around that sits a resolver service offering quotes and swap status over HTTP, a Scaffold-ETH 2 frontend, and ENS resolution on every address field so a counterparty can be named rather than pasted. Both escrows are deployed to testnets – Sepolia and Paseo Asset Hub – and the contracts use ReentrancyGuard and checks-effects-interactions. They have not received a security audit, and the demonstration fixes the exchange rate at 1 ETH to 100,000 DOT rather than pricing either asset. The claim here is about the atomic-swap mechanism, not readiness to move real value.

Hard parts

The two timelocks cannot be equal. The escrow enforces MIN_TIMELOCK = 12 hours, and the comment above that constant states the reason it exists: to ensure the Ethereum timeout exceeds the Polkadot one. If the side that reveals the secret second could expire first, the party who already revealed would be unable to refund while their counterparty could still claim. The asymmetry – twelve hours against six – is the safety property, and it is enforced in the contract rather than left to whoever calls it.

Making the propagation failure safe rather than silent. Sending an XCM message is an external call that can fail, and it happens after the secret has been observed. Treating a failed send as “the swap is done” would strand funds. The bridge therefore reverts its own bookkeeping on failure, which costs the automatic path but keeps the manual one available.

Bounding the damage from a stuck swap. Beyond the ordinary cancellation there is a second, longer rescueDelay window. A swap that reaches neither claim nor refund is not permanently locked value.