Assignment - Limit Order Test

This is the current error message im receiving


  Contract: Dex
    1) (Sell Order)should be in order from highest to lowest

    Events emitted during test:
    ---------------------------

    Ether.Approval(
      owner: <indexed> 0x5738aCDD50664b3A98153E0B8138E4EC90b99510 (type: address),
      spender: <indexed> 0x9E1314298a3Ee17A27d51bb0C59fc3dc411Ed745 (type: address),
      value: 500 (type: uint256)
    )


    ---------------------------

  Contract: Dex
    - should only be possible for the owner to add tokens
    - should handle deposits correctly
    - should handle faulty withdrawls correctly
    - should handle correct withdrawls correctly


  0 passing (2s)
  4 pending
  1 failing

  1) Contract: Dex
       (Sell Order)should be in order from highest to lowest:
     Error: Returned error: VM Exception while processing transaction: revert
      at Context.<anonymous> (test/dexTest.js:74:19)
      at processTicksAndRejections (node:internal/process/task_queues:96:5)

Line 74 is the deopsit function call:

        await dex.deposit(100, web3.utils.fromUtf8("LINK"));

I’ve tested both deposit.eth and deposit, both calls revert.

Link to my github:

https://github.com/oscaroneim/Dex2

Sorry for the ball ache.

Hi Evan, were you able to find out the issue?

regards,
Oscar

const Dex = artifacts.require("MyDex");
const Link = artifacts.require("Link");
const Aave = artifacts.require("Aave");
const truffleAssert = require("truffle-assertions");

// Test should be written before the actual code is written

// here are some conditions forcreating a limit order
// The user must have ETH deposited such that deposited ETH >= buy order value
// The user must have enough tokens deposited such that token balance >= sell order amount
// the first order ([0]) in the buy order book should have the higest price
// the first order ([0]) in the sell order book should have the lowest price
// sell order book should not mix different tokens
// buy order book should not mix different tokens

contract("Dex", accounts => {
    let buy = 0;
    let sell = 1;

    it("should only allow the amount of eth that is greater than or equal to the buy order value", async() => {
        let dex=await Dex.deployed();
        
        await truffleAssert.reverts (
            dex.createLimitOrder(buy, web3.utils.fromUtf8("LINK"), 10, 1)
        );
        
        await dex.depositEth({value: 10});

        await truffleAssert.passes (
            dex.createLimitOrder(buy, web3.utils.fromUtf8("LINK"), 10, 1)
        );
    });

    it("should require the token amount deposited be greater than or equal to the sell order value", async() => {
        let dex=await Dex.deployed();
        let link = await Link.deployed();
        
        await truffleAssert.reverts (
            dex.createLimitOrder(sell, web3.utils.fromUtf8("LINK"), 10, 1)
        );
        
        await link.approve(dex.address, 500);
        await dex.deposit(10, web3.utils.fromUtf8("LINK"));

        await truffleAssert.passes (
            dex.createLimitOrder(sell, web3.utils.fromUtf8("LINK"), 10, 1)
        );
    });

    it("buy orderbook should be sorted from the highest to lowest price", async() => {
        let dex=await Dex.deployed();
        let link = await Link.deployed();
        
        await dex.depositEth({value: 50});

        await link.approve(dex.address, 500);
        await dex.deposit(10, web3.utils.fromUtf8("LINK"));

        await dex.createLimitOrder(buy, web3.utils.fromUtf8("LINK"), 6, 3);
        await dex.createLimitOrder(buy, web3.utils.fromUtf8("LINK"), 8, 5);
        await dex.createLimitOrder(buy, web3.utils.fromUtf8("LINK"), 4, 2);
        await dex.createLimitOrder(buy, web3.utils.fromUtf8("LINK"), 10, 4);

        let buys = await dex.getOrderBook(web3.utils.fromUtf8("LINK"), buy);
        for (let index=0; i < buys.length - 1; index++) {
            assert(orderBook[index].price >= orderBook[index+1].price);
        }
    });

    it("sell orderbook should be sorted from the lowest to highest price", async() => {
        let dex=await Dex.deployed();
        let link = await Link.deployed();
        
        await dex.depositEth({value: 50});

        await link.approve(dex.address, 500);
        await dex.deposit(50, web3.utils.fromUtf8("LINK"));

        await dex.createLimitOrder(sell, web3.utils.fromUtf8("LINK"), 6, 3);
        await dex.createLimitOrder(sell, web3.utils.fromUtf8("LINK"), 8, 5);
        await dex.createLimitOrder(sell, web3.utils.fromUtf8("LINK"), 4, 2);
        await dex.createLimitOrder(sell, web3.utils.fromUtf8("LINK"), 10, 4);

        let buys = await dex.getOrderBook(web3.utils.fromUtf8("LINK"), buy);
        for (let index=0; i < buys.length - 1; index++) {
            assert(orderBook[index].price <= orderBook[index+1].price);
        }
    });

    it("buy orderbook should contain only one type of token", async() => {
        let dex=await Dex.deployed();

        await dex.depositEth({value: 50});

        await dex.createLimitOrder(buy, web3.utils.fromUtf8("AAVE"), 2, 3);
        await dex.createLimitOrder(buy, web3.utils.fromUtf8("LINK"), 2, 5);
        await dex.createLimitOrder(buy, web3.utils.fromUtf8("AAVE"), 2, 2);
        await dex.createLimitOrder(buy, web3.utils.fromUtf8("AAVE"), 2, 4);
        await dex.createLimitOrder(buy, web3.utils.fromUtf8("LINK"), 2, 5);

        let buys = await dex.getOrderBook(web3.utils.fromUtf8("AAVE"), buy);
        for (let index=0; i < buys.length - 1; index++) {
            assert(orderBook[index].ticker == web3.utils.fromUtf8("AAVE"));
        }
        buys = await dex.getOrderBook(web3.utils.fromUtf8("LINK"), buy);
        for (let index=0; i < buys.length - 1; index++) {
            assert(orderBook[index].ticker == web3.utils.fromUtf8("LINK"));
        }
    });
    it("sell orderbook should contain only one type of token", async() => {
        let dex=await Dex.deployed();
        let link = await Link.deployed();
        let aave = await Aave.deployed();

        await link.approve(dex.address, 500);
        await aave.approve(dex.address, 500);
        await dex.deposit(50, web3.utils.fromUtf8("LINK"));
        await dex.deposit(50, web3.utils.fromUtf8("AAVE"));

        await dex.createLimitOrder(sell, web3.utils.fromUtf8("AAVE"), 2, 3);
        await dex.createLimitOrder(sell, web3.utils.fromUtf8("LINK"), 2, 5);
        await dex.createLimitOrder(sell, web3.utils.fromUtf8("AAVE"), 2, 2);
        await dex.createLimitOrder(sell, web3.utils.fromUtf8("AAVE"), 2, 4);
        await dex.createLimitOrder(sell, web3.utils.fromUtf8("LINK"), 2, 5);

        let buys = await dex.getOrderBook(web3.utils.fromUtf8("AAVE"), sell);
        for (let index=0; i < buys.length - 1; index++) {
            assert(orderBook[index].ticker == web3.utils.fromUtf8("AAVE"));
        }
        buys = await dex.getOrderBook(web3.utils.fromUtf8("LINK"), sell);
        for (let index=0; i < buys.length - 1; index++) {
            assert(orderBook[index].ticker == web3.utils.fromUtf8("LINK"));
        }
    });
});
const Dex = artifacts.require("Dex");
const Link = artifacts.require("Link");
const truffleAssert = require("truffle-assertions");

