Assignment - Limit Order Test

Hi, my new attempt. i used decimals which gives me underflow errors. and i had to approve tokens before deposit in dex.

// the user must have ETH deposited such that eth >=  buy order value 
// the user must have enough tokens deposited such that token balance > sell order amount
// the BUY order must be ordered on price from the highest to lowest starting at index 0
// the SELL order must be ordered on price from the lowest to highest starting at index 0
// the BUY order must be processed when the prices of BUY and SELL orders matches   
// once an order is completed (i.e token amount of order reach zero) it must be delete from the orderbook

const Dex = artifacts.require("Dex")
const Token = artifacts.require("MyToken");
const TruffleAssert = require('truffle-assertions')
contract ("Dex", accounts => {
    it("Must have enough ETH",async ()=>{
        let token = await Token.deployed()
        let dex = await Dex.deployed()
        await dex.addToken(web3.utils.fromUtf8("MTK"),token.address)
        // have to create a payable  deposit function to deposit ether
        await dex.depositEther({value: 4500, from: accounts[1]})
        await TruffleAssert.reverts(
            dex.createLimitOrder(100,55,web3.utils.fromUtf8("MTK"),0,{from: accounts[1]})
        )
        await dex.depositEther({value:1000, from: accounts[1]})
        await TruffleAssert.passes(
            dex.createLimitOrder(100,55,web3.utils.fromUtf8("MTK"),0,{from: accounts[1]})
        )
    })    
 
    it("Must have enough Token",async ()=>{
        let token = await Token.deployed()
        let dex = await Dex.deployed()
        await dex.addToken(web3.utils.fromUtf8("MTK"),token.address)
        await TruffleAssert.reverts(
            dex.createLimitOrder(50,1,web3.utils.fromUtf8("MTK"),1,{from: accounts[2]})
        )
        await token.transfer(accounts[2],65,{from: accounts[0]})
        await token.approve(dex.address,50,{from:accounts[2]})
        await dex.deposit(web3.utils.fromUtf8("MTK"),40,{from: accounts[2]})
        await TruffleAssert.reverts(
            dex.createLimitOrder(50,1,web3.utils.fromUtf8("MTK"),1,{from: accounts[2]})
        )
        await TruffleAssert.passes(
            dex.createLimitOrder(30,1,web3.utils.fromUtf8("MTK"),1,{from: accounts[2]})
        )
    })    

       
    it("the buy orders must be ordered on price from highest to lowest",async ()=>{
        let token = await Token.deployed()
        let dex = await Dex.deployed()
        await dex.addToken(web3.utils.fromUtf8("MTK"),token.address)
        await dex.depositEther({value: 50, from: accounts[0]})
        await dex.depositEther({value: 300, from: accounts[1]})
        await dex.depositEther({value: 800, from: accounts[2]})
        await dex.depositEther({value: 550, from: accounts[3]})
        await dex.createLimitOrder(50,1,web3.utils.fromUtf8("MTK"),0,{from: accounts[1]})
        await dex.createLimitOrder(100,3,web3.utils.fromUtf8("MTK"),0,{from: accounts[2]})
        await dex.createLimitOrder(10,4,web3.utils.fromUtf8("MTK"),0,{from: accounts[0]})
        await dex.createLimitOrder(110,5,web3.utils.fromUtf8("MTK"),0,{from: accounts[3]})
        var BuyOrder = await dex.getOrderBook(web3.utils.fromUtf8("MTK"),0)
        assert(BuyOrder.length > 0)
        for(let i = 0; i<BuyOrder.length - 1; i++){
            assert(BuyOrder[i].price > BuyOrder[i+1].price,"BUY orders not arranged correctly")
        }
    })    


    it("the sell orders must be ordered on price from lowest to highest",async ()=>{
        let token = await Token.deployed()
        let dex = await Dex.deployed()
        await dex.addToken(web3.utils.fromUtf8("MTK"),token.address)
        await token.transfer(accounts[1],150,{from: accounts[0]})
        await token.transfer(accounts[2],250,{from: accounts[0]})
        await token.transfer(accounts[3],150,{from: accounts[0]})
        await token.approve(dex.address,100,{from: accounts[0]})
        await token.approve(dex.address,150,{from: accounts[1]})
        await token.approve(dex.address,250,{from: accounts[2]})
        await token.approve(dex.address,110,{from: accounts[3]})
        await dex.deposit(web3.utils.fromUtf8("MTK"),50,{from: accounts[0]})
        await dex.deposit(web3.utils.fromUtf8("MTK"),50,{from: accounts[1]})
        await dex.deposit(web3.utils.fromUtf8("MTK"),200,{from: accounts[2]})
        await dex.deposit(web3.utils.fromUtf8("MTK"),110,{from: accounts[3]})
        await dex.createLimitOrder(50,3,web3.utils.fromUtf8("MTK"),1,{from: accounts[1]})
        await dex.createLimitOrder(100,2,web3.utils.fromUtf8("MTK"),1,{from: accounts[2]})
        await dex.createLimitOrder(10,5,web3.utils.fromUtf8("MTK"),1,{from: accounts[0]})
        await dex.createLimitOrder(110,4,web3.utils.fromUtf8("MTK"),1,{from: accounts[3]})
        var SellOrder = await dex.getOrderBook(web3.utils.fromUtf8("MTK"),1)
        assert(SellOrder.length > 0)
        for(let i = 0; i<SellOrder.length; i++){
            console.log(SellOrder[i])
        }
    })

    it("must process matching orders",async ()=>{
        let token = await Token.deployed()
        let dex = await Dex.deployed()
        await dex.addToken(web3.utils.fromUtf8("MTK"),token.address)
        await token.approve(dex.address,2500)
        await dex.deposit(web3.utils.fromUtf8("MTK"),1000,{from: accounts[0]})
        dex.createLimitOrder(500,5,web3.utils.fromUtf8("MTK"),1,{from: accounts[0]})
        await dex.depositEther({value:1000, from: accounts[1]})
        var before_buyerbalance = await dex.balances(accounts[1],web3.utils.fromUtf8("MTK"))
        console.log(before_buyerbalance.toNumber())
        var before_sellerbalance = await dex.balances(accounts[0],web3.utils.fromUtf8("MTK"))
        console.log(before_sellerbalance.toNumber())
        await dex.createLimitOrder(100,5,web3.utils.fromUtf8("MTK"),0,{from: accounts[1]})
        var after_buyerbalance = await dex.balances(accounts[1],web3.utils.fromUtf8("MTK"))
        var after_sellerbalance = await dex.balances(accounts[0],web3.utils.fromUtf8("MTK"))
        console.log(after_sellerbalance.toNumber())
        console.log(after_buyerbalance.toNumber())
        assert(after_buyerbalance.toNumber() == before_buyerbalance.toNumber() + 100)
    })

    it("must delete completed Orders",async ()=>{
        let token = await Token.deployed()
        let dex = await Dex.deployed()
        await dex.addToken(web3.utils.fromUtf8("MTK"),token.address)
        token.approve(dex.address,2000)
        await dex.deposit(web3.utils.fromUtf8("MTK"),1000,{from: accounts[0]}) 
        await dex.createLimitOrder(500,5,web3.utils.fromUtf8("MTK"),1,{from: accounts[0]})
        var before_SellOrder = await dex.getOrderBook(web3.utils.fromUtf8("MTK"),1)
        await dex.depositEther({value:1000, from: accounts[1]})
        await dex.depositEther({value: 1250, from: accounts[2]})
        await dex.depositEther({value: 500, from: accounts[3]})
        await dex.createLimitOrder(200,5,web3.utils.fromUtf8("MTK"),0,{from: accounts[1]})
        await dex.createLimitOrder(250,5,web3.utils.fromUtf8("MTK"),0,{from: accounts[2]})
        await dex.createLimitOrder(100,5,web3.utils.fromUtf8("MTK"),0,{from: accounts[3]})
        var after_SellOrder = await dex.getOrderBook(web3.utils.fromUtf8("MTK"),1)
        assert.equal(after_SellOrder.length, before_SellOrder.length-1)
    })

})
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 that deposited eth >= buy order value
    it("Should ensure user has enough eth to create limit buy order", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await truffleAssert.reverts(dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 1, 2))
        dex.depositEth({value: 10})
        await truffleAssert.passes(dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 1, 2))
    })
    //The user must have enough tokens deposited such that token balance >= sell order amount
    it("Should ensure user has enough tokens to create limit sell order", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await truffleAssert.reverts(dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 1, 2))
        await link.approve(dex.address, 500);
        await dex.addToken(web3.utils.fromUtf8("LINK"), link.address, {from: accounts[0]})
        await dex.deposit(100, web3.utils.fromUtf8("LINK"));
        await truffleAssert.passes(dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 1, 2))
    })
    //The BUY order book should be ordered on price from highest to lowest starting at index 0
    it("Should ensure BUY orders are 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: 1000});
        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)

        let orderbook = await dex.getOrderBook(web3.utils.fromUtf8("LINK"), 0);
        for (let i = 0; i < orderbook.length - 1; i++) {
            assert(orderbook[i].price >= orderbook[i+1].price, "not right order in buy book")
        }
    })
    //The SELL order book should be ordered on price from lowest to highest starting at index 0
    it("Should ensure SELL orders are ordered lowest to highest", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await link.approve(dex.address, 500);
        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)

        let orderbook = await dex.getOrderBook(web3.utils.fromUtf8("LINK"), 1);
        for (let i = 0; i < orderbook.length - 1; i++) {
            assert(orderbook[i].price <= orderbook[i+1].price, "not right order in buy book")
        }
    })
})

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


