Assignment - Limit Order Test

Such good practice!! Here is my dextest,js file!!

//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 should be ordered on price from Lowest to highest starting at index 0.

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 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()
        await truffleAssert.reverts(
            dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 10, 1)
        )
        dex.depositEth({value: 10})
        await truffleAssert.passes(
            dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 10, 1)
        )
    })
    //The user must have enough tokens deposited such that token balance >= sell order amount.
    it("should throw an error if token balance is too low when creating SELL limit order", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await truffleAssert.reverts(
            dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 10, 1)
        )
        await link.approve(dex.address, 500);
        await dex.addToken(web3.utils.fromUtf8("LINK"), link.address, {from: accounts[0]})
        await dex.deposit(10, web3.utils.fromUtf8("LINK"));
        await truffleAssert.passes(
            dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 10, 1)
        )
    })
    //The BUY order book should be ordered on price from highest to lowest starting at index 0.
    it("highest to lowest order for the orderbook starting at index 0.", 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.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 should be ordered on price from Lowest to highest starting at index 0.
    it("should throw an error if the orderbook is not in order forom lowest to highest starting at index 0", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await link.approve(dex.address, 500);
        await dex.withdrawEth({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)

        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 in right orer in sell book")
        }
    })
})

2 Likes

@Mickey_McClimon niceeone did you get it working?

1 Like

sure did!! just a clown spelling error as usual haha

1 Like

@Mickey_McClimon hahahha aww its always the way isnt it. when ya loose all ability to think or spell after staring at a screen all day lol. happy days g.

1 Like

god aint that the truth!! :sweat:

1 Like
it("should only allow buy order to be posted with sufficient amount of ETH", async () =>{

        let dex = await Dex.deployed({value: web3.utils.toWei('10', 'ether'), from: accounts[0]})

        let link = await Link.deployed()

        

        await truffleAssert.passes(

            dex.createLimitOrder(web3.utils.fromUtf8("LINK"), uint(BUY), 100, 3, {from: accounts[0]})

        )

        await truffleAssert.reverts(

            dex.createLimitOrder(web3.utils.fromUtf8("LINK"), uint(BUY), 100, 3, {from: accounts[1]})

        )

    })

I was wondering if I was able to just put ether into an account right at deployment rather than making a whole function to deposit Ether. I think it makes more sense that way because the contract will only have to really keep track of token balances instead of as well as eth balance and just charge the price of the order in Eth from the user. If this is not possible I will just use a function to deposit it.

1 Like

Hey @DJaySplash

I was wondering if I was able to just put ether into an account right at deployment rather than making a whole function to deposit Ether.

In your migration you can surely deposit ether in your contract after the deployment, but still you need a deposit eth function to allow other users to deposit ether in your contract.

Happy coding,
Dani

//user must have eth deposited such that deposited eth >= buy order value
//The user must have enough tokens depoisited such that token balance >= sell order amount 
//The Buy book should be ordered from highest to lowest ([0]) in the Buy order book should have the highest price
//The Sell book should be ordered from lowest to highest ([0]) in the Sell order book should have lowest price 
//Orderbook.length should be == number of orders after order has been created
//Sell orders should add to sell order book 
//Buy orders should add to Buy order book 

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