//buy = 0
//sell = 1

contract("Dex", accounts => {

    it("should have more ETH deposited than the buy order value", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()

        await dex.addToken(web3.utils.sha3("LINK"), link.address, {from: accounts[0]})

        await truffleAssert.reverts(
            //function createLimitOrder(side, ticker, amount, price)
            dex.createLimitOrder(0, web3.utils.sha3("LINK"), 15, 1))

        await dex.depositEth({value: 25})       

        await truffleAssert.passes(
            //function createLimitOrder(side, ticker, amount, price)
            dex.createLimitOrder(0, web3.utils.sha3("LINK"), 15, 1)) 
    })

    it("Token deposit should be greater than sell order amount", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()

        await dex.addToken(web3.utils.sha3("LINK"), link.address, {from: accounts[0]})

        await truffleAssert.reverts(
            //function createLimitOrder(side, ticker, amount, price)
            dex.createLimitOrder(1, web3.utils.sha3("LINK"), 15, 1))

        await link.approve(dex.address, 500);

        await dex.deposit(100, web3.utils.sha3("LINK"));

        await truffleAssert.passes(
            //function createLimitOrder(side, ticker, amount, price)
            await dex.createLimitOrder(1, web3.utils.sha3("LINK"), 15, 1))
    })

    it("Buy order book should be ordered highest to lowest", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()

        await link.approve(dex.address, 500);
        await dex.depositEth({value: 3000});
        await dex.createLimitOrder(0, web3.utils.sha3("LINK"), 15, 1);
        await dex.createLimitOrder(0, web3.utils.sha3("LINK"), 16, 3);
        await dex.createLimitOrder(0, web3.utils.sha3("LINK"), 17, 7);

        let orderbook = await dex.getOrderBook(web3.utils.sha3("LINK"), 0);
        assert(orderbook.length > 0);
        console.log(orderbook);
        for (let i = 0; i < orderbook.length - 1; i++) {
            assert(orderbook[i].price >= orderbook[i + 1].price, "buy book order incorrect")
        } 
    })

    it("Sell order book should be ordered lowest to highest", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()

        await link.approve(dex.address, 500);
        await dex.createLimitOrder(1, web3.utils.sha3("LINK"), 15, 1);
        await dex.createLimitOrder(1, web3.utils.sha3("LINK"), 16, 3);
        await dex.createLimitOrder(1, web3.utils.sha3("LINK"), 17, 7);

        let orderbook = await dex.getOrderBook(web3.utils.sha3("LINK"), 1);
        assert(orderbook.length > 0);
        for (let i = 0; i < orderbook.length - 1; i++) {
            assert(orderbook[i].price <= orderbook[i + 1].price, "sell book order incorrect")
        }      
    })

})
1 Like
const DEX = artifacts.require("Dex")
const Link = artifacts.require("Link")
const truffleAssert = require('truffle-assertions');

contract("Dex", accounts => {

//The user must have ETH deposited such as deposited ETH >= buy order value

    it("should ensure that user has enough ETH deposited such as deposited ETH >= buy order value", async() => {
        let dex = await DEX.deployed()
        let link = await Link.deployed()
        //await link.approve (dex.address, 1000);
        await dex.addToken(web3.utils.fromUtf8("LINK"), link.address, {from : accounts[0]});
        await truffleAssert.passes(
            dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 10, 4677,0,{value:web3.utils.toWei('1','ether')}) // price in GWei
        )

        await truffleAssert.reverts(
            dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 10, 499999999,0, {value:web3.utils.toWei('1','ether')}) // price in GWei
        )

    })
//The user must have enough tokens deposited such that the token balance >= sell order amount
    it("should ensure that user has enough tokens deposited such that the token balance >= sell order amount", async() => {
        let dex = await DEX.deployed()
        let link = await Link.deployed()
        //console.log(dex.address);
        await link.approve (dex.address, 1000);
        await dex.addToken(web3.utils.fromUtf8("LINK"), link.address, {from : accounts[0]});
        //let balance = await dex.balances(accounts[0],web3.utils.fromUtf8("LINK"));
        await dex.deposit(500, web3.utils.fromUtf8("LINK"));
        await truffleAssert.passes(
            dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 300, 20,1) // tries to sell 300 out of a balance of 500
        )

        await truffleAssert.reverts(
            dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 600, 20,1) // tries to sell 600 out of a balance of 500
        )
    })

//The BUY order book should be ordered on price from highest to lowest starting at index 0