//The user must have ETH deposited such that 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?

contract("Dex", accounts => {
    it ("should only be possible for trader to put in a BUY order up to the amount of eth he has", async () => {
        let dex = await Dex.deployed();
        let link = await Link.deployed();
        
        
        await truffleAssert.reverts(
            dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 10, 30 ) 
        )
        
        dex.depositEth({value:100}) 
        await truffleAssert.passes(
            dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 10, 10 ) //10 @ price 10 = 100 eth
        )
    })

    it ("user should have enough tokens deposited token balance >= sell order amount", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await truffleAssert.reverts(
            dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 10, 10) 
        )
        await link.approve(dex.address,500);
        await dex.addToken(web3.utils.fromUtf8("LINK"), link.address, {from: accounts[0]});
        await dex.deposit(100, web3.utils.fromUtf8("LINK"), {from: accounts[0]}); 
        
        await truffleAssert.passes(
            dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 10, 10) 
        )
        
    })

    it ("should have a BUY order book ordered on price from highest to lowest starting at index 0", async () => { 
        let dex = await Dex.deployed() 
        let link = await Link.deployed()
        await link.approve(dex.address, 100);
        await dex.depositEth({value: 3000});
        
        
        await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 10, 10);
        await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 10, 30);
        await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 10, 20);
        await dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 10, 50);
        await dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 10, 40);
        
        let orderbook = await dex.getOrderBook(web3.utils.fromUtf8("LINK"), 0);
        assert(orderbook.length > 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 ("should have a SELL order book ordered on price from lowest to highest starting at index 0", async () => { 
        let dex = await Dex.deployed();
        let link = await Link.deployed();
        await link.approve(dex.address, 1000);

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

        let orderbook = await dex.getOrderBook(web3.utils.fromUtf8("LINK"), 1);
        assert(orderbook.length > 0);
        console.log(orderbook);
        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
const Dex = artifacts.require("Dex")
const Link = artifacts.require("Link")
const truffleAssert = require("truffle-assertions");

contract("Dex", accounts => {

it("should be an error if user ETH balance < buy limit order", async () => {
    let dex = await Dex.deployed()
    let link = await Link.deployed()
    await truffleAssert.reverts(
        dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 10, 1) //reverts because eth balance is zero, lower than 10 (in 3rd parameter)
    )
})
it("should be an error if user ETH balance < buy limit order", async () => {
    let dex = await Dex.deployed()
    let link = await Link.deployed()
    await dex.depositEth({value: 10}) //deposits 10 eth
    await truffleAssert.passes(  //passes because eth balance is 10, which is >= that 10 (in 3rd parameter)
        dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 10, 1)
    )
})
it("should be an error if token balance < than sell limit order", async () => {
    let dex = await Dex.deployed()
    let link = await Link.deployed()
    await truffleAssert.reverts(  // reverts because eth balance is 0, less than 10 (in 3rd parameter);
        dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 10, 10)
    )
})
it("should be an error if token balance < than sell limit order", async () => {
    let dex = await Dex.deployed()
    let link = await Link.deployed()
    await link.approve(dex.address, 500);  // calls approve function in ierc20 and sends parameters.. 
    await dex.addToken(web3.utils.fromUtf8("LINK"), link.address, {from: accounts[0]})  //adds token into contract
    await dex.deposit(10, web3.utils.fromUtf8("LINK"));
    await truffleAssert.passes(    // passes because token balance is >= 10 which is the amount in the 3rd parameter.
        dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 10, 1)
    ) 
})
it("The buy order book should be ordered by price from highest to lowest starting at index 0", async () => {
    let dex = await Dex.deployed()
    let link = await Link.deployed()
    await link.approve(dex.address, 100);  // calls approve function in ierc20 and sends parameters..   
    await dex.depositEth({value: 3000});  // deposits eth into contract
    await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 1, 300);  // creates 3 limit orders with varying prices
    await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 1, 100);
    await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 1, 200);


    let orderbook = await dex.getOrderBook(web3.utils.fromUtf8("LINK"), 0);  // gets the buy orderbook for chainlink.
    assert(orderbook.length > 0);  //asserts that the orderbook has orders

    for (let i = 0; i < orderbook.length -1; i++) {  // loops through orderbook
        assert(orderbook[i].price >= orderbook[i+1].price, "not right order in buy book")  //starts at index 0, checks that the order[0] has a higher 
        //price than the next order[1] and so on.
    }
})
it("The sell order book should be ordered by price from lowest to highest starting at index 0", async () => {
    let dex = await Dex.deployed()
    let link = await Link.deployed()
    await link.approve(dex.address, 100);  // calls approve function in ierc20 and sends parameters.. 
    await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 1, 300);  // creates 3 limit orders with varying prices
    await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 1, 100);
    await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 1, 200);

    let orderbook = await dex.getOrderBook(web3.utils.fromUtf8("LINK"), 1);  // gets the sell orderbook for chainlink.
    assert(orderbook.length > 0);  //asserts that the orderbook has orders
    for (let i = 0; i < orderbook.length -1; i++) {    //loops through the orderbook
        assert(orderbook[i].price <= orderbook[i+1].price, "not right order in buy book")  //starts at index 0, checks that the order[0] has a lower
        //price than the next order[1] and so on.
    }
})

})
1 Like