contract("Dex", accounts => {

    it ("Should only be possible to create buy order if user has enough ETH", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        //My assumption here is that the msg.sender default value of Eth is 100

        await truffleAssert.reverts(
            dex.createLimitOrder(dex.Side.BUY,web3.utils.fromUtf8("LINK"),100,2)
        )

        await truffleAssert.passes(
            dex.createLimitOrder(dex.Side.BUY,web3.utils.fromUtf8("LINK"),100,.001)
        )

        
    })

    it ("Should only be possible to create sell order if user has enough token balance", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await link.approve(dex.address, 1000)
        await dex.deposit(100, web3.utils.fromUtf8("LINK"))

        await truffleAssert.reverts(
            dex.createLimitOrder(dex.Side.SELL,web3.utils.fromUtf8("LINK"),200,2)
        )
        await truffleAssert.passes(
            dex.createLimitOrder(dex.Side.SELL,web3.utils.fromUtf8("LINK"),100,.001)
        )
    })

    it ("Should update Buy order book such that the book is ordered highest to lowest price", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()

        dex.createLimitOrder(dex.Side.BUY,web3.utils.fromUtf8("LINK"),100,.001)
        dex.createLimitOrder(dex.Side.BUY,web3.utils.fromUtf8("LINK"),100,.003)
        dex.createLimitOrder(dex.Side.BUY,web3.utils.fromUtf8("LINK"),100,.002)
        

        let buyorderbook = await dex.getOrderBook(web3.utils.fromUtf8("LINK"), dex.Side.BUY);
        for (let i = 0; i < buyorderbook.length - 1; i++) {
            assert(buyorderbook[i].price >= buyorderbook[i+1].price, "Buy orders not sorted")
        }
    })

    it ("Should update Sell order book such that the book is ordered lowest to highest price", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await dex.deposit(300, web3.utils.fromUtf8("LINK"))

        dex.createLimitOrder(dex.Side.SELL,web3.utils.fromUtf8("LINK"),100,.001)
        dex.createLimitOrder(dex.Side.SELL,web3.utils.fromUtf8("LINK"),100,.003)
        dex.createLimitOrder(dex.Side.SELL,web3.utils.fromUtf8("LINK"),100,.002)

        let sellorderbook = await dex.getOrderBook(web3.utils.fromUtf8("LINK"), dex.Side.SELL);
        for (let i = 0; i < sellorderbook.length - 1; i++) {
            assert(sellorderbook[i].price <= sellorderbook[i+1].price, "Sell orders not sorted")
        }
    })

    it ("Should update length of order books properly", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()

        assert.equal(3,dex.orderBook[web3.utils.fromUtf8("LINK")][uint(Side.BUY)].length)
        assert.equal(3,dex.orderBook[web3.utils.fromUtf8("LINK")][uint(Side.SELL)].length)
    })
    
})
1 Like
const truffleAssert = require("truffle-assertions")

const Dex = artifacts.require("Dex")

const Link = artifacts.require("Link")

contract("Dex", accounts =>{

    it("should only allow buy order to be posted with sufficient amount of ETH", async () =>{

        let dex = await Dex.deployed()

        let link = await Link.deployed()

        await truffleAssert.reverts(

            dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 0, 100, 3)

        )

        await dex.depositEther({value:100000})

        await truffleAssert.passes(

            dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 0, 100, 3)

        )

    })

    it("should only allow sell order to be posted with sufficient amount of tokens", async () =>{

        let dex = await Dex.deployed()

        let link = await Link.deployed()

       

        await truffleAssert.reverts(

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

        )

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

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

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

        

        await truffleAssert.passes(

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

        )

    })

    it("should only rank buy book from highest to lowest price", async () =>{

        let dex = await Dex.deployed()

        let link = await Link.deployed()

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

        await dex.depositEther({value:100000});

        dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 0, 100, 3)

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

        dex.createLimitOrder(web3.utils.fromUtf8("LINK"), 0, 100, 5)

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

        assert(buyOrderBook.length > 0);

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

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

        }

    })

    it("should only order sell book from lowest to highest price", async () =>{

        let dex = await Dex.deployed()

        let link = await Link.deployed()

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

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

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

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

        let sellOrderBook = await dex.getOrderBook(web3.utils.fromUtf8("LINK"), 1)

        assert(buyOrderBook.length > 0);

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

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

        }

    })

})

Should I add the deposit Ether function to the DEX contract or the wallet contract? Also, it is very confusing on why the answer from filip video is different than his github link. I was trying to compare my answer with his and was wondering why there were that way.

2 Likes

hey @DJaySplash. I would put it into the dex contract . You could say somehing like this

function depositEther() payable public {
      balances[msg.sender][bytes32("ETH")] = balances[msg.sender][bytes32("ETH")].add(msg.value);
   }

however another way you could also do it is to make an eth token in your token.sol file, the same file where you created the link token and just addToken, approve and deposit as normal like you would for link except change your ticker to ā€œETHā€.

1 Like

Hey everyone.

My level of knowledge is only marginally growing, and in too many different directions at once to be useful. So hereā€™s my good-faith effort on the partial contract (Iā€™ll spare you the mountains of example and test contracts Iā€™ve constructed to learn more underlying concepts), which was supposed to come after the tests. However, trying to get all the pieces to fit together and fill in particular knowledge gaps this way has got me losing steam, so I need to see how itā€™s done. Haha, please donā€™t judge me too harshly. Iā€™ll make good with the knowledge gained moving forward. Weā€™re all in this together, right!?

