Closed colin-axner closed 11 months ago
The development of this module should initially deliver a MVP with the following functionality.
I think version 2 should transition the coinswap module from being a basic decentralized exchange into adding governance for the zone and for each trading pair.
Governance for the module:
Governance for trading pairs voted on by LPs (and users?):
Imo this shouldn't live on the SDK but on Gaia and should be approved through governance. cosmos/cosmos-sdk#4642 could be more suitable for the SDK as it's a general-purpose module as opposed to an uniswap module. Thoughts @alexanderbez @jackzampolin @sunnya97 @marbar3778 ?
I agree @fedekunze . I think this feature will probably need its own repo. From its repo, its module level code could lie in x/coinswap
so its still easily importable. I don't think this needs to go through governance however, since I don't think it should live on the hub. Makes more sense to me if coinswap is its own zone with its own governance/validators
I'm OK with this living in the SDK as I could see it providing high utility for many projects. It does however continue to beg the questions: What belongs in the SDK and what doesn't (rather in it's own repo)?
I disagree @alexanderbez. The problem is if it stays in the SDK, it becomes incumbent on SDK developers to maintain it as we make breaking changes to the rest of the SDK.
I think we should only burden the SDK team to maintain modules that are necessary for most end-users.
If the coinswap module exists as a separate repo we could keep it on an older version of the SDK and make updates to it more gradually
yeah I'm not too opinionated on where this lives tbh. Outside of the SDK seems more appropriate.
Summary
Add a module that implements the functionality of uniswap
Problem Definition
As more assets are added to the hub/network, it will be useful to have a decentralized asset exchange. Uniswap is a fairly simple and accessible exchange that could fulfill this role.
Proposal
This module takes four different types of messages. One for each of the following actions: creating an exchange between two coins, swapping coins, adding liquidity to an exchange, removing liquidity from an exchange. A param for the native asset used to swap between coins will need to be specified. Each exchange will use its coin denomination as its unique id. Coins can only be directly swapped with the native asset. All other swaps will do an extra swap with the native asset to return the desired output coin.
Uniswap refers to the tokens receieved in exchange for contributing to a liquidity pool as UNI, that naming convention has been maintained in this write up. Uniswap uses
x*y=k
invariant to set prices. In this implementationnativePool * coinPool = k
. Uniswap enforces a fee of %0.3 paid to liquidity providers, this can be added as a param. Uniswap allows for two types of orders, buy/sell. In a buy order, the input is calculated, the output is specified. In a sell order, the input is specified, the output is calculatedmsgs.go
Initializes a new exchange pair between the specified coin and the native asset
If exchanging between 2 coins that are not the native asset, input coin -> native then native -> output coin. Otherwise, simply swap between native asset and specified coin. The cost of buying or selling is determined by current ratio at the time the transaction is included in a block. Bound is used to limit the amount a user is willing to buy or sell.
DepositAmount is 50% of the total value that is added. Must deposit an amount for native asset and coin pair; If first provider, then amount deposited determines exchange ratio (arbitrage traders bring prices to equilibrium if the ratio is off). The bounds are used to manage price changes between tx signed and executed. If the total liquidity is 0 for this exchange, then
MaxCoins
is used for the amount of the exchange coin to be depositedante.go
keeper.go
Formulas for calculating buy/sell amount will be taken from the uniswap implementation GetInputAmount() would correspond to GetOutputPrice() GetOutputAmount() would correspond to GetInputPrice()
handleMsgCreateExchange
handleMsgSwapOrder
handleAddLiquidity
totalLiquidity is the total number of UNI in existence
handleRemoveLiquidity
params.go
Notes: Each exchange will need to maintain a balance of liquidity that is deposited into it.What would be the best way to create accounts for each exchange? If exchanges have accounts with the CoinKeeper then the total liquidity of each exchange can be retrieved from there.
For Admin Use