I’m having a problem depositing eth to the wallet. All the sell functions are working for me.

1 Like
function createLimitOrder(
        Side side,
        bytes32 ticker,
        uint256 amount,
        uint256 price
    ) public {
        uint256 orderId = getOrderBook(ticker, side).length;
        Order memory order = Order(
            orderId,
            msg.sender,
            side,
            ticker,
            amount,
            price
        );

        orderBook[ticker][uint256(side)].push(order);

        if (uint256(side) == 1) {
            //Sell
            uint256 len = (orderBook[ticker][uint256(side)]).length;

            for (uint256 i = 0; i < len - 1; i++) {
                for (uint256 j = 0; j < len - 1; j++) {
                    if (
                        (orderBook[ticker][uint256(side)])[j].price >
                        (orderBook[ticker][uint256(side)])[j + 1].price
                    ) {
                        Order memory temp = (orderBook[ticker][uint256(side)])[
                            j
                        ];
                        (orderBook[ticker][uint256(side)])[j] = (
                            orderBook[ticker][uint256(side)]
                        )[j + 1];
                        (orderBook[ticker][uint256(side)])[j + 1] = temp;
                    }
                }
            }
        } else if (uint256(side) == 0) {
            // Buy
            uint256 len = (orderBook[ticker][uint256(side)]).length;
            for (uint256 i = 0; i < len - 1; i++) {
                for (uint256 j = 0; j < len - 1; j++) {
                    if (
                        (orderBook[ticker][uint256(side)])[j].price <
                        (orderBook[ticker][uint256(side)])[j + 1].price
                    ) {
                        Order memory temp = (orderBook[ticker][uint256(side)])[
                            j
                        ];
                        (orderBook[ticker][uint256(side)])[j] = (
                            orderBook[ticker][uint256(side)]
                        )[j + 1];
                        (orderBook[ticker][uint256(side)])[j + 1] = temp;
                    }
                }
            }
        }
    }