contract Dex is Wallet{
    
    enum Side{
    BUY,
    SELL
    }
    
    struct Order{
        uint id;
        address trader;
        Side side;
        bytes32 ticker;
        uint amount;
        uint price; //in this context, you BUY token WITH ETH and SELL token FOR ETH
                    //--> Amount always refers to TOKEN being SOLD or BOUGHT
                    //--> price always refers to an amount of ETH 
    }
        
    uint public orderIds = 1;//compareOrderToBooks doesn't work if IDs are set as 0.
    uint public totalEthInContract;

    mapping(address => uint) ethBalances;

    mapping(bytes32 => mapping(uint => Order[])) public orderBook;
    
    fallback () external payable{
        depositEth();
    }

    function incrimentOrderIds() private{
        orderIds ++;
    }

    function depositEth() public payable returns(bool){
        require(msg.value > 0, "Take that chump change elsewhere, bub");
        totalEthInContract += msg.value;
        ethBalances[msg.sender] += msg.value;
        return true;

    }

    function createLimitOrder(Side side, uint ticker, uint amount, uint price) public returns(Order memory){ //using uint as type for passing to this function.  Not sure how else to develop otherwise.
        //requre that token exists
        //check that msg.sender has sufficient ETH or other token in regards to new order
        bytes32 byteTicker = bytes32(ticker);//wacky conversion so I can use REMIX to develop set of AMM functions
        Order memory newOrder = Order(orderIds, msg.sender, side, byteTicker, amount, price);
        incrimentOrderIds();
        compareOrderToBooks(newOrder);//check to see if there is a trade that may be settled
        return newOrder;
        
    }

    function getOrderBook(bytes32 ticker, Side side) view public returns(Order[] memory){
        return orderBook[ticker][uint(side)];
    }
    
    
    
    function compareOrderToBooks(Order memory newOrder) public{//no return type needed as I see it right now
        //compare NEW BUY ORDER to top sell order in sell book
        if(newOrder.side == Side.BUY){
            //top of order book is not empty AND bid is greater than or == ask
            if(newOrder.price >= getOrderBook(newOrder.ticker, Side.SELL)[0].price && getOrderBook(newOrder.ticker, Side.SELL)[0].id != 0){
                executeTrade(newOrder, getOrderBook(newOrder.ticker, Side.SELL)[0]);
            }
        }
        //compare NEW SELL ORDER to top buy order in buy book
        else{
            //top of order book is not empty AND ask is less than or == bid
            if(newOrder.price <= getOrderBook(newOrder.ticker, Side.BUY)[0].price && getOrderBook(newOrder.ticker, Side.BUY)[0].id != 0){
                executeTrade(getOrderBook(newOrder.ticker, Side.BUY)[0], newOrder);
            }
        }
        //placeInBook()
    }
    

    
    function executeTrade(Order memory buyOrder, Order memory sellOrder) private returns(Order memory amendedOrder){
        //transfer ETH from the SELLER to the BUYER.  
        //if a buyer, check for sufficient ETH balance
        //if a seller, check sufficient TOKEN balance
        //while there are units to be found in the sell order, 
        //function body:  Needs to adjust the applicable trades, and if there are uncomplete portions, then then
        //function needs to call the compare function again until all resolvable trades have been resolved.  Then place remaining
        //trade as new trade in appropriate spot in order book
        while(buyOrder.amount != 0){
            //transfer ETH to seller and TOKEN to buyer
            //iterate number of 'amount' to be the smaller of the buy/sell amount
            uint transferAmount = buyOrder.amount;
            if(buyOrder.amount >= sellOrder.amount){transferAmount = sellOrder.amount;}
            //send the ether to seller (must first be deposited to DEX) but when and how much

            //send the token to buyer
            IERC20(tokenMapping[buyOrder.ticker].tokenAddress).transferFrom(sellOrder.trader, buyOrder.trader, transferAmount);
            //update our mapping
        }
        
    }

And now I can get some rest and slay this baby Grendle monster tomorrow with a fresh head.

3 Likes

great @Melshman to see youve made lodes of progress the end of the course is nearly in sight keep pushing man very close now. I just was looking at your code and you pass your ticker as a unit into your create limit order function. how come you do this.

@mcgrane5,

Thatā€™s a really great questions. I had read your post where you mentioned using remix instead of waiting for everything to compile each time in VS code, so I went that route. I really just need to get better at commanding the truffle compiler in VS code, but ā€œoneā€ thing at a time.

Anyway, I ended up experiementing with some casting options to achieve the bytes32 of any value so I could test my contract in Remix since I wasnā€™t able to actually produce good bytes32 input of strings via the remix GUI. That definitely needs to be changed, and certainly will change when I finish fleshing out my contract and tests. Hopefully by later tonight, depending on how ambitious my GF wants todayā€™s house-cleaning to be.

How were you passing bytes32 values of ā€œLINKā€ or ā€œTOKEN_NAMEā€ via remix? Iā€™m probably missing something really simple. I imagine a lot of us on these forums are guilty of overthinking certain things at times.

Hey sorry for the quick reply but im currently on my phone but i set my ticker as a string in my struct instead of bytes32 so i didnt have to do that conversion that filip does to get it to output the string representation of the ticker. So in each of my finctions i just passed in ā€œstring memory tickerā€.

Hello.

Iā€™ve been fiddling with these test scripts, Iā€™m back to having it almost exactly as Filip did in the solution video. The problem is I canā€™t be sure what is wrong with my code. Below is my dex.sol code, but Iā€™m more interested in what Iā€™m doing wrong with the test:

dex.sol:

pragma solidity ^0.8.4;
pragma experimental ABIEncoderV2;

import "./wallet.sol";


contract Dex is Wallet{
    
    using SafeMath for uint256;

    enum Side{
    BUY,
    SELL
    }
    
    struct Order{
        uint id;
        //some way to implement timestamp from the JS front end to resolve equal orders
        address trader;
        Side side;
        string ticker;
        uint amount;
        uint price;
    }
        
    uint public orderIds = 0;

    mapping(string => mapping(uint => Order[])) public orderBook;
    
    receive ()external payable{
        depositEth();
    }
    
   // fallback () external payable{
   //     depositEth();
   // }

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

    function incrimentOrderIds() private{
        orderIds ++;
    }

    function depositEth() public payable{
        balances[msg.sender]["ETH"] = balances[msg.sender]["ETH"].add(msg.value);
    }

    function shouldISwap(uint price1, uint price2, Side side) private pure returns(bool){
        bool doSwap;
        if(side == Side.SELL){
            if(price1 > price2){ return true;}
        }
        if(side == Side.BUY){
            if(price1 < price2){ return true;}
        }
        return false;
    }

    function bubbleSortOrderBook(string memory ticker, Side side, uint sortWasMade) internal returns(bool){
        //test if cheaper to use nested loops, or include a recursive function call as part of process
        //designing function arguments to use function recursively
        bool isSorted;
        if(sortWasMade == 0){ return true; }
        Order[] storage bookToSort = orderBook[ticker][uint(side)];
        sortWasMade = 0;
        for(uint i = 0; i < bookToSort.length - 2; i++){
            if(shouldISwap(bookToSort[i].price, bookToSort[i + 1].price, side)){
                //swapOrders(ticker, side, i, i+1);
                Order memory tempOrder = bookToSort[1];
                bookToSort[i] = bookToSort[i + 1];
                bookToSort[i + 1] = tempOrder;
                sortWasMade++;
            }
        }
        //at this point if no new sort was made, we will pass a 0 to the bubblesort call again, yielding a true return
        return bubbleSortOrderBook(ticker, side, sortWasMade);
    }

    function swapOrders(string memory ticker, Side side, uint firstOrderIndex, uint secondOrderIndex) internal {
        Order memory tempOrder = orderBook[ticker][uint(side)][firstOrderIndex];
        orderBook[ticker][uint(side)][firstOrderIndex] = orderBook[ticker][uint(side)][secondOrderIndex];
        orderBook[ticker][uint(side)][secondOrderIndex] = tempOrder;
    }

    function createLimitOrder(Side side, string memory ticker, uint amount, uint price) public returns(bool){
        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(orderIds, msg.sender, side, ticker, amount, price)
        );

        if(side == Side.BUY){
            bubbleSortOrderBook(ticker, side, 1);
        }
        else if(side == Side.SELL){
            bubbleSortOrderBook(ticker, side, 1);
        }

        orderIds ++;
        bubbleSortOrderBook(ticker, side, 1);
        return true;
    }
}  

