near / bounties

Specs for technical and non-technical work that earns NEAR tokens
https://devgovgigs.near.social
73 stars 8 forks source link

Implement Uniswap in Rust | Bounty: 5000 NEAR #6

Closed ilblackdragon closed 3 years ago

ilblackdragon commented 4 years ago

Description

Implement a Uniswap v2 contract in Rust on NEAR.

Context:

Flow:

Acceptance

Bounty

5000 Ⓝ

robert-zaremba commented 4 years ago

Hi @ilblackdragon - I'm happy to handle this.

  1. Is there a way to assign myself?
  2. Do we want to implement exactly same rules and parameters as Uniswap v1? Or do we want to do Uniswap v2?

Uniswap v2 is much better. But both have one big "default" - they lock lot of liquidity. There are better mechanisms. That being said it's still good to begin with Uniswap.

ilblackdragon commented 4 years ago
  1. Assigned to you
  2. I suggested in the bounty to do v2 directly. I haven't read the v2's code, so not sure how much more work it is

What is the better mechanisms you have in mind? Agree that Uniswap is a good primitive even if there are better exchange functionality - it will not always have enough liquidity for contracts to rely on it.

robert-zaremba commented 4 years ago

Cool, will start working on probably around Friday.

robert-zaremba commented 4 years ago

What is the better mechanisms you have in mind?

Both Uniswap v1 and v2 lockups lot of liquidity and makes it illiquid. So, in general it's not very efficient. However putting aside the "locking" mechanism, it provides an elegant solution for liquidity pools. Uniswap v2 is a bit better in that matter because one can use the pool for flash swaps - so reusing the pool without manipulating a price. This way the pool is active. There is more innovation to be researched in this subject (what to do with a pool to make it more active / liquid).

As for better solutions - I think something like Kyber has more to say. It reduces the slippage and is more active.

robert-zaremba commented 4 years ago

Uniswap v2 is much more complex (and much better in few aspects):

  1. Allows defining any pair pools. Uniswap v2 routing mechanisms This causes few problems: fragmentation of the liquidity and additional computational overhead of searching optimal routing for exchange. Even Loopring was/is limiting the size of loop because of this very reason (I think currently the max loop size is 4).
    • Personally I believe that optimizing mechanism for single denominator pairs (eg X -> NEAR & NEAR -> Y) are better than adding arbitrary pairs. Even huge centralized exchanges are limiting number of denominators.
  2. Flash swaps (as noted above very cool feature, makes the pools more active)
  3. Price oracles: Time Weighted Average Prices (TWAP)
robert-zaremba commented 4 years ago

So, discussing a scope, I would vote for not implementing custom denominators, reasons:

robert-zaremba commented 4 years ago

Here is a proposed scope:

Milestone 1:

Basically the Uniswap v1 implementation:

Milestone 2:

robert-zaremba commented 4 years ago

Any suggestion for name?

ilblackdragon commented 4 years ago

I don't think you can implement flash swaps on NEAR - all cross-contract calls are async, hence without very advanced locking there is no way to do "flash" stuff. Or I don't understand anything?

I think for now it's fine to start with NEAR <> X swaps and not have routing.

Does TWAP require separate contract? I thought it's just outcome of the existing swap contracts, where just save on first call in the block the current price into some container and then later compute weighted window when other contracts query.

Also as a side note in NEAR, factory can deploy specifically contracts under it's own name. E.g. if we can nearswap and deploy it to swap.near -> all the swap contracts can be deployed under dai.swap.near or eth.swap.near

robert-zaremba commented 4 years ago

Right. With NEAR flash loans are not possible. Any other such thing will be classified as a standard loan (flash loan by definition must close in the same transaction / block). TWAP can be implemented in the same smart contract or with a helper contract. The advantage of splitting the functionality is that we can have multiple TWAPs for the same pair (averaged by different time intervals). Uniswap is using the latter strategy. We can implement a default TWAP within a pool contract (to avoid amount of async calls) and enable external TWAPs as well. The default TWAP can be from 1h. What do you think?

