This proposal is for the continued development of ETH-XMR atomic swaps. The scope of this proposal includes usability and privacy enhancements, as well as codebase maintenance and bugfixes.
noot (github.com/noot) will be completing this proposal.
Atomic swaps are a method for trustlessly exchanging funds across blockchains. An ETH-XMR atomic swap will allow for users to, in a trustless and completely decentralized manner, exchange Ether for Monero. This connects the leading smart contract blockchain (and the home of DeFi) with the leading privacy-preserving blockchain. Along with the BTC-XMR atomic swaps, this will allow for completely decentralized cross-chain exchanges to be built that allow for XMR swaps.
In my previous CCS, I completed an implemenetation of the ETH-XMR atomic swap, deployed it to stagenet on 9 different servers, and extensively tested it. There is now an alpha release of ETH-XMR atomic swaps with the following functionality:
swapd
program which executes atomic swaps; includes:
swapcli
program which implements a CLI for users to interact with the daemon and easily make/take offersswaprecover
program which allows for funds to be recovered in case of a crashui
: a self-hosted UI for the swap that displays current offers on the network and allows users to take offers using their MetaMask wallet.I would like to continue work on the ETH-XMR atomic swap implementation by adding improvements for usability and privacy, as well as general codebase maintainence.
This proposal includes the following development work:
The current implementation of the protocol requires the ETH-recipient to have some ETH in their claiming account to pay for the transaction fees to claim the swap ETH. However, this is bad for UX and privacy, as users cannot withdraw to fresh ETH accounts.
To allow for users to claim ETH into a fresh account, integration with a relayer service can be implemented. This will allow users to withdraw to a fresh account by paying a small fee to a relayer to submit the transaction on their behalf.
On the ETH side of the swap, there is no privacy, and which accounts and amounts participating in the swap are visible. To improve privacy, the swap contract can have its funds stored in a shielded pool such as Tornado Cash Nova, which allows shielded transfers. However, this is dependent on whether it's possible to build applications on top of Tornado Cash Nova.
To support swaps for ERC20s without hurting liquidity, the swap contract can be integrated with a DEX such as Uniswap to automatically swap received ETH for the desired ERC20 token.
The current implementation of the swap does not store anything to disk apart from information needed for recovery of swap funds in case of failure. However, there are other components that should be stored to disk and restored upon reload, such as current swap offers made, historic swap information, and peer information. This will require a simple key-value database implementation.
See here for open issues on the repo. Issues not covered by the above work are part of this section. This includes RPC calls and documentation, codebase maintainence, testing, and fixes of any bugs found during testing.
The previous CCS was milestone-based, which I priced at a hourly rate of around $60 USD assuming I would work around 15 hours a week on average, for around 4 months. However, I ended up working more than that (took around 6 months). For this proposal, I would prefer to do a monthly payout instead of milestone-based and I will provide at minimum monthly updates in terms of CCS comments and Reddit posts. I also slightly raised the hourly rate to match my personal rate as well as address crypto price volatility.
Development costs: $70 USD per hour x 20 hours per week x 16 weeks = $22400 Server costs (10 DigitalOcean nodes): $267 USD per month x 4 months = $1068
At $145 USD / XMR = 162 XMR total
This proposal expires on September 18 2022.
This proposal is for the continued development of ETH-XMR atomic swaps. The scope of this proposal includes usability and privacy enhancements, as well as codebase maintenance and bugfixes.
noot (github.com/noot) will be completing this proposal.
Atomic swaps are a method for trustlessly exchanging funds across blockchains. An ETH-XMR atomic swap will allow for users to, in a trustless and completely decentralized manner, exchange Ether for Monero. This connects the leading smart contract blockchain (and the home of DeFi) with the leading privacy-preserving blockchain. Along with the BTC-XMR atomic swaps, this will allow for completely decentralized cross-chain exchanges to be built that allow for XMR swaps.
In my previous CCS, I completed an implemenetation of the ETH-XMR atomic swap, deployed it to stagenet on 9 different servers, and extensively tested it. There is now an alpha release of ETH-XMR atomic swaps with the following functionality:
swapd
program which executes atomic swaps; includes:
swapcli
program which implements a CLI for users to interact with the daemon and easily make/take offersswaprecover
program which allows for funds to be recovered in case of a crashui
: a self-hosted UI for the swap that displays current offers on the network and allows users to take offers using their MetaMask wallet.I would like to continue work on the ETH-XMR atomic swap implementation by adding improvements for usability and privacy, as well as general codebase maintainence.
This proposal includes the following development work:
The current implementation of the protocol requires the ETH-recipient to have some ETH in their claiming account to pay for the transaction fees to claim the swap ETH. However, this is bad for UX and privacy, as users cannot withdraw to fresh ETH accounts.
To allow for users to claim ETH into a fresh account, integration with a relayer service can be implemented. This will allow users to withdraw to a fresh account by paying a small fee to a relayer to submit the transaction on their behalf.
On the ETH side of the swap, there is no privacy, and which accounts and amounts participating in the swap are visible. To improve privacy, the swap contract can have its funds stored in a shielded pool such as Tornado Cash Nova, which allows shielded transfers. However, this is dependent on whether it's possible to build applications on top of Tornado Cash Nova.
To support swaps for ERC20s without hurting liquidity, the swap contract can be integrated with a DEX such as Uniswap to automatically swap received ETH for the desired ERC20 token.
The current implementation of the swap does not store anything to disk apart from information needed for recovery of swap funds in case of failure. However, there are other components that should be stored to disk and restored upon reload, such as current swap offers made, historic swap information, and peer information. This will require a simple key-value database implementation.
See here for open issues on the repo. Issues not covered by the above work are part of this section. This includes RPC calls and documentation, codebase maintainence, testing, and fixes of any bugs found during testing.
The previous CCS was milestone-based, which I priced at a hourly rate of around $60 USD assuming I would work around 15 hours a week on average, for around 4 months. However, I ended up working more than that (took around 6 months). For this proposal, I would prefer to do a monthly payout instead of milestone-based and I will provide at minimum monthly updates in terms of CCS comments and Reddit posts. I also slightly raised the hourly rate to match my personal rate as well as address crypto price volatility.
Development costs: $70 USD per hour x 20 hours per week x 16 weeks = $22400 Server costs (10 DigitalOcean nodes): $267 USD per month x 4 months = $1068
At $145 USD / XMR = 162 XMR total
This proposal expires on September 18 2022.
noot (dd9a918e) at 18 Jul 18:30
add proposal
Hey, milestone 7 (UI) has been completed! The UI has integration with Metamask so users can sign and submit transactions entirely in their browser and the swap daemon doesn't require access to an ETH private key. Currently, the UI needs to be run locally, as hosting it on a website requires quite significant changes to the daemon, and would work much nicer packaged as a GUI.
Relevant PRs:
payout address for this milestone is 45W8VY...pbYNmu
Hey, I've completed milestone 6 and the document is here: https://github.com/noot/atomic-swap/blob/master/docs/eth-xmr-atomic-swaps.pdf Although I've had some reviews, I would certainly appreciate any more.
To summarize what's in the article:
Hey again, happy to announce that milestone 5 and the final core development focused milestone for this CCS is done!
For this milestone, I created 9 swap instances in the cloud running on Monero stagenet and Ethereum's Goerli testnet, created an automated tester to make and take offers, and ran that against the nodes iteratively, fixing any issues along the way. I've left the nodes running and acting as XMR-makers, so that everyone can try it out themselves on stagenet.
Here are the relevant PRs:
The docs to join stagenet are here. The nodes currently up and running are:
/ip4/67.205.131.11/tcp/9900/p2p/12D3KooWT19g8cfBVYiGWkksU1ZojHCBNqTu3Hz5JLfhhytaHSwi
/ip4/143.198.123.27/tcp/9900/p2p/12D3KooWSc4yFkPWBFmPToTMbhChH3FAgGH96DNzSg5fio1pQYoN
/ip4/67.207.89.83/tcp/9900/p2p/12D3KooWLbfkLZZvvn8Lxs1KDU3u7gyvBk88ZNtJBbugytBr5RCG
/ip4/134.122.115.208/tcp/9900/p2p/12D3KooWDqCzbjexHEa8Rut7bzxHFpRMZyDRW1L6TGkL1KY24JH5
/ip4/164.92.103.160/tcp/9900/p2p/12D3KooWAZtRECEv7zN69zU1e7sPrHbMgfqFUn7QTLh1pKGiMuaM
/ip4/164.92.103.159/tcp/9900/p2p/12D3KooWSNQF1eNyapxC2zA3jJExgLX7jWhEyw8B3k7zMW5ZRvQz
/ip4/164.92.123.10/tcp/9900/p2p/12D3KooWG8z9fXVTB72XL8hQbahpfEjutREL9vbBQ4FzqtDKzTBu
/ip4/161.35.110.210/tcp/9900/p2p/12D3KooWS8iKxqsGTiL3Yc1VaAfg99U5km1AE7bWYQiuavXj3Yz6
/ip4/206.189.47.220/tcp/9900/p2p/12D3KooWGVzz2d2LSceVFFdqTYqmQXTqc5eWziw7PLRahCWGJhKB
edit: I currently only have 9 nodes available since I hit my digitalocean limit. If you'd like more nodes, let me know and I can try to upgrade my account.
Hello again, I've completed milestone 3 (DLEq integration). I ended up going the route of creating C bindings for kayabaNerve's DLEq library (https://github.com/kayabaNerve/dleq-rs/tree/develop) which you can find here: https://github.com/noot/cgo-dleq. The cgo-dleq library allows the Rust library to be called from Go via C. I figured this method made the most sense as there would be less code duplication and others can also use the C bindings for their projects in other languages.
The corresponding PRs are here:
Update on progress of other milestones:
Hey all, I've completed milestone 4 (end-to-end integration testing), it ended up taking a bit longer than expected as I ended up implementing a websockets server and quite a few subscription methods for easier testing (will also be used for the UI). Here are the PRs for the milestone:
net_takeOffer
endpoint, so you can take an offer and get push notifications when the status updates.net_makeOffer
endpoint, so you can make an offer and get updates when it's taken and it's status updates afterwards. also adds an endpoint for getting offers you currently advertise.There's also a test script ./scripts/run-integration-tests.sh
which sets up the environment, runs 3 swapd
nodes and runs the integration tests against them, for anyone who wishes to try them out.
Also a small update on what else I've been working on:
Hey, I've completed milestone 1 (maintainence of existing codebase).
Here are the PRs for the milestone:
swapfactory
package, which contains auto-generated Go bindings for the contract. most of the auto-generated code isn't used, so the coverage is quite low. for all the critical paths in the codebase, the various cases are covered.test coverage (from go test
):
$ go test ./... -short -timeout=30m -covermode=atomic -coverprofile=coverage.out
? github.com/noot/atomic-swap/cmd/client [no test files]
? github.com/noot/atomic-swap/cmd/client/client [no test files]
ok github.com/noot/atomic-swap/cmd/daemon 2.447s coverage: 69.7% of statements
ok github.com/noot/atomic-swap/cmd/recover 18.987s coverage: 69.2% of statements
? github.com/noot/atomic-swap/cmd/utils [no test files]
ok github.com/noot/atomic-swap/common 0.131s coverage: 70.0% of statements
? github.com/noot/atomic-swap/common/rpcclient [no test files]
ok github.com/noot/atomic-swap/common/types 0.030s coverage: 19.0% of statements
? github.com/noot/atomic-swap/crypto [no test files]
ok github.com/noot/atomic-swap/crypto/monero 0.025s coverage: 74.7% of statements
? github.com/noot/atomic-swap/crypto/secp256k1 [no test files]
ok github.com/noot/atomic-swap/dleq 2.944s coverage: 72.7% of statements
ok github.com/noot/atomic-swap/monero 83.724s coverage: 64.5% of statements
ok github.com/noot/atomic-swap/net 9.633s coverage: 70.1% of statements
? github.com/noot/atomic-swap/net/message [no test files]
ok github.com/noot/atomic-swap/protocol 3.213s coverage: 72.4% of statements
ok github.com/noot/atomic-swap/protocol/alice 159.036s coverage: 74.3% of statements
ok github.com/noot/atomic-swap/protocol/bob 258.495s coverage: 74.1% of statements
ok github.com/noot/atomic-swap/protocol/swap 0.005s coverage: 61.2% of statements
ok github.com/noot/atomic-swap/recover 19.548s coverage: 72.1% of statements
? github.com/noot/atomic-swap/rpc [no test files]
ok github.com/noot/atomic-swap/swapfactory 38.125s coverage: 11.2% of statements
ok github.com/noot/atomic-swap/tests 0.056s
the coverage profile can be checked with go tool cover -html=coverage.out
.
Hey, I've completed milestone 2 (swap contract refactor to make it a factory). the PR is here: https://github.com/noot/atomic-swap/pull/85 Hope it's okay I completed this before milestone 1, I figured it would be better to work on increased testing/coverage after this refactor was completed.
The PR contains a new solidity smart contract SwapFactory.sol which can be deployed onto a chain once, then new instances of a swap can be created within it whenever a user wishes to start a new swap. I also added unit tests for the happy and unhappy paths, and integrated it with the codebase. Also added documentation in docs/developing.md
on how to deploy the contract to a chain or use an existing contract. I also added the updated gas costs in the PR description, this refactor decreases the gas for the ETH holder by ~5.3x.
payment address (shared w/ luigi1111): 82yhwW...GznG3x
I have someone committed to working on the UI, and I'd like to add him to the proposal team so he can be sent the funds when the UI milestone is done.
noot (4b0ba652) at 18 Jan 02:16
update team section
noot (233dedd7) at 16 Jan 17:09
add licensing section
noot (e0186fee) at 16 Jan 03:21
add UI milestone
noot (15afe679) at 15 Jan 18:09
remove points that aren't needed anymore, update others
I've emailed Jordi about it and I'll post here if I receive a response.
otherwise, like I said previously, it'll be possible to change the license once the DLEq refactor is done as it removes the direct dependence on the ecsol library (this refactor is currently in progress), and the secp256k1 ecmul code is rewritten based of Vitalik's post (which I'm happy to do if needed).
however, I still prefer GPL. I hope the proposal can move forward either way, maybe we could keep it as GPL for now and I can change the license later on if that's desired.
@lederstrumpf is correct, the ecsol library is GPL. however the only code that will actually be used from that library is here: https://github.com/1Address/ecsol/blob/master/contracts/EC.sol#L200 which is based off Vitalik's code here https://ethresear.ch/t/you-can-kinda-abuse-ecrecover-to-do-ecmul-in-secp256k1-today/2384
if the community feels strongly about changing the license to LGPL I can either reach out to Jordi and ask him if he can change the license.
Personally I'd prefer sticking with GPL as I'd rather not have the code used in proprietary software at all, but I'm also ok with LGPL if the community prefers that.
edit: to clarify, after the DLEq integration, the only code that will be used from the 1Address library is in the function linked above, which isn't actually in the original library by Jordi. not sure if that will allow us to use a different license or not. otherwise, the code could be rewritten based of Vitalik's post.