1 Like

hey @bargerinare u still facing issues. if so drop me a dm or explain your post here ill look into it for u

Sadly i had to check out Filips code for help : (

//The user must have ETH deopsited 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 ot highest starting at index 0


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

//The user must have ETH deopsited such that deposited eth >= buy order value
contract("Dex", accounts => { //Side side, bytes32 ticker, uint256 amount, uint256 price 
    it("TheThe user must have ETH deopsited such that deposited eth >= buy order value user must have more ETH than the buy order value", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await truffleAssert.reverts(
               dex.createLimitOrder(0,web3.utils.fromUtf8("LINK"),20,1))
        })
          dex.deposit({value:20})
          await truffleAssert.passes(
          dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"),20,1))
      })
     
//The user must have enough tokens deposited such that token balance >= sell order amount
    it("TheThe user must have ETH deopsited such that deposited eth >= buy order value user must have more ETH than the buy order value", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await truffleAssert.revert( 
              dex.createLimitOrder(1,web3.utils.fromUtf8("LINK"),20,1)
        )
        })
        await link.approve(dex.address,500);
        await dex.addToken(web3.utils.fromUtf8("LINK"), link.address)
        await dex.deposit({value:20});
        await truffleAssert.passes(
            dex.createLimitOrder(1,web3.utils.fromUtf8("LINK"),20,1)
            
        )
        
    

