Project - DEX Final Code

hey @thecil. thank you so much for that. Ohh never would have though about trading vie widgets. Gonna look into these thanks sm.

Evan

1 Like

Hi,

Here is the link for my DEX project: https://github.com/mihirf/Decentralized-Exchange

I found the project fairly complex and a good exercise for improving my Solidity skills. I will continue to improve my solution by working on the market order function to make it efficient and add proper commenting. Most importantly, I would like to thank Filip for this amazing course!

3 Likes

Hey guys,

here is the code of my DEX project:
https://github.com/cpascoli/simple-dex

I added the following improvements, let me know what you think:

1) Optimised market order execution that does not depend on the size of the order book

I thought of a simple solution to the problem of this double loop that requires to iterate over the full orderbook to keep it sorted when filled limit orders are removed.
You just need to keep the buy orders sorted in ascending price order and the sell orders sorted in descending price order. This way filled orders are always at the end of the array and can be simply popped out without having to shift the rest of the order array.
You can check the code here.

2) Solved issue with trade execution when a user had withdrawn tokens/eth from their balance after creating a limit order.

In the original design, there was no guarantee that a trade could be successfully executed if an account had withdrawn his tokens/eth after creating a limit order.
I solved this by introducing a separate ā€œreservedBalancesā€ mapping to holds tokens involved in limit orders. When a limit order is added to the order book, the tokens/eth required to execute the limit order are moved to this separate balance and cannot be withdrawn. Cancelling the limit orders before itā€™s executed should allow to recover these funds.

3) Simple order history
I added an order history array to keep track of market and limit orders that were executed . Itā€™s also useful for tests to access market and limit orders that are removed from the the orderbook.

4) Improved tests
I put quite a bit of efforts into testing the dex functions. I especially wanted to avoid dependencies between tests so I added some functionality to reset the state of the dex before executing each test which is called in the beforeEach test block.
I also added this test to ensure partially filled limit orders are processed correctly by future market orders.
Initially I had missed that, for partially filled limit orders, only the amount still available to be filled should be used to fill the market order.

I really enjoyed this project and want to thank @filip for the great videos!

1 Like

Hello, I have a question when deploying into the test net. When I enter one of my accounts into the ropsten ethereum faucet first it showed me an error saying invalid address. I tried again then thatā€™s when it said you are greylisted for another 0 hours and 0 minutes. Iā€™ve also tried different accounts and I receive the same message. Could it perhaps be since Iā€™m using the moralis accounts its been used to many times already?

1 Like

hey @cecilia funny enough i just went to that faucet website to check for myself and i recieved the same message. It must be some sort of technical issue on their end. Strange message alright here are some other faucets. i reccomend this one as you can request 100 ether, however for this one you will need a bit in your wallet already to cover the tx cost.

https://faucet.metamask.io/

here is another one gives 5 ether
https://faucet.dimensions.network/

2 Likes

Hello,

Here is my code: https://github.com/nutrina/dex
It is differs a bit from Filips version, I have used another sorting algorithm.

There are also further things that can be improved:

  • events that are emitted
  • for limit orders with the same price it would make sense to fill them in the order they where inserted
  • problem: it is possible to withdraw funds after limit order was created -> this is not a critical issue, as it does not allow one to exploit the dex and steal funds (at least not that I can see any way), but still it is not that nice

Gerald

1 Like

hey @nutrina great that you finished the DEX. This is actually a bad explot with the balances. It could be solved easily though in a variety of ways. Off the top of my head you could make a seperate balance mapping called reservedBalances or pendingBalances or something that holds the limit order amount for a specific user you would increment this balance each time a user makes their limit order initially. Then in the wiithdraw function you could only allow the user to withdraw their an amount equal to balances[msg.sender][ticker] - reserverdBlanaces[msg.sender][ticker].

So if the user has no pending limit orders then reservedBalances will always be zero so they can withdraw their full balance. However if they have one or multiple limit orders then they will only be able to withdraw the difference in value. Then lastly to reslove the reservedBalances for a user i.e decrease it whenever the limit order gets settled you could simply just do thus logic in the part of both of your marketOrderBuy and marketOrderSell functions that deal with the updating of balances

2 Likes

Hello @mcgrane5,

