Project - Building a DEX

Hi @JohnVersus, thanks for the note.
Then I must be confused with the correct syntax to use. I did try the below test code thinking it should work but it says ReferenceError: dex is not defined:

/* @dev wallettest.js
* deployer.deploy(Dex) and deployer.deploy(Link) are done 
* in other migration files
*/
contract("Dex", accounts => {

    beforeEach(async () => {
        let dex = await Dex.deployed();
        let link = await Link.deployed();  
    });
    
    it("should only be possible for owner to add tokens", async () => {
        /* uncommenting the 2 lines below and removing the beforeEach() above 
        * makes it work nicely
        */
        // let dex = await Dex.deployed()
        // let link = await Link.deployed()

        await truffleAssert.passes(
            dex.addToken(web3.utils.fromUtf8("LINK"), link.address, {from: accounts[0]})
        );
        await truffleAssert.reverts(
            dex.addToken(web3.utils.fromUtf8("AAVE"), link.address, {from: accounts[1]})
        );
    });
});

Try like this. It will let the scope of dex and link values accessible in tests.

contract("Dex", accounts => {
   let dex;
   let link;
    beforeEach(async () => {
        dex = await Dex.deployed();
        link = await Link.deployed();  
    });
    
    it("should only be possible for owner to add tokens", async () => {
        // uncommenting the 2 lines below and removing the beforeEach() above makes it work nicely
        // let dex = await Dex.deployed()
        // let link = await Link.deployed()

        await truffleAssert.passes(
            dex.addToken(web3.utils.fromUtf8("LINK"), link.address, {from: accounts[0]})
        );
        await truffleAssert.reverts(
            dex.addToken(web3.utils.fromUtf8("AAVE"), link.address, {from: accounts[1]})
        );
    });
});
1 Like

all good, working nicely now.
Thanks a lot :slight_smile:

1 Like

Hi Guys,

I have an error when I deploy the contract, I got the following error

My code files:

const Link = artifacts.require("Link");
const Wallet = artifacts.require("Wallet");

module.exports = async function(deployer, network, accounts){
    await deployer.deploy(Link);
    let wallet = await Wallet.deployed()
    let link = await Link.deployed()
    await link.approve(wallet.address, 500)
    wallet.addToken(web3.utils.fromUtf8("LINK"), link.address)
    await wallet.deposit(100, web3.utils.fromUtf8("LINK"))
    let balanceOfLink = await wallet.balances(accounts[0], web3.utils.fromUtf8("LINK"));  
    console.log(balanceOfLink);
};

// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

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