it("should ensure that the BUY order book is ordered on price from highest to lowest starting at index 0", async() => {
    let dex = await DEX.deployed()
    await dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 200, 20,0,{value:web3.utils.toWei('1','ether')});  // creates 3 limit orders with varying prices
    await dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 300, 20,0,{value:web3.utils.toWei('1','ether')});
    await dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 100, 20,0,{value:web3.utils.toWei('1','ether')});
    let OrderBook = await dex.getOrderBook(web3.utils.fromUtf8("LINK"),0);
    let OrderBookLength= await OrderBook.length;
    var x = 0;
    for(var j = 0; j < OrderBookLength-1; j++) {
        if (OrderBook[j].price<OrderBook[j+1].price){
            x = 1;
            break;
        }
    }
    assert.equal(x,0,"Prices in BUY order book not ordered from highest to lowest");

})

//The SELL order book should be ordered on price from lowest to highest starting at index 0

it("should ensure that the SELL order book is ordered on price from lowest to highest starting at index 0", async() => {
    let dex = await DEX.deployed()
    let OrderBook = await dex.getOrderBook(web3.utils.fromUtf8("LINK"),1);
    let OrderBookLength= await OrderBook.length;
    var x = 0;
    for(var j = 1; j < OrderBookLength-1; j++) {
        if (OrderBook[j].price<OrderBook[j-1].price){
            x = 1;
            break;
        }
        assert.equal(x,0,"Prices in SELL order book not ordered from lowest to highest");
    }
    

})

//Shouldn't be possible to create a limit order for a non existing token
it("Shouldn't be possible to create a BUY limit order for a non existing token", async() => {
let dex = await DEX.deployed()
await truffleAssert.reverts(dex.createLimitOrder(web3.utils.fromUtf8("NONEXIST"), 10, 20,0,{value:web3.utils.toWei('1','ether')}))

})

})

my function createLimitOrder :

modifier balanceChecked (bytes32 ticker, uint amount, uint price, Side side) {
        if (side == Side.BUY) { // Buy order
            require(msg.value >= amount*price*1000000000, "ether balance not sufficient");
        }
        else { // Sell order
            require(balances[msg.sender][ticker] >= amount, "Your balance is too low to sell that amount");
        }
         _;
    }

function createLimitOrder(bytes32 ticker, uint amount, uint price, Side side)  payable public balanceChecked (ticker, amount, price, side) tokenExist(ticker) {

It appears as my solution is very different in many ways. Any problems with it ?

1 Like

DEX TEST:

const Dex = artifacts.require('Dex');
const Link = artifacts.require('Link');
const truffleAssert = require('truffle-assertions');

contract('Dex', accounts => {
  let dex, link;
  const LINK = web3.utils.fromUtf8('LINK');
  const BUY = 0;
  const SELL= 1;

it("The deposited crypto must be more than buy order", async() =>{
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await truffleAssert.reverts      
            dex.limitOrder(true, web3.utils.fromUtf8("LINK"), 10, 1, {from: accounts[0]})
        await dex.deposit({value: 20, from:accounts[0]})    
        await truffleAssert.passes(
limitOrder(bool buyOrder, bytes32 ticker, uint amount, uint price)
            dex.limitOrder(true, web3.utils.fromUtf8("LINK"), 10, 1, {from: accounts[0]})
        )
    })

 it("balance must be greater than or equal to sell order", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await truffleAssert.reverts(
            dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 20, 1)     
        )
        await link.approve(dex.address, 1000)
        await dex.addToken(web3.utils.fromUtf8("LINK"), link.address, {from: accounts[0]})
        await dex.deposit(20, web3.utils.fromUtf8("LINK")) 
        await truffleAssert.passes(
            dex.limitOrder(1, web3.utils.fromUtf8("LINK"), 10, 1)     
        )
    })
const Dex = artifacts.require("Dex")

const Link = artifacts.require("Link")

const truffleAssert = require('truffle-assertions')

contract("Dex", accounts => {

    it("should have enought ETH deposited", async () => {

        let dex = await Dex.deployed()

        let link = await Link.deployed()

        //Tries to buy 2 ETH worth of LINK at the price of 0,5 ETH/LINK

        await truffleAssert.reverts(

            dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 0, 2, 0.5)

        )

        await dex.depositETH({value: 2})

        await truffleAssert.passes(

            dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 0, 2, 0.5)

        )

    })

    it("should have enought tokens deposited", async () => {

        let dex = await Dex.deployed()

        let link = await Link.deployed()

        //Tries to sell 3 LINK worth of ETH at the price of 0,5 ETH/LINK

        await truffleAssert.reverts(

            dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 1, 3, 0.5)

        )

        await link.approve(dex.address, 3);

        await dex.addToken(web3.utils.fromUtf8("LINK"), link.address, {from: accounts[0]})

        await dex.deposit(3, web3.utils.fromUtf8("LINK"));

        await truffleAssert.passes(

            dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 1, 3, 0.5)

        )

    })

    it("The BUY order book should be ordered on price from highest to lowest", async () => {

        let dex = await Dex.deployed()

        let link = await Link.deployed()

        await link.approve(dex.address, 700);

        await dex.depositEth({value: 3000});

        await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 1, 300);

        await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 1, 100);

        await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 1, 200);

        await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 1, 150);

        await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 1, 50);

       

        let orderBook = await getOrderBook(web3.utils.fromUtf8("LINK"), 0);

        assert(orderBook.lenght > 0);

        for (let i = 0; i < orderbook.length - 1; i++) {

            assert(orderbook[i].price >= orderbook[i+1].price, "not right order in buy book")

        }

    )}

    it("The SELL order book should be ordered on price from lowest to highest", async () => {

        let dex = await Dex.deployed()

        let link = await Link.deployed()

        await link.approve(dex.address, 700);

        await dex.depositEth({value: 3000});

        await dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 1, 300);

        await dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 1, 100);

        await dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 1, 200);

        await dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 1, 150);

        await dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 1, 50);

       

        let orderBook = await getOrderBook(web3.utils.fromUtf8("LINK"), 0);

        assert(orderBook.lenght > 0);

        for (let i = 0; i < orderbook.length - 1; i++) {

            assert(orderbook[i].price <= orderbook[i+1].price, "not right order in sell book")

        }

    )}

})
2 Likes

