Trust-less liquidity pool

Trust-less liquidity pool###

In a nutshell: You run a program that places NBT and BTC orders on an exchange at 1 USD with a very small spread. The program will send proofs of those orders to a server which in turn pays you interest in form of NuBits.

###Getting started###

In order to participate in the pool beta you need to perform the following steps:

  1. Create a new exchange account at Bitcoin.co.id, BTER, CCEDK, or Poloniex and provide it with some funds
  2. Create an API key on the exchange which will provide you with two values, an api-key and an api-secret
  3. Download the client beta software from here: https://github.com/creon-nu/nu-pool/releases/latest
  4. Extract the archive and switch to the python subfolder you will find within the extracted directory.
  5. Create a file called users.dat (or on Windows optionally users.txt) in the following format:
    payout-nubits-address btc exchange api-key api-secret bid-interest ask-interest
    where payout-nubits-address is the NBT address you want to receive payouts on, exchange corresponds to the exchange name (bitcoincoid, bter, ccedk, or poloniex), and api-key and api-secret are the values obtained in step 2. The last two numbers are the minimal daily interest rates in percent (1% = 1.0) you want to get for the buy and sell side of the market respectively.
    You can add several lines in this file for different exchanges!
    Example:
    BQRKF4X8gFLyHGVeym8tuff57PcJczYPVg btc poloniex 85BQTQG1-N3D3PFKX-YUNIHIO1-WQCWTRER 1234abc 0.8 1.2
    Important: Please do not add a payout address which is not an NBT address. The server is only able to process payouts in NBT.
  6. Run the client:
  • Linux:
    Make sure you have python installed (should be the case):
    sudo apt-get install python
    Run the client in a terminal from the python folder:
    ./client.py 104.245.36.10:3333
  • Mac:
    @Ben confirmed that you can proceed as on Linux.
  • Windows: (I tested this on Windows 8, would be nice to get some feedback if this works for you)
    Download and install Python for Windows:
    https://www.python.org/downloads/release/python-279
    Go into the python folder of the archive extracted in step 4
    Create a new text file called users and add your exchange information
    Double click the beta.bat file to start the client

Let me know if you have any issues with the installation. After starting a correctly configured client you should see some output like this:

INFO: poloniex - balance: 0.00039520 rate 0.33% efficiency: 100.00% rejects: 0 missing: 0 - btc - ask: 0.6278 x 1.00%, 1.4946 x 0.66%, 3.6106 x 0.00% - 85BQTQG1-N3D3PFKX-YUNIHIO1-XXXXXXX

The balance shows the amount of unpaid NBT. Efficiency describes how many of your proofs were able to be credited. The client tries to auto adjust in the case that the efficiency drops below 80%. If you have continuously problems with low efficiency values, then please send me a message.

During the beta run the server pays 7.75% per month (0.25% per day) for each exchange and order side up to 200 NBT liquidity. Click here for more information on the payed beta. [Beta Phase 1 complete]

During phase 2 of the beta the pool will pay up to 1% per day for each exchange and order side up to 50 NBT. [Beta Phase 2 complete, see posts for conclusions]

###FAQ###

Can the pool operator steal my money?

No! Cryptography allows the user proof to the server that the orders are placed without giving it access to the funds. The data sent to the server only allows to view the current order status.

So I cannot lose money?

You can lose money if people are successfully hedging against you or if the exchange gets hacked. It is this risk what you are getting payed for. There is a lot of information in this forum on this topic and there are ways to transform the hedging risk into a calculable fee. Note that users are fully responsible for their funds used in the operation.

Is this legal?

The server will be ensured to run as a completely legal operation. The legal situation regarding participation depends on your home country. It is often considered similar to Bitcoin mining, but this doesn’t have to be the case. (I am not able to give any legal advice at all regarding this, so please consult an expert if you are not sure).

Do I need a good computer to run the client?

No, you only require a stable internet connection and Python.

Is there a minimum or maximum amount of liquidity I can provide?

There is no minimum. However, the server only pays interest up to a certain amount of liquidity, which can be seen on the server page.

Why is my client only placing very small orders although I have more funds on the exchange?

This means that other participant’s are offering a better minimal interest rate and therefore will be prioritized when liquidity is compensated up to the target value (see question above). If your client sees that the own liquidity will not be compensated then it will remove those funds. If you are not planning to reduce your minimal interest rate, then you may want to consider removing some of these funds from the exchange to reduce your risk.


I thought it might be appropriate to update the original post for newcomers. Here is the text originally posted:

Original Post (Idea)

