This is a proof of concept demonstrating how Fusion+ could implement a multi-chain swap from an EVM chain to Cardano, specifically swapping ETH for ADA.
There are two main directories:
Contains a Foundry project that re-implements an escrow smart contract, inspired by cross-chain-swap. It also includes a script to deploy the contract on a public testnet (Sepolia) and test its functionalities.
Relevant files are:
The script, as written, creates a Hashed Timelock contract by depositing 10 wei. It passes an arbitrary hash, a time limit, and a recipient address.
Subsequently, the script calls withdraw
on the contract, providing the preimage of the hash. The contract verifies the preimage, checks if the time limit has been exceeded, and releases the locked amount to the recipient.
If the time limit is exceeded, the amount can still be recovered by calling abort
(the amount will be returned to the creator of the contract).
The hash function used is exactly the same used by the current Fusion+ implementation for EVM chains, the _keccakBytes32
method has been copied into this contract.
Both the amount and the time limit are hardcoded in the script for simplicity. Also the hash is harcoded to 0x290DECD9548B62A8D60345A988386FC84BA6BC95484008F6362F93160EF3E563
i.e. the keccak256
hash of 0 for simplicity.
You can deploy and execute the script using the following helper:
nix run .#ethereum
This consists of an aiken project defining a validator (with accompanying tests) and a variety of JS scripts using the mesh library. These scripts are useful for creating the escrow contract and subsequently withdrawing the locked ADA.
Notable files:
- cardano/escrow/validators/escrow.ak is the validator script.
- cardano/escrow/ contains the aiken project.
- cardano/escrow/plutus.json is the plutus blueprint file generated by
aiken build
. - cardano/ is a JS project (managed with Bun) that interacts with the blockchain via
mesh
. - cardano/lock.js is the script that locks ADA on the Cardano validator.
- cardano/unlock.js is the script that unlocks it (under specific conditions) and transfers it.
First, you need to generate two wallets: the owner
(who will lock the ADA) and the beneficiary (who will receive it). To do this, run:
bun run generate-credentials.js
Four files (two per wallet) will appear in the directory; these will be used by the other scripts. These files are ignored by git. (Important: You need to acquire ADA from the preprod
testnet faucet and send it to the owner's wallet).
To lock the ADA, execute:
bun run lock.js
The amount locked is 3,000,000 Lovelace (ADA's smallest subdivision) and is hardcoded in the script, as are the maximum time limit and the hash. Also the hash (0x290DECD9548B62A8D60345A988386FC84BA6BC95484008F6362F93160EF3E563
) has been hardcoded.
Once the script is executed, the transaction hash will be printed.
To unlock the ADA, after waiting for the previous transaction to be included in a block, modify the txHashFromDeposit
variable with the hash you just obtained and then run:
bun run unlock.js
At this point, the hash of the new transaction should be printed.
The secret (the pre-image of the hash) is hardcoded into unlock.json
(0 by default).
You can verify all transactions on a blockchain explorer.
Both the escrow contracts are created using the same hash and can be funds can be withdrawn from them using the same secret pre-image.