//The BUY order book should be ordered on price from highest to lowest starting at index 0
    it("The user must have more ETH than the buy order value", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await link.approve(dex.address,500);
        await dex.deposit({value: 3000});
        await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 3, 300)
        await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 3, 100)
        await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 3, 200)
      
             let viewbook = await dex.getOrderBook(web3.utils.fromUtf8("LINK"), 0);
             for(let i=0;i < viewbook.length -1;i++){
                assert(viewbook[i].price >= viewbook[i+1].price, "The price order for 'BUY' is wrong") //-1 means the fist instance in the array, +1 is the next number inline. position 1 must be larger than position 2
             }
        }) 
  //The SELL order book should be ordered on price from lowest to highest starting at index 0
        it("The user must have more ETH than the buy order value", async () => {
            let dex = await Dex.deployed()
            let link = await Link.deployed()
            await link.approve(dex.address,500);
            await dex.deposit({value: 3000});
            await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 3, 300)
            await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 3, 100)
            await dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 3, 200)

            let viewbook = await dex.getOrderBook(web3.utils.fromUtf8("LINK"), 0);
            for(let i=0;i < viewbook.length -1;i++){
               assert(viewbook[i].price <= viewbook[i+1].price, "The price order for 'SELL' is wrong")
    
            }

        })
    



hi there, i can’t seem to get my code to pass as one. Separately both truffleAssert.reverts and truffleAssert.passes, pass, but when executed at the same time they fail.

contract("Dex", accounts => {
    //The user must have ETH deposited such that deposited eth >= buy order value
    it("should throw an error if ETH balance is too low when creating BUY limit order", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
       
        truffleAssert.reverts(
           dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 10, 1)
        )
        
        await dex.depositEth({value: 10})
           truffleAssert.passes(
            dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 10, 1)
        )
    })

error message

1) Contract: Dex
       should throw an error if ETH balance is too low when creating BUY limit order:
     Uncaught AssertionError: Did not fail
      at fails (node_modules/truffle-assertions/index.js:161:9)
      at processTicksAndRejections (node:internal/process/task_queues:96:5)



