pragma solidity ^0.5.1; //pragma experimental ABIEncoderV2; /*TODO: mapping of unsuccessful buyers. Adding bid requires payment. Rsoultion passes bidprice back to unsuccessful bidders. Wait until smart meter data comes in. Transfer %clearingPrice to sellers and (1-%)clearingPrice to buyers. SORT DISCREPANCY BETWEEN ENERGY SENT AND ENERGY RECEIVED*/ /*TODO: Establish inputs/outputs and function of contract with outside. Concept of time for bidding-EXECUTE AUCTION() AUTO-. Improve clearing function. Transfer of ether for successful buyers/sellers. Encryption/security improvements. Gas usage. Require statements. Unbounded loops (https://medium.com/robhitchens/solidity-crud-part-1-824ffa69509a).*/ contract doubleAuction { address internal owner; int256 internal buyerCount = 0; int256 internal sellerCount = 0; int256 internal clearingPrice = 0; int256 internal sucBuyerCount = 0; int256 internal sucSellerCount = 0; int256 internal unsucbuyercount =0; address payable internal toTransfer; bool smartData = false; bool auctionOpen = false; uint256 internal auctionStart = 0; struct Person { int _energyValue; int _bidPrice; int _personID; address payable _walletAddress; int _energyTransferred; } constructor () public{ owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner,"You do not have permission for this."); _; } mapping(int => Person) internal buyers; mapping(int => Person) internal sellers; mapping(int => Person) internal sucBuyers; mapping(int => Person) internal sucSellers; mapping(int => Person) internal unsucBuyers; function addBuyer (int _energyValue) public payable{ require(auctionOpen == true && now < (auctionStart+ 1 minutes),"Auction not open."); require(msg.value>0,"Please place bid value greater than 0 wei"); buyerCount++; buyers[buyerCount] = Person(_energyValue, int(msg.value),buyerCount,msg.sender,0); } function addSeller (int _energyValue, int _sellPrice) public { require(auctionOpen == true && now < (auctionStart+ 10 minutes),"Auction not open."); sellerCount++; sellers[sellerCount] = Person(_energyValue, _sellPrice,sellerCount,msg.sender,0); } function elimNegatives() internal{ int i = 0; while (i <= buyerCount){ if (buyers[i]._energyValue < 0){ delete buyers[i]; buyerCount -= 1; } i++; } i=0; while (i<= sellerCount){ if (sellers[i]._energyValue < 0){ delete sellers[i]; sellerCount -= 1; } i++; } } function calcClearingPrice() internal { int priceCount = 0; int i = 0; while (i<= buyerCount){ priceCount += buyers[i]._bidPrice; i++; } i=0; while (i<= sellerCount){ priceCount += sellers[i]._bidPrice; i++; } //Currently calculates clearing price as the mean price- needs improvement!!! clearingPrice = priceCount/(buyerCount+sellerCount); } function auction() internal{ calcClearingPrice(); int i = 0; int j = 0; int k = 0; while (i <= buyerCount){ if (buyers[i]._bidPrice >= clearingPrice){ sucBuyers[j] = buyers[i]; j++; sucBuyerCount++; } else { unsucBuyers[k] = buyers[i]; k++; } i++; } i=0; j=0; while (i<= sellerCount){ if (sellers[i]._bidPrice <= clearingPrice){ sucSellers[j] = sellers[i]; j++; sucSellerCount++; } i++; } } function returnUnsucBidders() internal { int i = 0; unsucbuyercount = buyerCount-sucBuyerCount; while (i <= unsucbuyercount){ toTransfer = unsucBuyers[i]._walletAddress; toTransfer.transfer(uint(unsucBuyers[i]._bidPrice)); delete unsucBuyers[i]; i++; } } function setSmartData() public onlyOwner { smartData = true; } function setEnergyTransferred(int _userID, int _energyTransfer) public { sellers[_userID]._energyTransferred = _energyTransfer; } /*function resolve() internal { require(smartData == true,"Energy transfer not yet complete. Please wait."); //STUFF }*/ function run() public onlyOwner { elimNegatives(); auction(); returnUnsucBidders(); // resolve(); } function openAuction() public onlyOwner{ auctionStart = now; auctionOpen = true; } function forceStopAuction() public onlyOwner { auctionOpen = false; } }
0.4.18