@PaulS96 ok so i fixed your wallet tests and one of your limit order tests. Your problems were not your actuall smart contratc code but just some syntax issues. One example is you were calling withdrawETH
in your test file but the function is called withdrawEth
. Also you were trying to assert that
balance.toNumber()
was equal to to some value. However balance.toNumber() seems not to be a function anymore so what i did to get around this issue was just to convert your balance back from wei using
web3.eth.utils.fromWei(balance.toString(), "ether")
this done the job. there was a few other things that were mainly syntaxual issues. However here is the modded test files so you can compare. Also note that i added a getBalance function in your wallet.sol contract and used this to query user balances
I purposely left two tests failing to motivate you to try fix these last two yourself. I fixed the three that were broken in the wallet tests and one in the dex test.
here is the code
WalletTest
const Dex = artifacts.require("Dex")
const Link = artifacts.require("Link")
const truffleAssert = require("truffle-assertions");
contract("Dex", accounts => {
it("Should only be possible for owners to add tokens", async () =>{
let dex = await Dex.deployed()
let link = await Link.deployed()
await truffleAssert.passes(
dex.addToken(web3.utils.fromUtf8("LINK"), link.address, {from: accounts[0]})
)
})
it("Should handle deposits correctly", async () =>{
let dex = await Dex.deployed()
let link = await Link.deployed()
await link.approve(dex.address, 500);
await dex.deposit(100, web3.utils.fromUtf8("LINK"));
let balance = await dex.balance(web3.utils.fromUtf8("LINK"))
console.log(balance)
assert.equal(balance.toString(), 100)
})
it("Should handle faulty withdrawals correctly", async () =>{
let dex = await Dex.deployed()
let link = await Link.deployed()
await truffleAssert.reverts(dex.withdraw(500, web3.utils.fromUtf8("LINK")))
})
it("Should handle withdrawals correctly", async () =>{
let dex = await Dex.deployed()
let link = await Link.deployed()
await truffleAssert.passes(dex.withdraw(100, web3.utils.fromUtf8("LINK")))
})
it("Should handle ETH deposits correctly", async () =>{
let dex = await Dex.deployed()
let link = await Link.deployed()
await dex.depositEth({value: web3.utils.toWei("10", "ether")});
let balance = await dex.balance(web3.utils.fromUtf8("ETH"))
// console.log(balance.toNumber())
console.log(balance)
assert.equal(web3.utils.fromWei(balance.toString(), "ether" ), 10)
})
it("Should handle faulty ETH withdrawals correctly", async () =>{
let dex = await Dex.deployed()
let link = await Link.deployed()
await truffleAssert.reverts(dex.withdrawEth(web3.utils.toWei("100", "ether")))
})
it("Should handle ETH withdrawals correctly", async () =>{
let dex = await Dex.deployed()
let link = await Link.deployed()
await truffleAssert.passes(dex.withdrawEth(web3.utils.toWei("10", "ether")))
})
})
DexTest
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 be more or as much ETH as buy order value", async () => {
let dex = await Dex.deployed()
let link = await Link.deployed()
await link.approve(dex.address, 500);
await truffleAssert.passes(
dex.addToken(web3.utils.fromUtf8("LINK"), link.address, {from: accounts[0]})
)
await truffleAssert.reverts(
dex.createLimitOrder(0, web3.utils.fromUtf8("LINK"), 10, 1)
)
await dex.depositEth({value: web3.utils.toWei( "10", "ether")})
await dex.deposit(100, web3.utils.fromUtf8("LINK"));
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 be bigger or equal token balance to sell order value", async () =>{
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.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 1000, 1)
)
await link.approve(dex.address, 500);
await dex.deposit(10, web3.utils.fromUtf8("LINK"));
await truffleAssert.passes(
dex.createLimitOrder(1, web3.utils.fromUtf8("LINK"), 110, 1)
)
})
//The BUY order book should be ordered on price from highest to lowest starting at index 0
it("Should order BUY order book from highest to lowest value", 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"), 0);
assert(orderbook.length>0);
for (let i = 0; i < orderbook.length - 1; i++) {
const element = array[index];
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 order SELL order book from lowest to highest value", async () =>{
let dex = await Dex.deployed()
let link = await Link.deployed()
await link.approve(dex.address, 500);
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)
let orderbook = await dex.getOrderBook(web3.utils.fromUtf8("LINK"), 1);
assert(orderbook.length>0);
for (let i = 0; i < orderbook.length - 1; i++) {
const element = array[index];
assert(orderbook[i].price <= orderbook[i+1].price, "not right order in SELL book")
}
})
})
wallet.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.11;
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;
//token consists of a ticker and the contract address
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), "Token not listed!");
_;
}
function balance(bytes32 ticker) external view returns (uint) {
return balances[msg.sender][ticker];
}
//add ERC20 Token
function addToken(bytes32 ticker, address tokenAddress) onlyOwner external {
tokenMapping[ticker] = Token(ticker, tokenAddress);
tokenList.push(ticker);
}
//deposit ERC20 Token
function deposit(uint amount, bytes32 ticker) tokenExist(ticker) external {
require(amount != 0, "cannot deposit nothing");
IERC20(tokenMapping[ticker].tokenAddress).transferFrom(msg.sender,address(this), amount);
balances[msg.sender][ticker] = balances[msg.sender][ticker].add(amount);
}
//withdraw ERC20 Token
function withdraw(uint amount, bytes32 ticker) tokenExist(ticker) external {
require(balances[msg.sender][ticker] >= amount, "Balance not sufficient");
IERC20(tokenMapping[ticker].tokenAddress).transfer(msg.sender, amount);
balances[msg.sender][ticker] = balances[msg.sender][ticker].sub(amount);
}
//deposit ETH
function depositEth() public payable {
require(msg.value != 0, "cannot deposit nothing");
//IERC20(tokenMapping["ETH"]).transferFrom(msg.sender,address(this), msg.value);
balances[msg.sender]["ETH"] += msg.value;
}
//withdraw ETH
function withdrawEth(uint amount) external {
require(balances[msg.sender]["ETH"] >= amount, "Balance not sufficient");
payable(msg.sender).transfer(amount);
//IERC20(tokenMapping["ETH"]).transfer(msg.sender, msg.value);
balances[msg.sender]["ETH"] -= amount;
}
}