The Nu Lagoon proposed by @henry is a great concept and allows really everyone who is able to use a wallet to participate. In total I see two major difficulties for liquidity providers (besides having the funds available):

  1. Running the NuBot, which essentially breaks down to three tasks that have to be accomplished:
    1.1 Being able to run a java program on a computer
    1.2 Make an exchange account and create an API access
    1.3 Configure the NuBot json files

  2. The custodial grant, which means
    2.1 Write a proposal
    2.2 Advertise the proposal to some extend
    2.3 Be available to answer questions and to provide updates

People will differently weight these two main points - I personally experience the second one as more “work” than the first one. So while @henry’s pool idea provides a way to completely avoid both aspects, I’d like to suggest a pool idea that only eliminates (2) for the customers and makes (1) easier.

Background for non-nerds: The communication with an exchange API is very similar to the public / private key system you know from cryptocurrencies (here its usually called API key and API secret). This means you proof to the exchange that you are eligible to access the data by signing the request with a private key and to send the request together with the public key. Each request furthermore contains a “nounce”, which usually has to be set to the current time.

The idea is to take advantage of this system.

Participants

  1. Register at the pool operator (bitmessage/website/whatever) by providing your API key and an NBT payout address
  2. Run the NuBot (with multiple-custodians=true to sync the walls)
  3. Create requests to show your orders on the exchange, sign them with the API secret, and send them to the pool operator

Pool Operator

  1. Get a custodial grant
  2. Run a server that receives requests from users
  3. Validate incoming orders by calling the exchange API
  4. Send a payout to the NBT address given in the registration of the corresponding API key
  5. Submit sum of orders as liquidity

So the pool operator here doesn’t even need to run a NuBot, while all participants do. Also note that the configuration on the side of the participants is extremely easy, because they don’t need a Nu daemon and also know the exchange. The pool operator could even provide a fully functional json config file and the user only needs to provide and API key and the corresponding secret.

Note that with this approach the participants never have to trust the pool operator (the only thing the pool operator could do is not sending the payout). Some software would be required, but nothing complicated. What do you think?

7 Likes

I’m missing what the point of the operator is in this scheme. That said I think a decentralized pool will compliment the Nu Lagoon. Not everyone has an always on computer to run a bot. Getting an aws instance going is nontrivial and costs money. Therefore people who have those resources would be better served using the decentralized pool where as everyone else can still use the lagoon. If setting up an aws instance to run a bot ever becomes as easy as signing up for email then that would be ideal.

1 Like

Its the only one with the custodian address and who is able to submit liquidity.

You don’t have to. You get payed for valid signed orders you send to the pool operator (similar to shares in mining). You can run the bot for 5 minutes, 3 hours or 24 hours if you like.

2 Likes

But you do need a computer to be on? If it’s not computationally expensive would it be a good idea to develop a phone app?

That’s a nice idea. Its not computational expensive, however a stable connection is crucial and an interruption can make you lose money (i.e. if the price changes and you are not able to adjust your orders).

good proposal.

I am interested in learning more on the “prepared request”.

While there normally is a decent level of coherence on how exchanges use the nonce parameter, that is not always the case, @woolly_sammoth can back me up on this.

Some APIs are more restrictive and require the nonce to be unique while other doesn’t. Some other also require the nonce to be in a 10 seconds time window within the server timestamp. Some other uses a shifting window etc.

I guess that here that by “send” you mean “immediately submit an HTTP request to pool operator’s server using a customised client” . If that’s the case, the server should also promptly send the request to the exchange before it expires. That would be feasible, however this three-way paradigm for calling an external API requires some decent level of effort to handle errors and send them back to the original sender and handle other edge cases (floods, ddos, MITM, connectivity problems )…

You do. You can buy a raspberry pi, also the old model works and leave in on 24/7 with minimum energy consumption. I am planning to prepare a wheezy image ready-to-go so you just have to insert the SD card, plug electricity and control the bot via SSH.

Alternatively we can also prepare images to load an amazon EC2 instance (or similar) with 2 clicks. That way you have a 24/7 server up and running for less than 10$ a month and require very little configuration effort.

Porting will not be too hard, but I am not sure that a 24/7 service should be run by a mobile phone app. I see in the future a mobile app that checks the status of a remote nubot pulling info via API, and allowing the user to have some minimal interaction .

2 Likes

I didn’t completely understand how the system worked at that time. The idea i had in my head was the operator sends out requests to participants for liquidity. The participants then send a reply with proof that have placed the liquidity. I’m not sure if this is possible or feasible but does allow for mobile use.

Yes, that is right. Also not all are using the hmac signature system. The whole idea could first be applied on an exchange where all conditions are satisfied (like poloniex, or in future bittrex).

