Trust-less liquidity pool

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.

Creon, I have about ~2 USD worth of BTC on poloniex but the client.py keeps showing

2015/03/08-16:01:37 INFO: Balance: 0.00000000 Exchange: poloniex Orders: {}

Very interesting, thanks for trying. You are CKYYKLJZ-… correct? It continuously says that it is not able to validate your requests. Can you just keep it running for a while?

There is also a _shift variable in the exchange class, which gets added to the nonce.

1 Like

that’s correct. btw: it’s 0.00723225 BTC exactly.

I pulled the software from git and ran client.py. I got some errors at first, because it had trouble writing logfiles. “mkdir logs” in the python folder did it for me.

the users.dat should meet your requirements.

Edit: Are withdraw rights necessary for the API key?

No in this state tier 3 liquidity has to be managed manually. I should have mentioned that you need to create the logs dir, git unfortunately doesn’t allow me to commit an empty folder.

I just saw that most of the requests you are sending are getting validated but somehow the data is not updated. I’ll look into it, thanks again for testing it.

Alright. I’ll keep it running for a few hours.

Could you restart your client? It just gives up right now if the connection gets refused and I had to restart the server. I am now connected with two clients and both are receiving credits. Now I am also printing the API server response and in all cases of a reject the response was that the nonce is wrong.

Can you also check your system time? Is it synced to an NTP? I can imagine that it is crucial that the server and client clocks don’t deviate much.

sudo ntpdate ntp3.fau.de
8 Mar 16:59:17 ntpdate[25407]: step time server 131.188.3.223 offset 2.428427 sec

Thanks. Its really strange. All your orders get validated, but it just seems that your NuBot is not placing any order. Can you verify in the NuBot logs (they are stored in the logs folder of the nubot subfolder) or on the exchange that the NuBot indeed places some orders? Maybe 2 NBT are not enough for the NuBot to work with.

The server only considers Tier 1 liquidity right now. In future a similar system can be implemented that allows users to send getbalance requests such that the server can verify Tier 2 liquidity.

I have never worked with NuBot so far, but I will give it a try.

Its probably sufficient to just to a

grep "Submit order" nubot/logs/*/log.csv