pragma solidity ^0.4.25; contract EthFund { uint constant BENEFICIARY_COMMISSION_DENOMINATOR = 20; // 5 % uint constant REFERRAL_COMMISSION_DENOMINATOR = 10; // 10 % uint constant CLOSING_KEY_VALUE = 0.000911 ether; uint constant CLOSING_REFUND_PERCENT = 60; address public beneficiary1; address public beneficiary2; mapping(address => uint[]) public balances; mapping(address => uint[]) public paid; mapping(address => uint) public depositedAt; mapping(address => uint) public timestamps; constructor() public { beneficiary1 = 0x8b14Be960Fb48792E32bAEb9ddd51A8a373D5A76; // 0x22Df7A778704DC915EB227e368E3824337452855; beneficiary2 = 0x4CFe5Cd9Ea0EC0715D2Cd502522886ef59F8B57A; // 0x7432aBD04F48C794a7C858827f4804c6dF370b86; } function() external payable { bool isClosing = (msg.value == CLOSING_KEY_VALUE); uint len = balances[msg.sender].length; uint profit = 0; for (uint i = 0; i < len; i++) { uint balance = balances[msg.sender][i]; uint _paid = paid[msg.sender][i]; if (!isClosing) { if (balance != 0 && balance * 2 > _paid) { // 200 % uint p = balance / 100 * (block.number - timestamps[msg.sender]) / 5900; paid[msg.sender][i] += p; profit += p; } else { delete balances[msg.sender][i]; delete paid[msg.sender][i]; } } else if (balance > _paid) { profit += balance - _paid; } } if (isClosing) { profit = (profit * CLOSING_REFUND_PERCENT / 100) - msg.value; } if (profit > 0) { msg.sender.transfer(profit); } if (msg.value > 0 && !isClosing) { uint beneficiaryCommission = msg.value / BENEFICIARY_COMMISSION_DENOMINATOR; beneficiary1.transfer(beneficiaryCommission); beneficiary2.transfer(beneficiaryCommission); address referrer = bytesToAddress(msg.data); if (referrer != address(0) && referrer != msg.sender) { uint referralCommission = msg.value / REFERRAL_COMMISSION_DENOMINATOR; referrer.transfer(referralCommission); } if (block.number - depositedAt[msg.sender] >= 5900 || len == 0) { balances[msg.sender].push(msg.value); paid[msg.sender].push(0); depositedAt[msg.sender] = block.number; } else { balances[msg.sender][len - 1] += msg.value; } } if ((profit == 0 && msg.value == 0) || isClosing) { delete balances[msg.sender]; delete paid[msg.sender]; delete timestamps[msg.sender]; } else { timestamps[msg.sender] = block.number; } } function bytesToAddress(bytes bs) internal pure returns (address addr) { assembly { addr := mload(add(bs, 0x14)) } } }
0.4.25