Tribler / tribler

Privacy enhanced BitTorrent client with P2P content discovery
https://www.tribler.org
GNU General Public License v3.0
4.81k stars 445 forks source link

A Mobile and Generic Asset Exchange using Liquidity Pooling [group 2] #5996

Closed devos50 closed 3 years ago

devos50 commented 3 years ago

This ticket contains the notes for the liquidity pooling project (#5944)

A Mobile and Generic Asset Exchange using Liquidity Pooling

Ever since the introduction of Bitcoin, there has been a proliferation of blockchain-based currencies and applications. Nowadays, the majority of blockchain-based applications orient around decentralized finance (DeFi), an experimental form of finance that enables value transfer and exchange directly between participants, without intermediaries. The number of different DeFi application is quickly growing. Many of these DeFi applications are deployed using smart contract logic, e.g., on Ethereum.

Currently, decentralized exchanges (DEXes) make up a significant part of the DeFi landscape. DEXes enable the trade between different pairs of digital assets, without risks. Some DEXes facilitate trade by having traders create buy and sell orders and automatically execute orders when a trading opportunity arises. Newer DEXes like Uniswap use a different approach to trade assets. In this approach, there is a pool for every pair of assets, and users can deposit assets in these pools. Such users are called Liquidity Providers and are rewarded with special 'share' tokens. Traders can then exchange asset A for B by depositing asset A in the pool, in exchange for asset B.

Existing DEXes using liquidity pooling only allow the trade of assets that are locked to the ecosystem in which the DEX operates. For example, Uniswap can only exchange Ethereum-based assets, significantly limiting the applicability of this approach. Recently, we have introduced an approach to enable generic asset trading using traditional order books (we will share the paper with you at the start of the project). This approach enables the trade of any asset, managed by any ecosystem. Risks are manageable by splitting up a trade into a series of smaller, intermediate payments.

The goal of this project is to engineer a basic and generic DEX, based on Liquidity Pooling. All operations and asset transfers will be recorded on TrustChain, our lightweight distributed ledger. This approach makes it possible to detect fraudulent behavior, specifically stealing assets. You will integrate this application in our Superapp, which already has several decentralized applications integrated and deployed (e.g., for social networking, music streaming, and federated machine learning). Your final demo will show a simple asset exchange between two real cryptocurrencies, e.g., Bitcoin and Ethereum tokens. For simplicity, you may assume that the liquidity pool will be managed by a trusted identity in the network.

anatomy

References:

(image source: https://uniswap.org/docs/v2/protocol-overview/how-uniswap-works/)

synctext commented 3 years ago

Sprint ToDo ideas.

devos50 commented 3 years ago

Meeting notes 15-02-2021:

chrislemaire commented 3 years ago

@devos50 I created a PR to create the one module for our project.

kchong97 commented 3 years ago

Some (possibly useful) links for basic reading:

kchong97 commented 3 years ago

Notes for next meeting:

Future things to look into later on in the project:

vstam1 commented 3 years ago

Links for ethereum wallet:

vstam1 commented 3 years ago

@devos50 How could we get some euro tokens to play with?

devos50 commented 3 years ago

Good question 😁 . @rwblokzijl or @xoriole could you answer/help with this?

rwblokzijl commented 3 years ago

The EuroToken system is currently closed. And since the system is collateralized with real euros, opening it up would expose me to all the laws and regulations that banks are subject to. We're looking into how to open the system up for scientific playing around after our trials, but the tokens would not have any value unless someone else picks up the project.

devos50 commented 3 years ago

@rwblokzijl thanks for your response! Do you have some kind of testnet environment where we can mint EuroTokens without backing collateral?

devos50 commented 3 years ago

Bitcoin added support for compilation with the Android NDK. Taproot implementation can be found here.

devos50 commented 3 years ago

Meeting notes 01-03-2021:

kchong97 commented 3 years ago

The current direction to work towards, the workflow for transferring eurotokens from a liquidity pool will work as follows:

  1. A eurotoken wallet that acts as the eurotoken part of the liquidity will request signatures from all share holders of the pool when it wants to do a transaction (i.e. when a user wants to trade with the pool by sending it bitcoins and expects eurotokens back)
  2. Once the wallet has enough signatures it will perform a transaction as usual with the transfer proposal blocks, but now with additional information about the signatures obtained.
  3. The gateway which usually checks these transactions and creates the checkpoints will now additionally check for the obtained signatures and only create the checkpoint if the signatures obtained are enough.
kchong97 commented 3 years ago

Current progress: Created a new block type on trust chain that allows one to join a liquidity pool on the eurotoken side. One device acts as the liquidity pool, with the list of pool owners that have joined this pool. The other device acts as a user who wants to join the pool.

Next step is to further work this out combining both sides of bitcoin and eurotoken into one workflow.

kchong97 commented 3 years ago

Finished the complete flow of joining a liquidity pool. A user now goes to this screen and sends both bitcoin and eurotokens before they are allowed to send a join pool request. When the liquidity pool receives bitcoins/eurotokens they keep track of this on trustchain, for eurotokens this is done using the regular transfer blocks, for bitcoin an extra block is added to the chain.

When the pool receives a join request, this request is accompanied by two hashes, one for the eurotoken transaction and one for the bitcoin transaction. The liquidity pool will look for the blocks containing the corresponding hashes, if they are found the pool will agree on this join request, if they are not found the pool will reject it.

When testing this, note that it can take quite some time for the bitcoin side to get fully verified.

kchong97 commented 3 years ago

Liquidity Pool

A liquidity pool is simulated using a single device that has both a bitcoin wallet and a eurotoken wallet. This pair of wallet will function as the pool, any user that wants to interact with the pool will need to have the pair of public key for this pool.

Join Pool

To join a liquidity pool a user needs to first provide liquidity. This is done by first transferring both eurotokens and bitcoins to the corresponding wallets of the liquidity pool. The hashes for both transactions will need to be remembered for the next step. The liquidity pool will handle a eurotoken transfer as usual, a bitcoin transaction will have an additional step, where the pool puts the hash and amount transferred on their own trustchain.

Once both transactions have been completed, the user can send a new proposal block to the pool using the public key of the pool's eurotoken wallet (i.e. their Ipv8 publickey). Once the pool receives this block, it will need to look up corresponding blocks containing these hashes. If found it can accept the request to join the liquidity pool, otherwise it will reject it.

Exchanging Funds

To trade with the liquidity pool, you need to first transfer some bitcoin/eurotokens and send trade proposal to the pool using the public key of the pool's eurotoken wallet (i.e. their Ipv8 publickey). This proposal block will include the hash of the transaction, the direction of the trade, as well as the address where you want to receive the exchanged funds. The liquidity pool will handle a eurotoken transfer as usual, a bitcoin transaction will have an additional step, where the pool puts the hash and amount transferred on their own trustchain. When the liquidity pool gets a trade proposal, they will look up the block with the corresponding hash in either the bitcoin/eurotoken blocks. If such a block is found, the pool will send an equivalent amount of funds of the opposite type to the address included in the proposal block.

As the liquidity pool can have multiple owners by this point, there should be some consensus before sending money from the pool. For this reason, the pool will need to collect signatures from the other pool owners. These signatures will then need to be checked by the gateway.

synctext commented 3 years ago
mmelas commented 3 years ago

Finished the Trading part. (Not tested on physical devices yet) Left device acts as the liquidity provider and right one as the trader. The first bitcoin wallet is the liquidity wallet. After the trader choses a currency and an amount to trade, he presses convert and cannot trade until the transaction has been made. The process after the trader presses convert is :

Screenshot 2021-03-22 at 7 20 38 PM Screenshot 2021-03-22 at 7 21 06 PM Screenshot 2021-03-22 at 8 03 19 PM
devos50 commented 3 years ago

Meeting notes 22-03-2021:

For next sprint: E2E demo of a BTC/EuroToken trade, if there are no unforeseen difficulties.

chrislemaire commented 3 years ago

We got a personal Eurotoken gateway up and running for testing purposes only. The gateway in the centralized transaction verification, and money creation and burning server for Eurotoken. The test gateway will run during the rest of the project under this address on a cheap machine.

For this, we needed to create a stub bank implementation on the gateway so that it would correctly approve creation of money. To create money for personal testing use, you can do the following:

  1. [GW] Go to the Exchange page
  2. [GW] Enter an amount in the first box and hit enter or the Convert button
  3. [GW] No click "Connect to gateway"
  4. [TC] In the app, remove all previous gateways under Eurotoken > Manage Gateways by holding the entry and tapping Delete.
  5. [TC] Now go to the Exchange tab and click Scan qr code to scan the code in your browser
  6. [TC] Make sure to save the gateway as your preferred gateway next and click "Connect"
  7. [GW] Finally, in the gateway, click "Select payment method", then "Pay with Tikkie", then "Waiting for payment", and then "Payment complete"

chrislemaire commented 3 years ago

@devos50

So we've (me and @vstam1) looked into implementing multi-sig transactions for Eurotoken. We found that it might be possible to add a multi signature transfer block to the Eurotoken gateway, but it would add no extra security if the gateway is unaware of the identities of the liquidity providers. This means the liquidity pool owner would be able to make up a few signatures (from generated keypairs) and send them along with their transfer. So the element of trust in this interaction is solely placed on the liquidity pool owner.

Would it be alright to trust the liquidity pool owner with this task of collecting and checking signatures? If so, we will also not need to make a special transfer block and implement this on the gateway side, as we can keep using the old one, as we can do the signature check fully at the liquidity pool owner side. If not, we can come up with a proposal for how to do this securely inside the gateway but might very well not have the time to implement a working prototype.

devos50 commented 3 years ago

it would add no extra security if the gateway is unaware of the identities of the liquidity providers.

What do you specifically mean by this? Does the gateway need to know the identities (public/private keypair) that are part of a particular liquidity pool? If so, that information is recorded on TrustChain upon joining a particular pool right?

chrislemaire commented 3 years ago

Yeah correct, it would need to know who is part of a particular pool-to-user transaction (which should be everyone that joined the pool before that transaction). The information should be available, but might be out of scope to retrieve on the gateway. We were thinking this would limit the genericness of a multi-sig implementation for eurotoken, making it only usable for liquidity pools. Thus we didn't think the gateway would be the right place for it, instead opting to put that same responsibility in the superapp. If we do implement it on the gateway, it would shift the focus of the gateway and also only be the same check that already happens at the pool owner.

devos50 commented 3 years ago

So the problem is that implementing the envisioned solution would create a hard dependency on the gateway, thus limiting genericness. This is not a very nice solution indeed.

Thus we didn't think the gateway would be the right place for it, instead opting to put that same responsibility in the superapp. If we do implement it on the gateway, it would shift the focus of the gateway and also only be the same check that already happens at the pool owner.

I agree. How much (additional) time would it cost to implement this functionality in a more generic way?

chrislemaire commented 3 years ago

Exactly! Yeah so this hard dependency is not preferred indeed.

An alternative, more generic approach might be possible, but we're having trouble coming up with a truly distributed solution. One approach could be as follows: on the gateway, the following blocks are processed:

  1. A transaction proposal block from the wallet owner with the public keys of those that can sign the transaction and the number that need to sign
  2. Any number of signature blocks by the signers
  3. A ready-to-send block or a verification block that the money is transferred once the n-out-of-m signatures.

In this solution the responsibilities are divided over wallet owner and gateway, but the wallet is not really owned by the n out of m people signing. Additionally, the wallet owner can then still come up with any number of people that need to sign or can sign. I think this might not be enough for a true proof of concept of multi-sig transactions as it doesn't solve these essential problems.

An alternative approach would need to consider seriously rewriting Eurotoken to no longer be strongly bound by the one peer hardwired in IPV8. I am not sure how this would work out, but I don't think we will have enough time to fully explore the options there.

Do you have any suggestions from this?

devos50 commented 3 years ago

I see. For now, I would target the easier (gateway-oriented) approach, even though it is not the optimal one. Document the limitations, shortcomings, and suggestions for further engineering efforts. This might be interesting content for a master thesis. At least then you have something to show at the end of the project.

I think this might not be enough for a true proof of concept of multi-sig transactions as it doesn't solve these essential problems.

We don't expect you to solve all identified problems; there are quite a few challenges left (e.g., security and economic ones). Building a fully functional, low-risk liquidity pool is challenging. As long as you can explain your design decisions, this is fine for me.

We can also discuss these matters further on Monday.

kchong97 commented 3 years ago
Joining Trading
ezgif-7-cf79192113a7 ezgif-7-6551d5dfef86

EDIT: Fixed the gif

kchong97 commented 3 years ago
Joining Trading
joining trading

The apk can be downloaded here (this is the last build also found in the aritfacts in the PR)

The readme can be found here

synctext commented 3 years ago
devos50 commented 3 years ago

Besides the stuff we already discussed in the meeting today, I have the following comments:

kchong97 commented 3 years ago

apk readme

synctext commented 3 years ago

"Hacky spaghetti" level of code in Superapp. At least it did not get worse with this pending PR

devos50 commented 3 years ago

Congratulations on passing the course 🎉 . Please finish the PR 👍

Final deliverables:

xoriole commented 3 years ago

https://github.com/Tribler/trustchain-superapp/pull/75 PR is merged, closing the issue