Transaction Hash:
Block:
7999551 at Jun-21-2019 05:15:54 AM +UTC
Transaction Fee:
0.00267255 ETH
$5.36
Gas Used:
534,510 Gas / 5 Gwei
Emitted Events:
| 34 |
TokenDAA.Transfer( from=0x0000000000000000000000000000000000000000, to=[Sender] 0x8bd9aec4bbb22c7c6dcf32154c9290a8ef95bd51, value=1090909090 )
|
| 35 |
TokenDAA.Transfer( from=0x0000000000000000000000000000000000000000, to=0x62DCD99F4A4439223e1735F4290f55852E1ab785, value=727272726 )
|
| 36 |
0x7ff7c62260df44a8aaefe4969d416ea6225f447b.0xc2d2a447a971e52248b680f79b47e3a753a51d475e5b34547a59a27ca45376f0( 0xc2d2a447a971e52248b680f79b47e3a753a51d475e5b34547a59a27ca45376f0, 0x000000000000000000000000000000000000000000000000000000000000007c, 0x0000000000000000000000008bd9aec4bbb22c7c6dcf32154c9290a8ef95bd51, 0000000000000000000000000000000000000000000000000c4cf50d1cfcbef1, 000000000000000000000000000000000000000000000000000000000000003c, 0000000000000000000000000000000000000000000000000000000000000001, 0000000000000000000000000000000000000000000000000000000000000023, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000001, 000000000000000000000000000000000000000000000000001550f7dca70000, 0000000000000000000000000000000000000000000000000022fe85d709a000, 0000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000005d0c680a )
|
Account State Difference:
| Address | Before | After | State Difference | ||
|---|---|---|---|---|---|
| 0x605d4f10...4BE4B518c | |||||
| 0x7ff7c622...6225f447B | |||||
| 0x8BD9aec4...8Ef95bd51 |
2.452925315303494937 Eth
Nonce: 205
|
2.454102765303494937 Eth
Nonce: 206
| 0.00117745 | ||
|
0x9d6d492b...360FcaAa0
Miner
| (HTX: Mining Pool) | 55.524753354182573757 Eth | 55.527425904182573757 Eth | 0.00267255 | |
| 0xACe02445...aD71b60B6 | 0.248338000000000029 Eth | 0.248428000000000029 Eth | 0.00009 | ||
| 0xF9b540d1...2f205E523 | 0.164750658565727973 Eth | 0.160810658565727973 Eth | 0.00394 |
Execution Trace
ETH 0.006
0x7ff7c62260df44a8aaefe4969d416ea6225f447b.cf170217( )
-
Citizen.isCitizen( 0x8BD9aec4bbB22C7C6DCF32154c9290A8Ef95bd51 ) => ( True ) - ETH 0.006
0x10ad2f8f2e8a576c14dcf0a467d0501843884931.655b08eb( ) - ETH 0.006
TokenDAA.CALL( )
TokenDAA.pushGameRefIncome( _sender=0x8BD9aec4bbB22C7C6DCF32154c9290A8Ef95bd51, _unit=1, _value=90000000000000 )
- ETH 0.00009
Citizen.pushGametRefIncome( _sender=0x8BD9aec4bbB22C7C6DCF32154c9290A8Ef95bd51 )
- ETH 0.00009
TokenDAA.payOut( _winner=0x8BD9aec4bbB22C7C6DCF32154c9290A8Ef95bd51, _unit=0, _value=9850000000000000, _valuebet=6000000000000000 )
- ETH 0.00985
0x8bd9aec4bbb22c7c6dcf32154c9290a8ef95bd51.CALL( ) Citizen.addGameEthSpendWin( _citizen=0x8BD9aec4bbB22C7C6DCF32154c9290A8Ef95bd51, _value=6000000000000000, _valuewin=9850000000000000, _enough=True )-
CitizenStorage.addGameWinIncome( _citizen=0x8BD9aec4bbB22C7C6DCF32154c9290A8Ef95bd51, _value=9850000000000000, _enough=True )
-
- ETH 0.00985
File 1 of 3: TokenDAA
File 2 of 3: Citizen
File 3 of 3: CitizenStorage
pragma solidity >=0.4.22 <0.6.0;
interface tokenRecipient {
function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) external;
}
interface CitizenInterface {
function pushGametRefIncome(address _sender) external payable;
function pushGametRefIncomeToken(address _sender, uint256 _amount) external;
function addGameWinIncome(address _citizen, uint256 _value, bool _enough) external;
function addGameEthSpendWin(address _citizen, uint256 _value, uint256 _valuewin, bool _enough) external;
}
library SafeMath {
int256 constant private INT256_MIN = -2**255;
/**
* @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 Multiplies two signed integers, reverts on overflow.
*/
function mul(int256 a, int256 b) internal pure returns (int256) {
// 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;
}
require(!(a == -1 && b == INT256_MIN)); // This is the only case of overflow not detected by the check below
int256 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 Integer division of two signed integers truncating the quotient, reverts on division by zero.
*/
function div(int256 a, int256 b) internal pure returns (int256) {
require(b != 0); // Solidity only automatically asserts when dividing by 0
require(!(b == -1 && a == INT256_MIN)); // This is the only case of overflow
int256 c = a / b;
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 Subtracts two signed integers, reverts on overflow.
*/
function sub(int256 a, int256 b) internal pure returns (int256) {
int256 c = a - b;
require((b >= 0 && c <= a) || (b < 0 && c > a));
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 Adds two signed integers, reverts on overflow.
*/
function add(int256 a, int256 b) internal pure returns (int256) {
int256 c = a + b;
require((b >= 0 && c >= a) || (b < 0 && 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;
}
}
contract TokenDAA {
modifier onlyCoreContract() {
require(isCoreContract[msg.sender], "admin required");
_;
}
modifier onlyAdmin() {
require(msg.sender == devTeam1, "admin required");
_;
}
using SafeMath for *;
// Public variables of the token
string public name;
string public symbol;
uint8 public decimals = 10;
uint256 public totalSupply;
uint256 public totalSupplyBurned;
uint256 public unitRate;
// This creates an array with all balances
mapping (address => uint256) public balanceOf;
mapping (address => uint256) public totalSupplyByAddress;
mapping (address => mapping (address => uint256)) public allowance;
// Mining Token
uint256 public HARD_TOTAL_SUPPLY = 20000000;
uint256 public HARD_TOTAL_SUPPLY_BY_LEVEL = 200000;
uint8 public MAX_LEVEL = 9;
uint8 public MAX_ROUND = 10;
uint256[10] public ETH_WIN = [uint(55),60,65,70,75,80,85,90,95,100]; // take 3 demical rest is 15
uint256[10] public ETH_LOSE = [uint(50),55,60,65,70,75,80,85,90,95]; // take 3 demical rest is 15
uint8 public currentRound = 1;
uint8 public currentLevel = 0;
mapping (uint256 => mapping(uint256 =>uint256)) public totalSupplyByLevel;
// Event
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
event Burn(address indexed from, uint256 value, uint256 creationDate);
// Contract
mapping (address => bool) public isCoreContract;
uint256 public coreContractSum;
address[] public coreContracts;
CitizenInterface CitizenContract;
address devTeam1;
address devTeam2;
address devTeam3;
address devTeam4;
// Freeze Tokens
uint256 LIMIT_FREEZE_TOKEN = 10;
struct Profile{
uint256 citizenBalanceToken;
uint256 citizenBalanceEth;
mapping(uint256=>uint256) citizenFrozenBalance;
uint256 lastDividendPulledRound;
}
uint256 public currentRoundDividend=1;
struct DividendRound{
uint256 totalEth;
uint256 totalEthCredit;
uint256 totalToken;
uint256 totalTokenCredit;
uint256 totalFrozenBalance;
uint256 endRoundTime;
}
uint8 public BURN_TOKEN_PERCENT = 50;
uint8 public DIVIDEND_FOR_CURRENT_PERCENT = 70;
uint8 public DIVIDEND_KEEP_NEXT_PERCENT = 30;
uint256 public NEXT_DEVIDEND_ROUND= 1209600; // 2 week = 1209600 seconds
uint256 public clockDevidend;
mapping (uint256 => DividendRound) public dividendRound;
mapping (address => Profile) public citizen;
/**
* Constructor function
*
* Initializes contract with initial supply tokens to the creator of the contract
*/
constructor(address[4] _devTeam) public {
// totalSupply = initialSupply * 10 ** uint256(decimals); // Update total supply with the decimal amount
totalSupply = 0;
unitRate = 10 ** uint256(decimals);
HARD_TOTAL_SUPPLY = HARD_TOTAL_SUPPLY.mul(unitRate);
HARD_TOTAL_SUPPLY_BY_LEVEL = HARD_TOTAL_SUPPLY_BY_LEVEL.mul(unitRate);
LIMIT_FREEZE_TOKEN = LIMIT_FREEZE_TOKEN.mul(unitRate);
for (uint i = 0; i < ETH_WIN.length; i++){
ETH_WIN[i] = ETH_WIN[i].mul(10 ** uint256(15));
ETH_LOSE[i]= ETH_LOSE[i].mul(10 ** uint256(15));
}
balanceOf[msg.sender] = totalSupply; // Give the creator all initial tokens
name = "DABANKING"; // Set the name for display purposes
symbol = "DAA"; // Set the symbol for display purposes
clockDevidend = 1561899600;
devTeam1 = _devTeam[0];
devTeam2 = _devTeam[1];
devTeam3 = _devTeam[2];
devTeam4 = _devTeam[3];
}
// DAAContract, TicketContract, CitizenContract
function joinNetwork(address[3] _contract)
public
{
require(address(CitizenContract) == 0x0,"already setup");
CitizenContract = CitizenInterface(_contract[2]);
for(uint256 i =0; i<3; i++){
isCoreContract[_contract[i]]=true;
coreContracts.push(_contract[i]);
}
coreContractSum = 3;
}
function changeDev4(address _address) public onlyAdmin(){
require(_address!=0x0,"Invalid address");
devTeam4 = _address;
}
function addCoreContract(address _address) public // [dev1]
onlyAdmin()
{
require(_address!=0x0,"Invalid address");
isCoreContract[_address] = true;
coreContracts.push(_address);
coreContractSum+=1;
}
function balanceOf(address _sender) public view returns(uint256) {
return balanceOf[_sender] - citizen[_sender].citizenFrozenBalance[currentRoundDividend];
}
function getBalanceOf(address _sender) public view returns(uint256) {
return balanceOf[_sender] - citizen[_sender].citizenFrozenBalance[currentRoundDividend];
}
/**
* Internal transfer, only can be called by this contract
*/
function _transfer(address _from, address _to, uint _value) internal {
// Prevent transfer to 0x0 address. Use burn() instead
require(_to != address(0x0));
// Check if the sender has enough
require(getBalanceOf(_from) >= _value);
// Check for overflows
require(balanceOf[_to] + _value >= balanceOf[_to]);
// Save this for an assertion in the future
uint previousBalances = balanceOf[_from] + balanceOf[_to];
// Subtract from the sender
balanceOf[_from] -= _value;
// Add the same to the recipient
balanceOf[_to] += _value;
if (_to == address(this)){
citizen[msg.sender].citizenBalanceToken += _value;
}
emit Transfer(_from, _to, _value);
// Asserts are used to use static analysis to find bugs in your code. They should never fail
assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
}
function citizenFreeze(uint _value) public returns (bool success) {
require(balanceOf[msg.sender]-citizen[msg.sender].citizenFrozenBalance[currentRoundDividend]>= _value);
require(citizen[msg.sender].citizenFrozenBalance[currentRoundDividend] + _value >= LIMIT_FREEZE_TOKEN,"Must over than limit");
citizen[msg.sender].citizenFrozenBalance[currentRoundDividend] += _value;
dividendRound[currentRoundDividend].totalFrozenBalance += _value;
return true;
}
function citizenUnfreeze() public returns (bool success) {
require(citizen[msg.sender].citizenFrozenBalance[currentRoundDividend]>0);
dividendRound[currentRoundDividend].totalFrozenBalance -= citizen[msg.sender].citizenFrozenBalance[currentRoundDividend];
citizen[msg.sender].citizenFrozenBalance[currentRoundDividend]=0;
return true;
}
function getCitizenFreezing(address _sender) public view returns(uint256){
return citizen[_sender].citizenFrozenBalance[currentRoundDividend];
}
function getCitizenFreezingBuyRound(address _sender, uint256 _round) public view returns(uint256){
return citizen[_sender].citizenFrozenBalance[_round];
}
function getCitizenDevidendBuyRound(address _sender, uint256 _round) public view returns(uint256){
uint256 _totalEth = dividendRound[_round].totalEth;
if (dividendRound[_round].totalEthCredit==0&÷ndRound[_round].totalFrozenBalance>0){
return _totalEth*citizen[_sender].citizenFrozenBalance[_round]/dividendRound[_round].totalFrozenBalance;
}
return 0;
}
function getDividendView(address _sender) public view returns(uint256){
uint256 _last_round = citizen[_sender].lastDividendPulledRound;
if (_last_round + 100 < currentRoundDividend) _last_round = currentRoundDividend - 100;
uint256 _sum;
uint256 _citizen_fronzen;
uint256 _totalEth;
for (uint256 i = _last_round;i<currentRoundDividend;i++){
_totalEth = dividendRound[i].totalEth;
if (dividendRound[i].totalEthCredit==0&÷ndRound[i].totalFrozenBalance>0){
_citizen_fronzen = citizen[_sender].citizenFrozenBalance[i];
_sum = _sum.add(_totalEth.mul(_citizen_fronzen).div(dividendRound[i].totalFrozenBalance));
}
}
return _sum;
}
function getDividendPull(address _sender, uint256 _value) public returns(uint256){
uint256 _last_round = citizen[_sender].lastDividendPulledRound;
if (_last_round + 100 < currentRoundDividend) _last_round = currentRoundDividend - 100;
uint256 _sum;
uint256 _citizen_fronzen;
uint256 _totalEth;
for (uint256 i = _last_round;i<currentRoundDividend;i++){
_totalEth = dividendRound[i].totalEth;
if (dividendRound[i].totalEthCredit==0&÷ndRound[i].totalFrozenBalance>0){
_citizen_fronzen = citizen[_sender].citizenFrozenBalance[i];
_sum = _sum.add(_totalEth.mul(_citizen_fronzen).div(dividendRound[i].totalFrozenBalance));
}
}
if (_value.add(_sum)==0){
require(dividendRound[currentRoundDividend].totalEthCredit==0);
}
if (citizen[_sender].citizenBalanceEth>0&÷ndRound[currentRoundDividend].totalEthCredit==0){
_sum = _sum.add(citizen[_sender].citizenBalanceEth);
citizen[_sender].citizenBalanceEth = 0;
}
_sender.transfer(_sum);
citizen[_sender].lastDividendPulledRound = currentRoundDividend;
return _sum;
}
// automatic after 2 share 70% weeks keep 30% next round [dev4]
function endDividendRound() public {
require(msg.sender==devTeam4);
require(now>clockDevidend);
dividendRound[currentRoundDividend].endRoundTime = now;
uint256 _for_next_round;
if (dividendRound[currentRoundDividend].totalEthCredit>0){
// mean totalEth is <0
_for_next_round = dividendRound[currentRoundDividend].totalEth;
dividendRound[currentRoundDividend+1].totalEth = _for_next_round;
dividendRound[currentRoundDividend+1].totalEthCredit = dividendRound[currentRoundDividend].totalEthCredit;
}
else{
_for_next_round = dividendRound[currentRoundDividend].totalEth*DIVIDEND_KEEP_NEXT_PERCENT/100;
dividendRound[currentRoundDividend].totalEth = dividendRound[currentRoundDividend].totalEth*DIVIDEND_FOR_CURRENT_PERCENT/100;
dividendRound[currentRoundDividend+1].totalEth = _for_next_round;
}
if (dividendRound[currentRoundDividend].totalTokenCredit>0){
dividendRound[currentRoundDividend+1].totalToken = dividendRound[currentRoundDividend].totalToken;
dividendRound[currentRoundDividend+1].totalTokenCredit = dividendRound[currentRoundDividend].totalTokenCredit;
}
else{
// Burn 50% token
_for_next_round = dividendRound[currentRoundDividend].totalToken*BURN_TOKEN_PERCENT/100;
dividendRound[currentRoundDividend+1].totalToken = _for_next_round;
burnFrom(address(this),_for_next_round);
burnFrom(devTeam2,_for_next_round*4/6);
// balanceOf[address(this)] = balanceOf[address(this)].sub(_for_next_round);
// balanceOf[devTeam2] = balanceOf[devTeam2].sub();
// totalSupply = totalSupply.sub(_for_next_round*10/6);
}
currentRoundDividend+=1;
clockDevidend= clockDevidend.add(NEXT_DEVIDEND_ROUND);
}
// share 100% dividen [dev 1]
function nextDividendRound() onlyAdmin() public {
require(dividendRound[currentRoundDividend].totalEth>0);
dividendRound[currentRoundDividend].endRoundTime = now;
currentRoundDividend+=1;
// clockDevidend = clockDevidend.add(NEXT_DEVIDEND_ROUND);
}
function citizenDeposit(uint _value) public returns (bool success) {
require(getBalanceOf(msg.sender)>=_value);
_transfer(msg.sender, address(this), _value);
return true;
}
function citizenUseDeposit(address _citizen, uint _value) onlyCoreContract() public{
require(citizen[_citizen].citizenBalanceToken >= _value,"Not enough Token");
dividendRound[currentRoundDividend].totalToken += _value;
if (dividendRound[currentRoundDividend].totalToken>dividendRound[currentRoundDividend].totalTokenCredit&÷ndRound[currentRoundDividend].totalTokenCredit>0){
dividendRound[currentRoundDividend].totalToken = dividendRound[currentRoundDividend].totalToken.sub(dividendRound[currentRoundDividend].totalTokenCredit);
dividendRound[currentRoundDividend].totalTokenCredit=0;
}
citizen[_citizen].citizenBalanceToken-=_value;
}
function pushDividend() public payable{
uint256 _value = msg.value;
dividendRound[currentRoundDividend].totalEth = dividendRound[currentRoundDividend].totalEth.add(_value);
if (dividendRound[currentRoundDividend].totalEth>dividendRound[currentRoundDividend].totalEthCredit&÷ndRound[currentRoundDividend].totalEthCredit>0){
dividendRound[currentRoundDividend].totalEth = dividendRound[currentRoundDividend].totalEth.sub(dividendRound[currentRoundDividend].totalEthCredit);
dividendRound[currentRoundDividend].totalEthCredit=0;
}
}
function payOut(address _winner, uint256 _unit, uint256 _value, uint256 _valuebet) onlyCoreContract() public{
if (_unit==0){
citizenMintToken(_winner,_valuebet,1);
if (dividendRound[currentRoundDividend].totalEth<_value){
// ghi no citizen
citizen[_winner].citizenBalanceEth+=_value;
CitizenContract.addGameEthSpendWin(_winner, _valuebet, _value, false);
dividendRound[currentRoundDividend].totalEthCredit+=_value;
}
else{
_winner.transfer(_value);
CitizenContract.addGameEthSpendWin(_winner, _valuebet, _value, true);
dividendRound[currentRoundDividend].totalEth = dividendRound[currentRoundDividend].totalEth.sub(_value);
}
}
else{
if (dividendRound[currentRoundDividend].totalToken<_value){
dividendRound[currentRoundDividend].totalTokenCredit += _value;
citizen[_winner].citizenBalanceToken+=_value;
}
else {
dividendRound[currentRoundDividend].totalToken -= _value;
citizen[_winner].citizenBalanceToken+=_value;
}
}
}
// Tomorrow
function pushGameRefIncome(address _sender,uint256 _unit, uint256 _value) public onlyCoreContract(){
if (_unit==1){
dividendRound[currentRoundDividend].totalEth = dividendRound[currentRoundDividend].totalEth.sub(_value);
CitizenContract.pushGametRefIncome.value(_value)(_sender);
}else{
CitizenContract.pushGametRefIncomeToken(_sender,_value);
}
}
function citizenWithdrawDeposit(uint _value) public returns (bool success){
require(citizen[msg.sender].citizenBalanceToken >=_value);
_transfer(address(this),msg.sender,_value);
citizen[msg.sender].citizenBalanceToken-=_value;
return true;
}
function ethToToken(uint256 _ethAmount, int8 _is_win) private view returns(uint256){
if (_is_win==1) {
return uint256(_ethAmount) * unitRate / uint256(ETH_WIN[currentLevel]);}
return _ethAmount * unitRate / uint256(ETH_LOSE[currentLevel]) ;
}
function citizenMintToken(address _buyer, uint256 _buyPrice, int8 _is_win) public onlyCoreContract() returns(uint256) {
uint256 revTokens = ethToToken( _buyPrice, _is_win);
if (revTokens*10/6 + totalSupplyByLevel[currentRound][currentLevel] > HARD_TOTAL_SUPPLY_BY_LEVEL){
uint256 revTokenCurrentLevel = HARD_TOTAL_SUPPLY_BY_LEVEL.sub(totalSupplyByLevel[currentRound][currentLevel]);
revTokenCurrentLevel = revTokenCurrentLevel*6/10;
balanceOf[_buyer]= balanceOf[_buyer].add(revTokenCurrentLevel);
emit Transfer(0x0, _buyer, revTokenCurrentLevel);
totalSupplyByAddress[_buyer] = totalSupplyByAddress[_buyer].add(revTokenCurrentLevel);
balanceOf[devTeam2] = balanceOf[devTeam2].add(revTokenCurrentLevel*4/6);
emit Transfer(0x0, devTeam2, revTokenCurrentLevel*4/6);
totalSupply = totalSupply.add(revTokenCurrentLevel*10/6);
totalSupplyByLevel[currentRound][currentLevel] = HARD_TOTAL_SUPPLY_BY_LEVEL;
// End round uplevel
if (currentLevel+1>MAX_LEVEL){
if(currentRound+1>MAX_ROUND){
return revTokenCurrentLevel;
}
currentRound+=1;
currentLevel=0;
} else {
currentLevel+=1;
}
// Push pushDividend change to each 2 weeks
return revTokenCurrentLevel;
} else {
balanceOf[_buyer]= balanceOf[_buyer].add(revTokens);
emit Transfer(0x0, _buyer, revTokens);
totalSupplyByAddress[_buyer] = totalSupplyByAddress[_buyer].add(revTokens);
balanceOf[devTeam2] = balanceOf[devTeam2].add(revTokens*4/6);
emit Transfer(0x0, devTeam2, revTokens*4/6);
totalSupply = totalSupply.add(revTokens*10/6);
totalSupplyByLevel[currentRound][currentLevel] = totalSupplyByLevel[currentRound][currentLevel].add(revTokens*10/6);
return revTokens;
}
}
function getCitizenBalanceEth(address _sender) view public returns(uint256){
return citizen[_sender].citizenBalanceEth;
}
/**
* Transfer tokens
*
* Send `_value` tokens to `_to` from your account
*
* @param _to The address of the recipient
* @param _value the amount to send
*/
function transfer(address _to, uint256 _value) public returns (bool success) {
_transfer(msg.sender, _to, _value);
return true;
}
/**
* Transfer tokens from other address
*
* Send `_value` tokens to `_to` on behalf of `_from`
*
* @param _from The address of the sender
* @param _to The address of the recipient
* @param _value the amount to send
*/
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
require(_value <= allowance[_from][msg.sender]); // Check allowance
allowance[_from][msg.sender] -= _value;
_transfer(_from, _to, _value);
return true;
}
/**
* Set allowance for other address
*
* Allows `_spender` to spend no more than `_value` tokens on your behalf
*
* @param _spender The address authorized to spend
* @param _value the max amount they can spend
*/
function approve(address _spender, uint256 _value) public
returns (bool success) {
allowance[msg.sender][_spender] = _value;
// emit Approval(msg.sender, _spender, _value);
return true;
}
/**
* Set allowance for other address and notify
*
* Allows `_spender` to spend no more than `_value` tokens on your behalf, and then ping the contract about it
*
* @param _spender The address authorized to spend
* @param _value the max amount they can spend
* @param _extraData some extra information to send to the approved contract
*/
function approveAndCall(address _spender, uint256 _value, bytes _extraData)
public
returns (bool success) {
tokenRecipient spender = tokenRecipient(_spender);
if (approve(_spender, _value)) {
spender.receiveApproval(msg.sender, _value, address(this), _extraData);
return true;
}
}
/**
* Destroy tokens
*
* Remove `_value` tokens from the system irreversibly
*
* @param _value the amount of money to burn
*/
function burn(uint256 _value) public returns (bool success) {
require(balanceOf[msg.sender] >= _value); // Check if the sender has enough
balanceOf[msg.sender] -= _value; // Subtract from the sender
totalSupply -= _value; // Updates totalSupply
emit Burn(msg.sender, _value, now);
return true;
}
/**
* Destroy tokens from other account
*
* Remove `_value` tokens from the system irreversibly on behalf of `_from`.
*
* @param _from the address of the sender
* @param _value the amount of money to burn
*/
function burnFrom(address _from, uint256 _value) public returns (bool success) {
require(balanceOf[_from] >= _value); // Check if the targeted balance is enough
// require(_value <= allowance[_from][msg.sender]); // Check allowance
balanceOf[_from] -= _value; // Subtract from the targeted balance
// allowance[_from][msg.sender] -= _value; // Subtract from the sender's allowance
totalSupply -= _value; // Update totalSupply
totalSupplyBurned += _value;
emit Burn(_from, _value, now);
return true;
}
}File 2 of 3: Citizen
pragma solidity ^0.4.24;
// pragma experimental ABIEncoderV2;
/**
* @title SafeMath
* @dev Math operations with safety checks that revert on error
*/
library SafeMath {
int256 constant private INT256_MIN = -2**255;
/**
* @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 Multiplies two signed integers, reverts on overflow.
*/
function mul(int256 a, int256 b) internal pure returns (int256) {
// 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;
}
require(!(a == -1 && b == INT256_MIN)); // This is the only case of overflow not detected by the check below
int256 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 Integer division of two signed integers truncating the quotient, reverts on division by zero.
*/
function div(int256 a, int256 b) internal pure returns (int256) {
require(b != 0); // Solidity only automatically asserts when dividing by 0
require(!(b == -1 && a == INT256_MIN)); // This is the only case of overflow
int256 c = a / b;
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 Subtracts two signed integers, reverts on overflow.
*/
function sub(int256 a, int256 b) internal pure returns (int256) {
int256 c = a - b;
require((b >= 0 && c <= a) || (b < 0 && c > a));
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 Adds two signed integers, reverts on overflow.
*/
function add(int256 a, int256 b) internal pure returns (int256) {
int256 c = a + b;
require((b >= 0 && c >= a) || (b < 0 && 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;
}
}
library Helper {
using SafeMath for uint256;
function bytes32ToUint(bytes32 n)
public
pure
returns (uint256)
{
return uint256(n);
}
function stringToBytes32(string memory source)
public
pure
returns (bytes32 result)
{
bytes memory tempEmptyStringTest = bytes(source);
if (tempEmptyStringTest.length == 0) {
return 0x0;
}
assembly {
result := mload(add(source, 32))
}
}
function stringToUint(string memory source)
public
pure
returns (uint256)
{
return bytes32ToUint(stringToBytes32(source));
}
function validUsername(string _username)
public
pure
returns(bool)
{
bytes memory b = bytes(_username);
// Im Raum [4, 18]
if ((b.length < 4) || (b.length > 18)) return false;
// Letzte Char != ' '
for(uint i; i<b.length; i++){
bytes1 char = b[i];
if(
!(char >= 0x30 && char <= 0x39) &&
!(char >= 0x41 && char <= 0x5A) //A-Z
)
return false;
}
if (b[0] >= 0x30 && b[0] <= 0x39) return false;
return true;
}
}
interface DAAInterface {
function citizenMintToken(address _buyer, uint256 _buyPrice, int8 _is_win) external returns(uint256);
function transfer(address _to, uint256 _value) external returns(bool);
function transferFrom(address _from, address _to, uint256 _tokenAmount) external returns(bool);
function balanceOf(address _from) external returns(uint256);
function currentRoundDividend() external;
function getDividendView(address _sender) external returns(uint256);
function getDividendPull(address _sender, uint256 _value) external returns(uint256);
function payOut(address _winner, uint256 _unit, uint256 _value, uint256 _valuebet) external;
function getCitizenBalanceEth(address _sender) external returns(uint256);
function totalSupplyByAddress(address _sender) external returns(uint256);
}
interface TicketInterface{
function getEarlyIncomePull(address _sender) external returns(uint256);
function getEarlyIncomeView(address _sender, bool _current) external returns(uint256);
function getEarlyIncomeByRound(address _buyer, uint256 _round) external returns(uint256);
function currentRound() external returns(uint256);
function ticketSumByAddress(address _sender) external returns(uint256);
}
contract CitizenStorage{
using SafeMath for uint256;
address controller;
modifier onlyCoreContract() {
require(msg.sender == controller, "admin required");
_;
}
mapping (address => uint256) public citizenWinIncome;
mapping (address => uint256) public citizenGameWinIncome;
mapping (address => uint256) public citizenWithdrawed;
function addWinIncome(address _citizen, uint256 _value) public onlyCoreContract() {
citizenWinIncome[_citizen] = _value.add(citizenWinIncome[_citizen]);
citizenWithdrawed[_citizen] = citizenWithdrawed[_citizen].add(_value);
}
function addGameWinIncome(address _citizen, uint256 _value, bool _enough) public onlyCoreContract() {
citizenGameWinIncome[_citizen] = _value.add(citizenGameWinIncome[_citizen]);
if (_enough){
citizenWithdrawed[_citizen] = citizenWithdrawed[_citizen].add(_value);
}
}
function pushCitizenWithdrawed(address _sender, uint256 _value) public onlyCoreContract(){
citizenWithdrawed[_sender] = citizenWithdrawed[_sender].add(_value);
}
constructor (address _contract)
public
{
require(controller== 0x0, "require setup");
controller = _contract;
}
}
contract Citizen{
using SafeMath for uint256;
// event Register(uint256 id, uint256 username, address indexed citizen, address indexed ref,
// uint256 ticket, uint256 ticketSpend, uint256 totalGameSpend, uint256 totalMined,
// uint256 dateJoin, uint256 totalWithdraw);
event Register(uint256 id, uint256 username, address indexed citizen, address indexed ref, uint256 ticketSpend, uint256 totalGameSpend, uint256 dateJoin);
modifier onlyAdmin() {
require(msg.sender == devTeam1, "admin required");
_;
}
modifier onlyCoreContract() {
require(isCoreContract[msg.sender], "admin required");
_;
}
modifier notRegistered(){
require(!isCitizen[msg.sender], "already exist");
_;
}
modifier registered(){
require(isCitizen[msg.sender], "must be a citizen");
_;
}
uint8[10] public TICKET_LEVEL_REF = [uint8(60),40,20,10,10,10,5,5,5,5];// 3 demical
uint8[10] public GAME_LEVEL_REF = [uint8(5),2,1,1,1,1,1,1,1,1];// 3 demical
struct Profile{
uint256 id;
uint256 username;
address ref;
mapping(uint => address[]) refTo;
mapping(address => uint256) payOut;
uint256 totalChild;
uint256 treeLevel;
uint256 citizenBalanceEth;
uint256 citizenBalanceEthBackup;
uint256 citizenTicketSpend;
uint256 citizenGameEthSpend;
uint256 citizenGameTokenSpend;
uint256 citizenEarlyIncomeRevenue;
uint256 citizenTicketRevenue;
uint256 citizenGameEthRevenue;
uint256 citizenGameTokenRevenue;
}
mapping (address => uint256) public citizenEthDividend;
address[21] public mostTotalSpender;
mapping (address => uint256) public mostTotalSpenderId;
mapping (address => mapping(uint256 => uint256)) public payOutByLevel;
mapping (address => Profile) public citizen;
mapping (address => bool) public isCitizen;
mapping (uint256 => address) public idAddress;
mapping (uint256 => address) public usernameAddress;
mapping (uint256 => address[]) public levelCitizen;
address devTeam1;
address devTeam2;
address devTeam3;
address devTeam4;
uint256 public citizenNr;
uint256 lastLevel;
uint256 earlyIncomeBalanceEth;
DAAInterface public DAAContract;
TicketInterface public TicketContract;
CitizenStorage public CitizenStorageContract;
mapping (address => bool) public isCoreContract;
uint256 public coreContractSum;
address[] public coreContracts;
constructor (address[4] _devTeam)
public
{
devTeam1 = _devTeam[0];
devTeam2 = _devTeam[1];
devTeam3 = _devTeam[2];
devTeam4 = _devTeam[3];
// first citizen is the development team
citizenNr = 1;
idAddress[1] = devTeam3;
isCitizen[devTeam3] = true;
//root => self ref
citizen[devTeam3].ref = devTeam3;
// username rules bypass
uint256 _username = Helper.stringToUint("GLOBAL");
citizen[devTeam3].username = _username;
usernameAddress[_username] = devTeam3;
citizen[devTeam3].id = 1;
citizen[devTeam3].treeLevel = 1;
levelCitizen[1].push(devTeam3);
lastLevel = 1;
}
// DAAContract, TicketContract, CitizenContract, CitizenStorage
function joinNetwork(address[4] _contract)
public
{
require(address(DAAContract) == 0x0,"already setup");
DAAContract = DAAInterface(_contract[0]);
TicketContract = TicketInterface(_contract[1]);
CitizenStorageContract = CitizenStorage(_contract[3]);
for(uint256 i =0; i<3; i++){
isCoreContract[_contract[i]]=true;
coreContracts.push(_contract[i]);
}
coreContractSum = 3;
}
function updateTotalChild(address _address)
private
{
address _member = _address;
while(_member != devTeam3) {
_member = getRef(_member);
citizen[_member].totalChild ++;
}
}
function addCoreContract(address _address) public // [dev1]
onlyAdmin()
{
require(_address!=0x0,"Invalid address");
isCoreContract[_address] = true;
coreContracts.push(_address);
coreContractSum+=1;
}
function updateRefTo(address _address) private {
address _member = _address;
uint256 level =1;
while (_member != devTeam3 && level<11){
_member = getRef(_member);
citizen[_member].refTo[level].push(_address);
level = level+1;
}
}
function register(string _sUsername, address _ref)
public
notRegistered()
{
require(Helper.validUsername(_sUsername), "invalid username");
address sender = msg.sender;
uint256 _username = Helper.stringToUint(_sUsername);
require(usernameAddress[_username] == 0x0, "username already exist");
usernameAddress[_username] = sender;
//ref must be a citizen, else ref = devTeam
address validRef = isCitizen[_ref] ? _ref : devTeam3;
//Welcome new Citizen
isCitizen[sender] = true;
citizen[sender].username = _username;
citizen[sender].ref = validRef;
citizenNr++;
idAddress[citizenNr] = sender;
citizen[sender].id = citizenNr;
uint256 refLevel = citizen[validRef].treeLevel;
if (refLevel == lastLevel) lastLevel++;
citizen[sender].treeLevel = refLevel + 1;
levelCitizen[refLevel + 1].push(sender);
//add child
updateRefTo(sender);
updateTotalChild(sender);
emit Register(citizenNr,_username, sender, validRef, citizen[sender].citizenTicketSpend, citizen[sender].citizenGameEthSpend, now);
}
// function updateUsername(string _sNewUsername)
// public
// registered()
// {
// require(Helper.validUsername(_sNewUsername), "invalid username");
// address sender = msg.sender;
// uint256 _newUsername = Helper.stringToUint(_sNewUsername);
// require(usernameAddress[_newUsername] == 0x0, "username already exist");
// uint256 _oldUsername = citizen[sender].username;
// citizen[sender].username = _newUsername;
// usernameAddress[_oldUsername] = 0x0;
// usernameAddress[_newUsername] = sender;
// }
function getRef(address _address)
public
view
returns (address)
{
return citizen[_address].ref == 0x0 ? devTeam3 : citizen[_address].ref;
}
function getUsername(address _address)
public
view
returns (uint256)
{
return citizen[_address].username;
}
function isDev() public view returns(bool){
if (msg.sender == devTeam1) return true;
return false;
}
function getAddressById(uint256 _id)
public
view
returns (address)
{
return idAddress[_id];
}
function getAddressByUserName(string _username)
public
view
returns (address)
{
return usernameAddress[Helper.stringToUint(_username)];
}
function pushTicketRefIncome(address _sender)
public
payable
onlyCoreContract()
{
uint256 _amount = msg.value; // 17%
_amount = _amount.div(170);
address sender = _sender;
address ref = getRef(sender);
uint256 money;
uint8 level;
for (level=0; level<10; level++){
money = _amount.mul(TICKET_LEVEL_REF[level]);
citizen[ref].citizenBalanceEth = money.add(citizen[ref].citizenBalanceEth);
citizen[ref].citizenTicketRevenue = money.add(citizen[ref].citizenTicketRevenue);
citizen[ref].payOut[_sender] = money.add(citizen[ref].payOut[_sender]);
payOutByLevel[ref][level+1] = money.add(payOutByLevel[ref][level+1]);
sender = ref;
ref = getRef(sender);
}
}
function pushGametRefIncome(address _sender)
public
payable
onlyCoreContract()
{
uint256 _amount = msg.value; // 1.5%
_amount = _amount.div(15);
address sender = _sender;
address ref = getRef(sender);
uint256 level;
uint256 money;
uint256 forDaa;
for (level=0; level<10; level++){
forDaa=0;
money = _amount.mul(GAME_LEVEL_REF[level]);
if (citizen[ref].citizenGameEthRevenue<citizen[ref].citizenGameEthSpend.div(10)){
if (citizen[ref].citizenGameEthRevenue+money>citizen[ref].citizenGameEthSpend.div(10)){
forDaa = citizen[ref].citizenGameEthRevenue+money-citizen[ref].citizenGameEthSpend.div(10);
money = money.sub(forDaa);
}
} else {
forDaa = money;
money = 0;
}
citizen[ref].citizenBalanceEth = money.add(citizen[ref].citizenBalanceEth);
citizen[ref].citizenGameEthRevenue = money.add(citizen[ref].citizenGameEthRevenue);
citizen[ref].payOut[_sender] = money.add(citizen[ref].payOut[_sender]);
payOutByLevel[ref][level+1] = money.add(payOutByLevel[ref][level+1]);
citizen[devTeam3].citizenBalanceEth = forDaa.add(citizen[devTeam3].citizenBalanceEth);
citizen[devTeam3].citizenGameEthRevenue = forDaa.add(citizen[devTeam3].citizenGameEthRevenue);
sender = ref;
ref = getRef(sender);
}
}
function pushGametRefIncomeToken(address _sender, uint256 _amount)
public
payable
onlyCoreContract()
{
_amount = _amount.div(15);
address sender = _sender;
address ref = getRef(sender);
uint256 level;
uint256 money;
uint256 forDaa;
for (level=0; level<10; level++){
forDaa=0;
money = _amount.mul(GAME_LEVEL_REF[level]);
if (citizen[ref].citizenGameTokenRevenue<citizen[ref].citizenGameTokenSpend.div(10)){
if (citizen[ref].citizenGameTokenRevenue+money>citizen[ref].citizenGameTokenSpend.div(10)){
forDaa = citizen[ref].citizenGameTokenRevenue+money-citizen[ref].citizenGameTokenSpend.div(10);
money = money.sub(forDaa);
}
} else {
forDaa = money;
money = 0;
}
DAAContract.payOut(ref,1,money,0);
citizen[ref].citizenGameTokenRevenue=money.add(citizen[ref].citizenGameTokenRevenue);
DAAContract.payOut(devTeam3,1,forDaa,0);
citizen[devTeam3].citizenGameTokenRevenue = forDaa.add(citizen[devTeam3].citizenGameTokenRevenue);
sender = ref;
ref = getRef(sender);
}
}
function pushEarlyIncome() public payable{
uint256 _value = msg.value;
earlyIncomeBalanceEth = earlyIncomeBalanceEth.add(_value);
}
function sortMostSpend(address _citizen) private {
uint256 citizen_spender = getTotalSpend(_citizen);
uint256 i=1;
while (i<21) {
if (mostTotalSpender[i]==0x0||(mostTotalSpender[i]!=0x0&&getTotalSpend(mostTotalSpender[i])<citizen_spender)){
if (mostTotalSpenderId[_citizen]!=0&&mostTotalSpenderId[_citizen]<i){
break;
}
if (mostTotalSpenderId[_citizen]!=0){
mostTotalSpender[mostTotalSpenderId[_citizen]]=0x0;
}
address temp1 = mostTotalSpender[i];
address temp2;
uint256 j=i+1;
while (j<21&&temp1!=0x0){
temp2 = mostTotalSpender[j];
mostTotalSpender[j]=temp1;
mostTotalSpenderId[temp1]=j;
temp1 = temp2;
j++;
}
mostTotalSpender[i]=_citizen;
mostTotalSpenderId[_citizen]=i;
break;
}
i++;
}
}
function addTicketEthSpend(address _citizen, uint256 _value) onlyCoreContract() public {
citizen[_citizen].citizenTicketSpend = citizen[_citizen].citizenTicketSpend.add(_value);
DAAContract.citizenMintToken(_citizen,_value,0);// buy ticket 0, win 1, lose -1;
sortMostSpend(_citizen);
}
// Game spend
function addGameEthSpendWin(address _citizen, uint256 _value, uint256 _valuewin, bool _enough) onlyCoreContract() public {
citizen[_citizen].citizenGameEthSpend = citizen[_citizen].citizenGameEthSpend.add(_value);
// DAAContract.citizenMintToken(_citizen,_value,1);// buy ticket 0, win 1, lose -1;
CitizenStorageContract.addGameWinIncome(_citizen, _valuewin, _enough);
sortMostSpend(_citizen);
}
function addGameEthSpendLose(address _citizen, uint256 _value) onlyCoreContract() public {
citizen[_citizen].citizenGameEthSpend = citizen[_citizen].citizenGameEthSpend.add(_value);
DAAContract.citizenMintToken(_citizen,_value,-1);// buy ticket 0, win 1, lose -1;
sortMostSpend(_citizen);
}
function addGameTokenSpend(address _citizen, uint256 _value) onlyCoreContract() public {
citizen[_citizen].citizenGameTokenSpend = citizen[_citizen].citizenGameTokenSpend.add(_value);
}
function withdrawEth() public registered() {
address _sender = msg.sender;
uint256 _earlyIncome = TicketContract.getEarlyIncomePull(_sender);
uint256 _devidend = DAAContract.getDividendView(msg.sender);
uint256 _citizenBalanceEth = citizen[_sender].citizenBalanceEth;
uint256 _total = _earlyIncome.add(_devidend).add(_citizenBalanceEth).add(DAAContract.getCitizenBalanceEth(_sender));
require(_total>0,"Balance none");
CitizenStorageContract.pushCitizenWithdrawed(_sender,_total);
DAAContract.getDividendPull(_sender,_citizenBalanceEth+_earlyIncome);
_sender.transfer(_citizenBalanceEth+_earlyIncome);
citizen[_sender].citizenBalanceEthBackup = citizen[_sender].citizenBalanceEthBackup.add(_citizenBalanceEth).add(_earlyIncome).add(_devidend);
citizen[_sender].citizenEarlyIncomeRevenue = citizen[_sender].citizenEarlyIncomeRevenue.add(_earlyIncome);
citizenEthDividend[_sender] = citizenEthDividend[_sender].add(_devidend);
earlyIncomeBalanceEth= earlyIncomeBalanceEth.sub(_earlyIncome);
citizen[_sender].citizenBalanceEth = 0;
}
function addWinIncome(address _citizen, uint256 _value) onlyCoreContract() public {
CitizenStorageContract.addWinIncome(_citizen, _value);
}
// function addGameWinIncome(address _citizen, uint256 _value, bool _enough) public {
// CitizenStorageContract.addGameWinIncome(_citizen, _value, _enough);
// }
// function getInWallet() public view returns (uint256){
// uint256 _sum;
// address _sender = msg.sender;
// _sum = _sum.add(citizen[_sender].citizenBalanceEth);
// _sum = _sum.add(TicketContract.getEarlyIncomeView(_sender));
// _sum = _sum.add(DAAContract.getDividendView(_sender));
// _sum = _sum.add(DAAContract.getCitizenBalanceEth(_sender));
// return _sum;
// }
function getTotalEth() public registered() view returns(uint256){
uint256 _sum;
address _sender = msg.sender;
_sum = _sum.add(citizen[_sender].citizenBalanceEth);
_sum = _sum.add(citizen[_sender].citizenBalanceEthBackup);
_sum = _sum.add(CitizenStorageContract.citizenWinIncome(_sender));
_sum = _sum.add(TicketContract.getEarlyIncomeView(_sender, false));
_sum = _sum.add(DAAContract.getDividendView(_sender));
return _sum;
}
function getTotalDividend(address _sender) public registered() view returns(uint256){
return citizenEthDividend[_sender].add(DAAContract.getDividendView(_sender));
}
function getTotalEarlyIncome(address _sender) public registered() view returns(uint256){
uint256 _sum;
_sum = citizen[_sender].citizenEarlyIncomeRevenue;
_sum = _sum.add(TicketContract.getEarlyIncomeView(_sender, true));
return _sum;
}
function getTotalSpend(address _sender) public view returns(uint256){
return citizen[_sender].citizenGameEthSpend+citizen[_sender].citizenTicketSpend;
}
function getMemberByLevelToTal(uint256 _level) public view returns(uint256, uint256){
address _sender = msg.sender;
return(citizen[_sender].refTo[_level].length,payOutByLevel[_sender][_level]);
}
function getMemberByLevel(uint256 _level, address _sender, uint256 _id) public view returns(address){
return citizen[_sender].refTo[_level][_id];
}
function citizenPayForRef(address _citizen, address _ref) public view returns(uint256){
return citizen[_ref].payOut[_citizen];
}
}File 3 of 3: CitizenStorage
pragma solidity ^0.4.24;
// pragma experimental ABIEncoderV2;
/**
* @title SafeMath
* @dev Math operations with safety checks that revert on error
*/
library SafeMath {
int256 constant private INT256_MIN = -2**255;
/**
* @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 Multiplies two signed integers, reverts on overflow.
*/
function mul(int256 a, int256 b) internal pure returns (int256) {
// 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;
}
require(!(a == -1 && b == INT256_MIN)); // This is the only case of overflow not detected by the check below
int256 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 Integer division of two signed integers truncating the quotient, reverts on division by zero.
*/
function div(int256 a, int256 b) internal pure returns (int256) {
require(b != 0); // Solidity only automatically asserts when dividing by 0
require(!(b == -1 && a == INT256_MIN)); // This is the only case of overflow
int256 c = a / b;
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 Subtracts two signed integers, reverts on overflow.
*/
function sub(int256 a, int256 b) internal pure returns (int256) {
int256 c = a - b;
require((b >= 0 && c <= a) || (b < 0 && c > a));
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 Adds two signed integers, reverts on overflow.
*/
function add(int256 a, int256 b) internal pure returns (int256) {
int256 c = a + b;
require((b >= 0 && c >= a) || (b < 0 && 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;
}
}
library Helper {
using SafeMath for uint256;
function bytes32ToUint(bytes32 n)
public
pure
returns (uint256)
{
return uint256(n);
}
function stringToBytes32(string memory source)
public
pure
returns (bytes32 result)
{
bytes memory tempEmptyStringTest = bytes(source);
if (tempEmptyStringTest.length == 0) {
return 0x0;
}
assembly {
result := mload(add(source, 32))
}
}
function stringToUint(string memory source)
public
pure
returns (uint256)
{
return bytes32ToUint(stringToBytes32(source));
}
function validUsername(string _username)
public
pure
returns(bool)
{
bytes memory b = bytes(_username);
// Im Raum [4, 18]
if ((b.length < 4) || (b.length > 18)) return false;
// Letzte Char != ' '
for(uint i; i<b.length; i++){
bytes1 char = b[i];
if(
!(char >= 0x30 && char <= 0x39) &&
!(char >= 0x41 && char <= 0x5A) //A-Z
)
return false;
}
if (b[0] >= 0x30 && b[0] <= 0x39) return false;
return true;
}
}
interface DAAInterface {
function citizenMintToken(address _buyer, uint256 _buyPrice, int8 _is_win) external returns(uint256);
function transfer(address _to, uint256 _value) external returns(bool);
function transferFrom(address _from, address _to, uint256 _tokenAmount) external returns(bool);
function balanceOf(address _from) external returns(uint256);
function currentRoundDividend() external;
function getDividendView(address _sender) external returns(uint256);
function getDividendPull(address _sender, uint256 _value) external returns(uint256);
function payOut(address _winner, uint256 _unit, uint256 _value, uint256 _valuebet) external;
function getCitizenBalanceEth(address _sender) external returns(uint256);
function totalSupplyByAddress(address _sender) external returns(uint256);
}
interface TicketInterface{
function getEarlyIncomePull(address _sender) external returns(uint256);
function getEarlyIncomeView(address _sender, bool _current) external returns(uint256);
function getEarlyIncomeByRound(address _buyer, uint256 _round) external returns(uint256);
function currentRound() external returns(uint256);
function ticketSumByAddress(address _sender) external returns(uint256);
}
contract CitizenStorage{
using SafeMath for uint256;
address controller;
modifier onlyCoreContract() {
require(msg.sender == controller, "admin required");
_;
}
mapping (address => uint256) public citizenWinIncome;
mapping (address => uint256) public citizenGameWinIncome;
mapping (address => uint256) public citizenWithdrawed;
function addWinIncome(address _citizen, uint256 _value) public onlyCoreContract() {
citizenWinIncome[_citizen] = _value.add(citizenWinIncome[_citizen]);
citizenWithdrawed[_citizen] = citizenWithdrawed[_citizen].add(_value);
}
function addGameWinIncome(address _citizen, uint256 _value, bool _enough) public onlyCoreContract() {
citizenGameWinIncome[_citizen] = _value.add(citizenGameWinIncome[_citizen]);
if (_enough){
citizenWithdrawed[_citizen] = citizenWithdrawed[_citizen].add(_value);
}
}
function pushCitizenWithdrawed(address _sender, uint256 _value) public onlyCoreContract(){
citizenWithdrawed[_sender] = citizenWithdrawed[_sender].add(_value);
}
constructor (address _contract)
public
{
require(controller== 0x0, "require setup");
controller = _contract;
}
}
contract Citizen{
using SafeMath for uint256;
// event Register(uint256 id, uint256 username, address indexed citizen, address indexed ref,
// uint256 ticket, uint256 ticketSpend, uint256 totalGameSpend, uint256 totalMined,
// uint256 dateJoin, uint256 totalWithdraw);
event Register(uint256 id, uint256 username, address indexed citizen, address indexed ref, uint256 ticketSpend, uint256 totalGameSpend, uint256 dateJoin);
modifier onlyAdmin() {
require(msg.sender == devTeam1, "admin required");
_;
}
modifier onlyCoreContract() {
require(isCoreContract[msg.sender], "admin required");
_;
}
modifier notRegistered(){
require(!isCitizen[msg.sender], "already exist");
_;
}
modifier registered(){
require(isCitizen[msg.sender], "must be a citizen");
_;
}
uint8[10] public TICKET_LEVEL_REF = [uint8(60),40,20,10,10,10,5,5,5,5];// 3 demical
uint8[10] public GAME_LEVEL_REF = [uint8(5),2,1,1,1,1,1,1,1,1];// 3 demical
struct Profile{
uint256 id;
uint256 username;
address ref;
mapping(uint => address[]) refTo;
mapping(address => uint256) payOut;
uint256 totalChild;
uint256 treeLevel;
uint256 citizenBalanceEth;
uint256 citizenBalanceEthBackup;
uint256 citizenTicketSpend;
uint256 citizenGameEthSpend;
uint256 citizenGameTokenSpend;
uint256 citizenEarlyIncomeRevenue;
uint256 citizenTicketRevenue;
uint256 citizenGameEthRevenue;
uint256 citizenGameTokenRevenue;
}
mapping (address => uint256) public citizenEthDividend;
address[21] public mostTotalSpender;
mapping (address => uint256) public mostTotalSpenderId;
mapping (address => mapping(uint256 => uint256)) public payOutByLevel;
mapping (address => Profile) public citizen;
mapping (address => bool) public isCitizen;
mapping (uint256 => address) public idAddress;
mapping (uint256 => address) public usernameAddress;
mapping (uint256 => address[]) public levelCitizen;
address devTeam1;
address devTeam2;
address devTeam3;
address devTeam4;
uint256 public citizenNr;
uint256 lastLevel;
uint256 earlyIncomeBalanceEth;
DAAInterface public DAAContract;
TicketInterface public TicketContract;
CitizenStorage public CitizenStorageContract;
mapping (address => bool) public isCoreContract;
uint256 public coreContractSum;
address[] public coreContracts;
constructor (address[4] _devTeam)
public
{
devTeam1 = _devTeam[0];
devTeam2 = _devTeam[1];
devTeam3 = _devTeam[2];
devTeam4 = _devTeam[3];
// first citizen is the development team
citizenNr = 1;
idAddress[1] = devTeam3;
isCitizen[devTeam3] = true;
//root => self ref
citizen[devTeam3].ref = devTeam3;
// username rules bypass
uint256 _username = Helper.stringToUint("GLOBAL");
citizen[devTeam3].username = _username;
usernameAddress[_username] = devTeam3;
citizen[devTeam3].id = 1;
citizen[devTeam3].treeLevel = 1;
levelCitizen[1].push(devTeam3);
lastLevel = 1;
}
// DAAContract, TicketContract, CitizenContract, CitizenStorage
function joinNetwork(address[4] _contract)
public
{
require(address(DAAContract) == 0x0,"already setup");
DAAContract = DAAInterface(_contract[0]);
TicketContract = TicketInterface(_contract[1]);
CitizenStorageContract = CitizenStorage(_contract[3]);
for(uint256 i =0; i<3; i++){
isCoreContract[_contract[i]]=true;
coreContracts.push(_contract[i]);
}
coreContractSum = 3;
}
function updateTotalChild(address _address)
private
{
address _member = _address;
while(_member != devTeam3) {
_member = getRef(_member);
citizen[_member].totalChild ++;
}
}
function addCoreContract(address _address) public // [dev1]
onlyAdmin()
{
require(_address!=0x0,"Invalid address");
isCoreContract[_address] = true;
coreContracts.push(_address);
coreContractSum+=1;
}
function updateRefTo(address _address) private {
address _member = _address;
uint256 level =1;
while (_member != devTeam3 && level<11){
_member = getRef(_member);
citizen[_member].refTo[level].push(_address);
level = level+1;
}
}
function register(string _sUsername, address _ref)
public
notRegistered()
{
require(Helper.validUsername(_sUsername), "invalid username");
address sender = msg.sender;
uint256 _username = Helper.stringToUint(_sUsername);
require(usernameAddress[_username] == 0x0, "username already exist");
usernameAddress[_username] = sender;
//ref must be a citizen, else ref = devTeam
address validRef = isCitizen[_ref] ? _ref : devTeam3;
//Welcome new Citizen
isCitizen[sender] = true;
citizen[sender].username = _username;
citizen[sender].ref = validRef;
citizenNr++;
idAddress[citizenNr] = sender;
citizen[sender].id = citizenNr;
uint256 refLevel = citizen[validRef].treeLevel;
if (refLevel == lastLevel) lastLevel++;
citizen[sender].treeLevel = refLevel + 1;
levelCitizen[refLevel + 1].push(sender);
//add child
updateRefTo(sender);
updateTotalChild(sender);
emit Register(citizenNr,_username, sender, validRef, citizen[sender].citizenTicketSpend, citizen[sender].citizenGameEthSpend, now);
}
// function updateUsername(string _sNewUsername)
// public
// registered()
// {
// require(Helper.validUsername(_sNewUsername), "invalid username");
// address sender = msg.sender;
// uint256 _newUsername = Helper.stringToUint(_sNewUsername);
// require(usernameAddress[_newUsername] == 0x0, "username already exist");
// uint256 _oldUsername = citizen[sender].username;
// citizen[sender].username = _newUsername;
// usernameAddress[_oldUsername] = 0x0;
// usernameAddress[_newUsername] = sender;
// }
function getRef(address _address)
public
view
returns (address)
{
return citizen[_address].ref == 0x0 ? devTeam3 : citizen[_address].ref;
}
function getUsername(address _address)
public
view
returns (uint256)
{
return citizen[_address].username;
}
function isDev() public view returns(bool){
if (msg.sender == devTeam1) return true;
return false;
}
function getAddressById(uint256 _id)
public
view
returns (address)
{
return idAddress[_id];
}
function getAddressByUserName(string _username)
public
view
returns (address)
{
return usernameAddress[Helper.stringToUint(_username)];
}
function pushTicketRefIncome(address _sender)
public
payable
onlyCoreContract()
{
uint256 _amount = msg.value; // 17%
_amount = _amount.div(170);
address sender = _sender;
address ref = getRef(sender);
uint256 money;
uint8 level;
for (level=0; level<10; level++){
money = _amount.mul(TICKET_LEVEL_REF[level]);
citizen[ref].citizenBalanceEth = money.add(citizen[ref].citizenBalanceEth);
citizen[ref].citizenTicketRevenue = money.add(citizen[ref].citizenTicketRevenue);
citizen[ref].payOut[_sender] = money.add(citizen[ref].payOut[_sender]);
payOutByLevel[ref][level+1] = money.add(payOutByLevel[ref][level+1]);
sender = ref;
ref = getRef(sender);
}
}
function pushGametRefIncome(address _sender)
public
payable
onlyCoreContract()
{
uint256 _amount = msg.value; // 1.5%
_amount = _amount.div(15);
address sender = _sender;
address ref = getRef(sender);
uint256 level;
uint256 money;
uint256 forDaa;
for (level=0; level<10; level++){
forDaa=0;
money = _amount.mul(GAME_LEVEL_REF[level]);
if (citizen[ref].citizenGameEthRevenue<citizen[ref].citizenGameEthSpend.div(10)){
if (citizen[ref].citizenGameEthRevenue+money>citizen[ref].citizenGameEthSpend.div(10)){
forDaa = citizen[ref].citizenGameEthRevenue+money-citizen[ref].citizenGameEthSpend.div(10);
money = money.sub(forDaa);
}
} else {
forDaa = money;
money = 0;
}
citizen[ref].citizenBalanceEth = money.add(citizen[ref].citizenBalanceEth);
citizen[ref].citizenGameEthRevenue = money.add(citizen[ref].citizenGameEthRevenue);
citizen[ref].payOut[_sender] = money.add(citizen[ref].payOut[_sender]);
payOutByLevel[ref][level+1] = money.add(payOutByLevel[ref][level+1]);
citizen[devTeam3].citizenBalanceEth = forDaa.add(citizen[devTeam3].citizenBalanceEth);
citizen[devTeam3].citizenGameEthRevenue = forDaa.add(citizen[devTeam3].citizenGameEthRevenue);
sender = ref;
ref = getRef(sender);
}
}
function pushGametRefIncomeToken(address _sender, uint256 _amount)
public
payable
onlyCoreContract()
{
_amount = _amount.div(15);
address sender = _sender;
address ref = getRef(sender);
uint256 level;
uint256 money;
uint256 forDaa;
for (level=0; level<10; level++){
forDaa=0;
money = _amount.mul(GAME_LEVEL_REF[level]);
if (citizen[ref].citizenGameTokenRevenue<citizen[ref].citizenGameTokenSpend.div(10)){
if (citizen[ref].citizenGameTokenRevenue+money>citizen[ref].citizenGameTokenSpend.div(10)){
forDaa = citizen[ref].citizenGameTokenRevenue+money-citizen[ref].citizenGameTokenSpend.div(10);
money = money.sub(forDaa);
}
} else {
forDaa = money;
money = 0;
}
DAAContract.payOut(ref,1,money,0);
citizen[ref].citizenGameTokenRevenue=money.add(citizen[ref].citizenGameTokenRevenue);
DAAContract.payOut(devTeam3,1,forDaa,0);
citizen[devTeam3].citizenGameTokenRevenue = forDaa.add(citizen[devTeam3].citizenGameTokenRevenue);
sender = ref;
ref = getRef(sender);
}
}
function pushEarlyIncome() public payable{
uint256 _value = msg.value;
earlyIncomeBalanceEth = earlyIncomeBalanceEth.add(_value);
}
function sortMostSpend(address _citizen) private {
uint256 citizen_spender = getTotalSpend(_citizen);
uint256 i=1;
while (i<21) {
if (mostTotalSpender[i]==0x0||(mostTotalSpender[i]!=0x0&&getTotalSpend(mostTotalSpender[i])<citizen_spender)){
if (mostTotalSpenderId[_citizen]!=0&&mostTotalSpenderId[_citizen]<i){
break;
}
if (mostTotalSpenderId[_citizen]!=0){
mostTotalSpender[mostTotalSpenderId[_citizen]]=0x0;
}
address temp1 = mostTotalSpender[i];
address temp2;
uint256 j=i+1;
while (j<21&&temp1!=0x0){
temp2 = mostTotalSpender[j];
mostTotalSpender[j]=temp1;
mostTotalSpenderId[temp1]=j;
temp1 = temp2;
j++;
}
mostTotalSpender[i]=_citizen;
mostTotalSpenderId[_citizen]=i;
break;
}
i++;
}
}
function addTicketEthSpend(address _citizen, uint256 _value) onlyCoreContract() public {
citizen[_citizen].citizenTicketSpend = citizen[_citizen].citizenTicketSpend.add(_value);
DAAContract.citizenMintToken(_citizen,_value,0);// buy ticket 0, win 1, lose -1;
sortMostSpend(_citizen);
}
// Game spend
function addGameEthSpendWin(address _citizen, uint256 _value, uint256 _valuewin, bool _enough) onlyCoreContract() public {
citizen[_citizen].citizenGameEthSpend = citizen[_citizen].citizenGameEthSpend.add(_value);
// DAAContract.citizenMintToken(_citizen,_value,1);// buy ticket 0, win 1, lose -1;
CitizenStorageContract.addGameWinIncome(_citizen, _valuewin, _enough);
sortMostSpend(_citizen);
}
function addGameEthSpendLose(address _citizen, uint256 _value) onlyCoreContract() public {
citizen[_citizen].citizenGameEthSpend = citizen[_citizen].citizenGameEthSpend.add(_value);
DAAContract.citizenMintToken(_citizen,_value,-1);// buy ticket 0, win 1, lose -1;
sortMostSpend(_citizen);
}
function addGameTokenSpend(address _citizen, uint256 _value) onlyCoreContract() public {
citizen[_citizen].citizenGameTokenSpend = citizen[_citizen].citizenGameTokenSpend.add(_value);
}
function withdrawEth() public registered() {
address _sender = msg.sender;
uint256 _earlyIncome = TicketContract.getEarlyIncomePull(_sender);
uint256 _devidend = DAAContract.getDividendView(msg.sender);
uint256 _citizenBalanceEth = citizen[_sender].citizenBalanceEth;
uint256 _total = _earlyIncome.add(_devidend).add(_citizenBalanceEth).add(DAAContract.getCitizenBalanceEth(_sender));
require(_total>0,"Balance none");
CitizenStorageContract.pushCitizenWithdrawed(_sender,_total);
DAAContract.getDividendPull(_sender,_citizenBalanceEth+_earlyIncome);
_sender.transfer(_citizenBalanceEth+_earlyIncome);
citizen[_sender].citizenBalanceEthBackup = citizen[_sender].citizenBalanceEthBackup.add(_citizenBalanceEth).add(_earlyIncome).add(_devidend);
citizen[_sender].citizenEarlyIncomeRevenue = citizen[_sender].citizenEarlyIncomeRevenue.add(_earlyIncome);
citizenEthDividend[_sender] = citizenEthDividend[_sender].add(_devidend);
earlyIncomeBalanceEth= earlyIncomeBalanceEth.sub(_earlyIncome);
citizen[_sender].citizenBalanceEth = 0;
}
function addWinIncome(address _citizen, uint256 _value) onlyCoreContract() public {
CitizenStorageContract.addWinIncome(_citizen, _value);
}
// function addGameWinIncome(address _citizen, uint256 _value, bool _enough) public {
// CitizenStorageContract.addGameWinIncome(_citizen, _value, _enough);
// }
// function getInWallet() public view returns (uint256){
// uint256 _sum;
// address _sender = msg.sender;
// _sum = _sum.add(citizen[_sender].citizenBalanceEth);
// _sum = _sum.add(TicketContract.getEarlyIncomeView(_sender));
// _sum = _sum.add(DAAContract.getDividendView(_sender));
// _sum = _sum.add(DAAContract.getCitizenBalanceEth(_sender));
// return _sum;
// }
function getTotalEth() public registered() view returns(uint256){
uint256 _sum;
address _sender = msg.sender;
_sum = _sum.add(citizen[_sender].citizenBalanceEth);
_sum = _sum.add(citizen[_sender].citizenBalanceEthBackup);
_sum = _sum.add(CitizenStorageContract.citizenWinIncome(_sender));
_sum = _sum.add(TicketContract.getEarlyIncomeView(_sender, false));
_sum = _sum.add(DAAContract.getDividendView(_sender));
return _sum;
}
function getTotalDividend(address _sender) public registered() view returns(uint256){
return citizenEthDividend[_sender].add(DAAContract.getDividendView(_sender));
}
function getTotalEarlyIncome(address _sender) public registered() view returns(uint256){
uint256 _sum;
_sum = citizen[_sender].citizenEarlyIncomeRevenue;
_sum = _sum.add(TicketContract.getEarlyIncomeView(_sender, true));
return _sum;
}
function getTotalSpend(address _sender) public view returns(uint256){
return citizen[_sender].citizenGameEthSpend+citizen[_sender].citizenTicketSpend;
}
function getMemberByLevelToTal(uint256 _level) public view returns(uint256, uint256){
address _sender = msg.sender;
return(citizen[_sender].refTo[_level].length,payOutByLevel[_sender][_level]);
}
function getMemberByLevel(uint256 _level, address _sender, uint256 _id) public view returns(address){
return citizen[_sender].refTo[_level][_id];
}
function citizenPayForRef(address _citizen, address _ref) public view returns(uint256){
return citizen[_ref].payOut[_citizen];
}
}