UnhandledRejections detected
Promise {
  <rejected> AssertionError: Did not fail
      at fails (node_modules/truffle-assertions/index.js:161:9)
      at processTicksAndRejections (node:internal/process/task_queues:96:5) {
    showDiff: false,
    uncaught: true
  }
} AssertionError: Did not fail
    at fails (node_modules/truffle-assertions/index.js:161:9)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  showDiff: false,
  uncaught: true
}

Is there a break type function like in javascript
that i can use to stop the code running after it passes the truffleAssert.reverts?

I hope my question makes sense.

you might need to use await at the start of each function call of the contract instance.

Carlos Z

hi Carlos,

Unfortunately I’ve already tried this. The error message I get from this is as follows:

1) Contract: Dex
       should throw an error if ETH balance is too low when creating BUY limit order:
     Uncaught AssertionError: Did not fail
      at fails (node_modules/truffle-assertions/index.js:161:9)
      at processTicksAndRejections (node:internal/process/task_queues:96:5)

When i remove the await keyword from the dex.createLimitOrder the test then passes.

 Contract: Dex
    ✔ should throw an error if ETH balance is too low when creating BUY limit order (3080ms)

  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


  1 passing (4s)
  4 pending

So far, I have tried the following:

  • swapped the positioning of reverts and passes incase the code reverting somehow affects the rest of the tests by being tested first

  • I’ve tested each test individually(all passed) then I tested 2 at a time then 3 at a time and then when adding the last test and it failed.

  • I tested them in reverse order and it seems like the issue is coming from the first test.

  • I’ve played around with adding and removing await on certain functions and in some cases the test passed, especially when removing it from the truffle assert function but again, getting the entire set of tests to pass together isn’t happening.

Let me know if you have any other ideas, I am currently running v0.8.0 of solidity.

1 Like

hey @unwise_guy you wull need the await in the tests usually. can u share a github repo for me to check and look at i will get to the bottom of your errors

1 Like

Sorry for the wait, here is a link to my repo

https://github.com/oscaroneim/Dex2

1 Like

hey @unwise_guy so im cloning your code now. will get back to you shortly

@unwise guy. i notice you have a few files missing from your github repo. can you upload all files from your project to your github repo

1 Like

Sorry for the late reply, i don’t seem to be getting any notifications when you reply. I have uploaded the rest.
Please let me know what you find.

1 Like

ok @unwise_guy do i fixed all of your tests and there were a few things. firstly the main reason they were failing was becaus eyou had no implemented the createLimitOrder function correctly. your function is as follows

function bubbleSort()public pure returns(Order[] memory){

          Order[] memory orders;

          uint length = orders.length;

          for(uint i=0; i<orders.length; i++){
          for(uint j=0; j<orders.length; j++){
              if(side == Side.BUY){
               uint currentValue = orders[j];
               orders[j] = orders[j+1];
               orders[j+1] = currentValue;
              }
             }
          }
         return orders;
              
     }

    function createLimitOrder(Side side, bytes32 ticker, uint price, uint amount)public {
          if(side == Side.BUY){
            require(balances[msg.sender]["ETH"] >= amount.mul(price)); //this makes sure that there is enough ETH in the BUY side account before executing 
          }
          else if(side == Side.SELL){
            require(balances[msg.sender][ticker] >= amount.mul(price)); ////this makes sure that there is enough ETH in the SELL side account before executing
    }
    
     Order[] storage orders = orderBook[ticker][uint(side)]; //created an array to push the limit orders into.

     orders.push(
      Order(nextOrderId, msg.sender, side, ticker, amount, price) //nextOrderId was created to fill the id criteria for the Order struct. This pushes the orders into the array but not in any order.
     );

i think its good that you tried to segregate the bibble sort logic into your own helper function. it shows that your trying to think for yourself by chaning it up from the videos source code. however this is what was causing a lot of your problems. firstly your contract wouldnt compile because of errors in the bubbleSort helper function. i changed your contract. so the new version with my edits are give below

pragma solidity ^0.8.0;
pragma experimental ABIEncoderV2;

import "./wallet.sol";

contract Dex is Wallet {
using SafeMath for uint256;
    
    enum Side {
        Buy, //0
        Sell //1
    }

    //order.side = Side.Buy
  

    struct Order {
        uint id;
        address trader;
        Side side;
        bytes32 ticker;
        uint amount;
        uint price; //limit orders
        uint filled;
    }

    uint public nextOrderID = 0;

    mapping(bytes32 => mapping(uint => Order[])) orderBook;

    function getTokenList() public view returns(uint256){
        return tokenList.length;
    }

    function getOrderBook(bytes32 ticker, Side side) view public returns(Order[] memory){
        return orderBook[ticker][uint(side)];
    }

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

        if(side == Side.Buy){
            require(balances[msg.sender]["ETH"] >= amount.mul(price));
        }
        else if(side == Side.Sell){
            require(balances[msg.sender][ticker] >= amount);
        }
        Order[] storage orders = orderBook[ticker][uint(side)];
        orders.push( Order(nextOrderID, msg.sender, side, ticker, amount, price, 0) );

        //Bubble Loop Algorithm to sort Buy and Sell orders
        uint i = orders.length > 0 ? orders.length -1 : 0;

        if(side == Side.Buy){
           while(i > 0){
               if(orders[i-1].price > orders[i].price){
                   break;
               }
               Order memory orderToMove = orders[i-1];
               orders[i - 1] = orders[i];
               orders[i] = orderToMove;
               i--;
           }
        }

        else if(side == Side.Sell){
            while(i > 0){
               if(orders[i - 1].price < orders[i].price){
                   break;
               }
               Order memory orderToMove = orders[i-1];
               orders[i - 1] = orders[i];
               orders[i] = orderToMove;
               i--;
           }
        }
        nextOrderID++;
}


}