The program could act as standalone and the NuBot does not need to be modified. We would only need a program that opens a connection to the pool operator and then frequently creates the order http requests in order to send them to the operator. I claim its less than a 100 lines of python code :slight_smile:

The server logic is not much more complicated. Of course it would be nice if every error is passed back to the customer, but it would only help for debugging purpose.

I am just worried about people cheating about how long their orders have been up . But that might be irrelevant. Another question.

This is not clear to me. If the liquidity never leavers the user’s account, how can the pool operator :

  1. understand when there is a profit that requires dividend payment.
  2. compute dividends : can you explain and also illustrate with an example how is this computed? what is it taken into account?
  3. what funds are used to pay dividends, provided that pool operators does not have access to the liquidity funds?
1 Like

Yes that is a valid concern. But since the client does not actually need to do the API call, we can say that a payout is credited iff the client sent 12 HTTP request within the last 60 seconds with at least 3 seconds in between of two requests.
On an exchange with timestamp based nonce the client could even send a bunch of valid requests for every 5 second time step in the next minute. The server then can randomly evaluate those orders (as much as the exchange API allows) and ban misbehaving users.

This is an example, the numbers are made up. Let’s say the pool operator trusts the shareholders. The next step is that he creates a custodian grant about 1 NBT offering a dynamic liquidity for one month with 10% fee that will be paid out after the operation. If the grant passes it provides the pool operator with a custodian address and the possibility to submit liquidity.

The pool operator now announces publicly that he pays 5% per month for sending signed order requests [at the right price] on a particular exchange (registration is required to get the NBT address). As mentioned above, if you can proof liquidity for 60 seconds then the pool operator will pay you 5% / (246031) NBT, out of the pool operators pocket in our scenario, and submits your liquidity to the network. After the term passed, the pool operator will provide the shareholders with the liquidity statistics and demand the 10% initially asked for.

Of course shareholders could provide the pool operator with more initial money that will be subtracted in the final grant - that’s a trust question.

2 Likes

This is a great idea, and given the knowledge @creon displays in his posts, chances are high he can implement the design.

I would still encourage others such as @henry, who is pursuing a solution that is easier and less demanding of pool participants. The advantage of @creon’s design is pool participants never hand funds over to a pool operator, minimizing counterparty risk.

@creon would this solution completely exclude tier 2 and 3 liquidity?

I could see this as providing a large portion of tier 1 liquidity in a somewhat unstable quantity (pool participants can remove funds at any moment) while solutions like what @henry has proposed would provide mostly tier 3 liquidity from more casual users in more stable quantities. They can work together quite nicely.

Pools providing tier 1 liquidity should be paid more than pools focused on tier 3 liquidity because of the difference in risk and utility.

Rules would need to be made and enforced by the pool about what spreads were acceptable. You may also need rules to provide incentive to balance buy and sell walls as well as balancing the liquidity between exchanges.

2 Likes

Tier 2 could be reported in a similar way by the clients and validated by the server. But since the clients don’t have the obligation to use it, the pool operator should only pay a small interest rate and only until a certain amount of Tier 2 liquidity was reached.

Tier 3 is completely up to the client and only tier 1 (and maybe tier 2) liquidity will be compensated. If a market movements requires to rebalance in order to get the same interest in the end, then this is only the clients concern.

In fact I am thinking about implementing the client and server side and if it is successful and if there is enough interest from the shareholders then I can even imagine to provide this service by myself (or of course help someone else to set it up).

Yes I believe this will be the case, especially as long as the pool is unpopular. However, just as the pool operator, the shareholders will pay for the liquidity provided and not more, so there is no financial risk for the shareholders.

1 Like

This is a very nice idea. I think that both this style of pool and the ‘Nu Lagoon’ model have good futures in the Nu landscape.

My main concern is that the latency in requests added by the extra hop from NuBot > Server > Exchange could mean that orders are dropped, not actioned correctly or not actioned in time. I think this is a small risk but I think there is a solution that could make it irrelevant.
Some exchanges allow api keys to be limited to their actions. I think the pool would work just as well if the customers ran NuBot but allowed it to make the requests directly to the exchange. The Pool operator runs software that only has access to customer API Keys that can read account details without being able to action trades or cancel orders. That means that the available liquidity can still be calculated and reported through the Custodial Address, and even less trust has to be put in the Pool Operator by the Pool customers.
(I just checked and it seems that of our suporting, or potentially supporting, exchanges only Bittrex offer this limiting of API actions from their web interface. Others may be able to offer the functionality in the back ground though.)