Thank you for the feedback. Yes the solution you proposed would work, this is also what I had in mind.
But now correct me if I am wrong. The solution that Filip posted has the same flaw. Or am I mistaking? https://github.com/filipmartinsson/dex/blob/dex_market_order_done/contracts/dex.sol

Thanks,
Gerald

1 Like

Thank you @mcgrane5! Can you happen to tell me how I can add/ transfer eth to my wallet? I know Filip had mention he was able to transfer eth from another account but he never showed us how.

1 Like

hey @cecilia. Sorry im not sure i understand. Do you mean how would you transfer eth to your dex application wallet. I assume if your deploying to testnet your trying to develop some sort of front end yes? Or are you just deploying to the testnet regardless. Anyway if you are on about transferring eth to your dex wallet then what you need to do is to use the faucets from the last post to credit your testnet account with ether. I assume you have already set up ganache, and imported one of your accounts into mestmask and also set up an ethereum node using infura. If you have done this and credited your account with faucet ether, then alls you need to do to transfer eth into your dex wallet is to call your depositETH function.

So say the account that your faucet eth is in is called account1. The simply call the deposit eth function like so

await dex.depositETH({from: accounts1, value: web3.utils.toWei("1", "ether")})

or if you are developing some sort of front end and you want to do this call in your main.js then you would write something like.

contractInstance.methods.depositETH().send({value: web3.utils.toWei("1", "ether") })

or something along the sorts. This asumes you have already initilised web3.js etc for use in your front end application.

Anyways these two methods will transfer the faucet ether from your metamsk testnet account to your dex wallet smart contract so that you can use it. Again i did not fully get your question so let me know if i misunderstood

2 Likes

hey @nutrina. Yeah i am pretty sure filips code has the same flaw. tbh its actually something i never even considered so very well done that you spotted this is such an easy thing to miss

1 Like

Ok, so I have implemented a fix for this issue in Filipā€™s repo.
This is my repo: https://github.com/nutrina/dex-1/tree/dex_market_order_done

This is the pull request: https://github.com/filipmartinsson/dex/pull/1

Gerald

2 Likes

So, I have been having a lot of issues with web3 and simply trying to link my web3 to my index.js file is not working. It throws this error:
Screenshot 2021-07-30 at 13.06.42

After some research, others suggested to use a require statement. I have tried using a require statement but it throws this error:

Screenshot 2021-07-30 at 12.59.26
So i searched further and was told i had to download the requireJS file in order for JavaScript to recognise the require statement. After doing that it still threw the error. Even after linking a script tag in my html file to the require.js file.

My next attempt was changing the require statement to an import statement (below). However it threw a different error this time:

Screenshot 2021-07-30 at 12.58.11

I have absolutely no idea what the issue is. I have been having issues with metamask and web3 on a different project (CryptoKitties Dapp) for 2+ months now and no one seems to know what the issue is. I have exhausted all options that i know of and I am stuck.

My repo: https://github.com/olfrank/Dex_DApp

1 Like

