├── solidity ├── README.md ├── signatureVerification.MD └── swap.sol ├── README.md ├── devEnviroment_notes.md ├── adaptorSignatures └── README.md └── draftProcess.md /solidity/README.md: -------------------------------------------------------------------------------- 1 | # Solidity Playground 2 | 3 | This folder houses all the solidity code for an escrow account for cross chain monero - ethereum swaps. 4 | 5 | 6 | 7 | ## Auction contract 8 | 9 | Example contract of an auction 10 | https://etherscan.io/address/0x60A3372cd31309FE728dbFfCC3FC1d68c9d97F19#code 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # xmr-eth-swap-playground 2 | Cross-chain atomic swap protocol between Monero and Ethereum 3 | 4 | This repo is for research in creating a proof of concept for cross chain trust-less Monero-Ethereum "atomic" swaps. 5 | 6 | *The swap is very similar to the Commit network btc-xmr atomic swaps but differs in that the hashed timelock contract is replaced with an escrow smart contract with built in auto reverse transactions.* 7 | 8 | 9 | ## How does it work? 10 | Draft Proposal of the swap process can be found here: [Draft Proposal](https://github.com/Crypt0-Bear/xmr-eth-swap-playground/blob/main/draftProcess.md) 11 | 12 | 13 | -------------------------------------------------------------------------------- /devEnviroment_notes.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | Notes for ethereum dev 4 | 5 | using hardhat to start a dev local blockchain 6 | 7 | npx hardhat node 8 | 9 | using brownie for a console and attaching to it 10 | 11 | brownie console --network hardhat 12 | 13 | 14 | 15 | Install Rust 16 | 17 | Installed a standalone version of rust 18 | 19 | https://forge.rust-lang.org/infra/other-installation-methods.html 20 | 21 | x86_64-unknown-linux-gnu 22 | 23 | 24 | https://static.rust-lang.org/dist/rust-1.55.0-x86_64-unknown-linux-gnu.tar.gz 25 | https://static.rust-lang.org/dist/rust-1.55.0-x86_64-unknown-linux-gnu.tar.gz.asc 26 | 27 | 28 | rustc --version 29 | 30 | rustc 1.55.0 (c8dfcfe04 2021-09-06) 31 | -------------------------------------------------------------------------------- /adaptorSignatures/README.md: -------------------------------------------------------------------------------- 1 | # Adaptor Signatures 2 | 3 | I am not an experienced cryptographer and don't have any background in rust. I am heavily relying on existing libraries and reference material to implement a proof of concept. 4 | 5 | ### References for adaptor signatures 6 | https://www.monerooutreach.org/stories/monero-atomic-swaps.html 7 | 8 | https://medium.com/crypto-garage/adaptor-signature-schnorr-signature-and-ecdsa-da0663c2adc4 9 | 10 | https://www.youtube.com/watch?v=Jj8rd4WOEy0 11 | 12 | https://comit.network/blog/2020/10/06/monero-bitcoin/ 13 | 14 | Looks like we could use this library for the cross curve proof between xmr and eth 15 | https://github.com/LLFourn/secp256kfun/blob/master/sigma_fun/src/ext/dl_secp256k1_ed25519_eq.rs 16 | 17 | 18 | ### Rust 19 | 20 | ecdsa library with a adaptor signature module 21 | 22 | https://docs.rs/ecdsa_fun/0.6.2/ecdsa_fun/ 23 | 24 | 25 | The COMMIT network's implementations and supporting libraries are built in rust. They can be found in the following location: 26 | 27 | https://github.com/comit-network/xmr-btc-swap 28 | 29 | Older implementation based on the draft proposal : 30 | https://github.com/h4sh3d/monero-swap-lib 31 | 32 | 33 | ### Python 34 | I found one implementation of adaptor signatures in python. I need to test the library and see if it works for a proof of concept. 35 | https://github.com/LeoComandini/adaptor-py 36 | -------------------------------------------------------------------------------- /solidity/signatureVerification.MD: -------------------------------------------------------------------------------- 1 | # Verifying signatures on chain in solidity 2 | 3 | 4 | /* 4. Verify signature 5 | signer = 0xB273216C05A8c0D4F0a4Dd0d7Bae1D2EfFE636dd 6 | to = 0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C 7 | amount = 123 8 | message = "coffee and donuts" 9 | nonce = 1 10 | signature = 11 | 0x993dab3dd91f5c6dc28e17439be475478f5635c92a56e17e82349d3fb2f166196f466c0b4e0c146f285204f0dcb13e5ae67bc33f4b888ec32dfe0a063e8f3f781b 12 | */ 13 | function verify( 14 | address _signer, 15 | address _to, 16 | uint _amount, 17 | string memory _message, 18 | uint _nonce, 19 | bytes memory signature 20 | ) public pure returns (bool) { 21 | bytes32 messageHash = getMessageHash(_to, _amount, _message, _nonce); 22 | bytes32 ethSignedMessageHash = getEthSignedMessageHash(messageHash); 23 | 24 | return recoverSigner(ethSignedMessageHash, signature) == _signer; 25 | } 26 | 27 | 28 | 29 | 30 | 31 | #### Sources : 32 | *https://ethereum.stackexchange.com/questions/49063/check-message-signature-in-solidity?rq=1* 33 | 34 | Yes, notably, Solidity includes a function ecrecover that can recover the account that signed a message. 35 | 36 | How to verify offchain signed messages on chain inside of solidy 37 | https://solidity-by-example.org/signature/ 38 | https://programtheblockchain.com/posts/2018/02/17/signing-and-verifying-messages-in-ethereum/. 39 | 40 | 41 | -------------------------------------------------------------------------------- /draftProcess.md: -------------------------------------------------------------------------------- 1 | # Classic Alice and Bob want to swap eth for xmr 2 | Cross-chain atomic swap protocol between Monero and Ethereum 3 | 4 | * 1- Alice:Create Deposit of eth into swap smart contract 5 | * 2- Bob:Fund xmr address and key split priv Key (K) into 2 parts (aK & bK) 6 | * 3- Bob:Submit adaptor sig to Alice (OffChain) 7 | * 3- Bob:Submit hash(aK) to contract (OnChain contract interaction) 8 | * 4- Alice:Lock withdraw address to B's + time lock with auto revert on expiry (OnChain contract interaction) 9 | * 5- Bob: claim eth deposit in contract using aK and signing it as part of the tx (OnChain contract interaction) 10 | * 6- Alice: calculates bK from signature and adaptor sig. Is able to spend xmr since they now have K 11 | 12 | 13 | *step 4 is needed to prevent front running attacks since only the withdraw address is able to withdraw. Time lock reverts funds to original funder after x amount of time. Financial incentive makes B claim deposit 14 | To further add privacy on the eth side, funds are pooled in the smart contract allowing for an anon set to increase the more atomic swaps that happen. (similar to tornado cash) 15 | 16 | 17 | 18 | Key advantage in this means that no zero-knowledge proofs are needed inside the smart contract as it all happens offchain. This reduces costs significantly and reduces the need for trusted key setups and complexity. The smart contract is basically a simple escrow contract which is locked for a period of time and reverts if nothing happens after x amount of time. 19 | The contract in a locked state can release funds by the withdrew address interacting with it and providing the Ak key shard as a claim key. The transaction that does this also contains a signature so this enables Alice to then calculate the monero priv key K from the shard received earlier (Ak) and adaptor sig + signature in tx to calculate bK. 20 | 21 | 22 | The contract not only time locks to allow enough time for the swap to happen, but it also locks the address. This is done to prevent the potential of a party brute forcing hashes for AK. This lowers the privacy a bit since the address is on chain in the contract but I think it isn't a big deal since it would be public when they withdrew anyways. In the future it could incorporate some zero knowledge proofs in contract but that's a later conversation. 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /solidity/swap.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.5; 4 | /* 5 | __ __ 6 | | \/ | 7 | | \ / | ___ _ __ ___ _ __ ___ 8 | | |\/| |/ _ \| '_ \ / _ \ '__/ _ \ 9 | | | | | (_) | | | | __/ | | (_) | 10 | |_|__|_|\___/|_| |_|\___|_| \___/ 11 | | ____| | | | 12 | | |__ | |_| |__ ___ _ __ ___ _ _ _ __ ___ 13 | | __| | __| '_ \ / _ \ '__/ _ \ | | | '_ ` _ \ 14 | | |____| |_| | | | __/ | | __/ |_| | | | | | | 15 | |______|\__|_| |_|\___|_| \___|\__,_|_|_|_| |_| 16 | /\ | | (_) / ____| 17 | / \ | |_ ___ _ __ ___ _ ___ | (_____ ____ _ _ __ 18 | / /\ \| __/ _ \| '_ ` _ \| |/ __| \___ \ \ /\ / / _` | '_ \ 19 | / ____ \ || (_) | | | | | | | (__ ____) \ V V / (_| | |_) | 20 | /_/ \_\__\___/|_| |_| |_|_|\___| |_____/ \_/\_/ \__,_| .__/ 21 | | | 22 | |_| 23 | 24 | https://github.com/Crypt0-Bear/xmr-eth-swap-playground 25 | https://twitter.com/Crypt0_Bear 26 | 27 | */ 28 | 29 | // Not needed above sol 0.8 30 | // https://ethereum.stackexchange.com/questions/91367/is-the-safemath-library-obsolete-in-solidity-0-8-0 31 | // import "OpenZeppelin/openzeppelin-contracts@3.0.0/contracts/math/SafeMath.sol"; 32 | 33 | // import "OpenZeppelin/openzeppelin-contracts@3.0.0/contracts/utils/Counters.sol"; 34 | import "@openzeppelin/contracts/utils/Counters.sol"; 35 | 36 | /** 37 | A smart contract for ethereum-monero atomic swaps 38 | This is a proof of concept in the works and should not be used in production 39 | Security has been ignored and needs to be properly secured to prevent common bugs. 40 | 41 | DO NOT USE IN PRODUCTION, COULD LEAD TO LOSS OF FUNDS. 42 | 43 | 44 | 45 | **/ 46 | 47 | 48 | 49 | contract Swap{ 50 | 51 | // using SafeMath for uint256; 52 | using Counters for Counters.Counter; 53 | Counters.Counter private _swapId; 54 | 55 | address public alice; 56 | address public bob; 57 | bool public locked; 58 | string public aK; 59 | //Eventually need to move this to a struct for knowing what hash function was used etc 60 | string public hashed_aK; 61 | uint public lockTime; 62 | uint public startBlock; 63 | uint public depositBalance; 64 | event Receive(uint value); 65 | event Withdraw(string _correct_aK); 66 | uint public deposit; 67 | 68 | 69 | 70 | 71 | 72 | constructor( 73 | uint _timeToLock 74 | ) 75 | public { 76 | alice = msg.sender; 77 | startBlock = block.number; 78 | lockTime = _timeToLock; 79 | deposit = msg.value; 80 | } 81 | 82 | fallback() external payable { 83 | Receive(msg.value); 84 | depositBalance += msg.value; 85 | } 86 | 87 | 88 | function lockContract(string _hashed_aK) public view returns (bool){ 89 | bob = msg.sender; 90 | hashed_aK = _hashed_aK; 91 | locked = true; 92 | return true; 93 | } 94 | 95 | //this is interacted by Bob to withdraw his ether from the contract. 96 | /** 97 | TODOs: 98 | Need to make sure that the eth transaction which interacts with this function is 99 | signing the value of aK when submitted. If not I must also include the signatre of aK as part of the 100 | input for the function 101 | 102 | **/ 103 | function withdraw(string _aK) public returns(bool){ 104 | require (locked == true); 105 | require ( sha256(string(_aK)) == hashed_aK); 106 | aK = string(_aK); 107 | //send eth to the withdrawer 108 | bob.send(depositBalance); 109 | //emit event and make it easier for alice to track value of the contract 110 | emit Withdraw(aK); 111 | 112 | 113 | } 114 | 115 | 116 | } 117 | --------------------------------------------------------------------------------