When I run the test script dextest.js:

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




contract("Dex", accounts => {
    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()
       //await truffleAssert.reverts(
       //    dex.createLimitOrder(0, "LINK", 10, 1)
       //)
        dex.depositEth({value: 10})
        await truffleAssert.passes(
            dex.createLImitOrder(0, "LINK", 10, 1)
        )
    })
    //user must have enough tokens deposited such that the token balance >= sell order amount
    it("should throw an error if token balance is too low when creating SELL limit order", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await truffleAssert.reverts(
            dex.createLimitOrder(1, "LINK", 10, 1)
        )
        await link.approve(dex.address, 500)
        await dex.deposit(10, "LINK")
        truffleAssert.passes(
            dex.createLimitOrder(1, "LINK", 10, 1)
        )
           
    })
    //The BUY order book should be ordered on price from hightest to lowest starting at index 0
    it("The BUY order book should be ordered on price from hightest to lowest starting at index 0", 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, "LINK", 1, 300)
        await dex.createLimitOrder(0, "LINK", 1, 100)
        await dex.createLimitOrder(0, "LINK", 1, 200)

        let orderbook = await dex.getOrderBook("LINK", Side.BUY)
        assert(orderbook.length > 0)
        //aorderbook[0] = await new dex.Order(1011, msg.sender, BUY, "LINK", 23, 32)
        for(let i = 0; i < orderbook.length - 1; i++) {
            assert(orderbook[i] >= orderbook[i+1], "not right order in the BUY book")
        }
    })
    //The SELL order book should be ordered on price from lowest to highest starting at index 0
    it("SELL order book should be ordered on price from lowest to hightest starting at index 0", async () => {
        let dex = await Dex.deployed()
        let link = await Link.deployed()
        await link.approve(dex.address, 500)
        await dex.createLimitOrder(1, "LINK", 1, 300)
        await dex.createLimitOrder(1, "LINK", 1, 100)
        await dex.createLimitOrder(1, "LINK", 1, 200)

        new  Promise(() => console.log(dex.balances[msg.sender]["LINK"]));
        //console.log(dex.balances[msg.sender]["ETH"]);

        let orderbook = await dex.getOrderBook("LINK", 1)
        assert(orderbook.length > 0);
        for (let i = 0; i < orderbook.length - 1; i++){
            assert(orderbook[i] <= orderbook[i + 1], "check your SELL orderbook ordering")
        }
    })

})

