// Contract address: 0xc1a0092a662ff7a33411ef0e283f9d8b7fae62ef // Contract name: ProofOfPassiveDividends // Etherscan link: https://etherscan.io/address/0xc1a0092a662ff7a33411ef0e283f9d8b7fae62ef#code pragma solidity ^0.4.21; contract ProofOfPassiveDividends { using SafeMath for uint256; event Deposit(address user, uint amount); event Withdraw(address user, uint amount); event Claim(address user, uint dividends); event Reinvest(address user, uint dividends); address owner; mapping(address => bool) preauthorized; bool gameStarted; // deposit tax is 14.2% uint constant depositTaxDivisor = 7; // deposit tax is 25% uint constant withdrawalTaxDivisor = 4; mapping(address => uint) public investment; mapping(address => uint) public stake; uint public totalStake; uint stakeValue; mapping(address => uint) dividendCredit; mapping(address => uint) dividendDebit; function ProofOfPassiveDividends() public { owner = msg.sender; preauthorized[owner] = true; } function preauthorize(address _user) public { require(msg.sender == owner); preauthorized[_user] = true; } function startGame() public { require(msg.sender == owner); gameStarted = true; } function depositHelper(uint _amount) private { uint _tax = _amount.div(depositTaxDivisor); uint _amountAfterTax = _amount.sub(_tax); if (totalStake > 0) stakeValue = stakeValue.add(_tax.div(totalStake)); uint _stakeIncrement = sqrt(totalStake.mul(totalStake).add(_amountAfterTax)).sub(totalStake); investment[msg.sender] = investment[msg.sender].add(_amountAfterTax); stake[msg.sender] = stake[msg.sender].add(_stakeIncrement); totalStake = totalStake.add(_stakeIncrement); dividendDebit[msg.sender] = dividendDebit[msg.sender].add(_stakeIncrement.mul(stakeValue)); } function deposit() public payable { require(preauthorized[msg.sender] || gameStarted); // Removed the referral feature due to nonsense fud! depositHelper(msg.value); emit Deposit(msg.sender, msg.value); } function withdraw(uint _amount) public { require(_amount > 0); require(_amount <= investment[msg.sender]); uint _tax = _amount.div(withdrawalTaxDivisor); uint _amountAfterTax = _amount.sub(_tax); uint _stakeDecrement = stake[msg.sender].mul(_amount).div(investment[msg.sender]); uint _dividendCredit = _stakeDecrement.mul(stakeValue); investment[msg.sender] = investment[msg.sender].sub(_amount); stake[msg.sender] = stake[msg.sender].sub(_stakeDecrement); totalStake = totalStake.sub(_stakeDecrement); if (totalStake > 0) stakeValue = stakeValue.add(_tax.div(totalStake)); dividendCredit[msg.sender] = dividendCredit[msg.sender].add(_dividendCredit); uint _creditDebitCancellation = min(dividendCredit[msg.sender], dividendDebit[msg.sender]); dividendCredit[msg.sender] = dividendCredit[msg.sender].sub(_creditDebitCancellation); dividendDebit[msg.sender] = dividendDebit[msg.sender].sub(_creditDebitCancellation); msg.sender.transfer(_amountAfterTax); emit Withdraw(msg.sender, _amount); } function claimHelper() private returns(uint) { uint _dividendsForStake = stake[msg.sender].mul(stakeValue); uint _dividends = _dividendsForStake.add(dividendCredit[msg.sender]).sub(dividendDebit[msg.sender]); dividendCredit[msg.sender] = 0; dividendDebit[msg.sender] = _dividendsForStake; return _dividends; } function claim() public { uint _dividends = claimHelper(); msg.sender.transfer(_dividends); emit Claim(msg.sender, _dividends); } function reinvest() public { uint _dividends = claimHelper(); depositHelper(_dividends); emit Reinvest(msg.sender, _dividends); } function dividendsForUser(address _user) public view returns (uint) { return stake[_user].mul(stakeValue).add(dividendCredit[_user]).sub(dividendDebit[_user]); } function min(uint x, uint y) private pure returns (uint) { return x <= y ? x : y; } function sqrt(uint x) private pure returns (uint y) { uint z = (x + 1) / 2; y = x; while (z < y) { y = z; z = (x / z + z) / 2; } } } /** * @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 a / b; } /** * @dev Subtracts 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; } }
v0.4.21