# Intmax1.0の取引所について
## セキュリティ条件
- Maker側はOfflineでも安全
- ネットワーク上に固有のステートはもたない
- Taker側はMakerと交渉する必要がない
- Makerは板を出していても他のTxを阻害しない
- Makerが出している板の分のトレードは必ずできる
- SlashやClaimの仕組みは入れない(Stakeするのがノードではなく一般ユーザーなのでSlashのためのstakeは大きくユーザビリティを損なう)
## 追加したい仕様
実装するにあたって一番の問題点はMakerが板を出している間は送金がPendingとなっているため、nonceが消費されず(あるいはそのTxのNonceがわからず)他のTxをうつことが出来ない点にある。
また、Takerの要望に対して臨機応変にMakerが対応することも考えられるがMakerはつねにオンラインでないと行けないという問題点がある。
上記の問題点を解決するために条件付き送金を導入したい。
条件付き送金ではまず空のアドレスに送金する処理を行う(資金のLock)。
このとき、OneTimeAddressである```Hash(Public key + nonce)```を消費する。
条件付き送金Txを送る側は通常のProofにくわえて
$$ ConditionSignature = Sig(Hash(AssetID + Amount + Conditions), SenderPrivkey) $$
$$C_{verifySignedPayment}(txHash, senderOneTimeAddress, senderOneTimeAddress2, Conditions), (publicKey, ConditionSignature)) \\ \to \{true,false\}$$
$$zkProve((txHash, senderOneTimeAddress, senderOneTimeAddress2, Conditions), (publicKey, ConditionSignature), C_{verifySignedTx}) \\ \to zkProof_{ConditionalPayment}$$<br />
(OneTimeAddress2はSuffixの入った受け取りTx用OnetimeAddress)
その後、別のTx(受け取りTx)が条件付き送金TxのProofをInputにしてTxを実行する。
Inputにした条件付きTxのProofの条件が満たされているTxが実行されれば条件付きTxの送金がそのTxのオーナーに対して行われる。
このとき、OneTimeAddressである```Hash(Public key + nonce + なんらかのSuffix)```を消費する。このOneTimeAddressはnonceは同じであるものの、Lock時とは異なるOneTimeAddressであり、衝突しない。また、次のOneTimeAddressとも衝突しないのでMakerの他Txには影響されない。
このとき受け取りTxが提出するProofは
$$ ReceiverSignature = Sig((txHash + Conditions), ReceiverPrivkey) $$
$$C_{verifyReceiveConditionalPayment}((txhash, ReceiverOneTimeAddress, ReceiverSignature, zkProof_{ConditionalPayment}), (publicKey)) \\ \to \{true,false\}$$
$$zkProve((txHash,onetimeAddress2), (publicKey, ReceiverSignature, zkProof_{ConditionalPayment}), C_{verify}) \to zkProof_{verifyReceiveConditionalPayment}$$<br />
```mermaid
sequenceDiagram
actor S as Sender
participant I as Intmax Network
actor R as Receiver
autonumber
S --> I : Lock Token via Conditional Tx
I --> I : Comsume OneTimeAddress Hash(Sender Pub + nonce)
R --> I : Submit Tx with Sender's Proof
I --> I : Check if Receiver's Tx fullfills Sender's condition
S --> R : Send Sender's Token
I --> S : Send Receipt with OneTimeAddress Hash(Sender Pub + nonce + Suffix)
```
## L2上の資産とのSwap
板取引みたいなSwapを考える。
Makerは上記の条件付き送金で「あるERC20を指定額・指定したアドレスに送金する」ことを条件に指定する。
TakerはそのOutput_ProofをInputに送金することでSwapを完了する。
## LNとのSwap
LNにおいてはMakerがLNでBTCをうけとってL2資産を放出する場合を考える。
MakerはInvoiceを生成し、PreImageを知っていることを条件としたOutPut_Proofを生成する。
Takerは送金してPreimageを取得しPreimageを埋め込んだTxをOutput_ProofをInputにして提出することでSwapを完了する
=> **途中のルーティングのノードもPreImageを知ってしまうので無理!!!**
## 秘密の値を渡す形式について考える
秘密の値を渡すことでルーティングノードがclaimする可能性をなくしたい。
方向性としてはCustomMessageでユーザーが公開鍵を送り、誰かがsaltを暗号化して送る方式。
### Makerがオンラインの場合
LNサーバーはオンラインの筈なのでそこでおくればよい。
メリットとしてはLNだけがオンラインであればよく(支払いが成立する条件として必須)、交渉が不要になる。
### トラストできる第三者が受け取りを代行する場合
MakerはLNサーバーもオフラインで良い。
ただし、第三者はClaimできる状態にある。
## この方式のメリットデメリット
### メリット
- コントラクトストレージが不要
- 板取引として機能している
- LNにも対応している
### デメリット
- アトミックにしか取引できない(一旦約定されたらその板はおしまいなので板を厚くするには最低ロットをたくさんなげる、みたいな挙動が必要になってしまう)
- 自動運用ができないため、Makerをうまく引き付けないとAMMのように自動で分厚い板は再現できない