CounterpartyXCP / counterparty-core

Counterparty Protocol Reference Implementation
http://counterparty.io
MIT License
283 stars 206 forks source link

Automated Market Making (?) #1892

Open adamkrellenstein opened 3 months ago

DerpHerpenstein commented 2 months ago

I really like the idea of adding automated market makers to counterparty. It would look something like this:

Basic Liquidity Pool (LP) Implementation A simple LP design utilizing the time tested function x*y=k (see uniswap v2 whitepaper) could be implemented into counterparty. Any asset pair could be created, but it would work smoothest with divisible assets.

Add Liquidity: User adds assets to the pool and LP tokens proportional to their stake are sent to them Remove Liquidity: User sends liquidity tokens to be destroyed in exchange for that proportion of the liquidity pool assets being send back to the user Swap: Exchange one asset for the other asset, allows for transfer to a wallet or to a tx output (see below)

Here are some quick resources if your not familiar with the basic idea.

https://betterprogramming.pub/uniswap-v2-in-depth-98075c826254

https://defipy.readthedocs.io/en/latest/

https://medium.com/@icmoore/analyze-uniswap-in-python-using-uniswappy-804acb8f2e5c

The drawback to this type of system is that it incentivizes MEV sandwiching. When a user creates a swap they identify the number of tokens they are trading and the minimum they must get in return. Since users don't want to waste money on transaction fees for a failed swap, they add a slippage percentage to ensure their tx goes through. This results in miners looking for a tx where the slippage is larger than the cost of two transactions, and if it is, they create two transactions to extract the leftover value.

Ideally the implementation here would be created in such a way that does not incentivize this behavior. A possible solution would be: if multiple users swap token a for token b, and others swap b for token a, the calculation xy >k will be performed using all inputs in a block, rather than per tx sequentially. If the swap fails because xy<=k the transactions with the exchange rates furthest will be removed one at a time until x*y >k is satisfied. This functionality would ensure that any MEV is only performed at the block level and not the transaction level.