the next error was an incorrect import of the ERC20 token contrat in both of your token contracts. in both of these file splease change

import "../node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol";

to

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

this was your second mistake. for some reason adding the full path to the openzeppelin library was causing issues with your tests. So the last issue was the tests themselves. there were too many bad issues here. but i decided to completely reqrite your tests because i was actually having some issues debugg yours.

the main thing to think about when your debugging tests is testing line by line. if your test is fialing. comment everything out except for the first line. run the tets and is it passes, comment out the next line and run again. if you keep doing this eventually youll get to the line that fails and from here its much easier to debug because you know where the source of the error is. your fixed tests are given below.

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 that deposited eth is >= to buy order value
    it("user's deposited ETH is >= buy order", async () => {
        let dex = await Dex.deployed()

        await truffleAssert.reverts( //buy will not be created due to no ETH
            dex.createLimitOrder(0, web3.utils.fromUtf8("Link"), 10, 1)
        )
        await dex.depositEth({value: 10}) //Eth deposited so will be created
        await truffleAssert.passes( 
            dex.createLimitOrder(0, web3.utils.fromUtf8("Link"), 10, 1)
        )
        //createLimitOrder(Side side, bytes32 ticker, uint amount, uint price) public {
    })
    // the user must have enough tokens deposited such that token balance is >= to sell order amount
    it("user's token balance is >= sell order amount", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await dex.addToken(web3.utils.fromUtf8("Link"), link.address, {from: accounts[0]})
        await truffleAssert.reverts( //reverts because no Link approved or deposited
            dex.createLimitOrder(1, web3.utils.fromUtf8("Link"), 10, 1)
        )
        await link.approve(dex.address, 500);
        await dex.deposit(100, web3.utils.fromUtf8("Link"));
        await truffleAssert.passes( //passes because deposit has been approved and settled
            dex.createLimitOrder(1, web3.utils.fromUtf8("Link"), 10, 1)
        )

        //createLimitOrder(Side side, bytes32 ticker, uint amount, uint price) public {
    })

    // the buy order should be ordered on price from highest to lowest from index 0
    it("(Buy Order)should be in order from highest to lowest", async ()=> {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await link.approve(dex.address, 500);
        await dex.depositEth({value: 1000});
        
        dex.createLimitOrder(0, web3.utils.fromUtf8("Link"), 1, 10)
        dex.createLimitOrder(0, web3.utils.fromUtf8("Link"), 1, 30)
        dex.createLimitOrder(0, web3.utils.fromUtf8("Link"), 1, 25)

        let orderbook = await dex.getOrderBook(web3.utils.fromUtf8("Link"), 0)
        assert(orderbook.length > 0)
        var i;
        for(i = 0; i < orderbook.length -1; i++){
            assert (orderbook[i].price >= orderbook[i+1].price, "Buy order book has not bee sorted")
        }
    })

    // the sell order should be ordered on price from highest to lowest from index 0
    it("(Sell Order)should be in order from highest to lowest", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await link.approve(dex.address, 500);
        // await dex.depositEth({value: 1000});
        await dex.deposit(100, web3.utils.fromUtf8("Link"));
        dex.createLimitOrder(1, web3.utils.fromUtf8("Link"), 1, 10)
        dex.createLimitOrder(1, web3.utils.fromUtf8("Link"), 1, 30)
        dex.createLimitOrder(1, web3.utils.fromUtf8("Link"), 1, 25)

        let orderbook = await dex.getOrderBook(web3.utils.fromUtf8("Link"), 1)
        assert(orderbook.length > 0)
        var i;
        for(i = 0; i < orderbook.length - 1; i++){
            assert (orderbook[i].price <= orderbook[i+1].price, "Sell order book has not bee sorted")
        }
    })
});

