(Part 7) Decentralized Exchange - Fetching the sell orders and how to actually use the exchange(PT 7)

in #utopian-io6 years ago

Repository

https://github.com/igormuba/DEX/blob/master/Class7/exchange.sol

What Will I Learn?

  • Implement the fetch logic to the sell book
  • How to connect the token to the exchange
  • Transferring(tokens and ETH) and placing orders

Requirements

  • Internet connection.
  • Code editor.
  • Browser.

Difficulty

  • Advanced.

Tutorial Contents

On the previous tutorial I have explained more in depth how the function to retrieve a book works, it was the connection between the structures we have built for the token and books to the data structures (queues and linked lists) for those structs. We have learned to manipulate the data structures and fetch.

On this tutorial, I will show how can you "spin" that function so it can work on the sell book, that is on the "opposite side" of the trading volume.

Also, so far, I have used mind maps and lots of examples so you could understand how do those books work, but after implementing the function to fetch the sell book, we will have enough code to do some "real world" (on a simulated environment, if that makes sense) testing. I recommend you to see the mindmaps from the previous class, so you can understand in theory what we will be testing in practice.

The function to see the sell book

I will go over this as briefly as possible because the theory and explanation of the logic were explained on the previous tutorial, this is just the implementation for the opposite book, the sell one. Also, I actually recommend you to try first to do this by yourself based on the previous class, if you can't, you can follow this tutorial to see the answer.

function getSellOrders(address _token) public view returns(uint[] memory, uint[] memory){
//code logic goes here
}

The function takes an address, which will be used to fetch a token from the token books we have, and it returns two arrays, one for the prices and one for the volumes. The arrays are in order so that the first position on both represents the same token.

Loading the token

Remember we had a mapping listing addresses to token markets. To make it easier to work with the token, we will load it into a variable so it is easier to work with it. Else we would need to do tokenList[_token]. Here is how it is loaded and where we can use the loaded token:

//loading token into the variable loadedToken
Token storage loadedToken = tokenList[_token];
//prices array to be returned later
uint[] memory ordersPrices = new uint[](loadedToken.amountSellPrice);
//volume array to be returned later
uint[] memory ordersvolumes = new uint[](loadedToken.amountSellPrice);

The two variables below are the arrays we will send back, and they have the size of the amount of sell orders on the book. Notice that for now, the difference form the fetch function on the other book is that we are working with the sell books and prices.

The loop to fill the prices

There are a few variables to work with to fill the prices array, check them below, and then what do they do:

//loads the lowest sell price
uint sellPrice = loadedToken.minSellPrice;
//starts the counter of loops
uint counter = 0;
//if the token has sell orders (not an empty book)
if (loadedToken.minSellPrice>0){
//do this loop until we reache the max price
while(sellPrice<loadedToken.maxSellPrice){
//the item of the array on the position "counter" stores the current price of the loop
ordersPrices[counter] = sellPrice;

The above is the part that in fact iterates through the loop.

The loop to fill the volume

This is a loop inside a loop, and goes right below the previous piece of code, inside the loop for prices:

//volume of sell orders at this price
uint priceVolume = 0;
//pointer to keep track if we finished iterating on this prices sell orders
uint offerPointer = loadedToken.sellBook[sellPrice].offerPointer;
//while the pointer is smaller than the size of the queue of orders at this price
    while(offerPointer <loadedToken.sellBook[sellPrice].offerLength){
//we add the volume of the current order in the queue to the volume
        priceVolume += loadedToken.sellBook[sellPrice].offers[offerPointer].amount;
//and go to the next order in the queu on this price
        offerPointer++;
    }

Storing the calculated data

Just after you close the inner loop, for volume, you do:

ordersvolumes[counter]=priceVolume;
if (sellPrice==loadedToken.sellBook[sellPrice].higherPrice){
    break;
}else{
    sellPrice=loadedToken.sellBook[sellPrice].higherPrice;
}
counter++;

That will save the volume, and exit the outer loop if we reach the end of the linked list of prices (when the higher price equals the current price).

And to return, we simply:

return(ordersPrices, ordersvolumes);

All together

I didn't go much in details because the logic is explained in the previous tutorial, so, I have recommended you to read the previous and try to do the same for the selling side. Here is the "answer", that was built on the previous sections of this tutorial, and how everything looks on the selling side after the adjustments:

    function getSellOrders(address _token) public view returns(uint[] memory, uint[] memory){
        Token storage loadedToken = tokenList[_token];
        uint[] memory ordersPrices = new uint[](loadedToken.amountSellPrice);
        uint[] memory ordersvolumes = new uint[](loadedToken.amountSellPrice);
        
        uint sellPrice = loadedToken.minSellPrice;
        uint counter = 0;
        
        if (loadedToken.minSellPrice>0){
            while(sellPrice<loadedToken.maxSellPrice){
                ordersPrices[counter] = sellPrice;
                uint priceVolume = 0;
                uint offerPointer = loadedToken.sellBook[sellPrice].offerPointer;
                
                while(offerPointer <loadedToken.sellBook[sellPrice].offerLength){
                    priceVolume += loadedToken.sellBook[sellPrice].offers[offerPointer].amount;
                    offerPointer++;
                }
                ordersvolumes[counter]=priceVolume;
                if (sellPrice==loadedToken.sellBook[sellPrice].higherPrice){
                    break;
                }else{
                    sellPrice=loadedToken.sellBook[sellPrice].higherPrice;
                }
                counter++;
            }
        }
        return(ordersPrices, ordersvolumes);
    }

Adding a token to the exchange

Now, finally, enough of theory and building, time to see it working in practice. For this, I will use a simple ERC20 token, we have covered many patterns to develop a fungible token, so I won't cover that here, though you can find an example on my github.

Note that I am doing this in a simulated environment, not with real ETH or tokens, just to test how the exchange works so far.

First, this is to deploy the exchange and the ERC20 token:
image.png

On the token contract, my account, as the creator, has a balance of 100 tokens. Before I can deposit to the exchange, I allow it to spend form my account on the ERC20 contract:
image.png

Then, on the exchange, I call the deposit function, which uses the API to call the "transfer from" function form the ERC20 contract, and also I send ETH to it using the fallback function.

Now, I am placing a couple of sell orders with different volumes and at different prices:
image.png

If I get the prices, they are correctly fetched in order:
image.png

The above means that there is 1 token to sell at the price of 20 and 1 to buy at the price of 10. There are 2 tokens to sell at 21 and 2 to buy at 11, and so on. The array will grow as new tokens are added, and the front end application should deal with that data.

Curriculum

Latest tutorial of the series:

First tutorial of the series:

Beneficiaries

This post has as beneficiaries

using the SteemPeak beneficiary tool

Captura de Tela 20190122 às 16.07.11.png

Sort:  

Thank you for your contribution @igormuba.
After analyzing your tutorial we suggest the following:

Excellent tutorial and very well written and structured. I really like your tutorials!
Keep up the good work.

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Chat with us on Discord.

[utopian-moderator]

Thank you for your review, @portugalcoin! Keep up the good work!

Hi @igormuba!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server

Hey, @igormuba!

Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

Coin Marketplace

STEEM 0.17
TRX 0.15
JST 0.028
BTC 59653.51
ETH 2353.20
USDT 1.00
SBD 2.47