Assumed as the migration scripts of assets handled deposits.

const Wallet = artifacts.require("Wallet");
const Dex = artifacts.require("Dex");
const Link = artifacts.require("Link");
const Ether = artifacts.require("Ether");
const assert = require("chai").assert;
const truffleAssert = require("truffle-assertions");

contract("Dex", (accounts) => {
  let wallet, dex, eth, link, msgSender;
  let orders = [];
  let buyOrders = [];
  let sellOrders = [];
  // utils
  let twei = (v) => {
    return web3.utils.toWei(v);
  };
  let tickerETH = web3.utils.fromUtf8("ETH");
  let tickerLINK = web3.utils.fromUtf8("LINK");

  const orderSide = {
    BUY: "buy",
    SELL: "sell",
  };

  function createLimitOrder(
    msgSender,
    orderType,
    symbol,
    orderAmount,
    pairPrice
  ) {
    // conditional
    if (!wallet) {
      console.error("wallet isn't defined yet");
      return;
    }
    const newOrder = {
      id: orders.length,
      trader: msgSender,
      buyOrder: orderType, //orderSide.BUY/SELL
      ticker: symbol, // :bytes32
      amount: orderAmount,
      price: pairPrice,
    };
    // orders.push(newOrder);
    // add limit order
    if (newOrder.buyOrder === "buy") {
      buyOrders.push(newOrder);
    } else {
      sellOrders.push(newOrder);
    }
    orders.push(newOrder);

    buyOrders.sort((a, b) => {
      return b.amount - a.amount;
    });
    sellOrders.sort((a, b) => {
      return a.amount - b.amount;
    });

    return newOrder;
  }

  function getLimit(ordersType) {
    let limit = 0;
    ordersType.forEach((order) => {
      if (order.amount > limit) {
        limit = order.amount;
      }
    });
    return limit;
  }

  before(async () => {
    wallet = await Wallet.deployed();
    link = await Link.deployed();
    dex = await Dex.deployed();
    eth = await Ether.deployed();
  });

  it("should pass while the user must have ETH deposited such that deposited eth >= buy order value", async () => {
    // Define
    msgSender = accounts[0];
    const symbol = "ETH";
    // Apply
    const walletBalance = await wallet.balances(
      msgSender,
      web3.utils.fromUtf8(symbol)
    );
    const order = createLimitOrder(
      msgSender,
      orderSide.BUY,
      web3.utils.fromUtf8(symbol),
      "84",
      "2000"
    );
    // Report
    console.log(`walletBalance: ${walletBalance} ${symbol}`);
    console.table({ order });
    // Assert
    await truffleAssert.passes(
      assert.isAtLeast(
        web3.utils.BN(walletBalance).toNumber(),
        web3.utils.BN(order.amount).toNumber(),
        `⛔ Not enough asset to create order (order amount is higher than user's asset)
        Balance: ${walletBalance} ${symbol} < Tried Order: ${order.amount} ${symbol}
        `
      )
    );
  });

  it("should pass while the user must have enough tokens deposited such that token balance >= sell order amount", async () => {
    // Define
    msgSender = accounts[0];
    const symbol = "LINK";
    // Apply
    const walletBalance = await wallet.balances(
      msgSender,
      web3.utils.fromUtf8(symbol)
    );
    const order = createLimitOrder(
      msgSender,
      orderSide.BUY,
      web3.utils.fromUtf8(symbol),
      "42",
      "2000"
    );
    // Report
    console.log(`walletBalance: ${walletBalance} ${symbol}`);
    console.table({ order });
    // Assert
    await truffleAssert.passes(
      assert.isAtLeast(
        web3.utils.BN(walletBalance).toNumber(),
        web3.utils.BN(order.amount).toNumber(),
        `⛔ Not enough asset to create order (order amount is higher than user's asset)
        Balance: ${walletBalance} ${symbol} < Tried Order: ${order.amount} ${symbol}
        `
      )
    );
  });

  it("should pass while the buy order book should be ordered on price from highest to lowest starting at index 0", async () => {
    // Define
    buyOrders = [];
    const msgSender = accounts[0];
    const ticker = web3.utils.fromUtf8("LINK");
    // Apply
    createLimitOrder(msgSender, orderSide.BUY, ticker, "32", "30");
    createLimitOrder(msgSender, orderSide.BUY, ticker, "18", "30");
    createLimitOrder(msgSender, orderSide.BUY, ticker, "64", "30");
    createLimitOrder(msgSender, orderSide.BUY, ticker, "05", "30");
    const highestOrder = getLimit(buyOrders);
    // Report
    console.table(buyOrders);
    // Assert
    await truffleAssert.passes(
      assert.equal(
        buyOrders[0].amount,
        highestOrder,
        `⛔ Highest Order is not the first element of orders list`
      )
    );
  });
});

Migration scripts are in the same repository:
https://github.com/emrea-works/simple-dex/tree/main/migrations

2 Likes

Anyone doing this course in 2023?

1 Like

Hi @justkaz

You can post your queries here if you have any. We will be happy to answer it. :smiley:

1 Like

Hi John

This Token/ETH swap between the traders.
How come the swap is direct from their wallets and not from address(this) smart contract. Don’t we have to Approve “spend on behalf” of the Trader?

Hope that makes sense.
Regards

type or paste code here
if(side == Side.BUY){
                //Verify that the buyer has enough ETH to cover the purchase (require)
                require(balances[msg.sender]["ETH"] >= cost);
                //msg.sender is the buyer
                balances[msg.sender][ticker] = balances[msg.sender][ticker].add(filled);
                balances[msg.sender]["ETH"] = balances[msg.sender]["ETH"].sub(cost);
                
                balances[orders[i].trader][ticker] = balances[orders[i].trader][ticker].sub(filled);
                balances[orders[i].trader]["ETH"] = balances[orders[i].trader]["ETH"].add(cost);
            }
            else if(side == Side.SELL){
                //Msg.sender is the seller
                balances[msg.sender][ticker] = balances[msg.sender][ticker].sub(filled);
                balances[msg.sender]["ETH"] = balances[msg.sender]["ETH"].add(cost);
                
                balances[orders[i].trader][ticker] = balances[orders[i].trader][ticker].add(filled);
                balances[orders[i].trader]["ETH"] = balances[orders[i].trader]["ETH"].sub(cost);
            }