if yu have any frther questions. please let me know

Evan

2 Likes

Hi Evan,

Thanks for looking into to all this.

I have a question about the SELL order test. For some reason the code fails at the assert function that checks that there are orders in the orderbook array. The code works fine for the BUY side test.

// the sell order should be ordered on price from highest to lowest from index 0
    it("(Sell Order)should be in order from highest to lowest", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await link.approve(dex.address, 500);
        await dex.depositEth({value: 1000});

        dex.createLimitOrder(1, web3.utils.fromUtf8("ETH"), 1, 10)
        dex.createLimitOrder(1, web3.utils.fromUtf8("ETH"), 1, 30)
        dex.createLimitOrder(1, web3.utils.fromUtf8("ETH"), 1, 25)

        let orderbook = await dex.getOrderBook(web3.utils.fromUtf8("ETH"), 1);

        assert(orderbook.length > 0);

        for(let i = 0; i < orderbook.length - 1; i++){
         assert (orderbook[i].price <= orderbook[i+1].price, "Sell order book has not bee sorted")
        }
    }
    )
}
);
3 passing (15s)
  4 pending
  1 failing

  1) Contract: Dex
       (Sell Order)should be in order from highest to lowest:
     AssertionError: Unspecified AssertionError
      at Context.<anonymous> (test/dexTest.js:77:9)
      at runMicrotasks (<anonymous>)
      at processTicksAndRejections (node:internal/process/task_queues:96:5)

If you comment out the assert, the code passes

//assert(orderbook.length > 0);
Contract: Dex
    ✔ user's deposited ETH is >= buy order (7353ms)
    ✔ user's token balance is >= sell order amount (4234ms)
    ✔ (Buy Order)should be in order from highest to lowest (2226ms)
    ✔ (Sell Order)should be in order from highest to lowest (2185ms)

  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


  4 passing (17s)
  4 pending

Let me know your thoughts.

Cheers,
Oscar

1 Like

hmm this is stranfe. can you console.log() the orderbook. it must be empty and this would make sense as to why your test is passing

1 Like

I’m not sure what i’m doing wrong but i can’t seem to get the console.log to show any information. I’ve placed it underneath the orderbook variable.

it("(Sell Order)should be in order from highest to lowest", async () => {

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

        await link.approve(dex.address, 500);
        //await dex.depositEth({value: 1000});
        await dex.deposit(100, web3.utils.fromUtf8("Link"));

        dex.createLimitOrder(1, web3.utils.fromUtf8("Link"), 1, 10)
        dex.createLimitOrder(1, web3.utils.fromUtf8("Link"), 1, 30)
        dex.createLimitOrder(1, web3.utils.fromUtf8("Link"), 1, 25)

        let orderbook = await dex.getOrderBook(web3.utils.fromUtf8("Link"), 1);
        console.log(orderbook);

        assert(orderbook.length > 0)

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

            assert (orderbook[i].price <= orderbook[i+1].price, "Sell order book has not bee sorted")

        }

    })