hey @ol_frank try using `import Web3 from ā€˜web3ā€™. Use this code for initiliasing web 3 and connectimg your browser. Its nice because you dont have to constatly switch out your abi and contract address if you redeploy and make changes to your smart contract

import Web3 from 'web3'

 async loadWeb3() {
    if (window.ethereum) {
      window.web3 = new Web3(window.ethereum)
      await window.ethereum.enable()
    }
    else if (window.web3) {
      window.web3 = new Web3(window.web3.currentProvider)
    }
    else {
      window.alert('Non-Ethereum browser detected. You should consider trying MetaMask!')
    }
  }

 async loadBlockchainData() {
    const web3 = window.web3
    // Load account
    // const accounts1 = "";
    const accounts = await web3.eth.getAccounts()
    // Network ID
    const networkId = await web3.eth.net.getId()
    const networkData = contractName.networks[networkId]
    if(networkData) {
      const contractinstance = new web3.eth.ContractName(contract.abi, networkData.address)
      this.setState({ contractinstance })
     
    } else {
      window.alert('contract not deployed to detected network.')
    }
  }


loadWeb3()
loadBlckchainData()

even try var web3 = new Web3(Web3.givenProvider); Have you definitely web 3 install try npm install web3 incase. Tbh i would copy and paste that "cannot use import statement outside of module error into google first g. " def use the code above its what first tho

3 Likes

Thank you for your reply @mcgrane5 , I tried your solution but unfortunately it hasnā€™t solved the issue. At this point i don think anything will haha. Beginning to think something larger is at fault here. Iā€™m using a MacBook pro, donā€™t know if they are prone to these kind of issues or not.

I am baffled as to what is happening. I have never been able to get metamask to work on any of my projects.
Iā€™ve downloaded Metamask Legacy, Iā€™ve used the local truffle blockchain like suggested by someone else. Iā€™ve downloaded and re-downloaded web3, plus ive copied the web3.min.js file that was provided in the Ethereum DApp Programming course and tried various syntaxes to try and point to the file but nothing is registering.

Iā€™m finding it strange that no one else is having the same lengthy issues that i am experiencing.

Iā€™m hoping that someone who works here is willing to clone my repository and take a deep dive into the issue because at the moment its just been guess work.

Thanks again Evan, I learnt something new from your code and it will likely help me in the future.

1 Like

@ol_frank ill clone your repo now. But the hard part will be replicating the error. Your right i think theres some bigger issue here i dont know what is is tho.

EDIT ā€”So i cloned your repo and i am actually getting the same error. Not sure why. So its leading me to belivee that theres something wrong with your project dependancies i.e something in package-lock.json. Im going to create a new project from scratch the way i normally do and just copy over your files. I can then create a pull request to your repo and if you clone into it it will work. Really weird like npm installing web 3 should have worked but it doesnt. I just say it had to do with when you first initiliased this project the face that i can replicate your error leads me to believe this, cant say for sure tho.

Anyway i will do all of that for you now later this evening when i get a chance. i will get back to you when im done. PS frontend looks great so far man

1 Like

Seems like you are importing web3 wrongly.
You cannot use require in javascript outside node.
Same thing with import.

In this case you have to add the web3 CDN to your index.html and then reference it in JS.

In your file dex.html web3 is wrongly imported.

import web3 cdn after index.js. This is the correct header

<meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Decentralized Exchange</title>

    <!-- <script src = "../node_modules/jquery/dist/jquery.min.js"></script> -->
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"
            integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
            crossorigin="anonymous">
    </script>
      <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>

    <script src = "index.js"></script>

    


    <link rel="stylesheet" 
              href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" 
              integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" 
              crossorigin="anonymous">

    <!-- <link rel="stylesheet" href="../node_modules/font-awesome/css/font-awesome.min.css"> -->
    <script src="https://kit.fontawesome.com/8d9e2e73ef.js" crossorigin="anonymous"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script>

    
    <link rel="stylesheet" href="./dex.css">
    <link rel="stylesheet" href="./shared.css">

    
    <script src = "abi.js"></script>
    
2 Likes

hey @ol_frank. so i made the whole project again the way i would and then copied your files over then i fiorked your repo and did all of them changes i did last night (ino lol a bit of an alward way to do it but hey). The web3 issue has been resolved. I dont know why it wouldnt work with your original repo but its working now. If you go to your repo and go to the pull requests section i have created a new pull request for a new branch if you accept it will merge and the fixed code will be available for you to use. I also fixed a few issues in your index.js. You are using jQuery so when you called for example

`$("btnDepositEth").on(click, depositEth)`

nothing was happening. This is the wromg syntax. You must use

$("btnDepositEth").click(depositEth)

The functions now execute when you click the respective buttons. However from what i see some of your actual functions have issues i.e bugs you need to fix as when i clicked on depositEth for example a few errors arose. You let balances = await dex.methods.balances(addressā€¦)ā€¦ function call for example has issues. Same with a few others you need to fix. Other than that everything seems to work.

Looks great man its gonna be very very cool when your done. One thing. I would reccomend maybe when your done to try code it with pure javascript instead of jQuery. I suppose its all down to personal preferance but what you could do instad of using jQuery is just for example say something like

const depositEther = document.getElementById("btnDepositEth");
depositEther.onclick = depositEth

This would do the exact same thing as the jQuery command above. Excited to see the finished result now tho man keep it up.

2 Likes

actually lol. from reading danis post if you switch the web3 import to be below the index.js import it breaks. wow hahahh sorry i did way to much effort creating new project and copying the files and thats all you had to do. well at least the problem is solved now. thanks @dan-i thats something i wasnt actually aware of good to know for myself.

3 Likes

This explained things much better, thanks for your help!

4 Likes