diff --git a/blockchain/source/contracts/Administratum.sol b/blockchain/source/contracts/Administratum.sol new file mode 100644 index 000000000..bf6adb089 --- /dev/null +++ b/blockchain/source/contracts/Administratum.sol @@ -0,0 +1,87 @@ +pragma solidity ^0.4.23; + +import "zeppelin-solidity/contracts/ownership/Ownable.sol"; +import "./AdministratumCrud.sol"; + +contract Administratum is Ownable { + + // events + event WorkerAnnounced(address indexed worker, address indexed master); + event WorkerConfirmed(address indexed worker, address indexed master, address indexed confirmator); + event WorkerRemoved(address indexed worker, address indexed master); + event AdminAdded(address indexed admin, address indexed master); + + // storage + + mapping(address => mapping(address => bool)) masterRequest; + + AdministratumCrud crud; + + + //constructor + constructor(address _administratumCrud){ + owner = msg.sender; + crud = AdministratumCrud(_administratumCrud); + } + + //funcs + + function RegisterWorker(address _master) public returns (bool) { + require(crud.GetMaster(msg.sender) == msg.sender); + require(!crud.isMaster(msg.sender)); + require(crud.GetMaster(_master) == _master); + masterRequest[_master][msg.sender] = true; + emit WorkerAnnounced(msg.sender, _master); + return true; + } + + function ConfirmWorker(address _worker) public returns (bool) { + require(masterRequest[msg.sender][_worker] == true || IsValid(_worker)); + crud.SetMaster(_worker, msg.sender); + crud.SwitchToMaster(msg.sender); + delete masterRequest[msg.sender][_worker]; + emit WorkerConfirmed(_worker, crud.GetMaster(_worker), msg.sender); + return true; + } + + function RemoveWorker(address _worker, address _master) public returns (bool) { + require(crud.GetMaster(_worker) == _master && (msg.sender == _worker || msg.sender == _master)); + crud.DeleteMaster(_worker); + emit WorkerRemoved(_worker, _master); + return true; + } + + function RegisterAdmin(address _admin) public returns (bool){ + require(GetMaster(msg.sender) == msg.sender); + require(msg.sender != _admin); + crud.SetAdmin(_admin, msg.sender); + return true; + } + + function Migrate (address _newAdministratum) public onlyOwner { + crud.transferOwnership(_newAdministratum); + suicide(msg.sender); + } + + + //INTERNAL + // check if transaction sended by valid admin + function IsValid(address _worker) internal view returns(bool){ + address master = crud.GetAdminMaster(msg.sender); + return master != address(0) && masterRequest[master][_worker] == true; + } + + + //GETTERS + + function GetMaster(address _worker) public view returns (address master) { + return crud.GetMaster(_worker); + } + + + + + //modifiers + + +} diff --git a/blockchain/source/contracts/AdministratumCrud.sol b/blockchain/source/contracts/AdministratumCrud.sol new file mode 100644 index 000000000..5b9ba1efb --- /dev/null +++ b/blockchain/source/contracts/AdministratumCrud.sol @@ -0,0 +1,60 @@ +pragma solidity ^0.4.23; + +import "./Administratable.sol"; + +contract AdministratumCrud is Administratable { + + // events + event WorkerAnnounced(address indexed worker, address indexed master); + event WorkerConfirmed(address indexed worker, address indexed master); + event WorkerRemoved(address indexed worker, address indexed master); + event AdminAdded(address indexed admin, address indexed master); + + // storage + mapping(address => address) masterOf; + + mapping(address => bool) flagIsMaster; + + mapping(address => mapping(address => bool)) masterRequest; + + //maps admin into its master; alternative method + //that's like asym cryptography, but implemented by design + mapping(address => address) admins; + + //constructor + constructor(){ + owner = msg.sender; + administrator = msg.sender; + } + + function SetMaster(address _worker, address _master) public onlyOwner { + masterOf[_worker] = _master; + } + + function SetAdmin(address _admin, address _master) public onlyOwner { + admins[_admin] = _master; + } + + function DeleteMaster(address _worker) public onlyOwner { + delete masterOf[_worker]; + } + + function SwitchToMaster(address _target) public onlyOwner { + flagIsMaster[_target] = true; + } + + function GetMaster(address _worker) public view returns (address) { + if (masterOf[_worker] == address(0) || flagIsMaster[_worker] == true){ + return _worker; + } + return masterOf[_worker]; + } + + function GetAdminMaster(address _admin) public view returns (address) { + return admins[_admin]; + } + + function isMaster(address _address) public view returns (bool) { + return flagIsMaster[_address]; + } +} diff --git a/blockchain/source/contracts/ChangeRequests.sol b/blockchain/source/contracts/ChangeRequests.sol new file mode 100644 index 000000000..170a4dd3a --- /dev/null +++ b/blockchain/source/contracts/ChangeRequests.sol @@ -0,0 +1,128 @@ +pragma solidity ^0.4.23; + +import "./Administratable.sol"; +import "zeppelin-solidity/contracts/math/SafeMath.sol"; +import "./Orders.sol"; + + +contract ChangeRequests is Administratable { + using SafeMath for uint256; + + mapping(uint => ChangeRequest) requests; + + mapping(uint => uint[2]) actualRequests; + + uint requestsAmount; + + struct ChangeRequest { + uint dealID; + Orders.OrderType requestType; + uint price; + uint duration; + RequestStatus status; + } + + enum RequestStatus { + REQUEST_UNKNOWN, + REQUEST_CREATED, + REQUEST_CANCELED, + REQUEST_REJECTED, + REQUEST_ACCEPTED + } + + + constructor() public { + owner = msg.sender; + administrator = msg.sender; + } + + function Write( + uint _dealID, + Orders.OrderType _requestType, + uint _price, + uint _duration, + RequestStatus _status) public onlyOwner returns(uint){ + + requestsAmount = requestsAmount.add(1); + + requests[requestsAmount] = ChangeRequest(_dealID, _requestType, _price, _duration, _status); + + return requestsAmount; + } + + //SETTERS + + function SetChangeRequestDealID(uint _changeRequestID, uint _dealID) public onlyOwner { + requests[_changeRequestID].dealID = _dealID; + } + + function SetChangeRequestType(uint _changeRequestID, Orders.OrderType _type) public onlyOwner { + requests[_changeRequestID].requestType = _type; + } + + function SetChangeRequestPrice(uint _changeRequestID, uint _price) public onlyOwner { + requests[_changeRequestID].price = _price; + } + + function SetChangeRequestDuration(uint _changeRequestID, uint _duration) public onlyOwner { + requests[_changeRequestID].duration = _duration; + } + + function SetChangeRequestStatus(uint _changeRequestID, RequestStatus _status) public onlyOwner { + requests[_changeRequestID].status = _status; + } + + function SetActualChangeRequest(uint dealID, uint role, uint _changeRequestID) public onlyOwner { + actualRequests[dealID][role] = _changeRequestID; + } + + // GETTERS + + function GetChangeRequestDealID(uint _changeRequestID) public view returns(uint) { + return requests[_changeRequestID].dealID; + } + + function GetChangeRequestType(uint _changeRequestID) public view returns(Orders.OrderType) { + return requests[_changeRequestID].requestType; + } + + function GetChangeRequestPrice(uint _changeRequestID) public view returns(uint) { + return requests[_changeRequestID].price; + } + + function GetChangeRequestDuration(uint _changeRequestID) public view returns(uint) { + return requests[_changeRequestID].duration; + } + + function GetChangeRequestStatus(uint _changeRequestID) public view returns(RequestStatus) { + return requests[_changeRequestID].status; + } + + function GetActualChangeRequest(uint dealID, uint role)public view returns(uint) { + return actualRequests[dealID][role]; + + } + + function GetChangeRequestsAmount() public view returns(uint) { + return requestsAmount; + } + + function GetChangeRequestInfo(uint changeRequestID) public view + returns ( + uint dealID, + Orders.OrderType requestType, + uint price, + uint duration, + RequestStatus status + ) { + return ( + requests[changeRequestID].dealID, + requests[changeRequestID].requestType, + requests[changeRequestID].price, + requests[changeRequestID].duration, + requests[changeRequestID].status + ); + } + + +} diff --git a/blockchain/source/contracts/Deals.sol b/blockchain/source/contracts/Deals.sol new file mode 100644 index 000000000..7c811125a --- /dev/null +++ b/blockchain/source/contracts/Deals.sol @@ -0,0 +1,222 @@ +pragma solidity ^0.4.23; + +import "./Administratable.sol"; + + +contract Deals is Administratable { + //events + + //enums + enum DealStatus { + STATUS_UNKNOWN, + STATUS_ACCEPTED, + STATUS_CLOSED + } + //data + + struct Deal { + DealInfo info; + DealParams params; + } + + struct DealInfo { + uint64[] benchmarks; + address supplierID; + address consumerID; + address masterID; + uint askID; + uint bidID; + uint startTime; + } + + struct DealParams { + uint duration; + uint price; //usd * 10^-18 + uint endTime; + DealStatus status; + uint blockedBalance; + uint totalPayout; + uint lastBillTS; + } + + mapping(uint => Deal) deals; + + mapping(address => uint[]) dealsID; + + uint dealsAmount = 0; + + //Constructor + constructor() public { + owner = msg.sender; + administrator = msg.sender; + } + + + function SetDealBenchmarks(uint dealID, uint64[] _benchmarks) public onlyOwner { + deals[dealID].info.benchmarks = _benchmarks; + } + + function SetDealSupplierID(uint dealID, address _supplierID) public onlyOwner { + deals[dealID].info.supplierID = _supplierID; + } + + function SetDealConsumerID(uint dealID, address _consumerID) public onlyOwner { + deals[dealID].info.consumerID = _consumerID; + } + + function SetDealMasterID(uint dealID, address _masterID) public onlyOwner { + deals[dealID].info.masterID = _masterID; + } + + function SetDealAskID(uint dealID, uint _askID) public onlyOwner { + deals[dealID].info.askID = _askID; + } + + function SetDealBidID(uint dealID, uint _bidID) public onlyOwner { + deals[dealID].info.bidID = _bidID; + } + + function SetDealStartTime(uint dealID, uint _startTime) public onlyOwner { + deals[dealID].info.startTime = _startTime; + } + + function SetDealStatus(uint dealID, DealStatus _status) public onlyOwner { + deals[dealID].params.status = _status; + } + + function SetDealEndTime(uint dealID, uint _endTime) public onlyOwner { + deals[dealID].params.endTime = _endTime; + } + + function SetDealBlockedBalance(uint dealID, uint _blockedBalance) public onlyOwner { + deals[dealID].params.blockedBalance = _blockedBalance; + } + + function SetDealLastBillTS(uint dealID, uint _lastBillTS) public onlyOwner { + deals[dealID].params.lastBillTS = _lastBillTS; + } + + function SetDealTotalPayout(uint dealID, uint _totalPayout) public onlyOwner { + deals[dealID].params.totalPayout = _totalPayout; + } + + function SetDealPrice(uint dealID, uint _price) public onlyOwner { + deals[dealID].params.price = _price; + } + + function SetDealDuration(uint dealID, uint _duration) public onlyOwner { + deals[dealID].params.duration = _duration; + } + + function IncreaseDealsAmount() public onlyOwner { + dealsAmount += 1; + } + + + //getters + + function GetDealInfo(uint dealID) public view + returns ( + uint64[] benchmarks, + address supplierID, + address consumerID, + address masterID, + uint askID, + uint bidID, + uint startTime + ) { + DealInfo memory info = deals[dealID].info; + return ( + info.benchmarks, + info.supplierID, + info.consumerID, + info.masterID, + info.askID, + info.bidID, + info.startTime + ); + } + + function GetDealParams(uint dealID) public view + returns ( + uint duration, + uint price, + uint endTime, + DealStatus status, + uint blockedBalance, + uint totalPayout, + uint lastBillTS + ) { + DealParams memory params = deals[dealID].params; + return ( + params.duration, + params.price, + params.endTime, + params.status, + params.blockedBalance, + params.totalPayout, + params.lastBillTS + ); + } + + function GetDealBenchmarks(uint dealID) public view returns(uint64[]) { + return deals[dealID].info.benchmarks; + } + + function GetDealConsumerID(uint dealID) public view returns(address) { + return deals[dealID].info.consumerID; + } + + function GetDealSupplierID(uint dealID) public view returns(address) { + return deals[dealID].info.supplierID; + } + + function GetDealMasterID(uint dealID) public view returns(address) { + return deals[dealID].info.masterID; + } + + function GetDealAskID(uint dealID) public view returns(uint) { + return deals[dealID].info.askID; + } + + function GetDealBidID(uint dealID) public view returns(uint) { + return deals[dealID].info.bidID; + } + + function GetDealStartTime(uint dealID) public view returns(uint) { + return deals[dealID].info.startTime; + } + + function GetDealDuration(uint dealID) public view returns(uint) { + return deals[dealID].params.duration; + } + + function GetDealPrice(uint dealID) public view returns(uint) { + return deals[dealID].params.price; + } + + function GetDealEndTime(uint dealID) public view returns(uint) { + return deals[dealID].params.endTime; + } + + function GetDealStatus(uint dealID) public view returns(DealStatus) { + return deals[dealID].params.status; + } + + function GetDealBlockedBalance(uint dealID) public view returns(uint) { + return deals[dealID].params.blockedBalance; + } + + function GetDealTotalPayout(uint dealID) public view returns(uint) { + return deals[dealID].params.totalPayout; + } + + function GetDealLastBillTS(uint dealID) public view returns(uint) { + return deals[dealID].params.lastBillTS; + } + + function GetDealsAmount() public view returns(uint) { + return dealsAmount; + } + +} diff --git a/blockchain/source/contracts/Market.sol b/blockchain/source/contracts/Market.sol index 35decf30a..fa7ccddde 100644 --- a/blockchain/source/contracts/Market.sol +++ b/blockchain/source/contracts/Market.sol @@ -7,6 +7,10 @@ import "./SNM.sol"; import "./Blacklist.sol"; import "./OracleUSD.sol"; import "./ProfileRegistry.sol"; +import "./Administratum.sol"; +import "./Orders.sol"; +import "./Deals.sol"; +import "./ChangeRequests.sol"; contract Market is Ownable, Pausable { @@ -15,81 +19,14 @@ contract Market is Ownable, Pausable { // DECLARATIONS - enum DealStatus{ - STATUS_UNKNOWN, - STATUS_ACCEPTED, - STATUS_CLOSED - } - - enum OrderType { - ORDER_UNKNOWN, - ORDER_BID, - ORDER_ASK - } - - enum OrderStatus { - UNKNOWN, - ORDER_INACTIVE, - ORDER_ACTIVE - } - - enum RequestStatus { - REQUEST_UNKNOWN, - REQUEST_CREATED, - REQUEST_CANCELED, - REQUEST_REJECTED, - REQUEST_ACCEPTED - } - enum BlacklistPerson { BLACKLIST_NOBODY, BLACKLIST_WORKER, BLACKLIST_MASTER } - struct Deal { - uint64[] benchmarks; - address supplierID; - address consumerID; - address masterID; - uint askID; - uint bidID; - uint duration; - uint price; //usd * 10^-18 - uint startTime; - uint endTime; - DealStatus status; - uint blockedBalance; - uint totalPayout; - uint lastBillTS; - } - - struct Order { - OrderType orderType; - OrderStatus orderStatus; - address author; - address counterparty; - uint duration; - uint256 price; - bool[] netflags; - ProfileRegistry.IdentityLevel identityLevel; - address blacklist; - bytes32 tag; - uint64[] benchmarks; - uint frozenSum; - uint dealID; - } - - struct ChangeRequest { - uint dealID; - OrderType requestType; - uint price; - uint duration; - RequestStatus status; - } // EVENTS - event OrderPlaced(uint indexed orderID); event OrderUpdated(uint indexed orderID); @@ -118,11 +55,15 @@ contract Market is Ownable, Pausable { OracleUSD oracle; - ProfileRegistry pr; + ProfileRegistry profiles; - uint ordersAmount = 0; + Orders ordersCrud; - uint dealAmount = 0; + Administratum administratum; + + Deals dealsCrud; + + ChangeRequests changeRequestsCrud; uint requestsAmount = 0; @@ -132,29 +73,27 @@ contract Market is Ownable, Pausable { // current length of netflags uint netflagsQuantity; - mapping(uint => Order) public orders; - - mapping(uint => Deal) public deals; - - mapping(address => uint[]) dealsID; - - mapping(uint => ChangeRequest) requests; - - mapping(uint => uint[2]) actualRequests; - - mapping(address => address) masterOf; - - mapping(address => bool) isMaster; - - mapping(address => mapping(address => bool)) masterRequest; - // INIT - constructor(address _token, address _blacklist, address _oracle, address _profileRegistry, uint _benchmarksQuantity, uint _netflagsQuantity) public { + constructor(address _token, + address _blacklist, + address _oracle, + address _profileRegistry, + address _administratum, + address _orders, + address _deals, + address _changeRequests, + uint _benchmarksQuantity, + uint _netflagsQuantity + ) public { token = SNM(_token); bl = Blacklist(_blacklist); oracle = OracleUSD(_oracle); - pr = ProfileRegistry(_profileRegistry); + profiles = ProfileRegistry(_profileRegistry); + administratum = Administratum(_administratum); + ordersCrud = Orders(_orders); + dealsCrud = Deals(_deals); + changeRequestsCrud = ChangeRequests(_changeRequests); benchmarksQuantity = _benchmarksQuantity; netflagsQuantity = _netflagsQuantity; } @@ -164,8 +103,8 @@ contract Market is Ownable, Pausable { // Order functions function PlaceOrder( - OrderType _orderType, - address _id_counterparty, + Orders.OrderType _orderType, + address _counterpartyID, uint _duration, uint _price, bool[] _netflags, @@ -173,7 +112,7 @@ contract Market is Ownable, Pausable { address _blacklist, bytes32 _tag, uint64[] _benchmarks - ) whenNotPaused public returns (uint){ + ) whenNotPaused public returns (uint) { require(_identityLevel >= ProfileRegistry.IdentityLevel.ANONYMOUS); require(_netflags.length <= netflagsQuantity); @@ -185,7 +124,7 @@ contract Market is Ownable, Pausable { uint lockedSum = 0; - if (_orderType == OrderType.ORDER_BID) { + if (_orderType == Orders.OrderType.ORDER_BID) { if (_duration == 0) { lockedSum = CalculatePayment(_price, 1 hours); } else if (_duration < 1 days) { @@ -193,18 +132,15 @@ contract Market is Ownable, Pausable { } else { lockedSum = CalculatePayment(_price, 1 days); } - // this line contains err. - require(token.transferFrom(msg.sender, this, lockedSum)); + require(token.transferFrom(msg.sender, address(this), lockedSum)); } - ordersAmount = ordersAmount.add(1); - uint256 orderId = ordersAmount; - orders[orderId] = Order( + ordersCrud.Write( _orderType, - OrderStatus.ORDER_ACTIVE, + Orders.OrderStatus.ORDER_ACTIVE, msg.sender, - _id_counterparty, + _counterpartyID, _duration, _price, _netflags, @@ -216,126 +152,164 @@ contract Market is Ownable, Pausable { 0 ); - emit OrderPlaced(orderId); - return orderId; + emit OrderPlaced(ordersCrud.GetOrdersAmount()); + + return ordersCrud.GetOrdersAmount(); } - function CancelOrder(uint orderID) public returns (bool){ - require(orderID <= ordersAmount); - require(orders[orderID].orderStatus == OrderStatus.ORDER_ACTIVE); - require(orders[orderID].author == msg.sender); + function CancelOrder(uint orderID) public returns (bool) { + require(orderID <= ordersCrud.GetOrdersAmount()); + + address author = ordersCrud.GetOrderAuthor(orderID); - require(token.transfer(msg.sender, orders[orderID].frozenSum)); - orders[orderID].orderStatus = OrderStatus.ORDER_INACTIVE; + uint frozenSum = ordersCrud.GetOrderFrozenSum(orderID); + + Orders.OrderStatus orderStatus = ordersCrud.GetOrderStatus(orderID); + + + require(orderStatus == Orders.OrderStatus.ORDER_ACTIVE); + require(author == msg.sender || administratum.GetMaster(author) == msg.sender); + + require(token.transfer(msg.sender, frozenSum)); + + ordersCrud.SetOrderStatus(orderID, Orders.OrderStatus.ORDER_INACTIVE); emit OrderUpdated(orderID); + return true; } function QuickBuy(uint askID, uint buyoutDuration) public whenNotPaused { - Order memory ask = orders[askID]; - require(ask.orderType == OrderType.ORDER_ASK); - require(ask.orderStatus == OrderStatus.ORDER_ACTIVE); - require(ask.duration >= buyoutDuration); - require(pr.GetProfileLevel(msg.sender) >= ask.identityLevel); - require(bl.Check(msg.sender, GetMaster(ask.author)) == false && bl.Check(ask.author, msg.sender) == false); - require(bl.Check(ask.blacklist, msg.sender) == false); + require(ordersCrud.GetOrderType(askID) == Orders.OrderType.ORDER_ASK); + require(ordersCrud.GetOrderStatus(askID) == Orders.OrderStatus.ORDER_ACTIVE); + + require(ordersCrud.GetOrderDuration(askID) >= buyoutDuration); + require(profiles.GetProfileLevel(msg.sender) >= ordersCrud.GetOrderIdentityLevel(askID)); + require(bl.Check(ordersCrud.GetOrderBlacklist(askID), msg.sender) == false); + require( + bl.Check(msg.sender, administratum.GetMaster(ordersCrud.GetOrderAuthor(askID))) == false + && bl.Check(ordersCrud.GetOrderAuthor(askID), msg.sender) == false); PlaceOrder( - OrderType.ORDER_BID, - GetMaster(ask.author), + Orders.OrderType.ORDER_BID, + administratum.GetMaster(ordersCrud.GetOrderAuthor(askID)), buyoutDuration, - ask.price, - ask.netflags, + ordersCrud.GetOrderPrice(askID), + ordersCrud.GetOrderNetflags(askID), ProfileRegistry.IdentityLevel.ANONYMOUS, address(0), bytes32(0), - ask.benchmarks); + ordersCrud.GetOrderBenchmarks(askID)); - OpenDeal(askID, GetOrdersAmount()); + OpenDeal(askID, ordersCrud.GetOrdersAmount()); } // Deal functions function OpenDeal(uint _askID, uint _bidID) whenNotPaused public { - Order memory ask = orders[_askID]; - Order memory bid = orders[_bidID]; - - require(ask.orderStatus == OrderStatus.ORDER_ACTIVE && bid.orderStatus == OrderStatus.ORDER_ACTIVE); - require((ask.counterparty == 0x0 || ask.counterparty == GetMaster(bid.author)) && (bid.counterparty == 0x0 || bid.counterparty == GetMaster(ask.author))); - require(ask.orderType == OrderType.ORDER_ASK); - require(bid.orderType == OrderType.ORDER_BID); require( - bl.Check(bid.blacklist, GetMaster(ask.author)) == false - && bl.Check(bid.blacklist, ask.author) == false - && bl.Check(bid.author, GetMaster(ask.author)) == false - && bl.Check(bid.author, ask.author) == false - && bl.Check(ask.blacklist, bid.author) == false - && bl.Check(GetMaster(ask.author), bid.author) == false - && bl.Check(ask.author, bid.author) == false); - require(ask.price <= bid.price); - require(ask.duration >= bid.duration); + ordersCrud.GetOrderStatus(_askID) == Orders.OrderStatus.ORDER_ACTIVE + && ordersCrud.GetOrderStatus(_bidID) == Orders.OrderStatus.ORDER_ACTIVE); + require(ordersCrud.GetOrderCounterparty(_askID) == 0x0 || ordersCrud.GetOrderCounterparty(_askID) == ordersCrud.GetOrderAuthor(_bidID)); + require( + ordersCrud.GetOrderCounterparty(_bidID) == 0x0 + || ordersCrud.GetOrderCounterparty(_bidID) == administratum.GetMaster(ordersCrud.GetOrderAuthor(_askID)) + || ordersCrud.GetOrderCounterparty(_bidID) == ordersCrud.GetOrderAuthor(_askID)); + require(ordersCrud.GetOrderType(_askID) == Orders.OrderType.ORDER_ASK); + require(ordersCrud.GetOrderType(_bidID) == Orders.OrderType.ORDER_BID); + require(!bl.Check(ordersCrud.GetOrderBlacklist(_bidID), administratum.GetMaster(ordersCrud.GetOrderAuthor(_askID)))); + require(!bl.Check(ordersCrud.GetOrderBlacklist(_bidID), ordersCrud.GetOrderAuthor(_askID))); + require(!bl.Check(ordersCrud.GetOrderAuthor(_bidID), administratum.GetMaster(ordersCrud.GetOrderAuthor(_askID)))); + require(!bl.Check(ordersCrud.GetOrderAuthor(_bidID), ordersCrud.GetOrderAuthor(_askID))); + require(!bl.Check(ordersCrud.GetOrderBlacklist(_askID), ordersCrud.GetOrderAuthor(_bidID))); + require(!bl.Check(administratum.GetMaster(ordersCrud.GetOrderAuthor(_askID)), ordersCrud.GetOrderAuthor(_bidID))); + require(!bl.Check(ordersCrud.GetOrderAuthor(_askID), ordersCrud.GetOrderAuthor(_bidID))); + require(ordersCrud.GetOrderPrice(_askID) <= ordersCrud.GetOrderPrice(_bidID)); + require(ordersCrud.GetOrderDuration(_askID) >= ordersCrud.GetOrderDuration(_bidID)); // profile level check - require(pr.GetProfileLevel(bid.author) >= ask.identityLevel); - require(pr.GetProfileLevel(ask.author) >= bid.identityLevel); + require(profiles.GetProfileLevel(ordersCrud.GetOrderAuthor(_bidID)) >= ordersCrud.GetOrderIdentityLevel(_askID)); + require(profiles.GetProfileLevel(administratum.GetMaster(ordersCrud.GetOrderAuthor(_askID))) >= ordersCrud.GetOrderIdentityLevel(_bidID)); //bug - if (ask.netflags.length < netflagsQuantity) { - ask.netflags = ResizeNetflags(ask.netflags); + bool[] memory askNetflags = ordersCrud.GetOrderNetflags(_askID); + if (askNetflags.length < netflagsQuantity) { + askNetflags = ResizeNetflags(askNetflags); } - if (bid.netflags.length < netflagsQuantity) { - bid.netflags = ResizeNetflags(ask.netflags); + bool[] memory bidNetflags = ordersCrud.GetOrderNetflags(_bidID); + if (bidNetflags.length < netflagsQuantity) { + bidNetflags = ResizeNetflags(bidNetflags); } - for (uint i = 0; i < ask.netflags.length; i++) { + for (uint i = 0; i < netflagsQuantity; i++) { // implementation: when bid contains requirement, ask necessary needs to have this // if ask have this one - pass - require(!bid.netflags[i] || ask.netflags[i]); + require(!bidNetflags[i] || askNetflags[i]); } - if (ask.benchmarks.length < benchmarksQuantity) { - ask.benchmarks = ResizeBenchmarks(ask.benchmarks); + uint64[] memory askBenchmarks = ordersCrud.GetOrderBenchmarks(_askID); + if (askBenchmarks.length < benchmarksQuantity) { + askBenchmarks = ResizeBenchmarks(askBenchmarks); } - if (bid.benchmarks.length < benchmarksQuantity) { - bid.benchmarks = ResizeBenchmarks(bid.benchmarks); + uint64[] memory bidBenchmarks = ordersCrud.GetOrderBenchmarks(_bidID); + if (bidBenchmarks.length < benchmarksQuantity) { + bidBenchmarks = ResizeBenchmarks(bidBenchmarks); } - for (i = 0; i < ask.benchmarks.length; i++) { - require(ask.benchmarks[i] >= bid.benchmarks[i]); + for (i = 0; i < benchmarksQuantity; i++) { + require(askBenchmarks[i] >= bidBenchmarks[i]); } - dealAmount = dealAmount.add(1); - address master = GetMaster(ask.author); - orders[_askID].orderStatus = OrderStatus.ORDER_INACTIVE; - orders[_bidID].orderStatus = OrderStatus.ORDER_INACTIVE; - orders[_askID].dealID = dealAmount; - orders[_bidID].dealID = dealAmount; + ordersCrud.SetOrderStatus(_askID, Orders.OrderStatus.ORDER_INACTIVE); + ordersCrud.SetOrderStatus(_bidID, Orders.OrderStatus.ORDER_INACTIVE); emit OrderUpdated(_askID); emit OrderUpdated(_bidID); - uint startTime = block.timestamp; - uint endTime = 0; - // `0` - for spot deal // if deal is normal - if (ask.duration != 0) { - endTime = startTime.add(bid.duration); + if (ordersCrud.GetOrderDuration(_askID) != 0) { + uint endTime = block.timestamp.add(ordersCrud.GetOrderDuration(_bidID)); + } else { + endTime = 0; + // `0` - for spot deal } - uint blockedBalance = bid.frozenSum; - deals[dealAmount] = Deal(ask.benchmarks, ask.author, bid.author, master, _askID, _bidID, bid.duration, ask.price, startTime, endTime, DealStatus.STATUS_ACCEPTED, blockedBalance, 0, block.timestamp); - emit DealOpened(dealAmount); + + dealsCrud.IncreaseDealsAmount(); + + uint dealID = dealsCrud.GetDealsAmount(); + + dealsCrud.SetDealBenchmarks(dealID, askBenchmarks); + dealsCrud.SetDealConsumerID(dealID, ordersCrud.GetOrderAuthor(_bidID)); + dealsCrud.SetDealSupplierID(dealID, ordersCrud.GetOrderAuthor(_askID)); + dealsCrud.SetDealMasterID(dealID, administratum.GetMaster(ordersCrud.GetOrderAuthor(_askID))); + dealsCrud.SetDealAskID(dealID, _askID); + dealsCrud.SetDealBidID(dealID, _bidID); + dealsCrud.SetDealDuration(dealID, ordersCrud.GetOrderDuration(_bidID)); + dealsCrud.SetDealPrice(dealID, ordersCrud.GetOrderPrice(_askID)); + dealsCrud.SetDealStartTime(dealID, block.timestamp); + dealsCrud.SetDealEndTime(dealID, endTime); + dealsCrud.SetDealStatus(dealID, Deals.DealStatus.STATUS_ACCEPTED); + dealsCrud.SetDealBlockedBalance(dealID, ordersCrud.GetOrderFrozenSum(_bidID)); + dealsCrud.SetDealTotalPayout(dealID, 0); + dealsCrud.SetDealLastBillTS(dealID, block.timestamp); + + + + emit DealOpened(dealsCrud.GetDealsAmount()); + + ordersCrud.SetOrderDealID(_askID, dealID); + ordersCrud.SetOrderDealID(_bidID, dealID); } function CloseDeal(uint dealID, BlacklistPerson blacklisted) public returns (bool){ - require((deals[dealID].status == DealStatus.STATUS_ACCEPTED)); - require(msg.sender == deals[dealID].supplierID || msg.sender == deals[dealID].consumerID || msg.sender == deals[dealID].masterID); + require((dealsCrud.GetDealStatus(dealID) == Deals.DealStatus.STATUS_ACCEPTED)); + require(msg.sender == dealsCrud.GetDealSupplierID(dealID) || msg.sender == dealsCrud.GetDealConsumerID(dealID) || msg.sender == dealsCrud.GetDealMasterID(dealID)); - if (block.timestamp <= deals[dealID].startTime.add(deals[dealID].duration)) { + if (block.timestamp <= dealsCrud.GetDealStartTime(dealID).add(dealsCrud.GetDealDuration(dealID))) { // after endTime - require(deals[dealID].consumerID == msg.sender); + require(dealsCrud.GetDealConsumerID(dealID) == msg.sender); } AddToBlacklist(dealID, blacklisted); InternalBill(dealID); @@ -351,266 +325,134 @@ contract Market is Ownable, Pausable { } function CreateChangeRequest(uint dealID, uint newPrice, uint newDuration) public returns (uint changeRequestID) { - require(msg.sender == deals[dealID].consumerID || msg.sender == deals[dealID].masterID || msg.sender == deals[dealID].supplierID); - require(deals[dealID].status == DealStatus.STATUS_ACCEPTED); - if (IsSpot(dealID)) { + require( + msg.sender == dealsCrud.GetDealConsumerID(dealID) + || msg.sender == dealsCrud.GetDealMasterID(dealID) + || msg.sender == dealsCrud.GetDealSupplierID(dealID)); + require(dealsCrud.GetDealStatus(dealID) == Deals.DealStatus.STATUS_ACCEPTED); + + if (dealsCrud.GetDealDuration(dealID) == 0) { require(newDuration == 0); } - requestsAmount = requestsAmount.add(1); - OrderType requestType; + Orders.OrderType requestType; - if (msg.sender == deals[dealID].consumerID) { - requestType = OrderType.ORDER_BID; + if (msg.sender == dealsCrud.GetDealConsumerID(dealID)) { + requestType = Orders.OrderType.ORDER_BID; } else { - requestType = OrderType.ORDER_ASK; + requestType = Orders.OrderType.ORDER_ASK; } - requests[requestsAmount] = ChangeRequest(dealID, requestType, newPrice, newDuration, RequestStatus.REQUEST_CREATED); - emit DealChangeRequestSet(requestsAmount); - - if (requestType == OrderType.ORDER_BID) { - emit DealChangeRequestUpdated(actualRequests[dealID][1]); - requests[actualRequests[dealID][1]].status = RequestStatus.REQUEST_CANCELED; - actualRequests[dealID][1] = requestsAmount; - ChangeRequest memory matchingRequest = requests[actualRequests[dealID][0]]; - - if (newDuration == deals[dealID].duration && newPrice > deals[dealID].price) { - requests[requestsAmount].status = RequestStatus.REQUEST_ACCEPTED; + uint currentID = changeRequestsCrud.Write(dealID, requestType, newPrice, newDuration, ChangeRequests.RequestStatus.REQUEST_CREATED); + emit DealChangeRequestSet(currentID); + + if (requestType == Orders.OrderType.ORDER_BID) { + uint oldID = changeRequestsCrud.GetActualChangeRequest(dealID, 1); + uint matchingID = changeRequestsCrud.GetActualChangeRequest(dealID, 0); + emit DealChangeRequestUpdated(oldID); + changeRequestsCrud.SetChangeRequestStatus(oldID, ChangeRequests.RequestStatus.REQUEST_CANCELED); + changeRequestsCrud.SetActualChangeRequest(dealID, 1, currentID); + + if (newDuration == dealsCrud.GetDealDuration(dealID) && newPrice > dealsCrud.GetDealPrice(dealID)) { + if (changeRequestsCrud.GetChangeRequestPrice(matchingID) <= newPrice) { + changeRequestsCrud.SetChangeRequestStatus(matchingID, ChangeRequests.RequestStatus.REQUEST_ACCEPTED); + } + changeRequestsCrud.SetChangeRequestStatus(currentID, ChangeRequests.RequestStatus.REQUEST_ACCEPTED); Bill(dealID); - deals[dealID].price = newPrice; - actualRequests[dealID][1] = 0; + dealsCrud.SetDealPrice(dealID, newPrice); + changeRequestsCrud.SetActualChangeRequest(dealID, 1, 0); emit DealChangeRequestUpdated(requestsAmount); - } else if (matchingRequest.status == RequestStatus.REQUEST_CREATED && matchingRequest.duration >= newDuration && matchingRequest.price <= newPrice) { - requests[requestsAmount].status = RequestStatus.REQUEST_ACCEPTED; - requests[actualRequests[dealID][0]].status = RequestStatus.REQUEST_ACCEPTED; - emit DealChangeRequestUpdated(actualRequests[dealID][0]); - actualRequests[dealID][0] = 0; - actualRequests[dealID][1] = 0; + } else if (changeRequestsCrud.GetChangeRequestStatus(matchingID) == ChangeRequests.RequestStatus.REQUEST_CREATED + && changeRequestsCrud.GetChangeRequestDuration(matchingID) >= newDuration + && changeRequestsCrud.GetChangeRequestPrice(matchingID) <= newPrice) { + + changeRequestsCrud.SetChangeRequestStatus(currentID, ChangeRequests.RequestStatus.REQUEST_ACCEPTED); + changeRequestsCrud.SetChangeRequestStatus(matchingID, ChangeRequests.RequestStatus.REQUEST_ACCEPTED); + emit DealChangeRequestUpdated(changeRequestsCrud.GetActualChangeRequest(dealID, 0)); + changeRequestsCrud.SetActualChangeRequest(dealID, 0, 0); + changeRequestsCrud.SetActualChangeRequest(dealID, 1, 0); Bill(dealID); - deals[dealID].price = matchingRequest.price; - deals[dealID].duration = newDuration; + dealsCrud.SetDealPrice(dealID, changeRequestsCrud.GetChangeRequestPrice(matchingID)); + dealsCrud.SetDealDuration(dealID, newDuration); emit DealChangeRequestUpdated(requestsAmount); } else { - return requestsAmount; + return currentID; } - - requests[actualRequests[dealID][1]].status = RequestStatus.REQUEST_CANCELED; - emit DealChangeRequestUpdated(actualRequests[dealID][1]); - actualRequests[dealID][1] = requestsAmount; + changeRequestsCrud.SetChangeRequestStatus(changeRequestsCrud.GetActualChangeRequest(dealID, 1), ChangeRequests.RequestStatus.REQUEST_CANCELED); + emit DealChangeRequestUpdated(changeRequestsCrud.GetActualChangeRequest(dealID, 1)); + changeRequestsCrud.SetActualChangeRequest(dealID, 1, changeRequestsCrud.GetChangeRequestsAmount()); } - if (requestType == OrderType.ORDER_ASK) { - emit DealChangeRequestUpdated(actualRequests[dealID][0]); - requests[actualRequests[dealID][0]].status = RequestStatus.REQUEST_CANCELED; - actualRequests[dealID][0] = requestsAmount; - matchingRequest = requests[actualRequests[dealID][1]]; + if (requestType == Orders.OrderType.ORDER_ASK) { + matchingID = changeRequestsCrud.GetActualChangeRequest(dealID, 1); + oldID = changeRequestsCrud.GetActualChangeRequest(dealID, 0); + emit DealChangeRequestUpdated(oldID); + changeRequestsCrud.SetChangeRequestStatus(oldID, ChangeRequests.RequestStatus.REQUEST_CANCELED); + changeRequestsCrud.SetActualChangeRequest(dealID, 0, currentID); + - if (newDuration == deals[dealID].duration && newPrice < deals[dealID].price) { - requests[requestsAmount].status = RequestStatus.REQUEST_ACCEPTED; + if (newDuration == dealsCrud.GetDealDuration(dealID) && newPrice < dealsCrud.GetDealPrice(dealID)) { + if (changeRequestsCrud.GetChangeRequestPrice(matchingID) >= newPrice) { + changeRequestsCrud.SetChangeRequestStatus(matchingID, ChangeRequests.RequestStatus.REQUEST_ACCEPTED); + } + changeRequestsCrud.SetChangeRequestStatus(currentID, ChangeRequests.RequestStatus.REQUEST_ACCEPTED); Bill(dealID); - deals[dealID].price = newPrice; - actualRequests[dealID][0] = 0; - emit DealChangeRequestUpdated(requestsAmount); - } else if (matchingRequest.status == RequestStatus.REQUEST_CREATED && matchingRequest.duration <= newDuration && matchingRequest.price >= newPrice) { - requests[requestsAmount].status = RequestStatus.REQUEST_ACCEPTED; - emit DealChangeRequestUpdated(actualRequests[dealID][1]); - actualRequests[dealID][0] = 0; - actualRequests[dealID][1] = 0; + dealsCrud.SetDealPrice(dealID, newPrice); + changeRequestsCrud.SetActualChangeRequest(dealID, 0, 0); + emit DealChangeRequestUpdated(currentID); + } else if (changeRequestsCrud.GetChangeRequestStatus(matchingID) == ChangeRequests.RequestStatus.REQUEST_CREATED + && changeRequestsCrud.GetChangeRequestDuration(matchingID) <= newDuration + && changeRequestsCrud.GetChangeRequestPrice(matchingID) >= newPrice) { + + changeRequestsCrud.SetChangeRequestStatus(currentID, ChangeRequests.RequestStatus.REQUEST_ACCEPTED); + changeRequestsCrud.SetChangeRequestStatus(matchingID, ChangeRequests.RequestStatus.REQUEST_ACCEPTED); + emit DealChangeRequestUpdated(matchingID); //bug + changeRequestsCrud.SetActualChangeRequest(dealID, 0, 0); + changeRequestsCrud.SetActualChangeRequest(dealID, 1, 0); Bill(dealID); - deals[dealID].price = newPrice; - deals[dealID].duration = matchingRequest.duration; - emit DealChangeRequestUpdated(requestsAmount); + dealsCrud.SetDealPrice(dealID, newPrice); + dealsCrud.SetDealDuration(dealID, changeRequestsCrud.GetChangeRequestDuration(matchingID)); + emit DealChangeRequestUpdated(currentID); } else { - return requestsAmount; + return currentID; } } - deals[dealID].endTime = deals[dealID].startTime.add(deals[dealID].duration); - return requestsAmount; + dealsCrud.SetDealEndTime(dealID, dealsCrud.GetDealStartTime(dealID).add(dealsCrud.GetDealEndTime(dealID))); + return currentID; } function CancelChangeRequest(uint changeRequestID) public returns (bool) { - ChangeRequest memory request = requests[changeRequestID]; - require(msg.sender == deals[request.dealID].supplierID || msg.sender == deals[request.dealID].masterID || msg.sender == deals[request.dealID].consumerID); - require(request.status != RequestStatus.REQUEST_ACCEPTED); + uint dealID = changeRequestsCrud.GetChangeRequestDealID(changeRequestID); + require(msg.sender == dealsCrud.GetDealSupplierID(dealID) || msg.sender == dealsCrud.GetDealMasterID(dealID) || msg.sender == dealsCrud.GetDealConsumerID(dealID)); + require(changeRequestsCrud.GetChangeRequestStatus(changeRequestID) != ChangeRequests.RequestStatus.REQUEST_ACCEPTED); - if (request.requestType == OrderType.ORDER_ASK) { - if (msg.sender == deals[request.dealID].consumerID) { - requests[changeRequestID].status = RequestStatus.REQUEST_REJECTED; + if (changeRequestsCrud.GetChangeRequestType(changeRequestID) == Orders.OrderType.ORDER_ASK) { + if (msg.sender == dealsCrud.GetDealConsumerID(dealID)) { + changeRequestsCrud.SetChangeRequestStatus(changeRequestID, ChangeRequests.RequestStatus.REQUEST_REJECTED); } else { - requests[changeRequestID].status = RequestStatus.REQUEST_CANCELED; + changeRequestsCrud.SetChangeRequestStatus(changeRequestID, ChangeRequests.RequestStatus.REQUEST_CANCELED); } - actualRequests[request.dealID][0] = 0; + changeRequestsCrud.SetActualChangeRequest(dealID, 0, 0); emit DealChangeRequestUpdated(changeRequestID); } - if (request.requestType == OrderType.ORDER_BID) { - if (msg.sender == deals[request.dealID].consumerID) { - requests[changeRequestID].status = RequestStatus.REQUEST_CANCELED; + if (changeRequestsCrud.GetChangeRequestType(changeRequestID) == Orders.OrderType.ORDER_BID) { + if (msg.sender == dealsCrud.GetDealConsumerID(dealID)) { + changeRequestsCrud.SetChangeRequestStatus(changeRequestID, ChangeRequests.RequestStatus.REQUEST_CANCELED); } else { - requests[changeRequestID].status = RequestStatus.REQUEST_REJECTED; + changeRequestsCrud.SetChangeRequestStatus(changeRequestID, ChangeRequests.RequestStatus.REQUEST_REJECTED); } - actualRequests[request.dealID][1] = 0; + changeRequestsCrud.SetActualChangeRequest(dealID, 1, 0); emit DealChangeRequestUpdated(changeRequestID); } return true; } - // Master-worker functions - - function RegisterWorker(address _master) public whenNotPaused returns (bool) { - require(GetMaster(msg.sender) == msg.sender); - require(isMaster[msg.sender] == false); - require(GetMaster(_master) == _master); - masterRequest[_master][msg.sender] = true; - emit WorkerAnnounced(msg.sender, _master); - return true; - } - - function ConfirmWorker(address _worker) public whenNotPaused returns (bool) { - require(masterRequest[msg.sender][_worker] == true); - masterOf[_worker] = msg.sender; - isMaster[msg.sender] = true; - delete masterRequest[msg.sender][_worker]; - emit WorkerConfirmed(_worker, msg.sender); - return true; - } - - function RemoveWorker(address _worker, address _master) public whenNotPaused returns (bool) { - require(GetMaster(_worker) == _master && (msg.sender == _worker || msg.sender == _master)); - delete masterOf[_worker]; - emit WorkerRemoved(_worker, _master); - return true; - } - // GETTERS - function GetOrderInfo(uint orderID) view public - returns ( - OrderType orderType, - address author, - address counterparty, - uint duration, - uint price, - bool[] netflags, - ProfileRegistry.IdentityLevel identityLevel, - address blacklist, - bytes32 tag, - uint64[] benchmarks, - uint frozenSum - ){ - Order memory order = orders[orderID]; - return ( - order.orderType, - order.author, - order.counterparty, - order.duration, - order.price, - order.netflags, - order.identityLevel, - order.blacklist, - order.tag, - order.benchmarks, - order.frozenSum - ); - } - - - function GetOrderParams(uint orderID) view public - returns ( - OrderStatus orderStatus, - uint dealID - ){ - Order memory order = orders[orderID]; - return ( - order.orderStatus, - order.dealID - ); - } - - function GetDealInfo(uint dealID) view public - returns ( - uint64[] benchmarks, - address supplierID, - address consumerID, - address masterID, - uint askID, - uint bidID, - uint startTime - ){ - return ( - deals[dealID].benchmarks, - deals[dealID].supplierID, - deals[dealID].consumerID, - deals[dealID].masterID, - deals[dealID].askID, - deals[dealID].bidID, - deals[dealID].startTime - - ); - } - - function GetDealParams(uint dealID) view public - returns ( - uint duration, - uint price, - uint endTime, - DealStatus status, - uint blockedBalance, - uint totalPayout, - uint lastBillTS - ){ - return ( - deals[dealID].duration, - deals[dealID].price, - deals[dealID].endTime, - deals[dealID].status, - deals[dealID].blockedBalance, - deals[dealID].totalPayout, - deals[dealID].lastBillTS - ); - } - - function GetMaster(address _worker) view public returns (address master) { - if (masterOf[_worker] == 0x0 || masterOf[_worker] == _worker) { - master = _worker; - } else { - master = masterOf[_worker]; - } - } - - function GetChangeRequestInfo(uint changeRequestID) view public - returns ( - uint dealID, - OrderType requestType, - uint price, - uint duration, - RequestStatus status - ){ - return ( - requests[changeRequestID].dealID, - requests[changeRequestID].requestType, - requests[changeRequestID].price, - requests[changeRequestID].duration, - requests[changeRequestID].status - ); - } - - function GetDealsAmount() public view returns (uint){ - return dealAmount; - } - - function GetOrdersAmount() public view returns (uint){ - return ordersAmount; - } - - function GetChangeRequestsAmount() public view returns (uint){ - return requestsAmount; - } - function GetBenchmarksQuantity() public view returns (uint) { return benchmarksQuantity; } @@ -623,72 +465,79 @@ contract Market is Ownable, Pausable { // INTERNAL function InternalBill(uint dealID) internal returns (bool){ - require(deals[dealID].status == DealStatus.STATUS_ACCEPTED); - require(msg.sender == deals[dealID].supplierID || msg.sender == deals[dealID].consumerID || msg.sender == deals[dealID].masterID); - Deal memory deal = deals[dealID]; + require(dealsCrud.GetDealStatus(dealID) == Deals.DealStatus.STATUS_ACCEPTED); + require( + msg.sender == dealsCrud.GetDealSupplierID(dealID) || + msg.sender == dealsCrud.GetDealConsumerID(dealID) || + msg.sender == dealsCrud.GetDealMasterID(dealID)); uint paidAmount; - if (!IsSpot(dealID) && deal.lastBillTS >= deal.endTime) { + if (dealsCrud.GetDealDuration(dealID) != 0 && dealsCrud.GetDealLastBillTS(dealID) >= dealsCrud.GetDealEndTime(dealID)) { // means we already billed deal after endTime return true; - } else if (!IsSpot(dealID) && block.timestamp > deal.endTime && deal.lastBillTS < deal.endTime) { - paidAmount = CalculatePayment(deal.price, deal.endTime.sub(deal.lastBillTS)); + } else if (dealsCrud.GetDealDuration(dealID) != 0 + && block.timestamp > dealsCrud.GetDealEndTime(dealID) + && dealsCrud.GetDealLastBillTS(dealID) < dealsCrud.GetDealEndTime(dealID)) { + paidAmount = CalculatePayment(dealsCrud.GetDealPrice(dealID), dealsCrud.GetDealEndTime(dealID).sub(dealsCrud.GetDealLastBillTS(dealID))); } else { - paidAmount = CalculatePayment(deal.price, block.timestamp.sub(deal.lastBillTS)); + paidAmount = CalculatePayment(dealsCrud.GetDealPrice(dealID), block.timestamp.sub(dealsCrud.GetDealLastBillTS(dealID))); } - if (paidAmount > deal.blockedBalance) { - if (token.balanceOf(deal.consumerID) >= paidAmount.sub(deal.blockedBalance)) { - require(token.transferFrom(deal.consumerID, this, paidAmount.sub(deal.blockedBalance))); - deals[dealID].blockedBalance = deals[dealID].blockedBalance.add(paidAmount.sub(deal.blockedBalance)); + if (paidAmount > dealsCrud.GetDealBlockedBalance(dealID)) { + if (token.balanceOf(dealsCrud.GetDealConsumerID(dealID)) >= paidAmount.sub(dealsCrud.GetDealBlockedBalance(dealID))) { + require(token.transferFrom(dealsCrud.GetDealConsumerID(dealID), this, paidAmount.sub(dealsCrud.GetDealBlockedBalance(dealID)))); + dealsCrud.SetDealBlockedBalance(dealID, dealsCrud.GetDealBlockedBalance(dealID).add(paidAmount.sub(dealsCrud.GetDealBlockedBalance(dealID)))); } else { - emit Billed(dealID, deals[dealID].blockedBalance); + emit Billed(dealID, dealsCrud.GetDealBlockedBalance(dealID)); InternalCloseDeal(dealID); - require(token.transfer(deal.masterID, deal.blockedBalance)); - deals[dealID].lastBillTS = block.timestamp; - deals[dealID].totalPayout = deals[dealID].totalPayout.add(deal.blockedBalance); - deals[dealID].blockedBalance = 0; + require(token.transfer(dealsCrud.GetDealMasterID(dealID), dealsCrud.GetDealBlockedBalance(dealID))); + dealsCrud.SetDealTotalPayout(dealID, dealsCrud.GetDealTotalPayout(dealID).add(dealsCrud.GetDealBlockedBalance(dealID))); + dealsCrud.SetDealBlockedBalance(dealID, 0); + dealsCrud.SetDealEndTime(dealID, block.timestamp); return true; } } - require(token.transfer(deal.masterID, paidAmount)); - deals[dealID].blockedBalance = deals[dealID].blockedBalance.sub(paidAmount); - deals[dealID].totalPayout = deals[dealID].totalPayout.add(paidAmount); - deals[dealID].lastBillTS = block.timestamp; + + require(token.transfer(dealsCrud.GetDealMasterID(dealID), paidAmount)); + dealsCrud.SetDealBlockedBalance(dealID, dealsCrud.GetDealBlockedBalance(dealID).sub(paidAmount)); + dealsCrud.SetDealTotalPayout(dealID, dealsCrud.GetDealTotalPayout(dealID).add(paidAmount)); + dealsCrud.SetDealLastBillTS(dealID, block.timestamp); emit Billed(dealID, paidAmount); return true; } function ReserveNextPeriodFunds(uint dealID) internal returns (bool) { uint nextPeriod; - Deal memory deal = deals[dealID]; + address consumerID = dealsCrud.GetDealConsumerID(dealID); - if (IsSpot(dealID)) { - if (deal.status == DealStatus.STATUS_CLOSED) { + (uint duration, uint price, uint endTime, Deals.DealStatus status, uint blockedBalance, , ) = dealsCrud.GetDealParams(dealID); + + if (duration == 0) { + if (status == Deals.DealStatus.STATUS_CLOSED) { return true; } nextPeriod = 1 hours; } else { - if (block.timestamp > deal.endTime) { + if (block.timestamp > endTime) { // we don't reserve funds for next period return true; } - if (deal.endTime.sub(block.timestamp) < 1 days) { - nextPeriod = deal.endTime.sub(block.timestamp); + if (endTime.sub(block.timestamp) < 1 days) { + nextPeriod = endTime.sub(block.timestamp); } else { nextPeriod = 1 days; } } - if (CalculatePayment(deal.price, nextPeriod) > deals[dealID].blockedBalance) { - uint nextPeriodSum = CalculatePayment(deal.price, nextPeriod).sub(deals[dealID].blockedBalance); + if (CalculatePayment(price, nextPeriod) > blockedBalance) { + uint nextPeriodSum = CalculatePayment(price, nextPeriod).sub(blockedBalance); - if (token.balanceOf(deal.consumerID) >= nextPeriodSum) { - require(token.transferFrom(deal.consumerID, this, nextPeriodSum)); - deals[dealID].blockedBalance = deals[dealID].blockedBalance.add(nextPeriodSum); + if (token.balanceOf(consumerID) >= nextPeriodSum) { + require(token.transferFrom(consumerID, this, nextPeriodSum)); + dealsCrud.SetDealBlockedBalance(dealID, blockedBalance.add(nextPeriodSum)); } else { - emit Billed(dealID, deals[dealID].blockedBalance); + emit Billed(dealID, blockedBalance); InternalCloseDeal(dealID); RefundRemainingFunds(dealID); return true; @@ -697,17 +546,19 @@ contract Market is Ownable, Pausable { return true; } - function RefundRemainingFunds(uint dealID) internal returns (bool){ - if (deals[dealID].blockedBalance != 0) { - token.transfer(deals[dealID].consumerID, deals[dealID].blockedBalance); - deals[dealID].blockedBalance = 0; + function RefundRemainingFunds(uint dealID) internal returns (bool) { + address consumerID = dealsCrud.GetDealConsumerID(dealID); + + uint blockedBalance = dealsCrud.GetDealBlockedBalance(dealID); + + if (blockedBalance != 0) { + token.transfer(consumerID, blockedBalance); + dealsCrud.SetDealBlockedBalance(dealID, 0); } return true; } - function IsSpot(uint dealID) internal view returns (bool){ - return deals[dealID].duration == 0; - } + function CalculatePayment(uint _price, uint _period) internal view returns (uint) { uint rate = oracle.getCurrentPrice(); @@ -715,23 +566,29 @@ contract Market is Ownable, Pausable { } function AddToBlacklist(uint dealID, BlacklistPerson role) internal { + (, address supplierID, address consumerID, address masterID, , , ) = dealsCrud.GetDealInfo(dealID); + // only consumer can blacklist - require(msg.sender == deals[dealID].consumerID || role == BlacklistPerson.BLACKLIST_NOBODY); + require(msg.sender == consumerID || role == BlacklistPerson.BLACKLIST_NOBODY); if (role == BlacklistPerson.BLACKLIST_WORKER) { - bl.Add(deals[dealID].consumerID, deals[dealID].supplierID); + bl.Add(consumerID, supplierID); } else if (role == BlacklistPerson.BLACKLIST_MASTER) { - bl.Add(deals[dealID].consumerID, deals[dealID].masterID); + bl.Add(consumerID, masterID); } } function InternalCloseDeal(uint dealID) internal { - if (deals[dealID].status == DealStatus.STATUS_CLOSED) { + ( , address supplierID, address consumerID, address masterID, , , ) = dealsCrud.GetDealInfo(dealID); + + Deals.DealStatus status = dealsCrud.GetDealStatus(dealID); + + if (status == Deals.DealStatus.STATUS_CLOSED) { return; } - require((deals[dealID].status == DealStatus.STATUS_ACCEPTED)); - require(msg.sender == deals[dealID].consumerID || msg.sender == deals[dealID].supplierID || msg.sender == deals[dealID].masterID); - deals[dealID].status = DealStatus.STATUS_CLOSED; - deals[dealID].endTime = block.timestamp; + require((status == Deals.DealStatus.STATUS_ACCEPTED)); + require(msg.sender == consumerID || msg.sender == supplierID || msg.sender == masterID); + dealsCrud.SetDealStatus(dealID, Deals.DealStatus.STATUS_CLOSED); + dealsCrud.SetDealEndTime(dealID, block.timestamp); emit DealUpdated(dealID); } @@ -753,30 +610,40 @@ contract Market is Ownable, Pausable { // SETTERS - function SetProfileRegistryAddress(address _newPR) onlyOwner public returns (bool) { - pr = ProfileRegistry(_newPR); + function SetProfileRegistryAddress(address _newPR) public onlyOwner returns (bool) { + profiles = ProfileRegistry(_newPR); return true; } - function SetBlacklistAddress(address _newBL) onlyOwner public returns (bool) { + function SetBlacklistAddress(address _newBL) public onlyOwner returns (bool) { bl = Blacklist(_newBL); return true; } - function SetOracleAddress(address _newOracle) onlyOwner public returns (bool) { + function SetOracleAddress(address _newOracle) public onlyOwner returns (bool) { require(OracleUSD(_newOracle).getCurrentPrice() != 0); oracle = OracleUSD(_newOracle); return true; } - function SetBenchmarksQuantity(uint _newQuantity) onlyOwner public returns (bool) { + function SetDealsAddress(address _newDeals) public onlyOwner returns (bool) { + dealsCrud = Deals(_newDeals); + return true; + } + + function SetOrdersAddress(address _newOrders) public onlyOwner returns (bool) { + ordersCrud = Orders(_newOrders); + return true; + } + + function SetBenchmarksQuantity(uint _newQuantity) public onlyOwner returns (bool) { require(_newQuantity > benchmarksQuantity); emit NumBenchmarksUpdated(_newQuantity); benchmarksQuantity = _newQuantity; return true; } - function SetNetflagsQuantity(uint _newQuantity) onlyOwner public returns (bool) { + function SetNetflagsQuantity(uint _newQuantity) public onlyOwner returns (bool) { require(_newQuantity > netflagsQuantity); emit NumNetflagsUpdated(_newQuantity); netflagsQuantity = _newQuantity; @@ -787,4 +654,13 @@ contract Market is Ownable, Pausable { token.transfer(owner, token.balanceOf(address(this))); selfdestruct(owner); } + + function Migrate(address _newMarket) public onlyOwner returns (bool) { + token.transfer(_newMarket, token.balanceOf(address(this))); + ordersCrud.transferOwnership(_newMarket); + dealsCrud.transferOwnership(_newMarket); + changeRequestsCrud.transferOwnership(_newMarket); + pause(); + + } } diff --git a/blockchain/source/contracts/OracleUSD.sol b/blockchain/source/contracts/OracleUSD.sol index b1c3f7001..f7e8fb5e5 100644 --- a/blockchain/source/contracts/OracleUSD.sol +++ b/blockchain/source/contracts/OracleUSD.sol @@ -20,7 +20,7 @@ contract OracleUSD is Ownable { emit PriceChanged(_price); } - function getCurrentPrice() public view returns (uint){ + function getCurrentPrice() public view returns (uint) { return currentPrice; } } diff --git a/blockchain/source/contracts/Orders.sol b/blockchain/source/contracts/Orders.sol new file mode 100644 index 000000000..330c5eb3f --- /dev/null +++ b/blockchain/source/contracts/Orders.sol @@ -0,0 +1,215 @@ +pragma solidity ^0.4.23; + +import "./Administratable.sol"; +import "./ProfileRegistry.sol"; + +contract Orders is Administratable { + //events + + //enums + + enum OrderStatus { + UNKNOWN, + ORDER_INACTIVE, + ORDER_ACTIVE + } + + enum OrderType { + ORDER_UNKNOWN, + ORDER_BID, + ORDER_ASK + } + + //DATA + struct Order { + OrderInfo info; + OrderParams params; + } + + struct OrderInfo { + OrderType orderType; + address author; + address counterparty; + uint duration; + uint price; + bool[] netflags; + ProfileRegistry.IdentityLevel identityLevel; + address blacklist; + bytes32 tag; + uint64[] benchmarks; + uint frozenSum; + uint requiredRating; + } + + struct OrderParams { + OrderStatus orderStatus; + uint dealID; + } + + mapping(uint => Order) public orders; + + uint ordersAmount = 0; + + //Constructor + + constructor() public { + owner = msg.sender; + administrator = msg.sender; + } + + function Write( + OrderType _orderType, + OrderStatus _orderStatus, + address _author, + address _counterparty, + uint _duration, + uint256 _price, + bool[] _netflags, + ProfileRegistry.IdentityLevel _identityLevel, + address _blacklist, + bytes32 _tag, + uint64[] _benchmarks, + uint _frozenSum, + uint _dealID) public onlyOwner returns(uint) { + + ordersAmount += 1; + + orders[ordersAmount].info.orderType = _orderType; + orders[ordersAmount].info.author = _author; + orders[ordersAmount].info.counterparty = _counterparty; + orders[ordersAmount].info.duration = _duration; + orders[ordersAmount].info.price = _price; + orders[ordersAmount].info.netflags = _netflags; + orders[ordersAmount].info.identityLevel = _identityLevel; + orders[ordersAmount].info.blacklist = _blacklist; + orders[ordersAmount].info.tag = _tag; + orders[ordersAmount].info.benchmarks = _benchmarks; + orders[ordersAmount].info.frozenSum = _frozenSum; + orders[ordersAmount].params.orderStatus = _orderStatus; + orders[ordersAmount].params.dealID = _dealID; + + return ordersAmount; + } + + function SetOrderStatus(uint orderID, OrderStatus _status) public onlyOwner { + orders[orderID].params.orderStatus = _status; + } + + function SetOrderDealID(uint orderID, uint _dealID) public onlyOwner { + orders[orderID].params.dealID = _dealID; + } + + function SetOrderBenchmarks(uint orderID, uint64[] _benchmarks) public onlyOwner { + orders[orderID].info.benchmarks = _benchmarks; + } + + function SetOrderNetflags(uint orderID, bool[] _netflags) public onlyOwner { + orders[orderID].info.netflags = _netflags; + } + + function SetOrderRequiredRating(uint orderID, uint _requiredRating) public onlyOwner { + orders[orderID].info.requiredRating = _requiredRating; + } + + function GetOrderInfo(uint orderID) public view + returns ( + OrderType orderType, + address author, + address counterparty, + uint duration, + uint price, + bool[] netflags, + ProfileRegistry.IdentityLevel identityLevel, + address blacklist, + bytes32 tag, + uint64[] benchmarks, + uint frozenSum, + uint requiredRating + ){ + OrderInfo memory info = orders[orderID].info; + return ( + info.orderType, + info.author, + info.counterparty, + info.duration, + info.price, + info.netflags, + info.identityLevel, + info.blacklist, + info.tag, + info.benchmarks, + info.frozenSum, + info.requiredRating + ); + } + function GetOrderType(uint orderID) public view returns (OrderType) { + return orders[orderID].info.orderType; + } + + function GetOrderAuthor(uint orderID) public view returns (address) { + return orders[orderID].info.author; + } + + function GetOrderCounterparty(uint orderID) public view returns (address) { + return orders[orderID].info.counterparty; + } + + function GetOrderDuration(uint orderID) public view returns (uint) { + return orders[orderID].info.duration; + } + + function GetOrderPrice(uint orderID) public view returns (uint) { + return orders[orderID].info.price; + } + + function GetOrderNetflags(uint orderID) public view returns (bool[]) { + return orders[orderID].info.netflags; + } + + function GetOrderIdentityLevel(uint orderID) public view returns (ProfileRegistry.IdentityLevel) { + return orders[orderID].info.identityLevel; + } + + function GetOrderBlacklist(uint orderID) public view returns (address) { + return orders[orderID].info.blacklist; + } + + function GetOrderTag(uint orderID) public view returns (bytes32) { + return orders[orderID].info.tag; + } + + function GetOrderBenchmarks(uint orderID) public view returns (uint64[]) { + return orders[orderID].info.benchmarks; + } + function GetOrderFrozenSum(uint orderID) public view returns (uint) { + return orders[orderID].info.frozenSum; + } + + function GetOrderRequiredRating(uint orderID) public view returns (uint) { + return orders[orderID].info.requiredRating; + } + + function GetOrdersAmount() public view returns (uint) { + return ordersAmount; + } + + function GetOrderParams(uint orderID) public view + returns ( + OrderStatus orderStatus, + uint dealID + ){ + OrderParams memory params = orders[orderID].params; + return ( + params.orderStatus, + params.dealID + ); + } + + function GetOrderStatus(uint orderID) public view returns (OrderStatus) { + return orders[orderID].params.orderStatus; + } + + function GetOrderDealID(uint orderID) public view returns (uint) { + return orders[orderID].params.dealID; + } +} diff --git a/blockchain/source/contracts/SimpleGatekeeperWithLimit.sol b/blockchain/source/contracts/SimpleGatekeeperWithLimit.sol index 95ad1a469..cad6ea383 100644 --- a/blockchain/source/contracts/SimpleGatekeeperWithLimit.sol +++ b/blockchain/source/contracts/SimpleGatekeeperWithLimit.sol @@ -123,7 +123,7 @@ contract SimpleGatekeeperWithLimit is Ownable { CommissionChanged(commission); } - function GetCommission() public view returns (uint256){ + function GetCommission() public view returns (uint256) { return commission; } diff --git a/blockchain/source/migrations/2_deploy_oracle.js b/blockchain/source/migrations/2_deploy_oracle.js index 26f474e06..65b7f5716 100644 --- a/blockchain/source/migrations/2_deploy_oracle.js +++ b/blockchain/source/migrations/2_deploy_oracle.js @@ -2,7 +2,7 @@ let OracleUSD = artifacts.require('./OracleUSD.sol'); module.exports = function (deployer, network) { if ((network === 'private') || (network === 'privateLive')) { - deployer.deploy(OracleUSD, { gasPrice: 0 }); + // deployer.deploy(OracleUSD, { gasPrice: 0 }); } else if (network === 'master') { // oracle haven't reason to deploy to mainnet } else if (network === 'rinkeby') { diff --git a/blockchain/source/migrations/3_deploy_profileRegistry.js b/blockchain/source/migrations/3_deploy_profileRegistry.js index eba35e58c..655c602a2 100644 --- a/blockchain/source/migrations/3_deploy_profileRegistry.js +++ b/blockchain/source/migrations/3_deploy_profileRegistry.js @@ -2,7 +2,7 @@ let ProfileRegistry = artifacts.require('./ProfileRegistry.sol'); module.exports = function (deployer, network) { if ((network === 'private') || (network === 'privateLive')) { - deployer.deploy(ProfileRegistry, { gasPrice: 0 }); + // deployer.deploy(ProfileRegistry, { gasPrice: 0 }); } else if (network === 'master') { // we do not deploy ProfileRegistry at master anytime } else if (network === 'rinkeby') { diff --git a/blockchain/source/migrations/4_deploy_blacklist.js b/blockchain/source/migrations/4_deploy_blacklist.js index 3a06abecc..d62da7936 100644 --- a/blockchain/source/migrations/4_deploy_blacklist.js +++ b/blockchain/source/migrations/4_deploy_blacklist.js @@ -2,7 +2,7 @@ let Blacklist = artifacts.require('./Blacklist.sol'); module.exports = function (deployer, network) { if ((network === 'private') || (network === 'privateLive')) { - deployer.deploy(Blacklist, { gasPrice: 0 }); + // deployer.deploy(Blacklist, { gasPrice: 0 }); } else if (network === 'master') { // blacklist haven't reason to deploy to mainnet } else if (network === 'rinkeby') { diff --git a/blockchain/source/migrations/5_deploy_crud.js b/blockchain/source/migrations/5_deploy_crud.js new file mode 100644 index 000000000..00563aec2 --- /dev/null +++ b/blockchain/source/migrations/5_deploy_crud.js @@ -0,0 +1,19 @@ +let Orders = artifacts.require('./Orders.sol'); +let Deals = artifacts.require('./Deals.sol'); +let ChangeRequests = artifacts.require('./ChangeRequests.sol'); +let AdministratumCrud = artifacts.require('./AdministratumCrud.sol'); + +module.exports = function (deployer, network) { + if ((network === 'private') || (network === 'privateLive')) { + // await deployer.deploy(Blacklist, { gasPrice: 0 }); + } else if (network === 'master') { + // will filled later + } else if (network === 'rinkeby') { + // later + } else { + deployer.deploy(Orders, { gasLimit: 20000000 }); + deployer.deploy(Deals, { gasLimit: 20000000 }); + deployer.deploy(ChangeRequests, { gasLimit: 20000000 }); + deployer.deploy(AdministratumCrud, { gasLimit: 10000000 }); + } +}; diff --git a/blockchain/source/migrations/6_deploy_administratum.js b/blockchain/source/migrations/6_deploy_administratum.js new file mode 100644 index 000000000..013030975 --- /dev/null +++ b/blockchain/source/migrations/6_deploy_administratum.js @@ -0,0 +1,14 @@ +let AdministratumCrud = artifacts.require('./AdministratumCrud.sol'); +let Administratum = artifacts.require('./Administratum.sol'); + +module.exports = function (deployer, network) { + if ((network === 'private') || (network === 'privateLive')) { + deployer.deploy(Administratum, { gasPrice: 0 }); + } else if (network === 'master') { + // will filled later + } else if (network === 'rinkeby') { + // later + } else { + deployer.deploy(Administratum, AdministratumCrud.address); + } +}; diff --git a/blockchain/source/migrations/5_deploy_market.js b/blockchain/source/migrations/7_deploy_market.js similarity index 57% rename from blockchain/source/migrations/5_deploy_market.js rename to blockchain/source/migrations/7_deploy_market.js index f576c58e2..95e709bc4 100644 --- a/blockchain/source/migrations/5_deploy_market.js +++ b/blockchain/source/migrations/7_deploy_market.js @@ -3,6 +3,10 @@ let Market = artifacts.require('./Market.sol'); let Blacklist = artifacts.require('./Blacklist.sol'); let OracleUSD = artifacts.require('./OracleUSD.sol'); let ProfileRegistry = artifacts.require('./ProfileRegistry.sol'); +let Administratum = artifacts.require('./Administratum.sol'); +let Orders = artifacts.require('./Orders.sol'); +let Deals = artifacts.require('./Deals.sol'); +let ChangeRequests = artifacts.require('./ChangeRequests.sol'); module.exports = function (deployer, network) { if ((network === 'private') || (network === 'privateLive')) { @@ -11,6 +15,10 @@ module.exports = function (deployer, network) { Blacklist.address, // Blacklist address OracleUSD.address, // Oracle address ProfileRegistry.address, // ProfileRegistry address + Administratum.address, + Orders.address, + Deals.address, + ChangeRequests.address, 12, // benchmarks quantity 3, // netflags quantity { gasPrice: 0 }); @@ -19,6 +27,17 @@ module.exports = function (deployer, network) { } else if (network === 'rinkeby') { // market haven't reason to deploy to rinkeby } else { - deployer.deploy(Market, SNM.address, Blacklist.address, OracleUSD.address, ProfileRegistry.address, 12, 3); + deployer.deploy(Market, + SNM.address, + Blacklist.address, + OracleUSD.address, + ProfileRegistry.address, + Administratum.address, + Orders.address, + Deals.address, + ChangeRequests.address, + 12, + 3, + { gasLimit: 1000000000 }); } }; diff --git a/blockchain/source/migrations/6_set_market_for_blacklist.js b/blockchain/source/migrations/8_set_market_for_blacklist.js similarity index 100% rename from blockchain/source/migrations/6_set_market_for_blacklist.js rename to blockchain/source/migrations/8_set_market_for_blacklist.js diff --git a/blockchain/source/scripts/test.sh b/blockchain/source/scripts/test.sh index 2da036a27..769a28685 100755 --- a/blockchain/source/scripts/test.sh +++ b/blockchain/source/scripts/test.sh @@ -40,9 +40,9 @@ start_testrpc() { ) if [ "$SOLIDITY_COVERAGE" = true ]; then - node_modules/.bin/testrpc-sc --gasLimit 0xfffffffffff --port "$testrpc_port" "${accounts[@]}" > /dev/null & + node_modules/.bin/testrpc-sc --gasLimit 0xfffffffffff --allowUnlimitedContractSize --port "$testrpc_port" "${accounts[@]}" > /dev/null & else - node_modules/.bin/ganache-cli --gasLimit 0xfffffffffff --port "$testrpc_port" "${accounts[@]}" > /dev/null & + node_modules/.bin/ganache-cli --gasLimit 0xfffffffffff --allowUnlimitedContractSize --port "$testrpc_port" "${accounts[@]}" > /dev/null & fi testrpc_pid=$! diff --git a/blockchain/source/test/blacklist.js b/blockchain/source/test/blacklist.js index 6dd85f57f..704583429 100644 --- a/blockchain/source/test/blacklist.js +++ b/blockchain/source/test/blacklist.js @@ -5,6 +5,11 @@ const Blacklist = artifacts.require('./Blacklist.sol'); const SNM = artifacts.require('./SNM.sol'); const OracleUSD = artifacts.require('./OracleUSD.sol'); const ProfileRegistry = artifacts.require('./ProfileRegistry.sol'); +const Orders = artifacts.require('./Orders.sol'); +const Deals = artifacts.require('./Deals.sol'); +const ChangeRequests = artifacts.require('./ChangeRequests.sol'); +const AdministratumCrud = artifacts.require('./AdministratumCrud.sol'); +const Administratum = artifacts.require('./Administratum.sol'); contract('Blacklist', async function (accounts) { let market; @@ -12,6 +17,11 @@ contract('Blacklist', async function (accounts) { let token; let oracle; let pr; + let administratumCrud; + let administratum; + let orders; + let deals; + let changeRequests; const owner = accounts[0]; const creeper = accounts[1]; @@ -26,7 +36,23 @@ contract('Blacklist', async function (accounts) { oracle = await OracleUSD.new(); pr = await ProfileRegistry.new(); await blacklist.AddMaster(master, { from: owner }); - market = await Market.new(token.address, blacklist.address, oracle.address, pr.address, 12, 3); + administratumCrud = await AdministratumCrud.new(); + administratum = await Administratum.new(administratumCrud.address); + orders = await Orders.new(); + deals = await Deals.new(); + changeRequests = await ChangeRequests.new(); + + market = await Market.new(token.address, + blacklist.address, + oracle.address, + pr.address, + administratum.address, + orders.address, + deals.address, + changeRequests.address, + 12, + 3, + { gasLimit: 30000000 }); }); it('test ACL', async function () { diff --git a/blockchain/source/test/helpers/common.js b/blockchain/source/test/helpers/common.js index 29f4059dc..3e89b693d 100644 --- a/blockchain/source/test/helpers/common.js +++ b/blockchain/source/test/helpers/common.js @@ -3,17 +3,17 @@ export async function checkBenchmarks (info, benchmarks) { assert.equal(JSON.stringify(benchmarks), JSON.stringify(b), 'Incorrect benchmarks'); } -export async function checkOrderStatus (market, key, orderId, status) { - let res = await market.GetOrderParams(orderId, { from: key }); +export async function checkOrderStatus (orders, key, orderId, status) { + let res = await orders.GetOrderParams(orderId, { from: key }); assert.equal(status, res[0], 'Incorrect order status'); } -export async function getDealIdFromOrder (market, key, orderId) { - let orderParams = await market.GetOrderParams(orderId, { from: key }); +export async function getDealIdFromOrder (orders, key, orderId) { + let orderParams = await orders.GetOrderParams(orderId, { from: key }); return orderParams[1].toNumber(10); } -export async function getDealInfoFromOrder (market, key, orderId) { - let dealId = await getDealIdFromOrder(market, key, orderId); - return market.GetDealInfo(dealId, { from: key }); +export async function getDealInfoFromOrder (deals, orders, key, orderId) { + let dealId = await getDealIdFromOrder(orders, key, orderId); + return deals.GetDealInfo(dealId, { from: key }); } diff --git a/blockchain/source/test/market.js b/blockchain/source/test/market.js index 66853503e..207d36f3b 100644 --- a/blockchain/source/test/market.js +++ b/blockchain/source/test/market.js @@ -31,6 +31,11 @@ const Market = artifacts.require('./Market.sol'); const OracleUSD = artifacts.require('./OracleUSD.sol'); const Blacklist = artifacts.require('./Blacklist.sol'); const ProfileRegistry = artifacts.require('./ProfileRegistry.sol'); +const Orders = artifacts.require('./Orders.sol'); +const Deals = artifacts.require('./Deals.sol'); +const ChangeRequests = artifacts.require('./ChangeRequests.sol'); +const AdministratumCrud = artifacts.require('./AdministratumCrud.sol'); +const Administratum = artifacts.require('./Administratum.sol'); const ONE_MILLION_TOKEN = 1e6 * 1e18; @@ -40,6 +45,11 @@ contract('Market', async (accounts) => { let oracle; let blacklist; let profileRegistry; + let administratumCrud; + let administratum; + let orders; + let deals; + let changeRequests; let supplier = accounts[1]; let consumer = accounts[2]; let master = accounts[3]; @@ -57,14 +67,31 @@ contract('Market', async (accounts) => { await oracle.setCurrentPrice(oraclePrice); blacklist = await Blacklist.new(); profileRegistry = await ProfileRegistry.new(); + administratumCrud = await AdministratumCrud.new(); + administratum = await Administratum.new(administratumCrud.address); + orders = await Orders.new(); + deals = await Deals.new(); + changeRequests = await ChangeRequests.new(); market = await Market.new( token.address, blacklist.address, oracle.address, profileRegistry.address, + administratum.address, + orders.address, + deals.address, + changeRequests.address, benchmarkQuantity, netflagsQuantity, + { gasLimit: 30000000 } ); + + await administratumCrud.transferOwnership(administratum.address); + await administratum.transferOwnership(market.address); + await orders.transferOwnership(market.address); + await deals.transferOwnership(market.address); + await changeRequests.transferOwnership(market.address); + await blacklist.SetMarketAddress(market.address); await token.transfer(consumer, oraclePrice / 1e7, { from: accounts[0] }); @@ -88,7 +115,7 @@ contract('Market', async (accounts) => { // TODO: test above normal deal let oid = await Ask({ market, supplier }); - let info = await market.GetOrderInfo(oid, { from: supplier }); + let info = await orders.GetOrderInfo(oid, { from: supplier }); assert.equal(OrderType.ASK, info[orderInfo.type]); assert.equal(supplier, info[orderInfo.author]); assert.equal('0x0000000000000000000000000000000000000000', info[orderInfo.counterparty]); @@ -110,7 +137,7 @@ contract('Market', async (accounts) => { it('CreateOrder forward bid', async () => { let balanceBefore = await token.balanceOf(consumer); let oid = await Bid({ market, consumer }); - let info = await market.GetOrderInfo(oid, { from: consumer }); + let info = await orders.GetOrderInfo(oid, { from: consumer }); assert.equal(OrderType.BID, info[orderInfo.type]); assert.equal(consumer, info[orderInfo.author]); assert.equal('0x0000000000000000000000000000000000000000', info[orderInfo.counterparty]); @@ -146,7 +173,7 @@ contract('Market', async (accounts) => { let marketBalanceAfter = await token.balanceOf(market.address); let marketDifference = marketBalanceAfter.toNumber() - marketBalanceBefore.toNumber(); - let info = await market.GetOrderInfo(oid, { from: consumer }); + let info = await orders.GetOrderInfo(oid, { from: consumer }); let frozenSum = info[orderInfo.frozenSum]; assert.equal(balanceBefore.toNumber() - frozenSum, balanceAfter.toNumber()); @@ -155,7 +182,7 @@ contract('Market', async (accounts) => { it('CreateOrder spot ask', async () => { let oid = await Ask({ market, supplier, duration: 0 }); - let info = await market.GetOrderInfo(oid, { from: supplier }); + let info = await orders.GetOrderInfo(oid, { from: supplier }); assert.equal(0, info[orderInfo.duration]); }); @@ -177,7 +204,7 @@ contract('Market', async (accounts) => { let balanceAfter = await token.balanceOf(supplier); assert.equal(balanceBefore.toNumber(), balanceAfter.toNumber()); - let res = await market.GetOrderParams(oid, { from: supplier }); + let res = await orders.GetOrderParams(oid, { from: supplier }); assert.equal(OrderStatus.INACTIVE, res[OrderParams.status]); assert.equal(0, res[OrderParams.dealId]); }); @@ -191,7 +218,7 @@ contract('Market', async (accounts) => { let balanceAfter = await token.balanceOf(consumer); assert.equal(balanceBefore.toNumber(), balanceAfter.toNumber()); - let res = await market.GetOrderParams(oid, { from: consumer }); + let res = await orders.GetOrderParams(oid, { from: consumer }); assert.equal(OrderStatus.INACTIVE, res[OrderParams.status]); assert.equal(0, res[OrderParams.dealId]); }); @@ -212,17 +239,18 @@ contract('Market', async (accounts) => { it('OpenDeal forward', async () => { let askId = await Ask({ market, supplier }); let bidId = await Bid({ market, consumer }); - let dealsAmountBefore = await market.GetDealsAmount({ from: consumer }); + let dealsAmountBefore = await deals.GetDealsAmount({ from: consumer }); await market.OpenDeal(askId, bidId, { from: consumer }); - let askParams = await market.GetOrderParams(askId, { from: supplier }); - let bidParams = await market.GetOrderParams(bidId, { from: consumer }); + let askParams = await orders.GetOrderParams(askId, { from: supplier }); + let bidParams = await orders.GetOrderParams(bidId, { from: consumer }); assert.equal(OrderStatus.INACTIVE, askParams[OrderParams.status]); assert.equal(OrderStatus.INACTIVE, bidParams[OrderParams.status]); let dealId = bidParams[1]; - let dealsAmountAfter = await market.GetDealsAmount({ from: consumer }); - let dealInfo = await market.GetDealInfo(dealId, { from: consumer }); - let dealParams = await market.GetDealParams(dealId, { from: consumer }); + let dealsAmountAfter = await deals.GetDealsAmount({ from: consumer }); + let dealInfo = await deals.GetDealInfo(dealId, { from: consumer }); + let dealParams = await deals.GetDealParams(dealId, { from: consumer }); + assert.equal(dealsAmountBefore.toNumber() + 1, dealsAmountAfter.toNumber()); assert.equal(DealStatus.ACCEPTED, dealParams[DealParams.status]); assert.ok(dealInfo[DealInfo.startTime].toNumber() === dealParams[DealParams.lastBillTs].toNumber(), @@ -247,14 +275,14 @@ contract('Market', async (accounts) => { let bidId = await Bid({ market, consumer, duration: 0 }); await market.OpenDeal(askId, bidId, { from: consumer }); - let askParams = await market.GetOrderParams(askId, { from: supplier }); - let bidParams = await market.GetOrderParams(bidId, { from: consumer }); + let askParams = await orders.GetOrderParams(askId, { from: supplier }); + let bidParams = await orders.GetOrderParams(bidId, { from: consumer }); assert.equal(OrderStatus.INACTIVE, askParams[OrderParams.status]); assert.equal(OrderStatus.INACTIVE, bidParams[OrderParams.status]); let dealId = bidParams[OrderParams.dealId]; - let dealInfo = await market.GetDealInfo(dealId, { from: consumer }); - let dealParams = await market.GetDealParams(dealId, { from: consumer }); + let dealInfo = await deals.GetDealInfo(dealId, { from: consumer }); + let dealParams = await deals.GetDealParams(dealId, { from: consumer }); assert.equal(DealStatus.ACCEPTED, dealParams[DealParams.status]); assert.ok(dealInfo[DealInfo.startTime].toNumber() === dealParams[DealParams.lastBillTs].toNumber(), 'lastBillTs not equal to startTime'); @@ -278,43 +306,43 @@ contract('Market', async (accounts) => { await market.OpenDeal(askId, bidId, { from: consumer }); await increaseTime(duration + 1); - let bidParams = await market.GetOrderParams(bidId, { from: consumer }); + let bidParams = await orders.GetOrderParams(bidId, { from: consumer }); let dealId = bidParams[OrderParams.dealId]; await market.CloseDeal(dealId, BlackListPerson.NOBODY, { from: consumer }); - let dealParams = await market.GetDealParams(dealId, { from: consumer }); + let dealParams = await deals.GetDealParams(dealId, { from: consumer }); assert.equal(DealStatus.CLOSED, dealParams[DealParams.status]); }); }); describe('Workers:', () => { it('Register worker', async () => { - let tx = await market.RegisterWorker(master, { from: supplier }); + let tx = await administratum.RegisterWorker(master, { from: supplier }); await eventInTransaction(tx, 'WorkerAnnounced'); }); it('Confirm worker', async () => { - let masterBefore = await market.GetMaster(supplier); - let tx = await market.ConfirmWorker(supplier, { from: master }); - let masterAfter = await market.GetMaster(supplier); + let masterBefore = await administratum.GetMaster(supplier); + let tx = await administratum.ConfirmWorker(supplier, { from: master }); + let masterAfter = await administratum.GetMaster(supplier); assert.ok(masterBefore !== masterAfter && masterAfter === master); await eventInTransaction(tx, 'WorkerConfirmed'); }); it('Remove worker from master', async () => { - let tx = await market.RemoveWorker(supplier, master, { from: master }); - let masterAfter = await market.GetMaster(supplier); + let tx = await administratum.RemoveWorker(supplier, master, { from: master }); + let masterAfter = await administratum.GetMaster(supplier); assert.equal(masterAfter, supplier); await eventInTransaction(tx, 'WorkerRemoved'); }); it('Register/confirm worker, remove master from worker', async () => { - await market.RegisterWorker(master, { from: supplier }); - await market.ConfirmWorker(supplier, { from: master }); + await administratum.RegisterWorker(master, { from: supplier }); + await administratum.ConfirmWorker(supplier, { from: master }); - let txRemove = await market.RemoveWorker(supplier, master, { from: supplier }); + let txRemove = await administratum.RemoveWorker(supplier, master, { from: supplier }); await eventInTransaction(txRemove, 'WorkerRemoved'); - let masterAfter = await market.GetMaster(supplier); + let masterAfter = await administratum.GetMaster(supplier); assert.equal(masterAfter, supplier); }); }); @@ -332,24 +360,24 @@ contract('Market', async (accounts) => { let askId = await Ask({ market, supplier }); let bidId = await Bid({ market, consumer }); await market.OpenDeal(askId, bidId, { from: consumer }); - let bidParams = await market.GetOrderParams(bidId, { from: consumer }); + let bidParams = await orders.GetOrderParams(bidId, { from: consumer }); presetFwdDealId = bidParams[OrderParams.dealId]; - presetFwdDealParams = await market.GetDealParams(presetFwdDealId, { from: consumer }); + presetFwdDealParams = await deals.GetDealParams(presetFwdDealId, { from: consumer }); - await market.RegisterWorker(master, { from: supplierWithMaster }); - await market.ConfirmWorker(supplierWithMaster, { from: master }); + await administratum.RegisterWorker(master, { from: supplierWithMaster }); + await administratum.ConfirmWorker(supplierWithMaster, { from: master }); let maskId = await Ask({ market, supplier: supplierWithMaster }); let mbidId = await Bid({ market, consumer }); await market.OpenDeal(maskId, mbidId, { from: consumer }); - let mbidParams = await market.GetOrderParams(mbidId, { from: consumer }); + let mbidParams = await orders.GetOrderParams(mbidId, { from: consumer }); presetMasterFwdDealId = mbidParams[OrderParams.dealId]; let saskId = await Ask({ market, supplier, duration: 0 }); let sbidId = await Bid({ market, consumer, duration: 0 }); await market.OpenDeal(saskId, sbidId, { from: consumer }); - let sbidParams = await market.GetOrderParams(sbidId, { from: consumer }); + let sbidParams = await orders.GetOrderParams(sbidId, { from: consumer }); presetSpotDealId = sbidParams[OrderParams.dealId]; - presetSpotDealParams = await market.GetDealParams(presetSpotDealId, { from: consumer }); + presetSpotDealParams = await deals.GetDealParams(presetSpotDealId, { from: consumer }); await increaseTime(secInHour / 2); }); @@ -375,7 +403,7 @@ contract('Market', async (accounts) => { let supplierBalanceAfter = await token.balanceOf(supplier); let marketBalanceAfter = await token.balanceOf(market.address); - let dealParamsAfter = await market.GetDealParams(presetSpotDealId); + let dealParamsAfter = await deals.GetDealParams(presetSpotDealId); let lastBillTSAfter = dealParamsAfter[DealParams.lastBillTs]; @@ -394,7 +422,7 @@ contract('Market', async (accounts) => { }); it('Billing forward deal', async () => { - let deal = await market.GetDealParams(presetFwdDealId); + let deal = await deals.GetDealParams(presetFwdDealId); let consumerBalanceBefore = await token.balanceOf(consumer); let supplierBalanceBefore = await token.balanceOf(supplier); let marketBalanceBefore = await token.balanceOf(market.address); @@ -407,7 +435,7 @@ contract('Market', async (accounts) => { let supplierBalanceAfter = await token.balanceOf(supplier); let marketBalanceAfter = await token.balanceOf(market.address); - let dealParamsAfter = await market.GetDealParams(presetFwdDealId); + let dealParamsAfter = await deals.GetDealParams(presetFwdDealId); let lastBillTSAfter = dealParamsAfter[DealParams.lastBillTs]; @@ -426,7 +454,7 @@ contract('Market', async (accounts) => { }); it('Billing forward deal, with master', async () => { - let deal = await market.GetDealParams(presetMasterFwdDealId); + let deal = await deals.GetDealParams(presetMasterFwdDealId); let consumerBalanceBefore = await token.balanceOf(consumer); let masterBalanceBefore = await token.balanceOf(master); let marketBalanceBefore = await token.balanceOf(market.address); @@ -438,7 +466,7 @@ contract('Market', async (accounts) => { let consumerBalanceAfter = await token.balanceOf(consumer); let masterBalanceAfter = await token.balanceOf(master); let marketBalanceAfter = await token.balanceOf(market.address); - let dealParamsAfter = await market.GetDealParams(presetMasterFwdDealId); + let dealParamsAfter = await deals.GetDealParams(presetMasterFwdDealId); let lastBillTSAfter = dealParamsAfter[DealParams.lastBillTs]; @@ -455,7 +483,7 @@ contract('Market', async (accounts) => { masterBalanceBefore.toNumber() + event.paidAmount.toNumber()); assert.equal(marketBalanceAfter.toNumber() - marketBalanceBefore.toNumber(), 0); - await market.RemoveWorker(supplierWithMaster, master, { from: master }); + await administratum.RemoveWorker(supplierWithMaster, master, { from: master }); }); it('Billing forward deal: not billed if deal.lastBillTS >= deal.endTime', async () => { @@ -477,18 +505,18 @@ contract('Market', async (accounts) => { let askId = await Ask({ market, supplier, price: testPrice }); let bidId = await Bid({ market, consumer, price: testPrice }); await market.OpenDeal(askId, bidId, { from: consumer }); - let bidParams = await market.GetOrderParams(bidId, { from: consumer }); + let bidParams = await orders.GetOrderParams(bidId, { from: consumer }); presetFwdDealId = bidParams[OrderParams.dealId]; let saskId = await Ask({ market, supplier, price: testPrice, duration: 0 }); let sbidId = await Bid({ market, consumer, price: testPrice, duration: 0 }); await market.OpenDeal(saskId, sbidId, { from: consumer }); - let sbidParams = await market.GetOrderParams(sbidId, { from: consumer }); + let sbidParams = await orders.GetOrderParams(sbidId, { from: consumer }); presetSpotDealId = sbidParams[OrderParams.dealId]; }); it('Create change request as supplier and close', async () => { - let chReqsBefore = await market.GetChangeRequestsAmount(); + let chReqsBefore = await changeRequests.GetChangeRequestsAmount(); // raising price let newPrice = 1e6; @@ -499,26 +527,26 @@ contract('Market', async (accounts) => { { from: supplier }); // price not changed - let dealParamsAfter = await market.GetDealParams(presetFwdDealId); + let dealParamsAfter = await deals.GetDealParams(presetFwdDealId); let priceAfter = dealParamsAfter[DealParams.price].toNumber(); assert.equal(testPrice, priceAfter); - let chReqsAfter = await market.GetChangeRequestsAmount(); + let chReqsAfter = await changeRequests.GetChangeRequestsAmount(); let currentChReq = chReqsBefore.toNumber() + 1; assert.equal(currentChReq, chReqsAfter.toNumber()); - let chReqInfoBefore = await market.GetChangeRequestInfo(currentChReq); + let chReqInfoBefore = await changeRequests.GetChangeRequestInfo(currentChReq); assert.equal(RequestStatus.REQUEST_CREATED, chReqInfoBefore[ChangeRequestInfo.status]); await market.CancelChangeRequest(currentChReq, { from: supplier }); - let chReqInfoAfter = await market.GetChangeRequestInfo(currentChReq); + let chReqInfoAfter = await changeRequests.GetChangeRequestInfo(currentChReq); assert.equal(RequestStatus.REQUEST_CANCELED, chReqInfoAfter[ChangeRequestInfo.status]); }); it('Create change request as consumer and close', async () => { - let chReqsBefore = await market.GetChangeRequestsAmount(); + let chReqsBefore = await changeRequests.GetChangeRequestsAmount(); // lowering price let newPrice = 1e2; @@ -529,26 +557,26 @@ contract('Market', async (accounts) => { { from: consumer }); // price not changed - let dealParamsAfter = await market.GetDealParams(presetFwdDealId); + let dealParamsAfter = await deals.GetDealParams(presetFwdDealId); let priceAfter = dealParamsAfter[DealParams.price].toNumber(); assert.equal(testPrice, priceAfter); - let chReqsAfter = await market.GetChangeRequestsAmount(); + let chReqsAfter = await changeRequests.GetChangeRequestsAmount(); let currentChReq = chReqsBefore.toNumber() + 1; assert.equal(currentChReq, chReqsAfter.toNumber()); - let chReqInfoBefore = await market.GetChangeRequestInfo(currentChReq); + let chReqInfoBefore = await changeRequests.GetChangeRequestInfo(currentChReq); assert.equal(RequestStatus.REQUEST_CREATED, chReqInfoBefore[ChangeRequestInfo.status]); await market.CancelChangeRequest(currentChReq, { from: consumer }); - let chReqInfoAfter = await market.GetChangeRequestInfo(currentChReq); + let chReqInfoAfter = await changeRequests.GetChangeRequestInfo(currentChReq); assert.equal(RequestStatus.REQUEST_CANCELED, chReqInfoAfter[ChangeRequestInfo.status]); }); it('Create change request as consumer and reject as supplier', async () => { - let chReqsBefore = await market.GetChangeRequestsAmount(); + let chReqsBefore = await changeRequests.GetChangeRequestsAmount(); // lowering price let newPrice = 1e2; @@ -559,27 +587,27 @@ contract('Market', async (accounts) => { { from: consumer }); // price not changed - let dealParamsAfter = await market.GetDealParams(presetFwdDealId); + let dealParamsAfter = await deals.GetDealParams(presetFwdDealId); let priceAfter = dealParamsAfter[DealParams.price].toNumber(); assert.equal(testPrice, priceAfter); - let chReqsAfter = await market.GetChangeRequestsAmount(); + let chReqsAfter = await changeRequests.GetChangeRequestsAmount(); let currentChReq = chReqsBefore.toNumber() + 1; assert.equal(currentChReq, chReqsAfter.toNumber()); - let chReqInfoBefore = await market.GetChangeRequestInfo(currentChReq); + let chReqInfoBefore = await changeRequests.GetChangeRequestInfo(currentChReq); assert.equal(RequestStatus.REQUEST_CREATED, chReqInfoBefore[ChangeRequestInfo.status]); // rejecting await market.CancelChangeRequest(currentChReq, { from: supplier }); - let chReqInfoAfter = await market.GetChangeRequestInfo(currentChReq); + let chReqInfoAfter = await changeRequests.GetChangeRequestInfo(currentChReq); assert.equal(RequestStatus.REQUEST_REJECTED, chReqInfoAfter[ChangeRequestInfo.status]); }); it('Create change request as supplier and reject as consumer', async () => { - let chReqsBefore = await market.GetChangeRequestsAmount(); + let chReqsBefore = await changeRequests.GetChangeRequestsAmount(); // raising price let newPrice = 1e6; @@ -590,21 +618,21 @@ contract('Market', async (accounts) => { { from: supplier }); // price not changed - let dealParamsAfter = await market.GetDealParams(presetFwdDealId); + let dealParamsAfter = await deals.GetDealParams(presetFwdDealId); let priceAfter = dealParamsAfter[DealParams.price].toNumber(); assert.equal(testPrice, priceAfter); - let chReqsAfter = await market.GetChangeRequestsAmount(); + let chReqsAfter = await changeRequests.GetChangeRequestsAmount(); let currentChReq = chReqsBefore.toNumber() + 1; assert.equal(currentChReq, chReqsAfter.toNumber()); - let chReqInfoBefore = await market.GetChangeRequestInfo(currentChReq); + let chReqInfoBefore = await changeRequests.GetChangeRequestInfo(currentChReq); assert.equal(RequestStatus.REQUEST_CREATED, chReqInfoBefore[ChangeRequestInfo.status]); // rejecting await market.CancelChangeRequest(currentChReq, { from: consumer }); - let chReqInfoAfter = await market.GetChangeRequestInfo(currentChReq); + let chReqInfoAfter = await changeRequests.GetChangeRequestInfo(currentChReq); assert.equal(RequestStatus.REQUEST_REJECTED, chReqInfoAfter[ChangeRequestInfo.status]); }); @@ -625,7 +653,7 @@ contract('Market', async (accounts) => { testDuration, { from: supplier }); - let dealParamsAfter = await market.GetDealParams(presetFwdDealId, { from: consumer }); + let dealParamsAfter = await deals.GetDealParams(presetFwdDealId, { from: consumer }); let priceAfter = dealParamsAfter[DealParams.price].toNumber(); assert.equal(newPrice, priceAfter); @@ -646,7 +674,7 @@ contract('Market', async (accounts) => { newDuration, { from: supplier }); - let dealParamsAfter = await market.GetDealParams(presetFwdDealId); + let dealParamsAfter = await deals.GetDealParams(presetFwdDealId); let durationAfter = dealParamsAfter[DealParams.duration].toNumber(); assert.equal(newDuration, durationAfter); }); @@ -667,7 +695,7 @@ contract('Market', async (accounts) => { 0, { from: supplier }); - let dealParamsAfter = await market.GetDealParams(presetSpotDealId, { from: consumer }); + let dealParamsAfter = await deals.GetDealParams(presetSpotDealId, { from: consumer }); let priceAfter = dealParamsAfter[DealParams.price].toNumber(); assert.equal(newPrice, priceAfter); @@ -692,7 +720,7 @@ contract('Market', async (accounts) => { { from: consumer }); // price changed - let dealParamsAfter = await market.GetDealParams(presetFwdDealId); + let dealParamsAfter = await deals.GetDealParams(presetFwdDealId); let priceAfter = dealParamsAfter[DealParams.price].toNumber(); assert.equal(newPrice, priceAfter); }); @@ -706,7 +734,7 @@ contract('Market', async (accounts) => { { from: supplier }); // price changed - let dealParamsAfter = await market.GetDealParams(presetFwdDealId); + let dealParamsAfter = await deals.GetDealParams(presetFwdDealId); let priceAfter = dealParamsAfter[DealParams.price].toNumber(); assert.equal(newPrice, priceAfter); }); @@ -727,7 +755,7 @@ contract('Market', async (accounts) => { newDuration, { from: consumer }); - let dealParamsAfter = await market.GetDealParams(presetFwdDealId); + let dealParamsAfter = await deals.GetDealParams(presetFwdDealId); let durationAfter = dealParamsAfter[DealParams.duration].toNumber(); let priceAfter = dealParamsAfter[DealParams.price].toNumber(); assert.equal(newDuration, durationAfter); @@ -748,8 +776,8 @@ contract('Market', async (accounts) => { assert.equal(balConsBefore.toNumber() - balConsInterm.toNumber(), 3600, 'incorrect consumer balance'); await market.OpenDeal(askId, bidId, { from: specialConsumer2 }); - let dealId = await getDealIdFromOrder(market, specialConsumer2, askId); - let paramsBeforeBill = await market.GetDealParams(dealId); + let dealId = await getDealIdFromOrder(orders, specialConsumer2, askId); + let paramsBeforeBill = await deals.GetDealParams(dealId); await increaseTime(secInHour - 3); assert.equal(paramsBeforeBill[DealParams.status].toNumber(), @@ -761,8 +789,8 @@ contract('Market', async (accounts) => { let balMarketAfter = await token.balanceOf(market.address); let balSuppAfter = await token.balanceOf(specialSupplier); let balConsAfter = await token.balanceOf(specialConsumer2); - let pAfterBill = await market.GetDealParams(dealId); - let iAfterBill = await market.GetDealInfo(dealId); + let pAfterBill = await deals.GetDealParams(dealId); + let iAfterBill = await deals.GetDealInfo(dealId); let dealTime = pAfterBill[DealParams.endTime].toNumber() - iAfterBill[DealInfo.startTime].toNumber(); assert.equal(pAfterBill[DealParams.totalPayout].toNumber(), dealTime, 'incorrect total payout'); assert.equal(balSuppAfter.toNumber() - balSuppBefore.toNumber(), @@ -782,7 +810,7 @@ contract('Market', async (accounts) => { let bidId = await Bid({ market, consumer: specialConsumer, price: 1e6, duration: 0 }); await market.OpenDeal(askId, bidId, { from: specialConsumer }); - let dealId = await getDealIdFromOrder(market, supplier, askId); + let dealId = await getDealIdFromOrder(orders, supplier, askId); await increaseTime(secInHour - 3); @@ -792,7 +820,7 @@ contract('Market', async (accounts) => { let balMarketAfter = await token.balanceOf(market.address); let balSuppAfter = await token.balanceOf(supplier); let balConsAfter = await token.balanceOf(specialConsumer); - let pAfterBill = await market.GetDealParams(dealId); + let pAfterBill = await deals.GetDealParams(dealId); assert.equal(pAfterBill[DealParams.totalPayout].toNumber(), 3600, 'incorrect total payout'); assert.equal(balSuppAfter.toNumber() - balSuppBefore.toNumber(), pAfterBill[DealParams.totalPayout].toNumber(), @@ -815,7 +843,7 @@ contract('Market', async (accounts) => { let bidId = await Bid({ market, consumer, price: 1e6, duration: 0 }); await market.OpenDeal(askId, bidId, { from: consumer }); - let dealId = await getDealIdFromOrder(market, consumer, askId); + let dealId = await getDealIdFromOrder(orders, consumer, askId); await increaseTime(secInHour - 3); await oracle.setCurrentPrice(priceAfter); @@ -824,8 +852,8 @@ contract('Market', async (accounts) => { let balSuppAfter = await token.balanceOf(supplier); let balConsAfter = await token.balanceOf(consumer); let balMarketAfter = await token.balanceOf(market.address); - let pAfterBill = await market.GetDealParams(dealId); - let iAfterBill = await market.GetDealInfo(dealId); + let pAfterBill = await deals.GetDealParams(dealId); + let iAfterBill = await deals.GetDealInfo(dealId); let dealTime = pAfterBill[DealParams.lastBillTs].toNumber() - iAfterBill[DealInfo.startTime].toNumber(); assert.equal(pAfterBill[DealParams.totalPayout].toNumber(), @@ -854,7 +882,7 @@ contract('Market', async (accounts) => { let bidId = await Bid({ market, consumer, price: 1e6, duration: 0 }); await market.OpenDeal(askId, bidId, { from: consumer }); - let dealId = await getDealIdFromOrder(market, consumer, askId); + let dealId = await getDealIdFromOrder(orders, consumer, askId); await increaseTime(secInHour - 3); await oracle.setCurrentPrice(priceAfter); @@ -863,8 +891,8 @@ contract('Market', async (accounts) => { let balSuppAfter = await token.balanceOf(supplier); let balConsAfter = await token.balanceOf(consumer); let balMarketAfter = await token.balanceOf(market.address); - let pAfterBill = await market.GetDealParams(dealId); - let iAfterBill = await market.GetDealInfo(dealId); + let pAfterBill = await deals.GetDealParams(dealId); + let iAfterBill = await deals.GetDealInfo(dealId); let dealTime = pAfterBill[DealParams.endTime].toNumber() - iAfterBill[DealInfo.startTime].toNumber(); assert.equal(pAfterBill[DealParams.totalPayout].toNumber(), priceAfter / priceBefore * dealTime, @@ -891,8 +919,8 @@ contract('Market', async (accounts) => { assert.equal(balConsBefore.toNumber() - balConsInterm.toNumber(), 3600, 'incorrect consumer balance'); await market.OpenDeal(askId, bidId, { from: consumer }); - let dealId = await getDealIdFromOrder(market, consumer, askId); - let paramsBeforeBill = await market.GetDealParams(dealId); + let dealId = await getDealIdFromOrder(orders, consumer, askId); + let paramsBeforeBill = await deals.GetDealParams(dealId); await increaseTime(secInHour + 3); assert.equal(paramsBeforeBill[DealParams.status].toNumber(), DealStatus.ACCEPTED, 'deal must be ACCEPTED'); @@ -902,7 +930,7 @@ contract('Market', async (accounts) => { let balMarketAfter = await token.balanceOf(market.address); let balSuppAfter = await token.balanceOf(supplier); let balConsAfter = await token.balanceOf(consumer); - let pAfterBill = await market.GetDealParams(dealId); + let pAfterBill = await deals.GetDealParams(dealId); assert.equal(pAfterBill[DealParams.totalPayout].toNumber(), 3600, 'incorrect total payout'); assert.equal(balSuppAfter.toNumber() - balSuppBefore.toNumber(), pAfterBill[DealParams.totalPayout].toNumber(), @@ -926,8 +954,8 @@ contract('Market', async (accounts) => { assert.equal(balConsBefore.toNumber() - balConsInterm.toNumber(), 3600, 'incorrect consumer balance'); await market.OpenDeal(askId, bidId, { from: consumer }); - let dealId = await getDealIdFromOrder(market, consumer, askId); - let paramsBeforeBill = await market.GetDealParams(dealId); + let dealId = await getDealIdFromOrder(orders, consumer, askId); + let paramsBeforeBill = await deals.GetDealParams(dealId); await increaseTime(secInHour / 2); assert.equal(paramsBeforeBill[DealParams.status].toNumber(), DealStatus.ACCEPTED, @@ -938,8 +966,8 @@ contract('Market', async (accounts) => { let balMarketAfter = await token.balanceOf(market.address); let balSuppAfter = await token.balanceOf(supplier); let balConsAfter = await token.balanceOf(consumer); - let pAfterBill = await market.GetDealParams(dealId); - let iAfterBill = await market.GetDealInfo(dealId); + let pAfterBill = await deals.GetDealParams(dealId); + let iAfterBill = await deals.GetDealInfo(dealId); let dealTime = pAfterBill[DealParams.endTime].toNumber() - iAfterBill[DealInfo.startTime].toNumber(); assert.equal(pAfterBill[DealParams.totalPayout].toNumber(), dealTime, 'incorrect total payout'); assert.equal(balSuppAfter.toNumber() - balSuppBefore.toNumber(), @@ -957,7 +985,7 @@ contract('Market', async (accounts) => { let bidId = await Bid({ market, consumer: consumer, price: 1e6, duration: 3600 }); let askId = await Ask({ market, supplier: supplier, price: 1e6, duration: 3600 }); await market.OpenDeal(askId, bidId, { from: consumer }); - let dealId = await getDealIdFromOrder(market, consumer, askId); + let dealId = await getDealIdFromOrder(orders, consumer, askId); await increaseTime(secInHour / 2); await assertRevert(market.CloseDeal(dealId, 0, { from: supplier })); }); @@ -965,12 +993,12 @@ contract('Market', async (accounts) => { describe('Blacklist', async () => { it('Prepare workers', async () => { - await market.RegisterWorker(blacklistMaster, { from: blacklistWorker1 }); - await market.RegisterWorker(blacklistMaster, { from: blacklistWorker2 }); - await market.ConfirmWorker(blacklistWorker1, { from: blacklistMaster }); - await market.ConfirmWorker(blacklistWorker2, { from: blacklistMaster }); - let master1 = await market.GetMaster(blacklistWorker1); - let master2 = await market.GetMaster(blacklistWorker2); + await administratum.RegisterWorker(blacklistMaster, { from: blacklistWorker1 }); + await administratum.RegisterWorker(blacklistMaster, { from: blacklistWorker2 }); + await administratum.ConfirmWorker(blacklistWorker1, { from: blacklistMaster }); + await administratum.ConfirmWorker(blacklistWorker2, { from: blacklistMaster }); + let master1 = await administratum.GetMaster(blacklistWorker1); + let master2 = await administratum.GetMaster(blacklistWorker2); assert.equal(master1, blacklistMaster, 'Worker not confirmed'); assert.equal(master2, blacklistMaster, 'Worker not confirmed'); @@ -986,15 +1014,15 @@ contract('Market', async (accounts) => { let bidId = await Bid({ market, consumer, price: 1e6, duration: 0 }); await market.OpenDeal(askId, bidId, { from: consumer }); - let dealId = await getDealIdFromOrder(market, consumer, askId); + let dealId = await getDealIdFromOrder(orders, consumer, askId); await increaseTime(secInHour - 3); // close deal with blacklist worker blacklistWorker1 await market.CloseDeal(dealId, 1, { from: consumer }); let balSuppAfter = await token.balanceOf(blacklistMaster); let balConsAfter = await token.balanceOf(consumer); let balMarketAfter = await token.balanceOf(market.address); - let pAfterClose = await market.GetDealParams(dealId); - let iAfterClose = await market.GetDealInfo(dealId); + let pAfterClose = await deals.GetDealParams(dealId); + let iAfterClose = await deals.GetDealInfo(dealId); let dealTime = pAfterClose[DealParams.lastBillTs].toNumber() - iAfterClose[DealInfo.startTime].toNumber(); assert.equal(pAfterClose[DealParams.totalPayout].toNumber(), dealTime, 'incorrect total payout'); assert.equal(balSuppAfter.toNumber() - balSuppBefore.toNumber(), @@ -1029,15 +1057,15 @@ contract('Market', async (accounts) => { let bidId = await Bid({ market, consumer, price: 1e6, duration: 0 }); await market.OpenDeal(askId, bidId, { from: consumer }); - let dealId = await getDealIdFromOrder(market, consumer, askId); + let dealId = await getDealIdFromOrder(orders, consumer, askId); await increaseTime(secInHour - 3); // close deal with blacklist master await market.CloseDeal(dealId, 2, { from: consumer }); let balSuppAfter = await token.balanceOf(blacklistMaster); let balConsAfter = await token.balanceOf(consumer); let balMarketAfter = await token.balanceOf(market.address); - let pAfterClose = await market.GetDealParams(dealId); - let iAfterClose = await market.GetDealInfo(dealId); + let pAfterClose = await deals.GetDealParams(dealId); + let iAfterClose = await deals.GetDealInfo(dealId); let dealTime = pAfterClose[DealParams.lastBillTs].toNumber() - iAfterClose[DealInfo.startTime].toNumber(); assert.equal(pAfterClose[DealParams.totalPayout].toNumber(), dealTime, 'incorrect total payout'); assert.equal(balSuppAfter.toNumber() - balSuppBefore.toNumber(), @@ -1072,9 +1100,9 @@ contract('Market', async (accounts) => { await oracle.setCurrentPrice(1e12); let askId = await Ask({ market, supplier, price: 1e6, duration: 3600 }); await market.QuickBuy(askId, 1800, { from: consumer }); - let dealId = await getDealIdFromOrder(market, consumer, askId); - let dealInfo = await market.GetDealInfo(dealId, { from: consumer }); - let dealParams = await market.GetDealParams(dealId, { from: consumer }); + let dealId = await getDealIdFromOrder(orders, consumer, askId); + let dealInfo = await deals.GetDealInfo(dealId, { from: consumer }); + let dealParams = await deals.GetDealParams(dealId, { from: consumer }); assert.equal(DealStatus.ACCEPTED, dealParams[DealParams.status]); assert.ok(dealInfo[DealInfo.startTime].toNumber() === dealParams[DealParams.lastBillTs].toNumber(), 'lastBillTs not equal to startTime'); @@ -1093,13 +1121,13 @@ contract('Market', async (accounts) => { }); it('QuickBuy forward with master', async () => { - await market.RegisterWorker(master, { from: supplier }); - await market.ConfirmWorker(supplier, { from: master }); + await administratum.RegisterWorker(master, { from: supplier }); + await administratum.ConfirmWorker(supplier, { from: master }); let askId = await Ask({ market, supplier, price: 1e6, duration: 3600 }); await market.QuickBuy(askId, 10, { from: consumer }); - let dealId = await getDealIdFromOrder(market, consumer, askId); - let dealInfo = await market.GetDealInfo(dealId, { from: consumer }); - let dealParams = await market.GetDealParams(dealId, { from: consumer }); + let dealId = await getDealIdFromOrder(orders, consumer, askId); + let dealInfo = await deals.GetDealInfo(dealId, { from: consumer }); + let dealParams = await deals.GetDealParams(dealId, { from: consumer }); assert.equal(DealStatus.ACCEPTED, dealParams[DealParams.status]); assert.ok(dealInfo[DealInfo.startTime].toNumber() === dealParams[DealParams.lastBillTs].toNumber(), 'lastBillTs not equal to startTime'); @@ -1131,22 +1159,22 @@ contract('Market', async (accounts) => { let bidNew = await Bid({ market, consumer, netFlags: [0, 0], benchmarks: newBenchmarksWZero }); let askNew = await Ask({ market, supplier, netFlags: [0, 0], benchmarks: newBenchmarks }); - let bidInfo = await market.GetOrderInfo(bidNew, { from: consumer }); + let bidInfo = await orders.GetOrderInfo(bidNew, { from: consumer }); checkBenchmarks(bidInfo[orderInfo.benchmarks], newBenchmarksWZero); - let askInfo = await market.GetOrderInfo(askNew, { from: consumer }); + let askInfo = await orders.GetOrderInfo(askNew, { from: consumer }); checkBenchmarks(askInfo[orderInfo.benchmarks], newBenchmarks); await market.OpenDeal(askOld, bidNew, { from: consumer }); await market.OpenDeal(askNew, bidOld, { from: consumer }); - await checkOrderStatus(market, supplier, askOld, OrderStatus.INACTIVE); - await checkOrderStatus(market, supplier, bidOld, OrderStatus.INACTIVE); - await checkOrderStatus(market, supplier, bidNew, OrderStatus.INACTIVE); - await checkOrderStatus(market, supplier, askNew, OrderStatus.INACTIVE); + await checkOrderStatus(orders, supplier, askOld, OrderStatus.INACTIVE); + await checkOrderStatus(orders, supplier, bidOld, OrderStatus.INACTIVE); + await checkOrderStatus(orders, supplier, bidNew, OrderStatus.INACTIVE); + await checkOrderStatus(orders, supplier, askNew, OrderStatus.INACTIVE); - let dealInfo1 = await getDealInfoFromOrder(market, consumer, bidNew); + let dealInfo1 = await getDealInfoFromOrder(deals, orders, consumer, bidNew); checkBenchmarks(dealInfo1[DealInfo.benchmarks], newBenchmarksWZero); - let dealInfo2 = await getDealInfoFromOrder(market, consumer, askNew); + let dealInfo2 = await getDealInfoFromOrder(deals, orders, consumer, askNew); checkBenchmarks(dealInfo2[DealInfo.benchmarks], newBenchmarks); }); @@ -1154,7 +1182,7 @@ contract('Market', async (accounts) => { let bid = await Bid({ market, consumer, benchmarks: newBenchmarksWZero }); let ask = await Ask({ market, supplier, benchmarks: newBenchmarks }); await market.OpenDeal(ask, bid, { from: consumer }); - let dealInfo = await getDealInfoFromOrder(market, consumer, bid); + let dealInfo = await getDealInfoFromOrder(deals, orders, consumer, bid); checkBenchmarks(dealInfo[DealInfo.benchmarks], newBenchmarks); }); @@ -1262,53 +1290,53 @@ contract('Market', async (accounts) => { }); }); - describe('RegisterWorker', () => { - before(async () => { - await market.pause(); - }); - - it('should revert', async () => { - await assertRevert(market.RegisterWorker(master, { from: supplier })); - }); - - after(async () => { - await market.unpause(); - }); - }); - - describe('ConfirmWorker', () => { - before(async () => { - await market.RegisterWorker(master, { from: accounts[0] }); - await market.pause(); - }); - - it('should revert', async () => { - await assertRevert(market.ConfirmWorker(supplier, { from: master })); - }); - - after(async () => { - await market.unpause(); - await market.ConfirmWorker(accounts[0], { from: master }); - await market.RemoveWorker(accounts[0], master, { from: master }); - }); - }); - - describe('RemoveWorker', () => { - before(async () => { - await market.RegisterWorker(master, { from: accounts[0] }); - await market.ConfirmWorker(accounts[0], { from: master }); - await market.pause(); - }); - - it('should revert', async () => { - await assertRevert(market.RemoveWorker(accounts[0], master, { from: master })); - }); - - after(async () => { - await market.unpause(); - await market.RemoveWorker(accounts[0], master, { from: master }); - }); - }); + // describe('RegisterWorker', () => { + // before(async () => { + // await market.pause(); + // }); + // + // it('should revert', async () => { + // await assertRevert(administratum.RegisterWorker(master, { from: supplier })); + // }); + // + // after(async () => { + // await market.unpause(); + // }); + // }); + // + // describe('ConfirmWorker', () => { + // before(async () => { + // await administratum.RegisterWorker(master, { from: accounts[0] }); + // await market.pause(); + // }); + // + // it('should revert', async () => { + // await assertRevert(administratum.ConfirmWorker(supplier, { from: master })); + // }); + // + // after(async () => { + // await market.unpause(); + // await administratum.ConfirmWorker(accounts[0], { from: master }); + // await administratum.RemoveWorker(accounts[0], master, { from: master }); + // }); + // }); + // + // describe('RemoveWorker', () => { + // before(async () => { + // await administratum.RegisterWorker(master, { from: accounts[0] }); + // await administratum.ConfirmWorker(accounts[0], { from: master }); + // await market.pause(); + // }); + // + // it('should revert', async () => { + // await assertRevert(administratum.RemoveWorker(accounts[0], master, { from: master })); + // }); + // + // after(async () => { + // await market.unpause(); + // await administratum.RemoveWorker(accounts[0], master, { from: master }); + // }); + // }); }); describe('kill market', () => { diff --git a/blockchain/source/truffle.js b/blockchain/source/truffle.js index 3389f3be9..c9f7480fe 100644 --- a/blockchain/source/truffle.js +++ b/blockchain/source/truffle.js @@ -29,6 +29,7 @@ module.exports = { host: 'localhost', port: 8535, network_id: '*', // eslint-disable-line camelcase + gas: 100000000, }, coverage: { host: 'localhost',