pragma solidity 0.4.24; /* TASKS 1. the creator sets the number of tickets and ticket price - Done 2. participants can buy as many tickets as are available - 3. the prize is awarded to a random participant once all tickets are sold - 4. the creator must purchase the first ticket on creation - */ /** * @title SafeMath * @dev Math operations with safety checks that revert on error */ library SafeMath { /** * @dev Multiplies two numbers, reverts on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b); return c; } /** * @dev Integer division of two numbers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0); // Solidity only automatically asserts 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 Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a); uint256 c = a - b; return c; } /** * @dev Adds two numbers, reverts on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } /** * @dev Divides two numbers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0); return a % b; } } contract TicketsDistribution { using SafeMath for uint256; address private _owner; // Id of current available ticket uint256 public ticketId = 1; struct Tickets { uint256 amount; uint256 price; } Tickets public ticket; // Storing information by buyer mapping (address => uint256 []) public buyers; // Events // Constructor constructor(uint256 tickets, uint256 price) public { _owner = msg.sender; buyers[msg.sender].push(ticketId); _increaseId(1); ticket.price = price; ticket.amount = tickets; } // Fallback function() public payable { buyTicket(msg.sender); } // Public functions function buyTicket(address buyer) public payable { uint256 amount = msg.value; _preValidation(buyer, amount); uint256 ticketsAmount = _calculateTicketsAmount(amount); _ticketsValidation(ticketsAmount); _sendEth(); } function getAvailableTicketsAmount() public view returns (uint256) { return ticket.amount.sub(ticketId); } // Internal functions function _preValidation(address _buyer, uint256 _amount) internal view { require(_buyer != address(0), "_preValidation: address is not correct"); require(_amount >= ticket.price, "_preValidation: msg.value is lower ticket price"); } function _ticketsValidation(uint256 _amount) internal view { require(getAvailableTicketsAmount() >= _amount, "_ticketsValidation: not enough tikens available"); } function _calculateTicketsAmount(uint256 amount) internal view returns (uint256) { return amount.div(ticket.price); } function _increaseId(uint256 id) internal { ticketId = ticketId.add(id); } function _tikensPurchased(address buyer, uint256 count) internal returns (bool) { for(uint256 i = 0; i < count; i++) { buyers[buyer].push(ticketId); _increaseId(1); } return true; } function _sendEth() internal { _owner.transfer(msg.value); } }
0.4.24