pragma solidity ^0.4.18;
contract TwoXMachine {
// Address of the contract creator
address public contractOwner;
// FIFO queue
BuyIn[] public buyIns;
// The current BuyIn queue index
uint256 public index;
// Total invested for entire contract
uint256 public contractTotalInvested;
// Total invested for a given address
mapping (address => uint256) public totalInvested;
// Total value for a given address
mapping (address => uint256) public totalValue;
// Total paid out for a given address
mapping (address => uint256) public totalPaidOut;
struct BuyIn {
uint256 value;
address owner;
}
modifier onlyContractOwner() {
require(msg.sender == contractOwner);
_;
}
function TwoXMachine() public {
contractOwner = msg.sender;
}
function purchase() public payable {
// I don't want no scrub
require(msg.value >= 0.01 ether);
// Take a 5% fee
uint256 value = SafeMath.div(SafeMath.mul(msg.value, 95), 100);
// HNNNNNNGGGGGG
uint256 valueMultiplied = SafeMath.mul(msg.value, 2);
contractTotalInvested += msg.value;
totalInvested[msg.sender] += msg.value;
while (index < buyIns.length && value > 0) {
BuyIn storage buyIn = buyIns[index];
if (value < buyIn.value) {
buyIn.owner.transfer(value);
totalPaidOut[buyIn.owner] += value;
totalValue[buyIn.owner] -= value;
buyIn.value -= value;
value = 0;
} else {
buyIn.owner.transfer(buyIn.value);
totalPaidOut[buyIn.owner] += buyIn.value;
totalValue[buyIn.owner] -= buyIn.value;
value -= buyIn.value;
buyIn.value = 0;
index++;
}
}
// if buyins have been exhausted, return the remaining
// funds back to the investor
if (value > 0) {
msg.sender.transfer(value);
valueMultiplied -= value;
totalPaidOut[msg.sender] += value;
}
totalValue[msg.sender] += valueMultiplied;
buyIns.push(BuyIn({
value: valueMultiplied,
owner: msg.sender
}));
}
function payout() public onlyContractOwner {
contractOwner.transfer(this.balance);
}
}
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
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;
}
}
{
"compilationTarget": {
"TwoXMachine.sol": "TwoXMachine"
},
"libraries": {},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"totalPaidOut","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"index","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"totalValue","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"buyIns","outputs":[{"name":"value","type":"uint256"},{"name":"owner","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"payout","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"purchase","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"totalInvested","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"contractOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"contractTotalInvested","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]