Hi @justkaz

The required approval of the tokens happen during the token deposit. The below code is from the wallet.sol of this course. In this the transferFrom function is used to transfer tokens from user wallet to contract and this function also handles required approval internally.

    function depositToken(uint256 _amount, bytes32 _ticker) external tokenExist(_ticker){
        IERC20(tokenMapping[_ticker].tokenAddress).transferFrom(msg.sender, address(this), _amount);
        balances[msg.sender][_ticker] = balances[msg.sender][_ticker].add(_amount);
    }

Hope this answers your question.:smiley:

1 Like

Thanks John. Yes, that makes sense.

Regards

1 Like
// user must have enough ETH deposited for the buy order to be filled
// user must have enough tokens to fill sell order
// first order in the BUY order book must have the highest price
const Dex = artifacts.require("Dex")
const Link = artifacts.require("Link")
const TruffleAssert = require("truffle-assertions")

contract("Dex", accounts => {
    it("should not be possible to place a buy order if a trader does not have enough ETH to fill it", async() => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await TruffleAssert.reverts(
            dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 1, 1000, {from: accounts[1]})
        )
    })
    it("should not be possible to place a sell order if a trader does not have enough tokens to fill it", async() => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await TruffleAssert.reverts(
            dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 1, 1000, {from: accounts[1]})
        )
    })
    it("should be possible to place a buy order if a trader has enough ETH to fill it", async() => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await dex.depositEth({from: accounts[1], value: 1})
        await TruffleAssert.passes(
            dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 1, 1000, {from: accounts[1]})
        )
    })
    it("should be possible to place a sell order if trader has enough tokens to fill it", async() => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await dex.deposit(100, web3.utils.fromUtf8("LINK"), {from: accounts[1]})
        await TruffleAssert.passes(
            dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 1, 1000, {from: accounts[1]})
        )
    })
    it("BUY order book should be ordered in descending order", async() => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        
        await dex.depositEth({value: 10})
        await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 1, 1000)
        await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 10, 2500)
        await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 50, 900)

        let orderBook = await dex.getOrderBook(0, web3.utils.fromUtf8("LINK"))
        for (var i = 1; i < orderBook.length; i++) {
            assert(orderBook[i-1] >= orderBook[i])
        }
    })
    it("SELL order book should be ordered in ascending order", async() => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        
        await link.approve(dex.address, 1000)
        await dex.deposit(1000, web3.utils.fromUtf8("LINK"))
        await dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 1, 1000)
        await dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 10, 2500)
        await dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 50, 900)

        let orderBook = await dex.getOrderBook(0, web3.utils.fromUtf8("LINK"))
        for (var i = 1; i <= orderBook.length; i++) {
            assert(orderBook[i-1] < orderBook[i])
        }
    })
})
const Dex = artifacts.require("Dex");
const TestToken = artifacts.require("TestToken");
const truffleAssert = require('truffle-assertions');