So it turns out that we will implement Uniswap v1 with TWAPs. It's a good start. But later it will be great to spend some time and think how to unlock and give some more use to the locked collateral.

robert-zaremba commented 4 years ago

factory can deploy specifically contracts under it's own name

That's a neat feature!

ilblackdragon commented 4 years ago

Also interesting approach to fees that seems to solve some of the LP-exploitation and to "easy to swing" price: Continuous Liquidity Pools (quick intro is here: https://twitter.com/Rewkang/status/1232414958706520064)

In short means that fee to LP increases with the slippage vs fixed 30 bps.

default TWAP can be from 1h

Oh, I actually thought caller can specify the window.

RE: locked collateral, I'm thinking if we can leverage this in order book exchange that we are planning to do. E.g. as LP you are loading up your liquidity into AMM with some conditions while also able to put "maker" orders on the books if you are active participant.

This is definitely outside of this bounty though. Let's focus here indeed on simple version that we can showcase (also will be good as a tutorial for Ethereum -> NEAR conversion).

robert-zaremba commented 4 years ago

Balancer CLP (B_CLP)* is reducing a price manipulation by introducing swap fees. TWAP is reducing it by averaging. Each has it's own downsides.

It seams that we could have B_CLP with TWAP (so no Uniswap liquidity model). If we assume, as I stated above, that a Liquidity Pool is there only for a last resort of arbitration then:

I will look more at the B_CLP description.

(*) CLP = Continuous Liquidity Pools - it's a project (smart-contract) which allows to continuously exchange certain trading pairs without any other trader involvement. In contrast to an order book trading, in CLP the trading happens based on the provide liquidity to a smart-contract.

robert-zaremba commented 4 years ago

Continuing a research about CLP and Uniswap, I drafted recently two ideas to solve the locked liquidity problem I described above:

  1. Create a NEAR_SWAP token . With it you can exchange a reserve base currency from one poll and use it inside the Uniswap/CLP ecosystem without impacting any other rates in CLP.
  2. Have a common reserve pool — with this maybe we could somehow limit the size of total reserve pool.

Both of them are related. Ideally I would like to have a way where the reserve is limited without impacting the economics of the exchange.

robert-zaremba commented 4 years ago

I was doing tests and found that liquidity providers can loose a value on providing liquidity if the market is very volatile and arbitrageurs will balance the AMMs. The reason is simple: the arbitrageurs gain a value - so someone has to loose. By googling it I found that it's a known problem called "Impermanent Loss". Currently all AMM are suffering from it. This is something what Bangor v2 wants to solve.

robert-zaremba commented 4 years ago

The implementation is available here (still WIP): https://github.com/robert-zaremba/near-clp/tree/master/contract

I'm currently testing the reserve token exchange.

bowenwang1996 commented 4 years ago

@robert-zaremba for impermanent loss, are we just acknowledging it? Right now there is no oracle support on NEAR so what bancor did is not feasible short term.

robert-zaremba commented 4 years ago

Good question. All CLP / AMM have this problem. You can only limit it if there is a stabilization mechanism (which would keep the exchange rate between 2 currencies stable), or by doing some smart pool mechanisms. The former would be limited only to coins which are relatively stable (eg tether <-> USDC). The latter is an area of active research. 

robert-zaremba commented 4 years ago

Interesting stats about Uniswap dominance in Ethereum (data from this week).

image

robert-zaremba commented 4 years ago

[update] Dynamic Fees

Highly volatile markets should have bigger fees to recompensate impermanent losses. However this leads to a problem : who can change fees. Good news is that we can build on that without changing the CLP contract. An entity who is allowed to do modifications can be a contract and owner / contract can always change to a new owner / contract, enhancing the governance. At the beginning this can be managed by a foundation. This is fine - centralized governance is good for start. And foundation is a perfect candidate.

[update] Pool factory

I dropped the idea to create pool / exchange factories (Uniswap is using it). After working on it during the weekend, I decided that there is no much benefit from using factories.

Factory could allow changing a contract which creates a new pool. But this doesn't solve the problem of updating already deployed pools.

Benefits of not having a pool factory. In fact there are clear benefits of dropping the factory pattern:

  1. Since NEAR cross contract calls are async and more complicated, a simple exchange can be do much easier
  2. Removing some attack vectors: front-runners could manipulate a price when they see a cross contract swap (token-token).
  3. With all liquidity residing in a single contract we can have a shared NEAR pool (version 2). I'm still building that idea. But this allows few new opportunities.
  4. We can reduce fees for token-token swaps (currently this is a double of token-near swap fee - as in the Uniswap). (currently this is a double of token-near swap fee - as in the Uniswap).

The single pool is already implemented.

robert-zaremba commented 4 years ago

Supporting multi token standard

CLP has it's own token liquidity share token. Let's call it CLPS (Continuous Liquidity Pool Share). The share allows contributors to redeem their contributions with transaction fees.

With all CLPs in one smart-contracts we have essentially a multi token contact.

This contract near-clp could be a prototype for the multi token standard.

robert-zaremba commented 4 years ago

With the governance token boooom taking place in DeFi I analyzed if it's really needed for AMM smart-contracts.

YFI is a governance token. Uniswap doesn't have governance token. IMHO, a good, AMM protocol doesn't need any governance. Market should decide about strategies. If you have better strategy, you modify a smart-contract code, deploy it and let users decide to move the funds. No need for governance tokens.

And in fact I prefer an AMM without governance because I can trust it.

Not every governance token makes sense.

fengkiej commented 4 years ago

@robert-zaremba agreed! I don't think every governance token does makes sense on broader terms.

But I would like to hear your considerations regarding incentive mechanism or liquidity mining scheme to gain early user tractions through the governance token (because yield farming is the hot stuff in DeFi)?

mesozoic-technology commented 4 years ago

Why rust vs assemblyscript?

robert-zaremba commented 4 years ago

There is no discussion about Rust vs AS. Both are good. Here we wanted to use Rust because it's more mature. That being said AS would also work perfectly.

robert-zaremba commented 4 years ago

NEARswap will be on the Hack the Rainbow hackathon! Here is a summary / plan of the next steps we can do there: NEARswap hacks the Rainbow

mattlockyer commented 3 years ago

@robert-zaremba excited to see this! Saw your comments about no gov token. I think that's smart to keep a v1 simple. I would spend more time and effort on making sure that upgradeability is smooth and there's no need for migrations either for orders or liquidity providers, i.e. the new contracts should extend on top of the same data structures and storage as the existing :+1:

robert-zaremba commented 3 years ago

Uniswap introduced a governance token. Most of the AMM have governance token. For me it's really a game. It's ridiculous to see that token like UNI or yearn.finance has market cap bigger than many layer-1 blockchains! Imagine how much resources (work) and innovation is done in the layer-1 vs Uniswap!!

How we can justify that the market cap of yearn.finance is 1bln USD today? For me this is pure speculation, as the governance token doesn't represent a work or future utility power worth 1bln USD!

derevyanayloshadka commented 3 years ago

is it still active?

robert-zaremba commented 3 years ago

This done. NEARswap beta is deployed on the testnet, here is the webapp_with_CDN or other version without CDN Here is a demo video: https://www.youtube.com/watch?v=_3j9yzf1TMg

During last month we added UI support for creating new pools and adding liquidity to the pool. On the smart contract side we are changing a curve algorithm. During the Christmas break we will have more time to publish new version, and then hopefully push to mainnet.

cameron-NEAR commented 3 years ago

Is this bounty completed and paid? If so, can I close it? @ilblackdragon @robert-zaremba

I'm asking this to identify which bounties are currently active and need to be completed.

robert-zaremba commented 3 years ago

Yes. https://siasky.net/AADIHaZZz73figEETkQizv2V7CB7vDh1Jn1Z3STTQsrsUA/

The work continues on a new design and ref-finance.