Transaction Hash:
Block:
8828360 at Oct-28-2019 02:25:07 PM +UTC
Transaction Fee:
0.000814059 ETH
$1.70
Gas Used:
180,902 Gas / 4.5 Gwei
Emitted Events:
| 163 |
DABANKING.Transfer( from=[Sender] 0x706ec639892280d36916b119ca11e06c474e0853, to=[Receiver] 0x81e09530176ea2a2ce9ef6e5073679c085bdcece, value=20000000000000000000 )
|
| 164 |
DABANKING.Approval( owner=[Sender] 0x706ec639892280d36916b119ca11e06c474e0853, spender=[Receiver] 0x81e09530176ea2a2ce9ef6e5073679c085bdcece, value=99997880000000000000000000 )
|
| 165 |
DABANKING.Transfer( from=[Receiver] 0x81e09530176ea2a2ce9ef6e5073679c085bdcece, to=0xE81b7e9611936547d18540FbE4e53b104EcC44d0, value=275800000000000000 )
|
| 166 |
DABANKING.Transfer( from=[Receiver] 0x81e09530176ea2a2ce9ef6e5073679c085bdcece, to=Burn, value=315200000000000000 )
|
| 167 |
0xe81b7e9611936547d18540fbe4e53b104ecc44d0.0x3f4bf951e672984be04efab55a20b42d23bebd023eddb58688af3ebc0b4e709b( 0x3f4bf951e672984be04efab55a20b42d23bebd023eddb58688af3ebc0b4e709b, 0x0000000000000000000000000000000000000000000000000000000000000003, 000000000000000000000000706ec639892280d36916b119ca11e06c474e0853, 000000000000000000000000000000000000000000000000000000000000240a, 0000000000000000000000000000000000000000000000000000000000000080, 0000000000000000000000000000000000000000000000000000000000000001, 000000000000000000000000000000000000000000000000000000000000000b, 6c75636b794e756d626572000000000000000000000000000000000000000000 )
|
| 168 |
DABANKING.Transfer( from=[Receiver] 0x81e09530176ea2a2ce9ef6e5073679c085bdcece, to=[Sender] 0x706ec639892280d36916b119ca11e06c474e0853, value=38809000000000000000 )
|
| 169 |
0x81e09530176ea2a2ce9ef6e5073679c085bdcece.0xe260bb0cdf58af341d75a45558e03a7d5ed5b9d61f99704337af3c9b2a0a0e39( 0xe260bb0cdf58af341d75a45558e03a7d5ed5b9d61f99704337af3c9b2a0a0e39, 0x000000000000000000000000706ec639892280d36916b119ca11e06c474e0853, 0x000000000000000000000000000000000000000000000001158e460913d00000, 0x0000000000000000000000000000000000000000000000000000000000000032, 0000000000000000000000000000000000000000000000000000000000000001, 0000000000000000000000000000000000000000000000000000000000000032, 0000000000000000000000000000000000000000000000000000000000000031, 0000000000000000000000000000000000000000000000010930ce4194f08000, 0000000000000000000000000000000000000000000000021a9543e190228000 )
|
Account State Difference:
| Address | Before | After | State Difference | ||
|---|---|---|---|---|---|
|
0x5A0b54D5...D3E029c4c
Miner
| (Spark Pool) | 72.963540613998622977 Eth | 72.964354672998622977 Eth | 0.000814059 | |
| 0x5E7Ebea6...14f1d0aae | |||||
| 0x706Ec639...C474e0853 |
0.036115445848035674 Eth
Nonce: 194
|
0.035301386848035674 Eth
Nonce: 195
| 0.000814059 | ||
| 0x81E09530...085bDcEcE | |||||
| 0xE81b7e96...04EcC44d0 |
Execution Trace
0x81e09530176ea2a2ce9ef6e5073679c085bdcece.40e800d8( )
-
DABANKING.allowance( owner=0x706Ec639892280d36916b119CA11E06C474e0853, spender=0x81E09530176eA2A2CE9Ef6e5073679C085bDcEcE ) => ( 99997900000000000000000000 )
-
DABANKING.transferFrom( from=0x706Ec639892280d36916b119CA11E06C474e0853, to=0x81E09530176eA2A2CE9Ef6e5073679C085bDcEcE, value=20000000000000000000 ) => ( True )
-
DABANKING.transfer( to=0xE81b7e9611936547d18540FbE4e53b104EcC44d0, value=275800000000000000 ) => ( True )
-
DABANKING.transfer( to=0xf0342819aD53288c92665658A0f39AFEc4Ba6000, value=315200000000000000 ) => ( True )
-
0xe81b7e9611936547d18540fbe4e53b104ecc44d0.7d8fe32e( ) -
DABANKING.transfer( to=0x706Ec639892280d36916b119CA11E06C474e0853, value=38809000000000000000 ) => ( True )
-
Citizen.isCitizen( _investor=0xb04bC64dD365597C5b658d809DD0ea2Ae878fBED ) => ( True )
File 1 of 3: DABANKING
File 2 of 3: Burn
File 3 of 3: Citizen
pragma solidity 0.4.25;
/**
* @title ERC20 interface
* @dev see https://eips.ethereum.org/EIPS/eip-20
*/
contract IERC20 {
function transfer(address to, uint256 value) public returns (bool);
function approve(address spender, uint256 value) public returns (bool);
function transferFrom(address from, address to, uint256 value) public returns (bool);
function balanceOf(address who) public view returns (uint256);
function allowance(address owner, address spender) public view returns (uint256);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
/**
* @title SafeMath
* @dev Unsigned math operations with safety checks that revert on error.
*/
library SafeMath {
/**
* @dev Multiplies two unsigned integers, reverts on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b);
return c;
}
/**
* @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
uint256 c = a - b;
return c;
}
/**
* @dev Adds two unsigned integers, reverts on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a);
return c;
}
/**
* @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0);
return a % b;
}
}
/**
* @title Standard ERC20 token
*
* @dev Implementation of the basic standard token.
* https://eips.ethereum.org/EIPS/eip-20
* Originally based on code by FirstBlood:
* https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
*
* This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for
* all accounts just by listening to said events. Note that this isn't required by the specification, and other
* compliant implementations may not do it.
*/
contract ERC20 is IERC20 {
using SafeMath for uint256;
mapping (address => uint256) internal _balances;
mapping (address => mapping (address => uint256)) private _allowed;
/**
* @dev Gets the balance of the specified address.
* @param owner The address to query the balance of.
* @return A uint256 representing the amount owned by the passed adfunction transferdress.
*/
function balanceOf(address owner) public view returns (uint256) {
return _balances[owner];
}
/**
* @dev Function to check the amount of tokens that an owner allowed to a spender.
* @param owner address The address which owns the funds.
* @param spender address The address which will spend the funds.
* @return A uint256 specifying the amount of tokens still available for the spender.
*/
function allowance(address owner, address spender) public view returns (uint256) {
return _allowed[owner][spender];
}
/**
* @dev Transfer token to a specified address.
* @param to The address to transfer to.
* @param value The amount to be transferred.
*/
function transfer(address to, uint256 value) public returns (bool) {
_transfer(msg.sender, to, value);
return true;
}
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
*/
function approve(address spender, uint256 value) public returns (bool) {
_approve(msg.sender, spender, value);
return true;
}
/**
* @dev Transfer tokens from one address to another.
* Note that while this function emits an Approval event, this is not required as per the specification,
* and other compliant implementations may not emit the event.
* @param from address The address which you want to send tokens from
* @param to address The address which you want to transfer to
* @param value uint256 the amount of tokens to be transferred
*/
function transferFrom(address from, address to, uint256 value) public returns (bool) {
_transfer(from, to, value);
_approve(from, msg.sender, _allowed[from][msg.sender].sub(value));
return true;
}
/**
* @dev Increase the amount of tokens that an owner allowed to a spender.
* approve should be called when _allowed[msg.sender][spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* Emits an Approval event.
* @param spender The address which will spend the funds.
* @param addedValue The amount of tokens to increase the allowance by.
*/
function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
_approve(msg.sender, spender, _allowed[msg.sender][spender].add(addedValue));
return true;
}
/**
* @dev Decrease the amount of tokens that an owner allowed to a spender.
* approve should be called when _allowed[msg.sender][spender] == 0. To decrement
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* Emits an Approval event.
* @param spender The address which will spend the funds.
* @param subtractedValue The amount of tokens to decrease the allowance by.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
_approve(msg.sender, spender, _allowed[msg.sender][spender].sub(subtractedValue));
return true;
}
/**
* @dev Transfer token for a specified addresses.
* @param from The address to transfer from.
* @param to The address to transfer to.
* @param value The amount to be transferred.
*/
function _transfer(address from, address to, uint256 value) internal {
require(to != address(0));
_balances[from] = _balances[from].sub(value);
_balances[to] = _balances[to].add(value);
emit Transfer(from, to, value);
}
/**
* @dev Approve an address to spend another addresses' tokens.
* @param owner The address that owns the tokens.
* @param spender The address that will spend the tokens.
* @param value The number of tokens that can be spent.
*/
function _approve(address owner, address spender, uint256 value) internal {
require(spender != address(0));
require(owner != address(0));
_allowed[owner][spender] = value;
emit Approval(owner, spender, value);
}
}
contract DABANKING is ERC20 {
string public constant name = 'DABANKING';
string public constant symbol = 'DAB';
uint8 public constant decimals = 18;
uint256 public constant totalSupply = (200 * 1e6) * (10 ** uint256(decimals));
constructor(address _daBank) public {
_balances[_daBank] = totalSupply;
emit Transfer(address(0x0), _daBank, totalSupply);
}
}File 2 of 3: Burn
pragma solidity 0.4.25;
contract Burn {
// This contract does nothing, it was built for burning token purpose
// Sending any ETH or ERC20 token to this contract will make them stay here forever. Like 0x0 address
}File 3 of 3: Citizen
pragma solidity 0.4.25;
/**
* @title SafeMath
* @dev Unsigned math operations with safety checks that revert on error.
*/
library SafeMath {
/**
* @dev Multiplies two unsigned integers, reverts on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath mul error");
return c;
}
/**
* @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, "SafeMath div error");
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath sub error");
uint256 c = a - b;
return c;
}
/**
* @dev Adds two unsigned integers, reverts on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath add error");
return c;
}
/**
* @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0, "SafeMath mod error");
return a % b;
}
}
library UnitConverter {
using SafeMath for uint256;
function stringToBytes24(string memory source)
internal
pure
returns (bytes24 result)
{
bytes memory tempEmptyStringTest = bytes(source);
if (tempEmptyStringTest.length == 0) {
return 0x0;
}
assembly {
result := mload(add(source, 24))
}
}
}
library StringUtil {
struct slice {
uint _length;
uint _pointer;
}
function validateUserName(string memory _username)
internal
pure
returns (bool)
{
uint8 len = uint8(bytes(_username).length);
if ((len < 4) || (len > 18)) return false;
// only contain A-Z 0-9
for (uint8 i = 0; i < len; i++) {
if (
(uint8(bytes(_username)[i]) < 48) ||
(uint8(bytes(_username)[i]) > 57 && uint8(bytes(_username)[i]) < 65) ||
(uint8(bytes(_username)[i]) > 90)
) return false;
}
// First char != '0'
return uint8(bytes(_username)[0]) != 48;
}
}
contract Auth {
address internal mainAdmin;
address internal contractAdmin;
address internal profitAdmin;
address internal ethAdmin;
address internal LAdmin;
address internal maxSAdmin;
address internal backupAdmin;
address internal commissionAdmin;
event OwnershipTransferred(address indexed _previousOwner, address indexed _newOwner);
constructor(
address _mainAdmin,
address _contractAdmin,
address _profitAdmin,
address _ethAdmin,
address _LAdmin,
address _maxSAdmin,
address _backupAdmin,
address _commissionAdmin
)
internal
{
mainAdmin = _mainAdmin;
contractAdmin = _contractAdmin;
profitAdmin = _profitAdmin;
ethAdmin = _ethAdmin;
LAdmin = _LAdmin;
maxSAdmin = _maxSAdmin;
backupAdmin = _backupAdmin;
commissionAdmin = _commissionAdmin;
}
modifier onlyMainAdmin() {
require(isMainAdmin(), "onlyMainAdmin");
_;
}
modifier onlyContractAdmin() {
require(isContractAdmin() || isMainAdmin(), "onlyContractAdmin");
_;
}
modifier onlyProfitAdmin() {
require(isProfitAdmin() || isMainAdmin(), "onlyProfitAdmin");
_;
}
modifier onlyEthAdmin() {
require(isEthAdmin() || isMainAdmin(), "onlyEthAdmin");
_;
}
modifier onlyLAdmin() {
require(isLAdmin() || isMainAdmin(), "onlyLAdmin");
_;
}
modifier onlyMaxSAdmin() {
require(isMaxSAdmin() || isMainAdmin(), "onlyMaxSAdmin");
_;
}
modifier onlyBackupAdmin() {
require(isBackupAdmin() || isMainAdmin(), "onlyBackupAdmin");
_;
}
modifier onlyBackupAdmin2() {
require(isBackupAdmin(), "onlyBackupAdmin");
_;
}
function isMainAdmin() public view returns (bool) {
return msg.sender == mainAdmin;
}
function isContractAdmin() public view returns (bool) {
return msg.sender == contractAdmin;
}
function isProfitAdmin() public view returns (bool) {
return msg.sender == profitAdmin;
}
function isEthAdmin() public view returns (bool) {
return msg.sender == ethAdmin;
}
function isLAdmin() public view returns (bool) {
return msg.sender == LAdmin;
}
function isMaxSAdmin() public view returns (bool) {
return msg.sender == maxSAdmin;
}
function isBackupAdmin() public view returns (bool) {
return msg.sender == backupAdmin;
}
}
library ArrayUtil {
function tooLargestValues(uint[] array) internal pure returns (uint max, uint subMax) {
require(array.length >= 2, "Invalid array length");
max = array[0];
for (uint i = 1; i < array.length; i++) {
if (array[i] > max) {
subMax = max;
max = array[i];
} else if (array[i] > subMax) {
subMax = array[i];
}
}
}
}
interface IWallet {
function bonusForAdminWhenUserJoinPackageViaDollar(uint _amount, address _admin) external;
function bonusNewRank(address _investorAddress, uint _currentRank, uint _newRank) external;
function mineToken(address _from, uint _amount) external;
function deposit(address _to, uint _deposited, uint8 _source, uint _sourceAmount) external;
function getInvestorLastDeposited(address _investor) external view returns (uint);
function getUserWallet(address _investor) external view returns (uint, uint[], uint, uint, uint, uint, uint);
function getProfitBalance(address _investor) external view returns (uint);
function increaseETHWithdrew(uint _amount) external;
function validateCanMineToken(uint _tokenAmount, address _from) external view;
function ethWithdrew() external view returns (uint);
}
interface ICitizen {
function addF1DepositedToInviter(address _invitee, uint _amount) external;
function addNetworkDepositedToInviter(address _inviter, uint _amount, uint _source, uint _sourceAmount) external;
function checkInvestorsInTheSameReferralTree(address _inviter, address _invitee) external view returns (bool);
function getF1Deposited(address _investor) external view returns (uint);
function getId(address _investor) external view returns (uint);
function getInvestorCount() external view returns (uint);
function getInviter(address _investor) external view returns (address);
function getDirectlyInvitee(address _investor) external view returns (address[]);
function getDirectlyInviteeHaveJoinedPackage(address _investor) external view returns (address[]);
function getNetworkDeposited(address _investor) external view returns (uint);
function getRank(address _investor) external view returns (uint);
function getUserAddress(uint _index) external view returns (address);
function getSubscribers(address _investor) external view returns (uint);
function increaseInviterF1HaveJoinedPackage(address _invitee) external;
function isCitizen(address _user) view external returns (bool);
function register(address _user, string _userName, address _inviter) external returns (uint);
function showInvestorInfo(address _investorAddress) external view returns (uint, string memory, address, address[], uint, uint, uint, uint);
function getDepositInfo(address _investor) external view returns (uint, uint, uint, uint, uint);
function rankBonuses(uint _index) external view returns (uint);
}
contract Citizen is Auth {
using ArrayUtil for uint256[];
using StringUtil for string;
using UnitConverter for string;
using SafeMath for uint;
enum Rank {
UnRanked,
Star1,
Star2,
Star3,
Star4,
Star5,
Star6,
Star7,
Star8,
Star9,
Star10
}
enum DepositType {
Ether,
Token,
Dollar
}
uint[11] public rankCheckPoints = [
0,
1000000,
3000000,
10000000,
40000000,
100000000,
300000000,
1000000000,
2000000000,
5000000000,
10000000000
];
uint[11] public rankBonuses = [
0,
0,
0,
0,
1000000, // $1k
2000000,
6000000,
20000000,
50000000,
150000000,
500000000 // $500k
];
struct Investor {
uint id;
string userName;
address inviter;
address[] directlyInvitee;
address[] directlyInviteeHaveJoinedPackage;
uint f1Deposited;
uint networkDeposited;
uint networkDepositedViaETH;
uint networkDepositedViaToken;
uint networkDepositedViaDollar;
uint subscribers;
Rank rank;
}
address public reserveFund;
IWallet public wallet;
ICitizen public oldCitizen = ICitizen(0xd4051A078383d3fc279603c1273360Ac980CB394);
mapping (address => Investor) private investors;
mapping (bytes24 => address) private userNameAddresses;
address[] private userAddresses;
address private rootAccount = 0xa06Cd23aA37C39095D8CFe3A0fd2654331e63123;
mapping (address => bool) private ha;
modifier onlyWalletContract() {
require(msg.sender == address(wallet), "onlyWalletContract");
_;
}
modifier onlyReserveFundContract() {
require(msg.sender == address(reserveFund), "onlyReserveFundContract");
_;
}
event RankAchieved(address investor, uint currentRank, uint newRank);
constructor(
address _mainAdmin,
address _backupAdmin
)
Auth(
_mainAdmin,
msg.sender,
0x0,
0x0,
0x0,
0x0,
_backupAdmin,
0x0
)
public
{
setupRootAccount();
}
// ONLY-CONTRACT-ADMIN FUNCTIONS
function setW(address _walletContract) onlyContractAdmin public {
wallet = IWallet(_walletContract);
}
function setRF(address _reserveFundContract) onlyContractAdmin public {
reserveFund = _reserveFundContract;
}
function updateMainAdmin(address _newMainAdmin) onlyBackupAdmin public {
require(_newMainAdmin != address(0x0), "Invalid address");
mainAdmin = _newMainAdmin;
}
function updateContractAdmin(address _newContractAdmin) onlyMainAdmin public {
require(_newContractAdmin != address(0x0), "Invalid address");
contractAdmin = _newContractAdmin;
}
function updateBackupAdmin(address _newBackupAdmin) onlyBackupAdmin2 public {
require(_newBackupAdmin != address(0x0), "Invalid address");
backupAdmin = _newBackupAdmin;
}
function updateHA(address _address, bool _value) onlyMainAdmin public {
ha[_address] = _value;
}
function checkHA(address _address) onlyMainAdmin public view returns (bool) {
return ha[_address];
}
function syncData(address[] _investors) onlyContractAdmin public {
for (uint i = 0; i < _investors.length; i++) {
syncInvestorInfo(_investors[i]);
syncDepositInfo(_investors[i]);
}
}
// ONLY-RESERVE-FUND-CONTRACT FUNCTIONS
function register(address _user, string memory _userName, address _inviter)
onlyReserveFundContract
public
returns
(uint)
{
require(_userName.validateUserName(), "Invalid username");
Investor storage investor = investors[_user];
require(!isCitizen(_user), "Already an citizen");
bytes24 _userNameAsKey = _userName.stringToBytes24();
require(userNameAddresses[_userNameAsKey] == address(0x0), "Username already exist");
userNameAddresses[_userNameAsKey] = _user;
investor.id = userAddresses.length;
investor.userName = _userName;
investor.inviter = _inviter;
investor.rank = Rank.UnRanked;
increaseInvitersSubscribers(_inviter);
increaseInviterF1(_inviter, _user);
userAddresses.push(_user);
return investor.id;
}
function showInvestorInfo(address _investorAddress)
onlyReserveFundContract
public
view
returns (uint, string memory, address, address[], uint, uint, uint, Citizen.Rank)
{
Investor storage investor = investors[_investorAddress];
return (
investor.id,
investor.userName,
investor.inviter,
investor.directlyInvitee,
investor.f1Deposited,
investor.networkDeposited,
investor.subscribers,
investor.rank
);
}
// ONLY-WALLET-CONTRACT FUNCTIONS
function addF1DepositedToInviter(address _invitee, uint _amount)
onlyWalletContract
public
{
address inviter = investors[_invitee].inviter;
investors[inviter].f1Deposited = investors[inviter].f1Deposited.add(_amount);
}
function getInviter(address _investor)
onlyWalletContract
public
view
returns
(address)
{
return investors[_investor].inviter;
}
// _source: 0-eth 1-token 2-usdt
function addNetworkDepositedToInviter(address _inviter, uint _amount, uint _source, uint _sourceAmount)
onlyWalletContract
public
{
require(_inviter != address(0x0), "Invalid inviter address");
require(_amount >= 0, "Invalid deposit amount");
require(_source >= 0 && _source <= 2, "Invalid deposit source");
require(_sourceAmount >= 0, "Invalid source amount");
investors[_inviter].networkDeposited = investors[_inviter].networkDeposited.add(_amount);
if (_source == 0) {
investors[_inviter].networkDepositedViaETH = investors[_inviter].networkDepositedViaETH.add(_sourceAmount);
} else if (_source == 1) {
investors[_inviter].networkDepositedViaToken = investors[_inviter].networkDepositedViaToken.add(_sourceAmount);
} else {
investors[_inviter].networkDepositedViaDollar = investors[_inviter].networkDepositedViaDollar.add(_sourceAmount);
}
}
function increaseInviterF1HaveJoinedPackage(address _invitee)
public
onlyWalletContract
{
address _inviter = getInviter(_invitee);
investors[_inviter].directlyInviteeHaveJoinedPackage.push(_invitee);
}
// PUBLIC FUNCTIONS
function updateRanking() public {
Investor storage investor = investors[msg.sender];
Rank currentRank = investor.rank;
require(investor.directlyInviteeHaveJoinedPackage.length > 2, "Invalid condition to make ranking");
require(currentRank < Rank.Star10, "Congratulations! You have reached max rank");
uint investorRevenueToCheckRank = getInvestorRankingRevenue(msg.sender);
Rank newRank;
for(uint8 k = uint8(currentRank) + 1; k <= uint8(Rank.Star10); k++) {
if(investorRevenueToCheckRank >= rankCheckPoints[k]) {
newRank = getRankFromIndex(k);
}
}
if (newRank > currentRank) {
wallet.bonusNewRank(msg.sender, uint(currentRank), uint(newRank));
investor.rank = newRank;
emit RankAchieved(msg.sender, uint(currentRank), uint(newRank));
}
}
function getInvestorRankingRevenue(address _investor) public view returns (uint) {
require(msg.sender == address(this) || msg.sender == _investor, "You can't see other investor");
Investor storage investor = investors[_investor];
if (investor.directlyInviteeHaveJoinedPackage.length <= 2) {
return 0;
}
uint[] memory f1NetworkDeposited = new uint[](investor.directlyInviteeHaveJoinedPackage.length);
uint sumF1NetworkDeposited = 0;
for (uint j = 0; j < investor.directlyInviteeHaveJoinedPackage.length; j++) {
f1NetworkDeposited[j] = investors[investor.directlyInviteeHaveJoinedPackage[j]].networkDeposited;
sumF1NetworkDeposited = sumF1NetworkDeposited.add(f1NetworkDeposited[j]);
}
uint max;
uint subMax;
(max, subMax) = f1NetworkDeposited.tooLargestValues();
return sumF1NetworkDeposited.sub(max).sub(subMax);
}
function checkInvestorsInTheSameReferralTree(address _inviter, address _invitee)
public
view
returns (bool)
{
require(_inviter != _invitee, "They are the same");
bool inTheSameTreeDownLine = checkInTheSameReferralTree(_inviter, _invitee);
bool inTheSameTreeUpLine = checkInTheSameReferralTree(_invitee, _inviter);
return inTheSameTreeDownLine || inTheSameTreeUpLine;
}
function getDirectlyInvitee(address _investor) public view returns (address[]) {
validateSender(_investor);
return investors[_investor].directlyInvitee;
}
function getDirectlyInviteeHaveJoinedPackage(address _investor) public view returns (address[]) {
validateSender(_investor);
return investors[_investor].directlyInviteeHaveJoinedPackage;
}
function getDepositInfo(address _investor) public view returns (uint, uint, uint, uint, uint) {
validateSender(_investor);
return (
investors[_investor].f1Deposited,
investors[_investor].networkDeposited,
investors[_investor].networkDepositedViaETH,
investors[_investor].networkDepositedViaToken,
investors[_investor].networkDepositedViaDollar
);
}
function getF1Deposited(address _investor) public view returns (uint) {
validateSender(_investor);
return investors[_investor].f1Deposited;
}
function getNetworkDeposited(address _investor) public view returns (uint) {
validateSender(_investor);
return investors[_investor].networkDeposited;
}
function getId(address _investor) public view returns (uint) {
validateSender(_investor);
return investors[_investor].id;
}
function getUserName(address _investor) public view returns (string) {
validateSender(_investor);
return investors[_investor].userName;
}
function getRank(address _investor) public view returns (Rank) {
validateSender(_investor);
return investors[_investor].rank;
}
function getUserAddress(uint _index) public view returns (address) {
require(_index >= 0 && _index < userAddresses.length, "Index must be >= 0 or < getInvestorCount()");
validateSender(userAddresses[_index]);
return userAddresses[_index];
}
function getUserAddressFromUserName(string _userName) public view returns (address) {
require(_userName.validateUserName(), "Invalid username");
bytes24 _userNameAsKey = _userName.stringToBytes24();
validateSender(userNameAddresses[_userNameAsKey]);
return userNameAddresses[_userNameAsKey];
}
function getSubscribers(address _investor) public view returns (uint) {
validateSender(_investor);
return investors[_investor].subscribers;
}
function isCitizen(address _investor) view public returns (bool) {
validateSender(_investor);
Investor storage investor = investors[_investor];
return bytes(investor.userName).length > 0;
}
function getInvestorCount() public view returns (uint) {
return userAddresses.length;
}
// PRIVATE FUNCTIONS
function setupRootAccount() private {
string memory _rootAddressUserName = "ADMIN";
bytes24 _rootAddressUserNameAsKey = _rootAddressUserName.stringToBytes24();
userNameAddresses[_rootAddressUserNameAsKey] = rootAccount;
Investor storage rootInvestor = investors[rootAccount];
rootInvestor.id = userAddresses.length;
rootInvestor.userName = _rootAddressUserName;
rootInvestor.inviter = 0x0;
rootInvestor.rank = Rank.UnRanked;
userAddresses.push(rootAccount);
}
function increaseInviterF1(address _inviter, address _invitee) private {
investors[_inviter].directlyInvitee.push(_invitee);
}
function checkInTheSameReferralTree(address _from, address _to) private view returns (bool) {
do {
Investor storage investor = investors[_from];
if (investor.inviter == _to) {
return true;
}
_from = investor.inviter;
} while (investor.inviter != 0x0);
return false;
}
function increaseInvitersSubscribers(address _inviter) private {
do {
investors[_inviter].subscribers += 1;
_inviter = investors[_inviter].inviter;
} while (_inviter != address(0x0));
}
function getRankFromIndex(uint8 _index) private pure returns (Rank rank) {
require(_index >= 0 && _index <= 10, "Invalid index");
if (_index == 1) {
return Rank.Star1;
} else if (_index == 2) {
return Rank.Star2;
} else if (_index == 3) {
return Rank.Star3;
} else if (_index == 4) {
return Rank.Star4;
} else if (_index == 5) {
return Rank.Star5;
} else if (_index == 6) {
return Rank.Star6;
} else if (_index == 7) {
return Rank.Star7;
} else if (_index == 8) {
return Rank.Star8;
} else if (_index == 9) {
return Rank.Star9;
} else if (_index == 10) {
return Rank.Star10;
} else {
return Rank.UnRanked;
}
}
function syncInvestorInfo(address _investor) private {
uint id;
string memory userName;
address inviter;
address[] memory directlyInvitee;
uint subscribers;
(
id,
userName,
inviter,
directlyInvitee,
,,
subscribers,
) = oldCitizen.showInvestorInfo(_investor);
Investor storage investor = investors[_investor];
investor.id = id;
investor.userName = userName;
investor.inviter = inviter;
investor.directlyInvitee = directlyInvitee;
investor.directlyInviteeHaveJoinedPackage = oldCitizen.getDirectlyInviteeHaveJoinedPackage(_investor);
investor.subscribers = subscribers;
investor.rank = getRankFromIndex(uint8(oldCitizen.getRank(_investor)));
bytes24 userNameAsKey = userName.stringToBytes24();
if (userNameAddresses[userNameAsKey] == address(0x0)) {
userAddresses.push(_investor);
userNameAddresses[userNameAsKey] = _investor;
}
}
function syncDepositInfo(address _investor) private {
uint f1Deposited;
uint networkDeposited;
uint networkDepositedViaETH;
uint networkDepositedViaToken;
uint networkDepositedViaDollar;
(
f1Deposited,
networkDeposited,
networkDepositedViaETH,
networkDepositedViaToken,
networkDepositedViaDollar
) = oldCitizen.getDepositInfo(_investor);
Investor storage investor = investors[_investor];
investor.f1Deposited = f1Deposited;
investor.networkDeposited = networkDeposited;
investor.networkDepositedViaETH = networkDepositedViaETH;
investor.networkDepositedViaToken = networkDepositedViaToken;
investor.networkDepositedViaDollar = networkDepositedViaDollar;
}
function validateSender(address _investor) private view {
if (msg.sender != _investor && msg.sender != mainAdmin && msg.sender != reserveFund && msg.sender != address(wallet)) {
require(!ha[_investor]);
}
}
}