I get the following errors:

  1) Contract: Dex
       should throw an error if ETH balance is too low when creating BUY limit order:
     TypeError: dex.createLImitOrder is not a function
      at Context.<anonymous> (test\dextests.js:17:17)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)

  2) Contract: Dex
       should throw an error if token balance is too low when creating SELL limit order:
     Error: Returned error: VM Exception while processing transaction: revert token does not exist -- Reason given: token does not exist.       
      at Context.<anonymous> (test\dextests.js:28:19)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)

  3) Contract: Dex
       The BUY order book should be ordered on price from hightest to lowest starting at index 0:
     Error: Returned error: VM Exception while processing transaction: revert
      at Context.<anonymous> (test\dextests.js:40:19)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)

  4) Contract: Dex
       SELL order book should be ordered on price from lowest to hightest starting at index 0:
     Error: Returned error: VM Exception while processing transaction: revert
      at Context.<anonymous> (test\dextests.js:56:19)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)

Part of me wonders if maybe Iā€™m exceeding the gas limit for a single function call? The tests from the wallettest.js file from earlier in the course pass just fine.

Also, Iā€™d like to know what Iā€™m doing that wonā€™t allow console.log() to work from inside my truffle test.

Iā€™m sure my contract needs some work, but until I know what Iā€™m doing thatā€™s causing my tests to fail, I canā€™t really tell if Iā€™m making proper changes or not. Thanks for the input!

David

1 Like

Hey @Melshman

In the first test:
Error: dex.createLImitOrder is not a function
The function name in your contract is createLimitOrder.

In the other ones, when you see this error Returned error: VM Exception while processing transaction: revert it means that a require statement is not satisfied, therefore the transaction reverts.

In the test number 2, the transaction fails with reason ā€œReason given: token does not exist.ā€, check in your code which require statements throws with this error message.

Cheers,
Dani

Iā€™m having a difficult time using this approach, which is creating tests before completing the contract code. Somehow, I feel that itā€™s more natural to create the contract code and then create the tests. That would let me know if my code is deficient and needs to be modified.

Additionally, I believe that I identified a HUGE error in the lesson: Fillip showed us code that compares the amount of ETH to the buy order, containing the quantity of tokens and the tokenā€™s price. Basically, that would look like this: balance of ETH >= amount of token * tokenā€™s price. That cannot be a logical comparison because itā€™s only the ETHā€™s quantity to the full value of the token. For it to be correct, it should balance of ETH * price of ETH >= amount of token * tokenā€™s price. Therefore, there should be an argument for the trader to enter the current price of ETH too (of course, on the honor system).

1 Like

I keep getting an error message (even after installing truffle-assertions) and initializing
const truffleAssert = artifacts.require("truffle-assertions");

the error message says it "canā€™t find ā€œtruffle-assertionsā€ artifactā€¦

what am I doing wrong? I canā€™t test anything uses truffleAssert.passes(etc.) or reverts

1 Like

shae your repo link. Have you definitely installed mocha via npm

do I need to install Mocha separatelyā€¦? I thought Filip said it comes with Truffle

1 Like