contract('Dex', accounts => {

// Deposited ETH > order value of buy order _plus_ any existing buy orders

  it("1: should be possible to place BUY order with order value less than ETH balance considering existing buy orders", async() => {
    let dex=await Dex.deployed();
    let testToken=await TestToken.deployed();
    await dex.depositETH({value: '50', from: accounts[0]});
    await dex.addToken(web3.utils.fromUtf8("TT"), testToken.address, {from: accounts[0]})
    await dex.createLimitOrder(web3.utils.fromUtf8("TT"), 0 /* BUY */, 2, 10, {from: accounts[0]})

    await truffleAssert.passes(
      // 2*10 (previous buy order) + 2*10=40 which is less than 50
      dex.createLimitOrder(web3.utils.fromUtf8("TT"), 0 /* BUY */, 2, 10, {from: accounts[0]})
    );
    
  })

// Deposited ETH < order value of buy order _plus_ any existing buy orders

  it("2: should not be possible to place BUY order with order value larger than ETH balance considering existing buy orders", async() => {
    let dex=await Dex.deployed();
    let testToken=await TestToken.deployed();
    await dex.depositETH({value: '50', from: accounts[0]});
    await dex.addToken(web3.utils.fromUtf8("TT"), testToken.address, {from: accounts[0]})    
    await truffleAssert.reverts(
      // 200*10=2000 which is larger than 50
      dex.createLimitOrder(web3.utils.fromUtf8("TT"), 0 /* BUY */, 200, 10, {from: accounts[0]})
    );
  })
  

// Deposited ETH > order value of buy order

it("2a: should not be possible to place BUY order with order value larger than ETH balance. Also considering existing BUY orders!", async() => {
  let dex=await Dex.deployed();
  let testToken=await TestToken.deployed();
  await dex.depositETH({value: '50', from: accounts[0]});
  await dex.addToken(web3.utils.fromUtf8("TT"), testToken.address, {from: accounts[0]})    
  await dex.createLimitOrder(web3.utils.fromUtf8("TT"), 0 /* BUY */, 5, 10, {from: accounts[0]})
  await truffleAssert.reverts(
    // 5*10=50 from previous order so the ETH balance is already exhaused. This should fail.
    dex.createLimitOrder(web3.utils.fromUtf8("TT"), 0 /* BUY */, 2, 10, {from: accounts[0]})
  );
})

// Tokens > sell order ammount

it("3: should be possible to place SELL order with amount less than token balance considering existing order", async() => {
  let dex=await Dex.deployed();
  let testToken=await TestToken.deployed();

  await dex.addToken(web3.utils.fromUtf8("TT"), testToken.address, {from: accounts[0]})    
  await testToken.approve(dex.address, 500);
  await dex.deposit(100, web3.utils.fromUtf8("TT"));

  await truffleAssert.passes(
    dex.createLimitOrder(web3.utils.fromUtf8("TT"), 1 /* SELL */, 20, 10, {from: accounts[0]})
  );
})
  
  it("4: should not be possible to place SELL order with amount larger than token balance considering existing order", async() => {
    let dex=await Dex.deployed();
    let testToken=await TestToken.deployed();
    
    await dex.addToken(web3.utils.fromUtf8("TT"), testToken.address, {from: accounts[0]})    
    await testToken.approve(dex.address, 500);
    await dex.deposit(100, web3.utils.fromUtf8("TT"));
  
    await dex.createLimitOrder(web3.utils.fromUtf8("TT"), 1 /* SELL */, 90, 10, {from: accounts[0]})

    await truffleAssert.reverts(
      // I only have 100 TT so placing a selling another 15 (105 total) should fail
      dex.createLimitOrder(web3.utils.fromUtf8("TT"), 1 /* SELL */, 15, 10, {from: accounts[0]})
    );
  })

  // Buy Orders ordred from high to low

  it("5: order book BUY orders should be sorted from high to low", async() => {
    let dex=await Dex.deployed();
    let testToken=await TestToken.deployed();
    await dex.depositETH({value: '50', from: accounts[0]});
    await dex.addToken(web3.utils.fromUtf8("TT"), testToken.address, {from: accounts[0]});
    await dex.createLimitOrder(web3.utils.fromUtf8("TT"), 0 /* BUY */, 2, 10, {from: accounts[0]});
    await dex.createLimitOrder(web3.utils.fromUtf8("TT"), 0 /* BUY */, 2, 20, {from: accounts[0]});
    await dex.createLimitOrder(web3.utils.fromUtf8("TT"), 0 /* BUY */, 2, 5, {from: accounts[0]});

    let orderBook = await dex.getOrderBook(web3.utils.fromUtf8("TT"), 0 /* BUY */);

    for (let i=0; i<orderBook.length-1; i++) {
      currentValue=orderBook[i].price;
      nextValue=orderBook[i+1].price;
      // Assert that the current price is greater or equal to the next price
      assert.isAtLeast(
        currentValue, nextValue
        );
    }

})

it("6: order book SELL orders should be sorted from low to high", async() => {
  let dex=await Dex.deployed();
  let testToken=await TestToken.deployed();
  await dex.depositETH({value: '50', from: accounts[0]});
  await dex.addToken(web3.utils.fromUtf8("TT"), testToken.address, {from: accounts[0]});
  await dex.createLimitOrder(web3.utils.fromUtf8("TT"), 1 /* SELL */, 2, 10, {from: accounts[0]});
  await dex.createLimitOrder(web3.utils.fromUtf8("TT"), 1 /* SELL */, 2, 20, {from: accounts[0]});
  await dex.createLimitOrder(web3.utils.fromUtf8("TT"), 1 /* SELL */, 2, 5, {from: accounts[0]});

  let orderBook = await dex.getOrderBook(web3.utils.fromUtf8("TT"), 1 /* SELL */);

    for (let i=0; i<orderBook.length-1; i++) {
      currentValue=orderBook[i].price;
      nextValue=orderBook[i+1].price;
      // Assert that the next price is greater or equal to the current price
      assert.isAtLeast(
        nextValue, currentValue
        );
    }
  })
  // It would be fine to allow sell orders with a price lower than the highest buy order however that should execute like a market order.
  // We check for that by checking the number of orders in the order book.
  it("7: order book SELL with a lower price than the highest buy order should execute as a limit order", async() => {
    let dex=await Dex.deployed();
    let testToken=await TestToken.deployed();
    await dex.depositETH({value: '50', from: accounts[0]});
    await dex.addToken(web3.utils.fromUtf8("TT"), testToken.address, {from: accounts[0]});
    await dex.createLimitOrder(web3.utils.fromUtf8("TT"), 1 /* SELL */, 2, 10, {from: accounts[0]});
    await dex.createLimitOrder(web3.utils.fromUtf8("TT"), 1 /* SELL */, 2, 20, {from: accounts[0]});
    await dex.createLimitOrder(web3.utils.fromUtf8("TT"), 1 /* SELL */, 2, 30, {from: accounts[0]});
    await dex.createLimitOrder(web3.utils.fromUtf8("TT"), 0 /* BUY */, 2, 9, {from: accounts[0]});
    await dex.createLimitOrder(web3.utils.fromUtf8("TT"), 0 /* BUY */, 2, 8, {from: accounts[0]});
    await dex.createLimitOrder(web3.utils.fromUtf8("TT"), 0 /* BUY */, 2, 7, {from: accounts[0]});
    
    // This should lead to a market order since the sell price is lower than the highes bid. Effectively the 2, 9 limit order should be filled.
    await dex.createLimitOrder(web3.utils.fromUtf8("TT"), 1 /* SELL */,2, 8, {from: accounts[0]});

    let orderBook = await dex.getOrderBook(web3.utils.fromUtf8("TT"), 1 /* SELL */);

    let orderCount=orderBook.length;

    // Should be only 5 order since the pervious order should fill the existing limit order
    assert.equal(
      orderCount, 5
      );

  })

  // It would be fine to allow buy orders with a price higher than the lowes sell order however that should execute like a market order.
  // We check for that by checking the number of orders in the order book.
  // ToDo: To be implemented 

});
  
1 Like

Remix IDE Solidity Unit Testing Version (INITIAL DRAFT):

// SPDX-License-Identifier: GPL-3.0
        
pragma solidity >=0.4.22 <0.9.0;

// This import is automatically injected by Remix
import "remix_tests.sol"; 

// This import is required to use custom transaction context
// Although it may fail compilation in 'Solidity Compiler' plugin
// But it will work fine in 'Solidity Unit Testing' plugin
import "remix_accounts.sol";
import "../contracts/new_wallet.sol";
import "../contracts/dex.sol";
import "../contracts/safemath.sol";

