Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SamsungGalaxyPlayer/e5f0f2bcd4a5d55a713bc6df051c2fb1 to your computer and use it in GitHub Desktop.
Save SamsungGalaxyPlayer/e5f0f2bcd4a5d55a713bc6df051c2fb1 to your computer and use it in GitHub Desktop.
Monero Thorchain Implementation Notes

Monero Thorchain Implementation Notes

Monero integration on Thorchain presents challenges that are (largely) unique to Monero. Many of the assumptions that Thorchain operates under, such as transaction memos and transparent addresses, fall apart at least in some form. This document should help address these misplaced assumptions to allow the inclusion of Monero into Thorchain with a reasonable implementation.

Issue #1: Monero tx_extra is nonstandard

The Monero community wants transactions to look as indistinguishable to each other as possible. If some transactions have a unique use of tx_extra (Monero’s arbitrary storage feature), they will undoubtedly stick out.

While one can proceed with the aggressive use of tx_extra in a nonstandard format, this is risky because the Monero community may move to make this incompatible with consensus rules.

Monero has a standard use of tx_extra called the payment ID. The payment ID is 16 characters (8 bytes). Sadly, I have learned that at least 1 cryptographer believes that packing a truncated hash in these 16 characters is insecure. So, the use of a payment ID is likely out.

This leaves the use of a Monero encrypted memo, proposed in #6410: monero-project/monero#6410

#6410 has not yet been merged into the Monero code sadly, and people have not yet agreed on the final implementation.

Issue #2: Where did that transaction come from?

In Monero, there is no easy way to know what addresses transactions are coming from. One cannot simply look at the Monero blockchain to see that two transactions are associated with the same private keys.

Thus, for additions of Monero liquidity, there needs to be some way to communicate a removal, other than “look for removal requests from the same Monero address.” This isn’t possible, at least easily.

The easiest solution is for a Monero transaction to have a means of delegating an address on another supported blockchain, such as Thorchain (and in theory Bitcoin, Litecoin, Ethereum, etc., though this is probably not needed). Transactions with commands can be issued from these specified keys to do things like remove liquidity.

The solution: Hashed REQUEST transactions

The best way to address these constraints is to allow a specific type of REQUEST transaction with accompanying command syntax, hash the string, and store part of the hash in the memo of a Monero transaction.

https://gitlab.com/thorchain/thornode/-/issues/919

REQUEST transactions append REQUEST: or r: to the front of other commands that follow a standard format.

Adjustments for Pooling

Currently, Thorchain has the following syntaxes for adding symmetric and asymmetric liquidity:

  • Symmetric: ADD:ASSET:thorAddress
  • Asymmetric: ADD:ASSET

And for removing:

  • Symmetric: WITHDRAW:ASSET:PERCENT
  • Asymmetric: WITHDRAW:ASSET:PERCENT:ASSET

This has the following incompatibilities (possibly among others):

  • Can’t add asymmetrically from XMR, since there is no way to delegate a command address to be able to remove the XMR.
  • Can’t remove XMR symmetrically (realistically unsolvable)
  • Can’t remove asymmetrically or symmetrically to XMR, since there’s no way to specify a Monero withdrawal address. Assets can only be removed from XMR-RUNE pool in RUNE, which will lead to extremely bad market behaviors.

Again for clarity, only RUNE can be removed from the RUNE-XMR pool, since there is no way to specify an XMR address currently.

The syntax for ADDING liquidity symmetrically and asymmetrically should be changed to allow for Monero asymmetric adds. For this, Monero needs a way to delegate an address, and it needs a way to differentiate the desire to add asymmetrically from a desire to add symmetrically. This can be done as follows (<> are optional parameters):

  • Symmetric: ADD<.SYMME>:ASSET:thorAddress:<affiliateAddress>:<affiliateFee>
  • Asymmetric: ADD.ASYMM:ASSET:thorAddress:<affiliateAddress>:<affiliateFee>

If neither SYMME nor ASYMM is specified, then Thorchain should assume that it is symmetric. Thorchain must also account for affiliate addresses and affiliate fees.

ADD.ASYMM:XMR.XMR:tbc1zpa4c6zpa4cyz9s93xuje2pwkswsqzn2zpa4c:tthor1ql2tcqyrqsgnql2tcqyj2n8kfdmt9lh0yzql2tcqy:10

Thorchain could add 2 new commands ADD.SYMME and ADD.ASYMM, or similar. ADD on its own would default to symmetric or asymmetric according to the legacy format for backwards compatibility.

The syntax for REMOVING liquidity should be changed to allow for the inclusion of an address.

  • Symmetric: WITHDRAW<.SYMME>:ASSET:PERCENT:<ASSET>:<assetAddress>
  • Asymmetric: WITHDRAW<.ASYMM>:ASSET:PERCENT:ASSET:assetAddress

Thorchain could add 2 new commands WITHDRAW.SYMME and WITHDRAW.ASYMM, or similar. WITHDRAW on its own would default to symmetric or asymmetric according to the legacy format for backwards compatibility. The explicit SYMME and ASYMM commands are useful for XMR, because there is no accompanying transaction command to withdraw on the XMR side that can be paired.

With these changes, it allows for the following for the XMR-RUNE pool:

Add Withdraw
Symmetric Send XMR with hash of REQUEST:ADD.SYMME:XMR.XMR:thorAddress:affiliateThorAddress:fee; Send RUNE with ADD.SYMME:XMR.XMR:affiliateThorAddress:fee Send RUNE from delegated address with WITHDRAW.SYMME:XMR.XMR:100:XMR.XMR:xmrAddress, resulting in 50% of the value going to each of the defined XMR and delegated RUNE addresses
Asymmetric Send XMR with hash of REQUEST:ADD.ASYMM:XMR.XMR:thorAddress:affiliateThorAddress:fee; Send RUNE with ADD.ASYMM:XMR.XMR:affiliateThorAddress:fee Send RUNE from delegated address with WITHDRAW.ASYMM:XMR.XMR:100:XMR.XMR:xmrAddress, resulting in 100% of the value going to the provided XMR address (100% would go to the delegated RUNE address if RUNE was specified instead, or it could be programmed to allow withdraws to arbitrary RUNE addresses as long as the initial request came from the delegated RUNE address)

Refund addresses

This implementation does NOT address refund addresses. Such a feature would require syntax along the lines of :REF=address

The ability to provide refund addresses is important for Monero because there is no known address to refund to if something goes wrong.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment