# Monero-Ethereum atomic swaps
Alice has ether and wants Monero.
Bob has Monero and wants ether.
## Ethereum smart contract interface
Offline phase:
- Both parties Alice and Bob select a secret: `s_a` & `s_b`, which are used to construct valid points on the ed25519 curve: `P_ed_a` and `P_ed_b` accordingly. The parties share their public keys with each other.
### Step 1.
Alice creates a smart contract on Ethereum and sends her ether to it. The contract has the following properties:
- it is non-destructible
- it is initiated with `P_ed_a` & `P_ed_b`
- it has a `ready` function, which can only be called by Alice. Once `ready` is invoked (in step 3), Bob can proceed with redeeming his ether. Alice has `t_0` time period to call `ready`, otherwise all funds are transferred to Bob.
- it has a `refund` function that can only be called by Alice, and only before `ready` is called. Once `ready` is invoked, Alice can no longer call `refund` within the next time duration`t_1`. After `t_1` has passed though, and Bob hasn't called `redeem`, `refund` is re-enabled to prevent a dead-lock.
- `refund` takes one parameter from Alice: `s_a`. This allows Alice to get her ether back in case Bob mis-behaves, but as it's public from now on, Bob can still redeem his monero (in case he was offline).
- `redeem` takes one parameter from Bob: `s_b`. At this point, Alice found out Bob's secret and can claim Monero by combining her and Bob's secrets.
- both the `refund` & `redeem` functions check, whether the argument `s_x` provided indeed corresponds to the public key `P_ed_x` and only if true, allows fund transfer.
### Step 2.
Bob sees the smart contract being created. He sends his monero to an account address constructed from `P_ed_a + P_ed_b`.
The funds can only be accessed by an entity having both `s_a` & `s_b`.
### Step 3.
Alice sees that monero has been sent. She calls `ready` on the smart contract.
From this point on, Bob can redeem his ether by calling `redeem(s_b)`.
By redeeming, Bob revealed his secret. Now Alice is the only one that has both `s_a` & `s_b` and she can access the monero in the account created from `P_ed_a + P_ed_b`.
## What could go wrong
### Step 2.
- Alice locked her ether, but Bob doesn't lock his monero.
Alice never calls `ready`, and can instead call `refund(s_a)` within `t_0`, getting her ether back.
### Step 3.
- Alice called `ready`, but Bob never redeems. Deadlocks are prevented thanks to a second timelock `t_1`, which re-enables Alice to call refund.
- Alice never calls `ready` within `t_1`. Bob can still claim his ETH, after `t_1` has passed, and XMR remains locked forever.
## Flowchart
```flow
st=>start: Spend key shares generation
ethContract=>operation: Alice creates ETH funded contract
lockMonero=>condition: Bob locks XMR < t_0
isLockMonero=>condition: Alice: is XMR locked?
refund_bt0=>condition: Alice refund(s_a) < t_0
claimBad=>condition: Bob claim(s_b) < t_1
ready=>condition: Alice ready() < t_0
claimY=>condition: Bob claim(s_b) < t_1
claimN=>condition: Bob claim(s_b) < t_1
refund_at1=>condition: Alice refund(s_a) > t_1
xmrEndAlice=>end: Alice controls XMR, Bob ETH
xmrEndBob=>end: Bob controls XMR, Alice ETH
deadEndAlice=>end: Dead lock until Alice
badEndBob=>end: Bob gets XMR + ETH
st->ethContract->lockMonero
lockMonero(yes)->ready
lockMonero(no)->refund_bt0
refund_bt0(yes)->xmrEndBob
refund_bt0(no)->claimBad
claimBad(yes)->badEndBob
claimBad(no)->refund_at1
ready(yes)->claimY
ready(no)->claimN
claimY(yes)->xmrEndAlice
claimY(no)->refund_at1
claimN(yes)->xmrEndAlice
claimN(no)->refund_at1
refund_at1(yes)->xmrEndBob
refund_at1(no)->deadEndAlice
```