Transaction Hash:
Block:
9202084 at Jan-02-2020 05:00:33 PM +UTC
Transaction Fee:
0.00395453 ETH
$7.72
Gas Used:
395,453 Gas / 10 Gwei
Emitted Events:
| 100 |
Absolutus.PaymentForHolder( _addr=0x292ba92eeac6081d15286c0c3fb62756472c9835, _index=1, _value=42000000000000000 )
|
| 101 |
Absolutus.PaymentForHolder( _addr=0x1a89f6af888035c8e2512f3701c9f7b478ec4a4c, _index=2, _value=4000000000000000 )
|
| 102 |
Absolutus.PaymentForHolder( _addr=0x38b13ec169f30518ed220c72e70a306edbea96d3, _index=3, _value=4000000000000000 )
|
| 103 |
Absolutus.GetMoneyForLevelEvent( _user=0x9dc56c606938cd32267ec9e81ef92325e99cb692, _referral=[Sender] 0x82683f46c69e068f244d86103317b37ebbf93779, _level=1, _time=1577984433, _price=450000000000000000, _prevLost=False )
|
| 104 |
Absolutus.PaymentForHolder( _addr=0x292ba92eeac6081d15286c0c3fb62756472c9835, _index=1, _value=84000000000000000 )
|
| 105 |
Absolutus.PaymentForHolder( _addr=0x1a89f6af888035c8e2512f3701c9f7b478ec4a4c, _index=2, _value=8000000000000000 )
|
| 106 |
Absolutus.PaymentForHolder( _addr=0x38b13ec169f30518ed220c72e70a306edbea96d3, _index=3, _value=8000000000000000 )
|
| 107 |
Absolutus.GetMoneyForLevelEvent( _user=0xc04c4c118d9fa554e19af2c1dfa5427d6c40926f, _referral=0x9dc56c606938cd32267ec9e81ef92325e99cb692, _level=2, _time=1577984433, _price=900000000000000000, _prevLost=False )
|
| 108 |
Absolutus.BuyLevelEvent( _user=0x9dc56c606938cd32267ec9e81ef92325e99cb692, _level=2, _time=1577984433 )
|
| 109 |
Absolutus.RegLevelEvent( _user=[Sender] 0x82683f46c69e068f244d86103317b37ebbf93779, _referrer=0x9dc56c606938cd32267ec9e81ef92325e99cb692, _id=745, _time=1577984433 )
|
Account State Difference:
| Address | Before | After | State Difference | ||
|---|---|---|---|---|---|
| 0x0C9e046e...FbD827260 | 134.1 Eth | 133.2 Eth | 0.9 | ||
| 0x1a89f6AF...478ec4A4c | 9.5939105 Eth | 9.6059105 Eth | 0.012 | ||
| 0x292BA92E...6472c9835 | 4.91756986867 Eth | 5.04356986867 Eth | 0.126 | ||
| 0x38b13eC1...EDBEA96d3 | 10.08087041 Eth | 10.09287041 Eth | 0.012 | ||
| 0x82683f46...ebbF93779 |
0.5388651749 Eth
Nonce: 94
|
0.0349106449 Eth
Nonce: 95
| 0.50395453 | ||
|
0x829BD824...93333A830
Miner
| (F2Pool Old) | 5,775.062534558657312112 Eth | 5,775.066489088657312112 Eth | 0.00395453 | |
| 0x9DC56C60...5e99cb692 | 1.185189121788329593 Eth | 1.535189121788329593 Eth | 0.35 | ||
| 0xc04C4c11...d6C40926f | 0.5433392413 Eth | 1.4433392413 Eth | 0.9 |
Execution Trace
ETH 0.5
Absolutus.9dc56c60( )
-
AbsDAO.STATICCALL( ) -
AbsDAO.getHolderPieAt( i=1 ) => ( 84 ) -
AbsDAO.getHolder( i=1 ) => ( 0x292BA92EeAC6081d15286c0c3fb62756472c9835 ) - ETH 0.042
0x292ba92eeac6081d15286c0c3fb62756472c9835.CALL( ) -
AbsDAO.getHolderPieAt( i=2 ) => ( 8 ) -
AbsDAO.getHolder( i=2 ) => ( 0x1a89f6AF888035C8e2512F3701C9f7B478ec4A4c ) - ETH 0.004
0x1a89f6af888035c8e2512f3701c9f7b478ec4a4c.CALL( ) -
AbsDAO.getHolderPieAt( i=3 ) => ( 8 ) -
AbsDAO.getHolder( i=3 ) => ( 0x38b13eC169f30518eD220C72E70a306EDBEA96d3 ) - ETH 0.004
0x38b13ec169f30518ed220c72e70a306edbea96d3.CALL( ) -
AbsDAO.STATICCALL( ) -
AbsDAO.getHolderPieAt( i=1 ) => ( 84 ) -
AbsDAO.getHolder( i=1 ) => ( 0x292BA92EeAC6081d15286c0c3fb62756472c9835 ) - ETH 0.084
0x292ba92eeac6081d15286c0c3fb62756472c9835.CALL( ) -
AbsDAO.getHolderPieAt( i=2 ) => ( 8 ) -
AbsDAO.getHolder( i=2 ) => ( 0x1a89f6AF888035C8e2512F3701C9f7B478ec4A4c ) - ETH 0.008
0x1a89f6af888035c8e2512f3701c9f7b478ec4a4c.CALL( ) -
AbsDAO.getHolderPieAt( i=3 ) => ( 8 ) -
AbsDAO.getHolder( i=3 ) => ( 0x38b13eC169f30518eD220C72E70a306EDBEA96d3 ) - ETH 0.008
0x38b13ec169f30518ed220c72e70a306edbea96d3.CALL( ) - ETH 0.9
0xc04c4c118d9fa554e19af2c1dfa5427d6c40926f.CALL( ) - ETH 0.35
0x9dc56c606938cd32267ec9e81ef92325e99cb692.CALL( )
File 1 of 2: Absolutus
File 2 of 2: AbsDAO
/**
* Absolutus smart contract by BioHazzardt
*/
pragma solidity ^0.5.7;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a * b;
require(a == 0 || c / a == b, 'Invalid values');
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a / b;
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, 'Substraction result smaller than zero');
return a - b;
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, 'Invalid values');
return c;
}
}
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
contract Ownable {
address public owner;
address public manager;
address public ownerWallet;
address public adminWallet;
uint adminPersent;
constructor() public {
owner = msg.sender;
manager = msg.sender;
adminWallet = 0xcFebf7C3Ec7B407DFf17aa20a2631c95c8ff508c;
ownerWallet = 0xcFebf7C3Ec7B407DFf17aa20a2631c95c8ff508c;
adminPersent = 10;
}
modifier onlyOwner() {
require(msg.sender == owner, "only for owner");
_;
}
modifier onlyOwnerOrManager() {
require((msg.sender == owner)||(msg.sender == manager), "only for owner or manager");
_;
}
function transferOwnership(address newOwner) public onlyOwner {
owner = newOwner;
}
function setManager(address _manager) public onlyOwnerOrManager {
manager = _manager;
}
function setAdminWallet(address _admin) public onlyOwner {
adminWallet = _admin;
}
}
contract WalletOnly {
function isContract(address account) internal view returns (bool) {
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
// for accounts without code, i.e. `keccak256('')`
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line no-inline-assembly
assembly { codehash := extcodehash(account) }
return (codehash != accountHash && codehash != 0x0);
}
}
contract Absolutus is Ownable, WalletOnly {
// Events
event RegLevelEvent(address indexed _user, address indexed _referrer, uint _id, uint _time);
event BuyLevelEvent(address indexed _user, uint _level, uint _time);
event ProlongateLevelEvent(address indexed _user, uint _level, uint _time);
event GetMoneyForLevelEvent(address indexed _user, address indexed _referral, uint _level, uint _time, uint _price, bool _prevLost);
event LostMoneyForLevelEvent(address indexed _user, address indexed _referral, uint _level, uint _time, uint _price, bool _prevLost);
// New events
event PaymentForHolder(address indexed _addr, uint _index, uint _value);
event PaymentForHolderLost(address indexed _addr, uint _index, uint _value);
// Common values
mapping (uint => uint) public LEVEL_PRICE;
address canSetLevelPrice;
uint REFERRER_1_LEVEL_LIMIT = 3;
uint PERIOD_LENGTH = 365 days; // uncomment before production
uint MAX_AUTOPAY_COUNT = 5; // Automatic level buying limit per one transaction (to prevent gas limit reaching)
struct UserStruct {
bool isExist;
uint id;
uint referrerID;
uint fund; // Fund for the automatic level pushcase
uint currentLvl; // Current user's level
address[] referral;
mapping (uint => uint) levelExpired;
mapping (uint => uint) paymentsCount;
}
mapping (address => UserStruct) public users;
mapping (uint => address) public userList;
mapping (address => uint) public allowUsers;
uint public currUserID = 0;
bool nostarted = false;
AbsDAO _dao; // DAO contract
bool daoSet = false; // if true payment processed for DAO holders
using SafeMath for uint; // <== do not forget about this
constructor() public {
// Prices in ETH: production
LEVEL_PRICE[1] = 0.5 ether;
LEVEL_PRICE[2] = 1.0 ether;
LEVEL_PRICE[3] = 2.0 ether;
LEVEL_PRICE[4] = 4.0 ether;
LEVEL_PRICE[5] = 16.0 ether;
LEVEL_PRICE[6] = 32.0 ether;
LEVEL_PRICE[7] = 64.0 ether;
LEVEL_PRICE[8] = 128.0 ether;
UserStruct memory userStruct;
currUserID++;
canSetLevelPrice = owner;
// Create root user
userStruct = UserStruct({
isExist : true,
id : currUserID,
referrerID : 0,
fund: 0,
currentLvl: 1,
referral : new address[](0)
});
users[ownerWallet] = userStruct;
userList[currUserID] = ownerWallet;
users[ownerWallet].levelExpired[1] = 77777777777;
users[ownerWallet].levelExpired[2] = 77777777777;
users[ownerWallet].levelExpired[3] = 77777777777;
users[ownerWallet].levelExpired[4] = 77777777777;
users[ownerWallet].levelExpired[5] = 77777777777;
users[ownerWallet].levelExpired[6] = 77777777777;
users[ownerWallet].levelExpired[7] = 77777777777;
users[ownerWallet].levelExpired[8] = 77777777777;
// Set inviting registration only
nostarted = true;
}
function () external payable {
require(!isContract(msg.sender), 'This contract cannot support payments from other contracts');
uint level;
// Check for payment with level price
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 if (msg.value == LEVEL_PRICE[7]) {
level = 7;
} else if (msg.value == LEVEL_PRICE[8]) {
level = 8;
} else {
// Pay to user's fund
if (!users[msg.sender].isExist || users[msg.sender].currentLvl >= 8)
revert('Incorrect Value send');
users[msg.sender].fund += msg.value;
updateCurrentLevel(msg.sender);
// if the referer is have funds for autobuy next level
if (LEVEL_PRICE[users[msg.sender].currentLvl+1] <= users[msg.sender].fund) {
buyLevelByFund(msg.sender, 0);
}
return;
}
// Buy level or register user
if (users[msg.sender].isExist) {
buyLevel(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');
// refId = 1;
}
regUser(refId);
} else {
revert("Please buy first level for 0.1 ETH");
}
}
// allow user in invite mode
function allowUser(address _user) public onlyOwner {
require(nostarted, 'You cant allow user in battle mode');
allowUsers[_user] = 1;
}
// disable inviting
function battleMode() public onlyOwner {
require(nostarted, 'Battle mode activated');
nostarted = false;
}
// this function sets the DAO contract address
function setDAOAddress(address payable _dao_addr) public onlyOwner {
require(!daoSet, 'DAO address already set');
_dao = AbsDAO(_dao_addr);
daoSet = true;
}
// process payment to administrator wallet
// or DAO holders
function payToAdmin(uint _amount) internal {
if (daoSet) {
// Pay for DAO
uint holderCount = _dao.getHolderCount(); // get the DAO holders count
for (uint i = 1; i <= holderCount; i++) {
uint val = _dao.getHolderPieAt(i); // get pie of holder with index == i
address payable holder = _dao.getHolder(i); // get the holder address
if (val > 0) { // check of the holder pie value
uint payValue = _amount.div(100).mul(val); // calculate amount for pay to the holder
holder.transfer(payValue);
emit PaymentForHolder(holder, i, payValue); // payment ok
} else {
emit PaymentForHolderLost(holder, i, val); // holder's pie value is zero
}
}
} else {
// pay to admin wallet
address(uint160(adminWallet)).transfer(_amount);
}
}
// user registration
function regUser(uint referrerID) public payable {
require(!isContract(msg.sender), 'This contract cannot support payments from other contracts');
if (nostarted) {
require(allowUsers[msg.sender] > 0, 'You cannot use this contract on start');
}
require(!users[msg.sender].isExist, 'User exist');
require(referrerID > 0 && referrerID <= currUserID, 'Incorrect referrer Id');
require(msg.value==LEVEL_PRICE[1], 'Incorrect Value');
// NOTE: use one more variable to prevent 'Security/No-assign-param' error (for vscode-solidity extension).
// Need to check the gas consumtion with it
uint _referrerID = referrerID;
if (users[userList[referrerID]].referral.length >= REFERRER_1_LEVEL_LIMIT) {
_referrerID = users[findFreeReferrer(userList[referrerID])].id;
}
UserStruct memory userStruct;
currUserID++;
// add user to list
userStruct = UserStruct({
isExist : true,
id : currUserID,
referrerID : _referrerID,
fund: 0,
currentLvl: 1,
referral : new address[](0)
});
users[msg.sender] = userStruct;
userList[currUserID] = msg.sender;
users[msg.sender].levelExpired[1] = now + PERIOD_LENGTH;
users[msg.sender].levelExpired[2] = 0;
users[msg.sender].levelExpired[3] = 0;
users[msg.sender].levelExpired[4] = 0;
users[msg.sender].levelExpired[5] = 0;
users[msg.sender].levelExpired[6] = 0;
users[msg.sender].levelExpired[7] = 0;
users[msg.sender].levelExpired[8] = 0;
users[userList[_referrerID]].referral.push(msg.sender);
// pay for referer
payForLevel(
1,
msg.sender,
msg.sender,
0,
false
);
emit RegLevelEvent(
msg.sender,
userList[_referrerID],
currUserID,
now
);
}
// buy level function
function buyLevel(uint _level) public payable {
require(!isContract(msg.sender), 'This contract cannot support payments from other contracts');
require(users[msg.sender].isExist, 'User not exist');
require(_level>0 && _level<=8, 'Incorrect level');
require(msg.value==LEVEL_PRICE[_level], 'Incorrect Value');
if (_level > 1) { // Replace for condition (_level == 1) on top (done)
for (uint i = _level-1; i>0; i--) {
require(users[msg.sender].levelExpired[i] >= now, 'Buy the previous level');
}
}
// if(users[msg.sender].levelExpired[_level] == 0){ <-- BUG
// if the level expired in the future, need add PERIOD_LENGTH to the level expiration time,
// or set the level expiration time to 'now + PERIOD_LENGTH' in other cases.
if (users[msg.sender].levelExpired[_level] > now) {
users[msg.sender].levelExpired[_level] += PERIOD_LENGTH;
} else {
users[msg.sender].levelExpired[_level] = now + PERIOD_LENGTH;
}
// Set user's current level
if (users[msg.sender].currentLvl < _level)
users[msg.sender].currentLvl = _level;
// provide payment for the user's referer
payForLevel(
_level,
msg.sender,
msg.sender,
0,
false
);
emit BuyLevelEvent(msg.sender, _level, now);
}
function setLevelPrice(uint _level, uint _price) public {
require(_level >= 0 && _level <= 8, 'Invalid level');
require(msg.sender == canSetLevelPrice, 'Invalid caller');
require(_price > 0, 'Price cannot be zero or negative');
LEVEL_PRICE[_level] = _price * 1.0 finney;
}
function setCanUpdateLevelPrice(address addr) public onlyOwner {
canSetLevelPrice = addr;
}
// for interactive correction of the limitations
function setMaxAutopayForLevelCount(uint _count) public onlyOwnerOrManager {
MAX_AUTOPAY_COUNT = _count;
}
// buyLevelByFund provides automatic payment for next level for user
function buyLevelByFund(address referer, uint _counter) internal {
require(users[referer].isExist, 'User not exists');
uint _level = users[referer].currentLvl + 1; // calculate a next level
require(users[referer].fund >= LEVEL_PRICE[_level], 'Not have funds to autobuy level');
uint remaining = users[referer].fund - LEVEL_PRICE[_level]; // Amount for pay to the referer
// extend the level's expiration time
if (users[referer].levelExpired[_level] >= now) {
users[referer].levelExpired[_level] += PERIOD_LENGTH;
} else {
users[referer].levelExpired[_level] = now + PERIOD_LENGTH;
}
users[referer].currentLvl = _level; // set current level for referer
users[referer].fund = 0; // clear the referer's fund
// process payment for next referer with increment autopay counter
payForLevel(
_level,
referer,
referer,
_counter+1,
false
);
address(uint160(referer)).transfer(remaining); // send the remaining amount to referer
emit BuyLevelEvent(referer, _level, now); // emit the buy level event for referer
}
// updateCurrentLevel calculate 'currentLvl' value for given user
function updateCurrentLevel(address _user) internal {
users[_user].currentLvl = actualLevel(_user);
}
// helper function
function actualLevel(address _user) public view returns(uint) {
require(users[_user].isExist, 'User not found');
for (uint i = 1; i <= 8; i++) {
if (users[_user].levelExpired[i] <= now) {
return i-1;
}
}
return 8;
}
// payForLevel provides payment processing for user's referer and automatic buying referer's next
// level.
function payForLevel(uint _level, address _user, address _sender, uint _autoPayCtr, bool prevLost) internal {
address referer;
address referer1;
address referer2;
address referer3;
if (_level == 1 || _level == 5) {
referer = userList[users[_user].referrerID];
} else if (_level == 2 || _level == 6) {
referer1 = userList[users[_user].referrerID];
referer = userList[users[referer1].referrerID];
} else if (_level == 3 || _level == 7) {
referer1 = userList[users[_user].referrerID];
referer2 = userList[users[referer1].referrerID];
referer = userList[users[referer2].referrerID];
} else if (_level == 4 || _level == 8) {
referer1 = userList[users[_user].referrerID];
referer2 = userList[users[referer1].referrerID];
referer3 = userList[users[referer2].referrerID];
referer = userList[users[referer3].referrerID];
}
if (!users[referer].isExist) {
referer = userList[1];
}
uint amountToUser;
uint amountToAdmin;
amountToAdmin = LEVEL_PRICE[_level] / 100 * adminPersent;
amountToUser = LEVEL_PRICE[_level] - amountToAdmin;
if (users[referer].id <= 4) {
payToAdmin(LEVEL_PRICE[_level]);
emit GetMoneyForLevelEvent(
referer,
_sender,
_level,
now,
amountToUser,
prevLost
);
return;
}
if (users[referer].levelExpired[_level] >= now) {
payToAdmin(amountToAdmin);
// update current referer's level
updateCurrentLevel(referer);
// check for the user has right level and automatic payment counter
// smaller than the 'MAX_AUTOPAY_COUNT' value
if (_level == users[referer].currentLvl && _autoPayCtr < MAX_AUTOPAY_COUNT && users[referer].currentLvl < 8) {
users[referer].fund += amountToUser;
emit GetMoneyForLevelEvent(
referer,
_sender,
_level,
now,
amountToUser,
prevLost
);
// if the referer is have funds for autobuy next level
if (LEVEL_PRICE[users[referer].currentLvl+1] <= users[referer].fund) {
buyLevelByFund(referer, _autoPayCtr);
}
} else {
// send the ethers to referer
address(uint160(referer)).transfer(amountToUser);
emit GetMoneyForLevelEvent(
referer,
_sender,
_level,
now,
amountToUser,
prevLost
);
}
} else {
// pay for the referer's referer
emit LostMoneyForLevelEvent(
referer,
_sender,
_level,
now,
amountToUser,
prevLost
);
payForLevel(
_level,
referer,
_sender,
_autoPayCtr,
true
);
}
}
function findFreeReferrer(address _user) public view returns(address) {
if (users[_user].referral.length < REFERRER_1_LEVEL_LIMIT) {
return _user;
}
address[] memory referrals = new address[](363);
referrals[0] = users[_user].referral[0];
referrals[1] = users[_user].referral[1];
referrals[2] = users[_user].referral[2];
address freeReferrer;
bool noFreeReferrer = true;
for (uint i = 0; i<363; i++) {
if (users[referrals[i]].referral.length == REFERRER_1_LEVEL_LIMIT) {
if (i<120) {
referrals[(i+1)*3] = users[referrals[i]].referral[0];
referrals[(i+1)*3+1] = users[referrals[i]].referral[1];
referrals[(i+1)*3+2] = users[referrals[i]].referral[2];
}
} else {
noFreeReferrer = false;
freeReferrer = referrals[i];
break;
}
}
require(!noFreeReferrer, 'No Free Referrer');
return freeReferrer;
}
function viewUserReferral(address _user) public view returns(address[] memory) {
return users[_user].referral;
}
function viewUserLevelExpired(address _user, uint _level) public view returns(uint) {
return users[_user].levelExpired[_level];
}
function bytesToAddress(bytes memory bys) private pure returns (address addr ) {
assembly {
addr := mload(add(bys, 20))
}
}
}
contract AbsDAO is Ownable, WalletOnly {
// events
event TransferPie(address indexed _from, address indexed _to, uint _value);
event NewHolder(address indexed _addr, uint _index);
event HolderChanged(address indexed _from, address indexed _to, uint _index);
event PaymentReceived(address indexed _from, uint _value);
event PaymentForHolder(address indexed _addr, uint _index, uint _value);
event PaymentForHolderLost(address indexed _addr, uint _index, uint _value);
struct Holder {
bool isExist;
uint id;
uint value;
address payable addr;
}
mapping(address => Holder) public holders;
mapping(uint=>address payable) holderAddrs;
uint holderCount;
uint _initialPie = 100;
using SafeMath for uint;
constructor() public {
// creating root hoder
holderCount = 1;
holders[msg.sender] = Holder({
isExist: true,
id: 1,
value: _initialPie,
addr: msg.sender
});
holderAddrs[1] = msg.sender;
}
function () external payable {
require(!isContract(msg.sender), 'This contract cannot support payments from other contracts');
emit PaymentReceived(msg.sender, msg.value);
for (uint i = 1; i <= holderCount; i++) {
if (holders[holderAddrs[i]].value > 0) {
uint payValue = msg.value.div(100).mul(holders[holderAddrs[i]].value);
holderAddrs[i].transfer(payValue);
emit PaymentForHolder(holderAddrs[i], i, payValue);
} else {
emit PaymentForHolderLost(holderAddrs[i], i, holders[holderAddrs[i]].value);
}
}
}
function getHolderPieAt(uint i) public view returns(uint) {
return holders[holderAddrs[i]].value;
}
function getHolder(uint i) public view returns(address payable) {
return holderAddrs[i];
}
function getHolderCount() public view returns(uint) {
return holderCount;
}
function transferPie(uint _amount, address payable _to) public {
require(holders[msg.sender].isExist, 'Holder not found');
require(_amount > 0 && _amount <= holders[msg.sender].value, 'Invalid amount');
if (_amount == holders[msg.sender].value) {
uint id = holders[msg.sender].id;
delete holders[msg.sender];
holders[_to] = Holder({
isExist: true,
id: id,
value: _amount,
addr: _to
});
holderAddrs[id] = _to;
emit HolderChanged(msg.sender, _to, id);
} else {
if (holders[_to].isExist) {
holders[msg.sender].value -= _amount;
holders[_to].value += _amount;
} else if (holderCount < 20) {
holderCount += 1;
holders[msg.sender].value -= _amount;
holders[_to] = Holder({
isExist: true,
id: holderCount,
value: _amount,
addr: _to
});
holderAddrs[holderCount] = _to;
emit NewHolder(_to, holderCount);
} else {
revert('Holder limit excised');
}
}
emit TransferPie(msg.sender, _to, _amount);
}
}File 2 of 2: AbsDAO
/*
❤ https://cryptohands.org - first open MLM smart-contract without comission
❤ https://doubleway.io - high-income binary matrix from the creators of CryptoHands
____0000000000______0000000000_____
__000________000__000________000___
_000___________0000___________000__
000_____________00_____________000_
000____________________________000_
000____________________________000_
_000________CRYPTOHANDS_______000__
__000________DOUBLEWAY_______000___
___000_____________________000____
_____000__________________000______
_______000______________000________
_________000__________000__________
____________000____000_____________
______________000000_______________
________________00_________________
*/
pragma solidity ^0.5.7;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a * b;
require(a == 0 || c / a == b, 'Invalid values');
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a / b;
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, 'Substraction result smaller than zero');
return a - b;
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, 'Invalid values');
return c;
}
}
contract Ownable {
address public owner;
address public manager;
address public ownerWallet;
address public adminWallet;
uint adminPersent;
constructor() public {
owner = msg.sender;
manager = msg.sender;
adminWallet = 0xcFebf7C3Ec7B407DFf17aa20a2631c95c8ff508c;
ownerWallet = 0xcFebf7C3Ec7B407DFf17aa20a2631c95c8ff508c;
adminPersent = 10;
}
modifier onlyOwner() {
require(msg.sender == owner, "only for owner");
_;
}
modifier onlyOwnerOrManager() {
require((msg.sender == owner)||(msg.sender == manager), "only for owner or manager");
_;
}
function transferOwnership(address newOwner) public onlyOwner {
owner = newOwner;
}
function setManager(address _manager) public onlyOwnerOrManager {
manager = _manager;
}
function setAdminWallet(address _admin) public onlyOwner {
adminWallet = _admin;
}
}
contract WalletOnly {
function isContract(address account) internal view returns (bool) {
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
// for accounts without code, i.e. `keccak256('')`
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line no-inline-assembly
assembly { codehash := extcodehash(account) }
return (codehash != accountHash && codehash != 0x0);
}
}
contract AbsDAO is Ownable, WalletOnly {
// events
event TransferPie(address indexed _from, address indexed _to, uint _value);
event NewHolder(address indexed _addr, uint _index);
event HolderChanged(address indexed _from, address indexed _to, uint _index);
event PaymentReceived(address indexed _from, uint _value);
event PaymentForHolder(address indexed _addr, uint _index, uint _value);
event PaymentForHolderLost(address indexed _addr, uint _index, uint _value);
struct Holder {
bool isExist;
uint id;
uint value;
address payable addr;
}
mapping(address => Holder) public holders;
mapping(uint=>address payable) holderAddrs;
uint holderCount;
uint _initialPie = 100;
using SafeMath for uint;
constructor() public {
// creating root hoder
holderCount = 1;
holders[msg.sender] = Holder({
isExist: true,
id: 1,
value: _initialPie,
addr: msg.sender
});
holderAddrs[1] = msg.sender;
}
function () external payable {
require(!isContract(msg.sender), 'This contract cannot support payments from other contracts');
emit PaymentReceived(msg.sender, msg.value);
for (uint i = 1; i <= holderCount; i++) {
if (holders[holderAddrs[i]].value > 0) {
uint payValue = msg.value.div(100).mul(holders[holderAddrs[i]].value);
holderAddrs[i].transfer(payValue);
emit PaymentForHolder(holderAddrs[i], i, payValue);
} else {
emit PaymentForHolderLost(holderAddrs[i], i, holders[holderAddrs[i]].value);
}
}
}
function getHolderPieAt(uint i) public view returns(uint) {
return holders[holderAddrs[i]].value;
}
function getHolder(uint i) public view returns(address payable) {
return holderAddrs[i];
}
function getHolderCount() public view returns(uint) {
return holderCount;
}
function transferPie(uint _amount, address payable _to) public {
require(holders[msg.sender].isExist, 'Holder not found');
require(_amount > 0 && _amount <= holders[msg.sender].value, 'Invalid amount');
if (_amount == holders[msg.sender].value) {
uint id = holders[msg.sender].id;
delete holders[msg.sender];
holders[_to] = Holder({
isExist: true,
id: id,
value: _amount,
addr: _to
});
holderAddrs[id] = _to;
emit HolderChanged(msg.sender, _to, id);
} else {
if (holders[_to].isExist) {
holders[msg.sender].value -= _amount;
holders[_to].value += _amount;
} else if (holderCount < 20) {
holderCount += 1;
holders[msg.sender].value -= _amount;
holders[_to] = Holder({
isExist: true,
id: holderCount,
value: _amount,
addr: _to
});
holderAddrs[holderCount] = _to;
emit NewHolder(_to, holderCount);
} else {
revert('Holder limit excised');
}
}
emit TransferPie(msg.sender, _to, _amount);
}
}