文件 1 的 1:Etrix.sol
pragma solidity 0.5.11;
contract Etrix {
address public _owner;
struct UserStruct {
bool isExist;
uint id;
uint referrerIDMatrix1;
uint referrerIDMatrix2;
address[] referralMatrix1;
address[] referralMatrix2;
uint referralCounter;
mapping(uint => uint) levelExpiredMatrix1;
mapping(uint => uint) levelExpiredMatrix2;
}
uint constant private REFERRER_1_LEVEL_LIMIT = 2;
uint constant private PERIOD_LENGTH = 60 days;
uint public availablePersonID;
address [] public shareHolders;
mapping(uint => uint) public LEVEL_PRICE;
mapping (address => UserStruct) public users;
mapping (uint => address) public userList;
uint public currUserID = 0;
event regLevelEvent(address indexed _user, address indexed _referrer, uint _time);
event buyLevelEvent(address indexed _user, uint _level, uint _time, uint _matrix);
event prolongateLevelEvent(address indexed _user, uint _level, uint _time);
event getMoneyForLevelEvent(address indexed _user, address indexed _referral, uint _level, uint _time, uint _matrix);
event lostMoneyForLevelEvent(address indexed _user, address indexed _referral, uint _level, uint _time, uint _matrix);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() public {
_owner = msg.sender;
LEVEL_PRICE[1] = 0.05 ether;
LEVEL_PRICE[2] = 0.1 ether;
LEVEL_PRICE[3] = 0.3 ether;
LEVEL_PRICE[4] = 1.25 ether;
LEVEL_PRICE[5] = 5 ether;
LEVEL_PRICE[6] = 10 ether;
availablePersonID = 1;
}
modifier onlyOwner() {
require(msg.sender == _owner, "only Owner");
_;
}
function () external payable {
uint level;
if(msg.value == LEVEL_PRICE[1]) level = 1;
else if(msg.value == LEVEL_PRICE[2]) level = 2;
else if(msg.value == LEVEL_PRICE[3]) level = 3;
else if(msg.value == LEVEL_PRICE[4]) level = 4;
else if(msg.value == LEVEL_PRICE[5]) level = 5;
else if(msg.value == LEVEL_PRICE[6]) level = 6;
else revert('Incorrect Value send, please check');
if(users[msg.sender].isExist)
buyLevelMatrix1(level);
else if(level == 1) {
uint refId = 0;
address referrer = bytesToAddress(msg.data);
if(users[referrer].isExist) refId = users[referrer].id;
else revert('Incorrect referrer id');
regUser(refId);
}
else revert('Please buy first level for 0.05 ETH and then proceed');
}
function regUser(uint _referrerID) public payable {
require(!users[msg.sender].isExist, 'User exist');
require(_referrerID > 0 && _referrerID <= currUserID, 'Incorrect referrer Id');
require(msg.value == LEVEL_PRICE[1], 'Incorrect Value');
uint _referrerIDMatrix1;
uint _referrerIDMatrix2 = _referrerID;
_referrerIDMatrix1 = findAvailablePersonMatrix1();
if(users[userList[_referrerIDMatrix2]].referralMatrix2.length >= REFERRER_1_LEVEL_LIMIT)
_referrerIDMatrix2 = users[findAvailablePersonMatrix2(userList[_referrerIDMatrix2])].id;
UserStruct memory userStruct;
currUserID++;
userStruct = UserStruct({
isExist: true,
id: currUserID,
referrerIDMatrix1: _referrerIDMatrix1,
referrerIDMatrix2: _referrerIDMatrix2,
referralCounter: 0,
referralMatrix1: new address[](0),
referralMatrix2: new address[](0)
});
users[msg.sender] = userStruct;
userList[currUserID] = msg.sender;
users[msg.sender].levelExpiredMatrix1[1] = now + PERIOD_LENGTH;
users[userList[_referrerIDMatrix1]].referralMatrix1.push(msg.sender);
users[userList[_referrerIDMatrix2]].referralMatrix2.push(msg.sender);
payForLevelMatrix1(1,msg.sender);
users[userList[_referrerID]].referralCounter++;
emit regLevelEvent(msg.sender, userList[_referrerID], now);
}
function preRegAdmins(address [] memory _adminAddress) public onlyOwner{
require(currUserID <= 100, "No more admins can be registered");
UserStruct memory userStruct;
for(uint i = 0; i < _adminAddress.length; i++){
require(!users[_adminAddress[i]].isExist, 'One of the users exist');
currUserID++;
if(currUserID == 1){
userStruct = UserStruct({
isExist: true,
id: currUserID,
referrerIDMatrix1: 1,
referrerIDMatrix2: 1,
referralCounter: 2,
referralMatrix1: new address[](0),
referralMatrix2: new address[](0)
});
users[_adminAddress[i]] = userStruct;
userList[currUserID] = _adminAddress[i];
for(uint j = 1; j <= 6; j++) {
users[_adminAddress[i]].levelExpiredMatrix1[j] = 66666666666;
users[_adminAddress[i]].levelExpiredMatrix2[j] = 66666666666;
}
}
else {
uint _referrerIDMatrix1;
uint _referrerIDMatrix2 = 1;
_referrerIDMatrix1 = findAvailablePersonMatrix1();
if(users[userList[_referrerIDMatrix2]].referralMatrix2.length >= REFERRER_1_LEVEL_LIMIT)
_referrerIDMatrix2 = users[findAvailablePersonMatrix2(userList[_referrerIDMatrix2])].id;
userStruct = UserStruct({
isExist: true,
id: currUserID,
referrerIDMatrix1: _referrerIDMatrix1,
referrerIDMatrix2: _referrerIDMatrix2,
referralCounter: 2,
referralMatrix1: new address[](0),
referralMatrix2: new address[](0)
});
users[_adminAddress[i]] = userStruct;
userList[currUserID] = _adminAddress[i];
for(uint j = 1; j <= 6; j++) {
users[_adminAddress[i]].levelExpiredMatrix1[j] = 66666666666;
users[_adminAddress[i]].levelExpiredMatrix2[j] = 66666666666;
}
users[userList[_referrerIDMatrix1]].referralMatrix1.push(_adminAddress[i]);
users[userList[_referrerIDMatrix2]].referralMatrix2.push(_adminAddress[i]);
}
}
}
function addShareHolder(address [] memory _shareHolderAddress) public onlyOwner returns(address[] memory){
for(uint i=0; i < _shareHolderAddress.length; i++){
if(shareHolders.length < 20) {
shareHolders.push(_shareHolderAddress[i]);
}
}
return shareHolders;
}
function removeShareHolder(address _shareHolderAddress) public onlyOwner returns(address[] memory){
for(uint i=0; i < shareHolders.length; i++){
if(shareHolders[i] == _shareHolderAddress) {
shareHolders[i] = shareHolders[shareHolders.length-1];
delete shareHolders[shareHolders.length-1];
shareHolders.length--;
}
}
return shareHolders;
}
function findAvailablePersonMatrix1() internal returns(uint){
uint _referrerID;
uint _referralLength = users[userList[availablePersonID]].referralMatrix1.length;
if(_referralLength == REFERRER_1_LEVEL_LIMIT) {
availablePersonID++;
_referrerID = availablePersonID;
}
else if( _referralLength == 1) {
_referrerID = availablePersonID;
availablePersonID++;
}
else{
_referrerID = availablePersonID;
}
return _referrerID;
}
function findAvailablePersonMatrix2(address _user) public view returns(address) {
if(users[_user].referralMatrix2.length < REFERRER_1_LEVEL_LIMIT) return _user;
address[] memory referrals = new address[](1022);
referrals[0] = users[_user].referralMatrix2[0];
referrals[1] = users[_user].referralMatrix2[1];
address freeReferrer;
bool noFreeReferrer = true;
for(uint i = 0; i < 1022; i++) {
if(users[referrals[i]].referralMatrix2.length == REFERRER_1_LEVEL_LIMIT) {
if(i < 510) {
referrals[(i+1)*2] = users[referrals[i]].referralMatrix2[0];
referrals[(i+1)*2+1] = users[referrals[i]].referralMatrix2[1];
}
}
else {
noFreeReferrer = false;
freeReferrer = referrals[i];
break;
}
}
require(!noFreeReferrer, 'No Free Referrer');
return freeReferrer;
}
function buyLevelMatrix1(uint _level) public payable {
require(users[msg.sender].isExist, 'User not exist');
require(_level > 0 && _level <= 6, 'Incorrect level');
if(_level == 1) {
require(msg.value == LEVEL_PRICE[1], 'Incorrect Value');
if(users[msg.sender].levelExpiredMatrix1[1] > now)
users[msg.sender].levelExpiredMatrix1[1] += PERIOD_LENGTH;
else
users[msg.sender].levelExpiredMatrix1[1] = now + PERIOD_LENGTH;
}
else {
require(msg.value == LEVEL_PRICE[_level], 'Incorrect Value');
for(uint l =_level - 1; l > 0; l--) require(users[msg.sender].levelExpiredMatrix1[l] >= now, 'Buy the previous level');
if(users[msg.sender].levelExpiredMatrix1[_level] == 0 || now > users[msg.sender].levelExpiredMatrix1[_level])
users[msg.sender].levelExpiredMatrix1[_level] = now + PERIOD_LENGTH;
else users[msg.sender].levelExpiredMatrix1[_level] += PERIOD_LENGTH;
}
payForLevelMatrix1(_level, msg.sender);
emit buyLevelEvent(msg.sender, _level, now, 1);
}
function buyLevelMatrix2(uint _level) public payable {
require(users[msg.sender].isExist, 'User not exist');
require(users[msg.sender].referralCounter >= 2, 'Need atleast 2 direct referrals to activate Team Matrix');
require(_level > 0 && _level <= 6, 'Incorrect level');
if(_level == 1) {
require(msg.value == LEVEL_PRICE[1], 'Incorrect Value');
if(users[msg.sender].levelExpiredMatrix2[1] > now)
users[msg.sender].levelExpiredMatrix2[1] += PERIOD_LENGTH;
else
users[msg.sender].levelExpiredMatrix2[1] = now + PERIOD_LENGTH;
}
else {
require(msg.value == LEVEL_PRICE[_level], 'Incorrect Value');
for(uint l =_level - 1; l > 0; l--) require(users[msg.sender].levelExpiredMatrix2[l] >= now, 'Buy the previous level');
if(users[msg.sender].levelExpiredMatrix2[_level] == 0 || now > users[msg.sender].levelExpiredMatrix2[_level])
users[msg.sender].levelExpiredMatrix2[_level] = now + PERIOD_LENGTH;
else users[msg.sender].levelExpiredMatrix2[_level] += PERIOD_LENGTH;
}
payForLevelMatrix2(_level, msg.sender);
emit buyLevelEvent(msg.sender, _level, now, 2);
}
function payForLevelMatrix1(uint _level, address _user) internal {
address actualReferer;
address tempReferer1;
address tempReferer2;
uint userID;
if(_level == 1) {
actualReferer = userList[users[_user].referrerIDMatrix1];
userID = users[actualReferer].id;
}
else if(_level == 2) {
tempReferer1 = userList[users[_user].referrerIDMatrix1];
actualReferer = userList[users[tempReferer1].referrerIDMatrix1];
userID = users[actualReferer].id;
}
else if(_level == 3) {
tempReferer1 = userList[users[_user].referrerIDMatrix1];
tempReferer2 = userList[users[tempReferer1].referrerIDMatrix1];
actualReferer = userList[users[tempReferer2].referrerIDMatrix1];
userID = users[actualReferer].id;
}
else if(_level == 4) {
tempReferer1 = userList[users[_user].referrerIDMatrix1];
tempReferer2 = userList[users[tempReferer1].referrerIDMatrix1];
tempReferer1 = userList[users[tempReferer2].referrerIDMatrix1];
actualReferer = userList[users[tempReferer1].referrerIDMatrix1];
userID = users[actualReferer].id;
}
else if(_level == 5) {
tempReferer1 = userList[users[_user].referrerIDMatrix1];
tempReferer2 = userList[users[tempReferer1].referrerIDMatrix1];
tempReferer1 = userList[users[tempReferer2].referrerIDMatrix1];
tempReferer2 = userList[users[tempReferer1].referrerIDMatrix1];
actualReferer = userList[users[tempReferer2].referrerIDMatrix1];
userID = users[actualReferer].id;
}
else if(_level == 6) {
tempReferer1 = userList[users[_user].referrerIDMatrix1];
tempReferer2 = userList[users[tempReferer1].referrerIDMatrix1];
tempReferer1 = userList[users[tempReferer2].referrerIDMatrix1];
tempReferer2 = userList[users[tempReferer1].referrerIDMatrix1];
tempReferer1 = userList[users[tempReferer2].referrerIDMatrix1];
actualReferer = userList[users[tempReferer1].referrerIDMatrix1];
userID = users[actualReferer].id;
}
if(!users[actualReferer].isExist) actualReferer = userList[1];
bool sent = false;
if(userID > 0 && userID <= 63) {
for(uint i=0; i < shareHolders.length; i++) {
address(uint160(shareHolders[i])).transfer(LEVEL_PRICE[_level]/(shareHolders.length));
emit getMoneyForLevelEvent(shareHolders[i], msg.sender, _level, now, 1);
}
if(address(this).balance > 0)
address(uint160(userList[1])).transfer(address(this).balance);
}
else{
if(users[actualReferer].levelExpiredMatrix1[_level] >= now && users[actualReferer].referralCounter >= 2) {
sent = address(uint160(actualReferer)).send(LEVEL_PRICE[_level]);
if (sent) {
emit getMoneyForLevelEvent(actualReferer, msg.sender, _level, now, 1);
}
}
if(!sent) {
emit lostMoneyForLevelEvent(actualReferer, msg.sender, _level, now, 1);
payForLevelMatrix1(_level, actualReferer);
}
}
}
function payForLevelMatrix2(uint _level, address _user) internal {
address actualReferer;
address tempReferer1;
address tempReferer2;
uint userID;
if(_level == 1) {
actualReferer = userList[users[_user].referrerIDMatrix2];
userID = users[actualReferer].id;
}
else if(_level == 2) {
tempReferer1 = userList[users[_user].referrerIDMatrix2];
actualReferer = userList[users[tempReferer1].referrerIDMatrix2];
userID = users[actualReferer].id;
}
else if(_level == 3) {
tempReferer1 = userList[users[_user].referrerIDMatrix2];
tempReferer2 = userList[users[tempReferer1].referrerIDMatrix2];
actualReferer = userList[users[tempReferer2].referrerIDMatrix2];
userID = users[actualReferer].id;
}
else if(_level == 4) {
tempReferer1 = userList[users[_user].referrerIDMatrix2];
tempReferer2 = userList[users[tempReferer1].referrerIDMatrix2];
tempReferer1 = userList[users[tempReferer2].referrerIDMatrix2];
actualReferer = userList[users[tempReferer1].referrerIDMatrix2];
userID = users[actualReferer].id;
}
else if(_level == 5) {
tempReferer1 = userList[users[_user].referrerIDMatrix2];
tempReferer2 = userList[users[tempReferer1].referrerIDMatrix2];
tempReferer1 = userList[users[tempReferer2].referrerIDMatrix2];
tempReferer2 = userList[users[tempReferer1].referrerIDMatrix2];
actualReferer = userList[users[tempReferer2].referrerIDMatrix2];
userID = users[actualReferer].id;
}
else if(_level == 6) {
tempReferer1 = userList[users[_user].referrerIDMatrix2];
tempReferer2 = userList[users[tempReferer1].referrerIDMatrix2];
tempReferer1 = userList[users[tempReferer2].referrerIDMatrix2];
tempReferer2 = userList[users[tempReferer1].referrerIDMatrix2];
tempReferer1 = userList[users[tempReferer2].referrerIDMatrix2];
actualReferer = userList[users[tempReferer1].referrerIDMatrix2];
userID = users[actualReferer].id;
}
if(!users[actualReferer].isExist) actualReferer = userList[1];
bool sent = false;
if(userID > 0 && userID <= 63) {
for(uint i=0; i < shareHolders.length; i++) {
address(uint160(shareHolders[i])).transfer(LEVEL_PRICE[_level]/(shareHolders.length));
emit getMoneyForLevelEvent(shareHolders[i], msg.sender, _level, now, 2);
}
if(address(this).balance > 0)
address(uint160(userList[1])).transfer(address(this).balance);
}
else{
if(users[actualReferer].levelExpiredMatrix2[_level] >= now) {
sent = address(uint160(actualReferer)).send(LEVEL_PRICE[_level]);
if (sent) {
emit getMoneyForLevelEvent(actualReferer, msg.sender, _level, now, 2);
}
}
if(!sent) {
emit lostMoneyForLevelEvent(actualReferer, msg.sender, _level, now, 2);
payForLevelMatrix2(_level, actualReferer);
}
}
}
function transferOwnership(address newOwner) external onlyOwner {
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0), "New owner cannot be the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
function viewUserReferralMatrix1(address _user) public view returns(address[] memory) {
return users[_user].referralMatrix1;
}
function viewUserReferralMatrix2(address _user) public view returns(address[] memory) {
return users[_user].referralMatrix2;
}
function viewUserLevelExpiredMatrix1(address _user, uint _level) public view returns(uint256) {
return users[_user].levelExpiredMatrix1[_level];
}
function viewUserLevelExpiredMatrix2(address _user, uint _level) public view returns(uint256) {
return users[_user].levelExpiredMatrix2[_level];
}
function bytesToAddress(bytes memory bys) private pure returns (address addr) {
assembly {
addr := mload(add(bys, 20))
}
}
}