There are updates coming for NuBot to allow for push notifications of price changes which will cause Nubot to shift the walls (in the current system, Nubot pulls in data feeds, performs calculations and actions the wall shifts itself). I can see this pool model working well with that change as the Pool operator can dicate when to move the walls and what price to set them to.

I also hope that the extra-hop will not cause too much delay. I’ll do some experiments over the weekend and report how much of a problem this is.

This would be the perfect scenario. I remember excoin had it (but their API was kind of special in many ways).

So you say the pool operator should trigger a wall shift of the clients? I was hoping that the NTP synchronization by using multiple-custodians=true would be sufficient to ensure that everyone uses the same price.

The multiple custodians setting with NTP is what will work for now.
We are in the process of bulding a server to calculate a ‘Nu’ price which then pushes the price to NuBots using web sockets. It should reduce the amount of time where orders have been removed and staty removed until the next window or orders don;t get placed due to price feed issues.
As a standard opperation you wouldn’t notice much difference in the behaviour of NuBot. However, the new method gives the pool operator then option of setting up their own push server setting the price instead of using the standard Nu server

1 Like

I started a little something:

Its Python so far, but in the end I am planning to implement the server logic in PHP and the client in Java. You can see that implementing a compatible client is extremely easy and can be accomplished in very few lines in every modern programming language. The server code is a little bit hacky, i’ll try to clean it up later.

Client

The client reads a file called users.dat which contains one login per line in the form:

payout-address units exchange api-key api-secret

e.g.

BQRKF4X8gFLyHGVeym8tuff57PcJczYPVg BTC poloniex 85BQTQG1-N3D3PFKX-YUNIHIO1-WQCWTRER 1234abc

Afterwards you can call the client by providing the server you want to connect to, e.g.:

./client.py 104.245.36.10:2019

(this is in fact a running server on a VPS and you can test with it as much as you want)

The client will internally start NuBots for each key and currency, configure them automatically, and guard their existence.

Server

You will need a running nud with all customized parameters specified in the default config file in order to make payouts, but this is currently disabled. To start the server just run

./server.py

and everything should work. On the top of the server.py file you can adjust several parameters like:

  • The supported exchanges, pairs, and corresponding interest rate curves and maximum liquidity
  • How often per minute requests should be validated
  • How much the price of an order may deviate from the price of the ticker (right now its only bitfinex)

The payout is calculated at each validation point, and interest is payed up to a maximum cap, controlled by a soft thresholding function (inverse logistic sigmoid). This ensures that the maximum liquidity by an operation, and therefore the fee for the shareholders, is not unbounded. The order ID determines the order in which competing client liquidity is considered when the interest is calculated.

The server further supports a very simple public JSON API (which I am planning to extent). So for example for the key above you can query some statistics by simply opening:

http://104.245.36.10:2019/85BQTQG1-N3D3PFKX-YUNIHIO1-WQCWTRER

Experiments

I am using a sampling rate of 12 validations per minute. This means every 5 seconds the server checks if the clients sent a new order request and validates them correspondingly. Experiments on localhost always lead to 12 / 12 accepted requests.
My VPS is not very response from my location, and pings of more than 100 ms are normal. Here it happens sometimes that one request cannot be validated, maybe in 1 of 12 cases. I think this can still be improved by cheating a little bit with the nonce on the client side.

In total the experiments are extremely encouraging! It would be great if someone could give it a try (with very small funds of course) to see how easy it is :smile:

7 Likes

Good job! Will try it soon!

This looks a bit of magic, in the sense that it will configure the bot using a lot of defaults parameters. I still wish there is a way to manually prepare/change configs.

Can you expand a bit on :point_up_2:

thanks again!

This sounds interesting but I am not exactly sure how to try. I clicked on the 104.24… link but got server not found error.

I won’t mind if you keep it python forever. :smile: I always wished there is a pure python PPC and NU wallet.

Edit: Successfully connected to @creon’s server. Monitoring the client now.

Yes that would be a nice if those values can be overwritten. However, the default user ideally should not have to do it.

Regarding the order ID: Let’s say I am paying interest up a liquidity of 100 NBT and person A provides 75 NBT and person B also wants to provide 75 NBT. Both will place their order at the current price and submit their requests, and lets say A is a bit faster and got the order ID 1001 and B got 1006. However, since I am only paying 100 NBT and not 150 NBT, I am paying interest for A’s 75 NBT first and afterwards only for 25 NBT of B’s liquidity, so A will get the full interest rate while B only gets a third.

Yes I was asleep and the server shut down. It is up again, sorry for that.