pragma solidity ^0.4.19; // solhint-disable-line contract Cryptato { /*** EVENTS ***/ event PotatoFlipped(string newOwnerName, uint256 price, string prevOwnerName); /*** DATATYPES ***/ address public currentOwnerAddress; string public currentOwnerName; uint256 public currentPrice; struct Record { address ownerAddress; string ownerName; uint256 pricePaid; string timeBought; } Record[] public records; uint256 public flipCount = 0; address public quipAddress; address public monoAddress; address public daddyAddress; /*** ACCESS MODIFIERS ***/ /// Access modifier for team-only functionality modifier teamOnly() { require(msg.sender == quipAddress || msg.sender == monoAddress || msg.sender == daddyAddress); _; } /*** CONSTRUCTOR ***/ function Cryptato() public { quipAddress = msg.sender; monoAddress = msg.sender; daddyAddress = msg.sender; currentOwnerAddress = msg.sender; currentOwnerName = "Contract"; currentPrice = 0.005 ether; } /*** PUBLIC FUNCTIONS ***/ /// Returns all information about a specific ownership record function getRecord(uint256 _recordId) public view returns (address ownerAddress, string ownerName, uint256 pricePaid, string timeBought) { Record storage record = records[_recordId]; ownerAddress = record.ownerAddress; ownerName = record.ownerName; pricePaid = record.pricePaid; timeBought = record.timeBought; } /// Get that sweet, sweet ether /// Specify an amount to leave remaining in the contract's balance function payout(uint256 _remainder) public teamOnly { _payout(_remainder); } /// Allows someone to send ether and purchase the potato /// Returns id of the record of ownership created from the purchase function purchase(string _newOwnerName, string _currentTime) public payable returns (uint256) { address oldOwner = currentOwnerAddress; address newOwner = msg.sender; // Make sure potato owner is not sending to self require(oldOwner != newOwner); // Safety check to prevent against an unexpected 0x0 default. require(_addressNotNull(newOwner)); // Making sure sent amount is greater than or equal to the price of the potato require(msg.value >= currentPrice); // Taking the 6% cut uint256 payment = uint256(SafeMath.div(SafeMath.mul(currentPrice, 94), 100)); // Calculate the buyer's change if they paid too much uint256 change = SafeMath.sub(msg.value, currentPrice); // Update the potato's price if (currentPrice < 1 ether) { // first stage currentPrice = SafeMath.div(SafeMath.mul(currentPrice, 200), 94); } else if (currentPrice < 10 ether) { // second stage currentPrice = SafeMath.div(SafeMath.mul(currentPrice, 120), 94); } else if (currentPrice < 40 ether) { // third stage currentPrice = SafeMath.div(SafeMath.mul(currentPrice, 115), 94); } else { currentPrice = SafeMath.div(SafeMath.mul(currentPrice, 110), 94); } currentOwnerAddress.transfer(payment); msg.sender.transfer(change); // Add new ownership record to the array uint256 recordId = _addRecord(msg.sender, _newOwnerName, currentPrice, _currentTime); // Emit the PotatoFlipped event PotatoFlipped(_newOwnerName, currentPrice, currentOwnerName); currentOwnerAddress = newOwner; currentOwnerName = _newOwnerName; flipCount++; return recordId; } /// Team member can set quip function setQuip(address _quip) public teamOnly { require(_quip != address(0)); quipAddress = _quip; } /// Team member can set mono function setMono(address _mono) public teamOnly { require(_mono != address(0)); monoAddress = _mono; } /// Team member can set daddy function setDaddy(address _daddy) public teamOnly { require(_daddy != address(0)); daddyAddress = _daddy; } /*** PRIVATE FUNCTIONS ***/ /// Add record of ownership to the array function _addRecord(address _ownerAddress, string _ownerName, uint256 _pricePaid, string _timeBought) private returns (uint256) { Record memory record = Record(_ownerAddress, _ownerName, _pricePaid, _timeBought); records.push(record); return records.length - 1; } /// Safety check on _to address to prevent against an unexpected 0x0 default function _addressNotNull(address _to) private pure returns (bool) { return _to != address(0); } /// For paying out the balance on the contract function _payout(uint256 _remainder) private { uint256 split = SafeMath.div(SafeMath.sub(this.balance, _remainder * 1 ether), 3); quipAddress.transfer(split); monoAddress.transfer(split); daddyAddress.transfer(split); } } library SafeMath { /** * @dev Multiplies two numbers, throws on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; assert(c / a == b); return c; } /** * @dev Integer division of two numbers, truncating the quotient. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // assert(b > 0); // Solidity automatically throws when dividing by 0 uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } /** * @dev Adds two numbers, throws on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c >= a); return c; } }
0.4.19