Any ideas?
My contract:
pragma solidity ^0.4.0;
contract shares {
enum OrderType{BUY,SELL}
struct Order{
address solicitant;
uint price;
uint quantity;
}
Order[] internal buyList;
Order[] internal sellList;
Order auxiliary;
mapping (address=>uint) public balanceOf;
uint sharePrice;
function shares(uint initialSupply){
balanceOf[msg.sender]=initialSupply;
}
function insertBuyOrder(uint proposedPrice, uint quantity){
if(msg.sender.balance<quantity*proposedPrice) throw;
insert(Order(msg.sender,proposedPrice,quantity), OrderType.BUY);
resolveBuyMatches();
}
function resolveBuyMatches() internal{
if(sellList.length>0 && getBiggestBuyOrder().price>=getSmallestSellOrder().price){
if(getBiggestBuyOrder().quantity>=getSmallestSellOrder().quantity){
transferShares(getSmallestSellOrder().solicitant,getBiggestBuyOrder().solicitant,getSmallestSellOrder().quantity);
remove(OrderType.SELL);
getBiggestBuyOrder().quantity-=getSmallestSellOrder().quantity;
if(getBiggestBuyOrder().quantity==0) remove(OrderType.BUY);
else resolveBuyMatches();
}
else {
transferShares(getSmallestSellOrder().solicitant,getBiggestBuyOrder().solicitant,getBiggestBuyOrder().quantity);
remove(OrderType.BUY);
getSmallestSellOrder().quantity-=getBiggestBuyOrder().quantity;
}
}
}
function insertSellOrder(uint proposedPrice, uint quantity){
if(balanceOf[msg.sender]<quantity) throw;
insert(Order(msg.sender,proposedPrice,quantity), OrderType.SELL);
resolveSellMatches();
}
function resolveSellMatches() internal{
if(buyList.length>0 && getBiggestBuyOrder().price>=getSmallestSellOrder().price){
if(getBiggestBuyOrder().quantity>=getSmallestSellOrder().quantity){
transferShares(getSmallestSellOrder().solicitant,getBiggestBuyOrder().solicitant,getSmallestSellOrder().quantity);
remove(OrderType.SELL);
getBiggestBuyOrder().quantity-=getSmallestSellOrder().quantity;
if(getBiggestBuyOrder().quantity==0) remove(OrderType.BUY);
}
else {
transferShares(getSmallestSellOrder().solicitant,getBiggestBuyOrder().solicitant,getBiggestBuyOrder().quantity);
remove(OrderType.BUY);
getSmallestSellOrder().quantity-=getBiggestBuyOrder().quantity;
resolveSellMatches();
}
}
}
function transferShares(address from, address to, uint quantity){
if(balanceOf[from]<quantity) throw;
balanceOf[from]-=quantity;
balanceOf[to]+=quantity;
}
function getSmallestSellOrder() internal returns (Order smallestSellOrder){
smallestSellOrder = sellList[0];
}
function getBiggestBuyOrder() internal returns (Order biggestBuyOrder){
biggestBuyOrder = buyList[0];
}
function remove(OrderType orderType) internal
{
Order[] orderList = buyList;
if(orderType==OrderType.SELL) orderList = sellList;
orderList[0]=orderList[orderList.length-1];
orderList.length--;
reorderAfterRemove(orderList,0);
}
function reorderAfterRemove(Order[] orderList,uint relocatingNodeIndex) internal
{
uint smallestChildIndex = relocatingNodeIndex*2;
if(relocatingNodeIndex*2>=orderList.length) return;
if(orderList[relocatingNodeIndex*2+1].quantity<orderList[relocatingNodeIndex*2].quantity) smallestChildIndex=(relocatingNodeIndex*2+1);
if(orderList[smallestChildIndex].quantity<orderList[relocatingNodeIndex].quantity)
{
swap(orderList,relocatingNodeIndex,smallestChildIndex);
relocatingNodeIndex=smallestChildIndex;
reorderAfterRemove(orderList, relocatingNodeIndex);
}
}
function insert(Order newOrder, OrderType orderType) internal{
Order[] orderList = buyList;
if(orderType==OrderType.SELL) orderList = sellList;
uint length = orderList.length;
buyList.push(newOrder);
orderList.length++;
reorderAfterInsert(orderList,length/2, length);
}
function reorderAfterInsert(Order[] orderList, uint smallerIndex, uint biggerIndex) internal{
if(biggerIndex>0 && orderList[smallerIndex].quantity>orderList[biggerIndex].quantity)
{
swap(orderList,smallerIndex,biggerIndex);
reorderAfterInsert(orderList,smallerIndex/2, smallerIndex);
}
}
function swap(Order[] orderList, uint smallerIndex, uint biggerIndex) internal{
auxiliary = orderList[smallerIndex];
orderList[smallerIndex] = orderList[biggerIndex];
orderList[biggerIndex] = auxiliary;
}
}