文件 1 的 1:LionShare.sol
pragma solidity 0.6.8;
contract LionShare {
struct Account {
uint32 id;
uint32 directSales;
uint8[] activeLevel;
bool exists;
address sponsor;
mapping(uint8 => L1) x31Positions;
mapping(uint8 => L2) x22Positions;
}
struct L1 {
uint32 directSales;
uint16 cycles;
uint8 passup;
uint8 reEntryCheck;
uint8 placement;
address sponsor;
}
struct L2 {
uint32 directSales;
uint16 cycles;
uint8 passup;
uint8 cycle;
uint8 reEntryCheck;
uint8 placementLastLevel;
uint8 placementSide;
address sponsor;
address placedUnder;
address[] placementFirstLevel;
}
uint internal constant ENTRY_ENABLED = 1;
uint internal constant ENTRY_DISABLED = 2;
uint public constant REENTRY_REQ = 2;
mapping(address => Account) public members;
mapping(uint32 => address) public idToMember;
mapping(uint8 => uint) public levelCost;
uint internal reentry_status;
uint32 public lastId;
uint8 public topLevel;
address internal owner;
event Registration(address member, uint memberId, address sponsor);
event Upgrade(address member, address sponsor, uint8 matrix, uint8 level);
event PlacementL1(address member, address sponsor, uint8 level, uint8 placement, bool passup);
event PlacementL2(address member, address sponsor, uint8 level, uint8 placementSide, address placedUnder, bool passup);
event Cycle(address indexed member, address fromPosition, uint8 matrix, uint8 level);
event PlacementReEntry(address indexed member, address reEntryFrom, uint8 matrix, uint8 level);
event FundsPayout(address indexed member, address payoutFrom, uint8 matrix, uint8 level);
event FundsPassup(address indexed member, address passupFrom, uint8 matrix, uint8 level);
modifier isOwner(address _account) {
require(owner == _account, "Restricted Access!");
_;
}
modifier isMember(address _addr) {
require(members[_addr].exists, "Register Account First!");
_;
}
modifier blockReEntry() {
require(reentry_status != ENTRY_DISABLED, "Security Block");
reentry_status = ENTRY_DISABLED;
_;
reentry_status = ENTRY_ENABLED;
}
constructor(address _addr) public {
owner = msg.sender;
reentry_status = ENTRY_ENABLED;
levelCost[1] = 0.02 ether;
topLevel = 1;
createAccount(_addr, _addr, true);
handlePositionL1(_addr, _addr, _addr, 1, true);
handlePositionL2(_addr, _addr, _addr, 1, true);
}
fallback() external payable blockReEntry() {
preRegistration(msg.sender, bytesToAddress(msg.data));
}
receive() external payable blockReEntry() {
preRegistration(msg.sender, idToMember[1]);
}
function registration(address _sponsor) external payable blockReEntry() {
preRegistration(msg.sender, _sponsor);
}
function preRegistration(address _addr, address _sponsor) internal {
require((levelCost[1] * 2) == msg.value, "Require .04 eth to register!");
createAccount(_addr, _sponsor, false);
members[_sponsor].directSales++;
handlePositionL1(_addr, _sponsor, _sponsor, 1, false);
handlePositionL2(_addr, _sponsor, _sponsor, 1, false);
handlePayout(_addr, 0, 1);
handlePayout(_addr, 1, 1);
}
function createAccount(address _addr, address _sponsor, bool _initial) internal {
require(!members[_addr].exists, "Already a member!");
if (_initial == false) {
require(members[_sponsor].exists, "Sponsor dont exist!");
}
lastId++;
members[_addr] = Account({id: lastId, sponsor: _sponsor, exists: true, directSales: 0, activeLevel: new uint8[](2)});
idToMember[lastId] = _addr;
emit Registration(_addr, lastId, _sponsor);
}
function purchaseLevel(uint8 _matrix, uint8 _level) external payable isMember(msg.sender) blockReEntry() {
require((_matrix == 1 || _matrix == 2), "Invalid matrix identifier.");
require((_level > 0 && _level <= topLevel), "Invalid matrix level.");
uint8 activeLevel = members[msg.sender].activeLevel[(_matrix - 1)];
uint8 otherLevel = 1;
if (_matrix == 2) {
otherLevel = 0;
}
require((activeLevel < _level), "Already active at level!");
require((activeLevel == (_level - 1)), "Level upgrade req. in order!");
require(((members[msg.sender].activeLevel[otherLevel] * 2) >= _level), "Double upgrade exeeded.");
require((msg.value == levelCost[_level]), "Wrong amount transferred.");
address sponsor = members[msg.sender].sponsor;
Upgrade(msg.sender, sponsor, _matrix, _level);
if (_matrix == 1) {
handlePositionL1(msg.sender, sponsor, findActiveSponsor(msg.sender, sponsor, 0, _level, true), _level, false);
} else {
handlePositionL2(msg.sender, sponsor, findActiveSponsor(msg.sender, sponsor, 1, _level, true), _level, false);
}
handlePayout(msg.sender, (_matrix - 1), _level);
}
function handlePositionL1(address _addr, address _mainSponsor, address _sponsor, uint8 _level, bool _initial) internal {
Account storage member = members[_addr];
member.activeLevel[0] = _level;
member.x31Positions[_level] = L1({sponsor: _sponsor, placement: 0, directSales: 0, cycles: 0, passup: 0, reEntryCheck: 0});
if (_initial == true) {
return;
} else if (_mainSponsor == _sponsor) {
members[_mainSponsor].x31Positions[_level].directSales++;
} else {
member.x31Positions[_level].reEntryCheck = 1;
}
sponsorPlaceL1(_addr, _sponsor, _level, false);
}
function sponsorPlaceL1(address _addr, address _sponsor, uint8 _level, bool passup) internal {
L1 storage position = members[_sponsor].x31Positions[_level];
emit PlacementL1(_addr, _sponsor, _level, (position.placement + 1), passup);
if (position.placement >= 2) {
emit Cycle(_sponsor, _addr, 1, _level);
position.placement = 0;
position.cycles++;
if (_sponsor != idToMember[1]) {
position.passup++;
sponsorPlaceL1(_sponsor, position.sponsor, _level, true);
}
} else {
position.placement++;
}
}
function handlePositionL2(address _addr, address _mainSponsor, address _sponsor, uint8 _level, bool _initial) internal {
Account storage member = members[_addr];
member.activeLevel[1] = _level;
member.x22Positions[_level] = L2({sponsor: _sponsor, directSales: 0, cycles: 0, passup: 0, cycle: 0, reEntryCheck: 0, placementSide: 0, placedUnder: _sponsor, placementFirstLevel: new address[](0), placementLastLevel: 0});
if (_initial == true) {
return;
} else if (_mainSponsor == _sponsor) {
members[_mainSponsor].x22Positions[_level].directSales++;
} else {
member.x22Positions[_level].reEntryCheck = 1;
}
sponsorPlaceL2(_addr, _sponsor, _level, false);
}
function sponsorPlaceL2(address _addr, address _sponsor, uint8 _level, bool passup) internal {
L2 storage member = members[_addr].x22Positions[_level];
L2 storage position = members[_sponsor].x22Positions[_level];
if (position.placementFirstLevel.length < 2) {
if (position.placementFirstLevel.length == 0) {
member.placementSide = 1;
} else {
member.placementSide = 2;
}
member.placedUnder = _sponsor;
position.placementFirstLevel.push(_addr);
if (_sponsor != idToMember[1]) {
position.passup++;
}
positionPlaceLastLevelL2(_addr, _sponsor, position.placedUnder, position.placementSide, _level);
} else {
if (position.placementLastLevel == 0) {
member.placementSide = 1;
member.placedUnder = position.placementFirstLevel[0];
position.placementLastLevel += 1;
} else if ((position.placementLastLevel & 2) == 0) {
member.placementSide = 2;
member.placedUnder = position.placementFirstLevel[0];
position.placementLastLevel += 2;
} else if ((position.placementLastLevel & 4) == 0) {
member.placementSide = 1;
member.placedUnder = position.placementFirstLevel[1];
position.placementLastLevel += 4;
} else {
member.placementSide = 2;
member.placedUnder = position.placementFirstLevel[1];
position.placementLastLevel += 8;
}
if (member.placedUnder != idToMember[1]) {
members[member.placedUnder].x22Positions[_level].placementFirstLevel.push(_addr);
}
}
if ((position.placementLastLevel & 15) == 15) {
emit Cycle(_sponsor, _addr, 2, _level);
position.placementFirstLevel = new address[](0);
position.placementLastLevel = 0;
position.cycles++;
if (_sponsor != idToMember[1]) {
position.cycle++;
sponsorPlaceL2(_sponsor, position.sponsor, _level, true);
}
}
emit PlacementL2(_addr, _sponsor, _level, member.placementSide, member.placedUnder, passup);
}
function positionPlaceLastLevelL2(address _addr, address _sponsor, address _position, uint8 _placementSide, uint8 _level) internal {
L2 storage position = members[_position].x22Positions[_level];
if (position.placementSide == 0 && _sponsor == idToMember[1]) {
return;
}
if (_placementSide == 1) {
if ((position.placementLastLevel & 1) == 0) {
position.placementLastLevel += 1;
} else {
position.placementLastLevel += 2;
}
} else {
if ((position.placementLastLevel & 4) == 0) {
position.placementLastLevel += 4;
} else {
position.placementLastLevel += 8;
}
}
if ((position.placementLastLevel & 15) == 15) {
emit Cycle(_position, _addr, 2, _level);
position.placementFirstLevel = new address[](0);
position.placementLastLevel = 0;
position.cycles++;
if (_position != idToMember[1]) {
position.cycle++;
sponsorPlaceL2(_position, position.sponsor, _level, true);
}
}
}
function findActiveSponsor(address _addr, address _sponsor, uint8 _matrix, uint8 _level, bool _emit) internal returns (address) {
address sponsorAddress = _sponsor;
while (true) {
if (members[sponsorAddress].activeLevel[_matrix] >= _level) {
return sponsorAddress;
}
if (_emit == true) {
emit FundsPassup(sponsorAddress, _addr, (_matrix + 1), _level);
}
sponsorAddress = members[sponsorAddress].sponsor;
}
}
function handleReEntryL1(address _addr, uint8 _level) internal {
L1 storage member = members[_addr].x31Positions[_level];
bool reentry = false;
member.reEntryCheck++;
if (member.reEntryCheck >= REENTRY_REQ) {
address sponsor = members[_addr].sponsor;
if (members[sponsor].activeLevel[0] >= _level) {
member.reEntryCheck = 0;
reentry = true;
} else {
sponsor = findActiveSponsor(_addr, sponsor, 0, _level, false);
if (member.sponsor != sponsor && members[sponsor].activeLevel[0] >= _level) {
reentry = true;
}
}
if (reentry == true) {
member.sponsor = sponsor;
emit PlacementReEntry(sponsor, _addr, 1, _level);
}
}
}
function handleReEntryL2(address _addr, uint8 _level) internal {
L2 storage member = members[_addr].x22Positions[_level];
bool reentry = false;
member.reEntryCheck++;
if (member.reEntryCheck >= REENTRY_REQ) {
address sponsor = members[_addr].sponsor;
if (members[sponsor].activeLevel[1] >= _level) {
member.reEntryCheck = 0;
member.sponsor = sponsor;
reentry = true;
} else {
address active_sponsor = findActiveSponsor(_addr, sponsor, 1, _level, false);
if (member.sponsor != active_sponsor && members[active_sponsor].activeLevel[1] >= _level) {
member.sponsor = active_sponsor;
reentry = true;
}
}
if (reentry == true) {
emit PlacementReEntry(member.sponsor, _addr, 2, _level);
}
}
}
function findPayoutReceiver(address _addr, uint8 _matrix, uint8 _level) internal returns (address) {
address from;
address receiver;
if (_matrix == 0) {
receiver = members[_addr].x31Positions[_level].sponsor;
while (true) {
L1 storage member = members[receiver].x31Positions[_level];
if (member.passup == 0) {
return receiver;
}
member.passup--;
from = receiver;
receiver = member.sponsor;
if (_level > 1 && member.reEntryCheck > 0) {
handleReEntryL1(from, _level);
}
}
} else {
receiver = members[_addr].x22Positions[_level].sponsor;
while (true) {
L2 storage member = members[receiver].x22Positions[_level];
if (member.passup == 0 && member.cycle == 0) {
return receiver;
}
if (member.passup > 0) {
member.passup--;
receiver = member.placedUnder;
} else {
member.cycle--;
from = receiver;
receiver = member.sponsor;
if (_level > 1 && member.reEntryCheck > 0) {
handleReEntryL2(from, _level);
}
}
}
}
}
function handlePayout(address _addr, uint8 _matrix, uint8 _level) internal {
address receiver = findPayoutReceiver(_addr, _matrix, _level);
emit FundsPayout(receiver, _addr, (_matrix + 1), _level);
(bool success, ) = address(uint160(receiver)).call{ value: levelCost[_level], gas: 40000 }("");
if (success == false) {
(success, ) = address(uint160(idToMember[1])).call{ value: levelCost[_level], gas: 40000 }("");
require(success, 'Transfer Failed');
}
}
function getAffiliateId() external view returns (uint) {
return members[msg.sender].id;
}
function getAffiliateWallet(uint32 memberId) external view returns (address) {
return idToMember[memberId];
}
function setupAccount(address _addr, address _sponsor, uint8 _level) external isOwner(msg.sender) {
createAccount(_addr, _sponsor, false);
compLevel(_addr, 1, _level);
compLevel(_addr, 2, _level);
}
function compLevel(address _addr, uint8 _matrix, uint8 _level) public isOwner(msg.sender) isMember(_addr) {
require((_matrix == 1 || _matrix == 2), "Invalid matrix identifier.");
require((_level > 0 && _level <= topLevel), "Invalid matrix level.");
uint8 matrix = _matrix - 1;
uint8 activeLevel = members[_addr].activeLevel[matrix];
address sponsor = members[_addr].sponsor;
require((activeLevel < _level), "Already active at level!");
for (uint8 num = (activeLevel + 1);num <= _level;num++) {
Upgrade(_addr, sponsor, _matrix, num);
if (matrix == 0) {
handlePositionL1(_addr, sponsor, findActiveSponsor(_addr, sponsor, 0, num, true), num, false);
} else {
handlePositionL2(_addr, sponsor, findActiveSponsor(_addr, sponsor, 1, num, true), num, false);
}
}
}
function addLevel(uint _levelPrice) external isOwner(msg.sender) {
require((levelCost[topLevel] < _levelPrice), "Check price point!");
topLevel++;
levelCost[topLevel] = _levelPrice;
handlePositionL1(idToMember[1], idToMember[1], idToMember[1], topLevel, true);
handlePositionL2(idToMember[1], idToMember[1], idToMember[1], topLevel, true);
}
function updateLevelCost(uint8 _level, uint _levelPrice) external isOwner(msg.sender) {
require((_level > 0 && _level <= topLevel), "Invalid matrix level.");
require((_levelPrice > 0), "Check price point!");
if (_level > 1) {
require((levelCost[(_level - 1)] < _levelPrice), "Check price point!");
}
if (_level < topLevel) {
require((levelCost[(_level + 1)] > _levelPrice), "Check price point!");
}
levelCost[_level] = _levelPrice;
}
function bytesToAddress(bytes memory _source) private pure returns (address addr) {
assembly {
addr := mload(add(_source, 20))
}
}
}