contract Link is ERC20{
  constructor() ERC20("Chainlink", "LINK") {
     _mint(msg.sender, 1000);
    }
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import "../node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../node_modules/@openzeppelin/contracts/utils/math/SafeMath.sol";
import "../node_modules/@openzeppelin/contracts/access/Ownable.sol";

contract Wallet is Ownable {

  using SafeMath for uint256;

struct Token {
    bytes32 ticker;
    address tokenAddress;
}

mapping (bytes32 => Token) public tokenMapping;

bytes32 [] public tokenList;

mapping (address => mapping(bytes32 => uint256)) public balances;

modifier tokenExist(bytes32 ticker){
require(tokenMapping[ticker].tokenAddress != address(0));
_;
}

function addToken(bytes32 ticker, address tokenAddress)  onlyOwner external{
     tokenMapping[ticker] =  Token(ticker, tokenAddress);
     tokenList.push(ticker);
}

function deposit(uint amount, bytes32 ticker) tokenExist(ticker) external {
  IERC20(tokenMapping[ticker].tokenAddress).transferFrom(msg.sender, address(this), amount);  
  balances[msg.sender][ticker] = balances[msg.sender][ticker].add(amount); 




}

function withdraw(uint amount, bytes32 ticker) tokenExist(ticker) external{
  require (balances[msg.sender][ticker] >= amount, "Balance not sufficient");
  balances[msg.sender][ticker] = balances[msg.sender][ticker].sub(amount); 
  IERC20(tokenMapping[ticker].tokenAddress).transfer(msg.sender, amount);  
}

}

Hi @Ahmad_Abd_Allah

A few small corrections are required here. Try with this code.

const Link = artifacts.require("Link");
const Wallet = artifacts.require("Wallet");

module.exports = async function (deployer, network, accounts) {
  await deployer.deploy(Link);
  await deployer.deploy(Wallet); // πŸ‘ˆ Wallet is not deployed
  let wallet = await Wallet.deployed();
  let link = await Link.deployed();

  await link.approve(wallet.address, 500);
  await wallet.addToken(web3.utils.fromUtf8("LINK"), link.address);  // πŸ‘ˆ This needs to be awaited.
  await wallet.deposit(100, web3.utils.fromUtf8("LINK"));

  let balanceOfLink = await wallet.balances(
    accounts[0],
    web3.utils.fromUtf8("LINK")
  );
  console.log(balanceOfLink);
};
1 Like

Hi @JohnVersus

Thanks for your response.
but I still have errors in the dex.sol contract

// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
pragma experimental ABIencoderV2;
import "../contracts/wallet.sol";

contract Dex is Wallet{

    enum Side{
        BUY,
        SELL
    }

    struct Order{
     uint id;
     address trader;
     bool buyOrder;
     bytes32 ticker;
     uint amount;
     uint price;
    }

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

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

    function createLimitOrder(type name ) {
        
    }
}

Here it’s my code

// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import "../node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../node_modules/@openzeppelin/contracts/utils/math/SafeMath.sol";
import "../node_modules/@openzeppelin/contracts/access/Ownable.sol";

contract Wallet is Ownable {

  using SafeMath for uint256;

struct Token {
    bytes32 ticker;
    address tokenAddress;
}

mapping (bytes32 => Token) public tokenMapping;

bytes32 [] public tokenList;

mapping (address => mapping(bytes32 => uint256)) public balances;

modifier tokenExist(bytes32 ticker){
require(tokenMapping[ticker].tokenAddress != address(0));
_;
}

function addToken(bytes32 ticker, address tokenAddress)  onlyOwner external{
     tokenMapping[ticker] =  Token(ticker, tokenAddress);
     tokenList.push(ticker);
}

function deposit(uint amount, bytes32 ticker) tokenExist(ticker) external {
  IERC20(tokenMapping[ticker].tokenAddress).transferFrom(msg.sender, address(this), amount);  
  balances[msg.sender][ticker] = balances[msg.sender][ticker].add(amount); 




}

function withdraw(uint amount, bytes32 ticker) tokenExist(ticker) external{
  require (balances[msg.sender][ticker] >= amount, "Balance not sufficient");
  balances[msg.sender][ticker] = balances[msg.sender][ticker].sub(amount); 
  IERC20(tokenMapping[ticker].tokenAddress).transfer(msg.sender, amount);  
}

}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

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

contract Link is ERC20{
  constructor() ERC20("Chainlink", "LINK") {
     _mint(msg.sender, 1000);
    }

}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
pragma experimental ABIencoderV2;
import "../contracts/wallet.sol";

contract Dex is Wallet{

    enum Side{
        BUY,
        SELL
    }

    struct Order{
     uint id;
     address trader;
     bool buyOrder;
     bytes32 ticker;
     uint amount;
     uint price;
    }

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

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

    function createLimitOrder(type name ) {
        
    }
}
const Wallet = artifacts.require("Wallet");

module.exports = function(deployer){
    deployer.deploy(Wallet);
};

The following file already corrected as per your advice

const Link = artifacts.require("Link");
const Wallet = artifacts.require("Wallet");

module.exports = async function(deployer, network, accounts){
    await deployer.deploy(Link);
    await deployer.deploy(Wallet);
    let wallet = await Wallet.deployed();
    let link = await Link.deployed();

    await link.approve(wallet.address, 500);
    await wallet.addToken(web3.utils.fromUtf8("LINK"), link.address);
    await wallet.deposit(100, web3.utils.fromUtf8("LINK"));
    let balanceOfLink = await wallet.balances(accounts[0], web3.utils.fromUtf8("LINK"));  
    console.log(balanceOfLink);


};

Maybe error is related to this part of code. There is no type in solidity.

1 Like