// File name has to end with '_test.sol', this file can contain more than one testSuite contracts
contract LimitOrderTest {

    Dex dex;
    NewWallet nw;
    Link link;
    Ethereum ethereum;

    /// 'beforeAll' runs before all other tests
    /// More special functions are: 'beforeEach', 'beforeAll', 'afterEach' & 'afterAll'
    function beforeAll() public {
        // <instantiate contract>
        dex = new Dex();
        nw = new NewWallet();
        link = new Link(100000);
        ethereum = new Ethereum(100000);
        dex.addToken("LINK", address(link));
        dex.addToken("ETH", address(ethereum));
        link.approve(address(dex), 7);
        nw.newDeposit("LINK", 7);
        link.approve(address(dex), 7);
        nw.newDeposit("ETH", 7);
    }

    function testSufficientETH() public {
        try dex.createLimitBuyOrder("LINK", 1, 0.004) {
            Assert.ok(true, 'should be successful');
        }
        catch {
            Assert.ok(false, 'failed unexpectedly');
        }
    }

    function testInsufficientETH() public {
        try dex.createLimitBuyOrder("LINK", 1751, 0.004) {
            Assert.ok(false, 'should be false');
        }
        catch {
            Assert.ok(true, 'failed unexpectedly');
        }
    }

    function testSufficientTokens() public {
        try dex.createLimitSellOrder("LINK", 1, 238) {
            Assert.ok(true, 'should be successful');
        }
        catch {
            Assert.ok(false, 'failed unexpectedly');
        }
    }

    function testInsufficientTokens() public {
        try dex.createLimitSellOrder("LINK", 8, 238) {
            Assert.ok(false, 'should be false');
        }
        catch {
            Assert.ok(true, 'failed unexpectedly');
        }
    }

    function testBuyOrderBookSorting() public {
        try dex.getBuyOrderBook("ETH") {
            for (uint i = 0; i < buyOrderBook.length.sub(1); i++) {
                if(buyOrderBook[i].price > buyOrderBook[i.add(1)].price){}
                else {
                    Assert.ok(false, 'the buy order book sort test failed');
                }
            }
        Assert.ok(true, 'should be successful');
        }
        catch {
            Assert.ok(false, 'failed unexpectedly');
        }
    }

    function testSellOrderBookSorting() public {
        try dex.getSellOrderBook("ETH") {
            for (uint i = 0; i < sellOrderBook.length.sub(1); i++) {
                if(sellOrderBook[i].price > sellOrderBook[i.add(1)].price){}
                else {
                    Assert.ok(false, 'the sell order book sort test failed');
                }
            }
        Assert.ok(true, 'should be successful');
        }
        catch {
            Assert.ok(false, 'failed unexpectedly');
        }
    }
}
2 Likes

my dextest.js:

//1. the user must have ETH deposited such that deposited eth >= buy order value

//2. the user must have enough tokens deposited such that otken balnce >= sell order amount

//3. the first order ([0]) in the BUY order book should have the highest price, 
//the BUY order book should be ordered on price from highest to lowest starting at index 0

const Dex = artifacts.require("Dex");
const Link = artifacts.require("Link");
const truffleAssert = require('truffle-assertions');

contract("Dex", accounts => {
    let link, dex;
    const ticker = web3.utils.keccak256("LINK");

    it("Should require sufficient ETH for buy orders", async () => {
        link = await Link.deployed();
        dex = await Dex.deployed();
       
        await dex.addToken(ticker, link.address, { from: accounts[0] });
        await dex.depositEth({ from: accounts[0], value: web3.utils.toWei('10', 'ether') });
        await link.approve(dex.address, 500, { from: accounts[0] });
        await dex.deposit(500, ticker, { from: accounts[0] });

        let buyAmount = 10;
        let buyPrice = 1; // Price in ETH
        let buyOrderValue = buyAmount * buyPrice;

        let ethBalance = await dex.balances(accounts[0], web3.utils.fromAscii("ETH"));
        assert(ethBalance >= buyOrderValue, "Insufficient ETH balance for buy order");

        await truffleAssert.passes(
            dex.createLimitOrder(Side.BUY, ticker, buyAmount, buyPrice, { from: accounts[0] })
        );
    });

    it("Should require sufficient tokens for sell orders", async () => {
        link = await Link.deployed();
        dex = await Dex.deployed();
       
        await dex.addToken(ticker, link.address, { from: accounts[0] });
        await dex.depositEth({ from: accounts[0], value: web3.utils.toWei('10', 'ether') });
        await link.approve(dex.address, 500, { from: accounts[0] });
        await dex.deposit(500, ticker, { from: accounts[0] });

        let sellAmount = 10;
        let sellPrice = 1;

        let tokenBalance = await dex.balances(accounts[0], ticker);
        assert(tokenBalance >= sellAmount, "Insufficient token balance for sell order");

        await truffleAssert.passes(
            dex.createLimitOrder(Side.SELL, ticker, sellAmount, sellPrice, { from: accounts[0] })
        );
    });

    it("BUY order book should be sorted by price from highest to lowest", async () => {
        link = await Link.deployed();
        dex = await Dex.deployed();
       
        await dex.addToken(ticker, link.address, { from: accounts[0] });
        await dex.depositEth({ from: accounts[0], value: web3.utils.toWei('10', 'ether') });
        await link.approve(dex.address, 500, { from: accounts[0] });
        await dex.deposit(500, ticker, { from: accounts[0] });

        // Add multiple buy orders
        await dex.createLimitOrder(Side.BUY, ticker, 1, 10, { from: accounts[0] });
        await dex.createLimitOrder(Side.BUY, ticker, 1, 15, { from: accounts[0] });
        await dex.createLimitOrder(Side.BUY, ticker, 1, 12, { from: accounts[0] });

        let buyOrderBook = await dex.getOrderBook(ticker, Side.BUY);
        assert(buyOrderBook.length > 0, "Buy order book should not be empty");

        // If we don't have a sorting algorithme, then this will fail
        // this check the value in index before should be bigger than the value in index next.
        for (let i = 0; i < buyOrderBook.length - 1; i++) {
            assert(buyOrderBook[i].price >= buyOrderBook[i + 1].price, "Buy order book is not sorted correctly");
        }
    });
});
1 Like

