Without watching any hint videos
Took me almost a day! Debugging is ultra hardā¦
dex.sol
function createMarketOrder(Side _side, bytes32 _ticker, uint _amount) public{
Order[] storage orders = orderBook[_ticker][_side==Side.BUY ? 1 : 0];
uint totalFilled = 0;
if(_side == Side.BUY){
require(balances[msg.sender]["ETH"] > 0, "insufficient balance");
}else{
require(balances[msg.sender][_ticker] >= _amount, "insufficient balance");
}
for(uint i=0; i < orders.length && totalFilled < _amount; i++){
//How much we can fill from order[i]
if(totalFilled + orders[i].amount >= _amount){
orders[i].filled = _amount - totalFilled;
}else{
orders[i].filled = orders[i].amount;
}
//Update totalFilled;
totalFilled += orders[i].filled;
orders[i].amount -= orders[i].filled;
//Execute the trade & shift balances between buyer/seller
if(_side == Side.BUY){
//Verify that the buyer has enough ETH to cover the purchase (require)
require(balances[msg.sender]["ETH"] >= orders[i].filled*orders[i].price, "insufficient balance");
balances[msg.sender]["ETH"] -= orders[i].filled*orders[i].price;
balances[msg.sender][_ticker] += orders[i].filled;
balances[orders[i].trader]["ETH"] += orders[i].filled*orders[i].price;
balances[orders[i].trader][_ticker] -= orders[i].filled;
}else{
//Verify that the seller has enough _ticker to cover the purchase (require)
require(balances[msg.sender][_ticker] >= orders[i].filled, "insufficient balance");
balances[msg.sender][_ticker] -= orders[i].filled;
balances[msg.sender]["ETH"] += orders[i].filled*orders[i].price;
balances[orders[i].trader][_ticker] += orders[i].filled;
balances[orders[i].trader]["ETH"] -= orders[i].filled*orders[i].price;
}
}
if(orders.length != 0){
//Loop through the orderbook and remove 100% filled orders
uint numOfFilledOrders = 0;
for(uint i=0; i < orders.length && orders[i].amount == 0;i++){
numOfFilledOrders++;
}
for(uint i=0; numOfFilledOrders!=0 && i< orders.length - numOfFilledOrders; i++){
orders[i] = orders[i+numOfFilledOrders];
}
for(uint i=1; i <= numOfFilledOrders; i++){
orders.pop();
}
}
}
Note: I decided to decrease orders[i].amount as it gets filled. This has to be commented out from the test code.
assert.equal(orderbook[0].amount, 5);