CreateLimitOrder function header

function createLimitOrder(
    bytes32 _ticker, 
    uint _numTokens, 
    address _trader, 
    uint256 _orderValue, 
    Side _side) public payable {
       
}

My tests

//The user must have ETH deposited such that deposited eth >= buy order value
//The user must have enough tokens deposited such that token balance >= sell order amount
//The BUY order book should be ordered on price from highest to lowest starting at index 0
//The SELL order book should be ordered on price from lowest to highest starting at index 0

const Link = artifacts.require("Link");
const Dex = artifacts.require("Dex");
const truffleAssert = require("truffle-assertions");

contract("Dex", accounts => {
    it("Test 1 - ETH balance >= buy order value - trader has less eth balance", async () => {

        let dex = await Dex.deployed();
        let link = await Link.deployed();
      
        //create buy order - 500 Link tokens for 1 ether - trader has no Eth balance
        await truffleAssert.reverts(
            dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 500, accounts[1],
            web3.utils.toWei("1", "ether"), 0, {from: accounts[1]})
        );
    });

    it("Test 2 - ETH balance >= buy order value - trader has sufficient eth balance", async () => {

        let dex = await Dex.deployed();
        let link = await Link.deployed();
      
        //deposit eth to user account to have balance of 2 Eth
        await dex.depositEth(accounts[1], web3.utils.toWei("2", "ether"), {from: accounts[0]});
        let userBalanceEth = await dex.getUserEthBalance(accounts[1]);
        console.log("User" + accounts[1] +
                   " has " + web3.utils.fromWei(userBalanceEth, "ether") + " ETHER");
        

        //create buy order - 500 Link tokens for 0.5 ether - trader has 2 Eth balance
        await truffleAssert.passes(
            dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 500, accounts[1],
            web3.utils.toWei("0.5", "ether"), 0, {from: accounts[1]})
        );

    });


    it("Test 3 - Token balance >= sell order amount - trader has less token balance", async () => {

        let dex = await Dex.deployed();
        let link = await Link.deployed();
      
        //deposit eth to user account to have balance of Eth 2
        await dex.depositEth(accounts[0], web3.utils.toWei("2", "ether"));
        
        //Add Link token to Dex contract
        await truffleAssert.passes(
            dex.addToken(web3.utils.fromUtf8("LINK"), link.address, {from: accounts[0]})
        );

        await link.approve(dex.address, 3000);
        await dex.deposit(100, web3.utils.fromUtf8("LINK"));

        //Sell order for 500 tokens - trader has 100 tokens
        await truffleAssert.reverts(
            dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 500, accounts[0],
            web3.utils.toWei("0.5", "ether"), 1)
        ); 
    });

    it("Test 4 - Token balance >= sell order amount - trader has sufficient token balance", async () => {

        let dex = await Dex.deployed();
        let link = await Link.deployed();
      
        //deposit eth to user account to have balance of Eth 2
        await dex.depositEth(accounts[0], web3.utils.toWei("2", "ether"));
        
        //Add Link token to Dex contract
        await truffleAssert.passes(
            dex.addToken(web3.utils.fromUtf8("LINK"), link.address, {from: accounts[0]})
        );

        await link.approve(dex.address, 3000);
        await dex.deposit(1000, web3.utils.fromUtf8("LINK"));

        //Sell order for 500 - trader has 1000 tokens
        await truffleAssert.passes(
            dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 500, accounts[0],
            web3.utils.toWei("0.5", "ether"), 1)
        ); 

    });

    it("Test 5  - Buy orderbook ordered by price highest to lowest", async () => {

        let dex = await Dex.deployed();
        let link = await Link.deployed();

        //deposit eth to user account to have balance of Eth 5
        await dex.depositEth(accounts[0], web3.utils.toWei("5", "ether"));

        //add token, approve dex and deposit tokens
        await dex.addToken(web3.utils.fromUtf8("LINK"), link.address, {from: accounts[0]})
        await link.approve(dex.address, 3000);
        await dex.deposit(1000, web3.utils.fromUtf8("LINK"));

        //create buy orders
        await  dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 100, accounts[0], web3.utils.toWei("0.1", "ether"), 0);
        await  dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 200, accounts[0], web3.utils.toWei("0.5", "ether"), 0);
        await  dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 100, accounts[0], web3.utils.toWei("0.3", "ether"), 0);
       
        //get Buy order book
        let buyOrderBook = await dex.getOrderBook(web3.utils.fromUtf8("LINK"), 0);

        if(buyOrderBook.length > 0) {
            for(let i = 0; i < buyOrderBook.length - 1; i++) {
                assert(buyOrderBook[i].price >= buyOrderBook[i+1].price, 
                    "Buy Orderbook is not sorted in descending order of price");
            }   
        }
    });

    it("Test 6  - Sell orderbook ordered by price lowest to highest", async () => {

        let dex = await Dex.deployed();
        let link = await Link.deployed();

        //add token, approve dex and deposit tokens
        await dex.addToken(web3.utils.fromUtf8("LINK"), link.address, {from: accounts[0]})
        await link.approve(dex.address, 3000);
        await dex.deposit(1000, web3.utils.fromUtf8("LINK"));

        //create sell orders
        await  dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 300, accounts[0], web3.utils.toWei("0.1", "ether"), 1);
        await  dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 200, accounts[0], web3.utils.toWei("0.5", "ether"), 1);
        await  dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 400, accounts[0], web3.utils.toWei("0.3", "ether"), 1);

        //get Sell order book
        let sellOrderBook = await dex.getOrderBook(web3.utils.fromUtf8("LINK"), 1);

        if(sellOrderBook.length > 0) {
            for(let i = 0; i < sellOrderBook.length - 1; i++) {
                assert(sellOrderBook[i].price <= sellOrderBook[i+1].price, 
                    "Sell Orderbook is not sorted in ascending order of price");
            }   
        }
    });
})

2 Likes