ETH Price: $2,439.00 (+0.46%)

Transaction Decoder

Block:
5702637 at May-30-2018 12:44:35 PM +UTC
Transaction Fee:
0.002993914 ETH $7.30
Gas Used:
213,851 Gas / 14 Gwei

Emitted Events:

182 IronHands.Deposit( amount=50000000000000000, depositer=[Sender] 0x94debc57081c4c58dd69f4dfce589b82fc3c2866 )
183 REV1.onWithdraw( customerAddress=[Receiver] IronHands, ethereumWithdrawn=51236710021299 )
184 IronHands.Dividends( amount=51236710021299 )
185 REV1.onTokenPurchase( customerAddress=[Receiver] IronHands, incomingEthereum=12512809177505324, tokensMinted=6016840590738141609, referredBy=[Sender] 0x94debc57081c4c58dd69f4dfce589b82fc3c2866 )
186 IronHands.Purchase( amountSpent=12512809177505324, tokensReceived=0 )
187 IronHands.Payout( amount=37538427532515975, creditor=0x22db120459576ee9db8ba925568530e9e0f3d33c )

Account State Difference:

  Address   Before After State Difference Code
0x05215FCE...31DBCE69A 205.809330953800956858 Eth205.821792526268440883 Eth0.012461572467484025
0x22DB1204...9e0F3d33C 0.726199493500370982 Eth0.763737921032886957 Eth0.037538427532515975
(Spark Pool)
1,479.035323228963813087 Eth1,479.038317142963813087 Eth0.002993914
0x94DEbC57...2fc3C2866
1.118780711624870146 Eth
Nonce: 589
1.065786797624870146 Eth
Nonce: 590
0.052993914
0xa5629861...665Eb1c05

Execution Trace

ETH 0.05 IronHands.CALL( )
  • REV1.myDividends( _includeReferralBonus=True ) => ( 51236710021299 )
  • REV1.CALL( )
    • ETH 0.000051236710021299 IronHands.CALL( )
    • ETH 0.012512809177505324 REV1.buy( _referredBy=0x94DEbC57081C4c58Dd69F4DFCE589b82fc3C2866 ) => ( 0 )
    • ETH 0.037538427532515975 0x22db120459576ee9db8ba925568530e9e0f3d33c.CALL( )
      File 1 of 2: IronHands
      pragma solidity ^0.4.21;
      
      /**
       * 
       * 
       *                
       *
       * ATTENTION!
       * 
       * This code? IS NOT DESIGNED FOR ACTUAL USE.
       * 
       * The author of this code really wishes you wouldn't send your ETH to it, but it's been
       * done with P3D and there are very happy users because of it.
       * 
       * No, seriously. It's probablly illegal anyway. So don't do it.
       * 
       * Let me repeat that: Don't actually send money to this contract. You are 
       * likely breaking several local and national laws in doing so.
       * 
       * This code is intended to educate. Nothing else. If you use it, expect S.W.A.T 
       * teams at your door. I wrote this code because I wanted to experiment
       * with smart contracts, and I think code should be open source. So consider
       * it public domain, No Rights Reserved. Participating in pyramid schemes
       * is genuinely illegal so just don't even think about going beyond
       * reading the code and understanding how it works.
       * 
       * Seriously. I'm not kidding. It's probablly broken in some critical way anyway
       * and will suck all your money out your wallet, install a virus on your computer
       * sleep with your wife, kidnap your children and sell them into slavery,
       * make you forget to file your taxes, and give you cancer.
       * 
       * 
       * What it does:
       * 
       * It takes 50% of the ETH in it and buys tokens.
       * It takes 50% of the ETH in it and pays back depositors.
       * Depositors get in line and are paid out in order of deposit, plus the deposit
       * percent.
       * The tokens collect dividends, which in turn pay into the payout pool
       * to be split 50/50.
       * 
       * If you're seeing this contract in it's initial configuration, it should be
       * set to 200% (double deposits), and pointed at PoWH:
       * 0xB3775fB83F7D12A36E0475aBdD1FCA35c091efBe
       * 
       * But you should verify this for yourself.
       *  
       *  
       */
      
      contract ERC20Interface {
          function transfer(address to, uint256 tokens) public returns (bool success);
      }
      
      contract REV {
          
          function buy(address) public payable returns(uint256);
          function withdraw() public;
          function myTokens() public view returns(uint256);
          function myDividends(bool) public view returns(uint256);
      }
      
      contract Owned {
          address public owner;
          address public ownerCandidate;
      
          constructor() public {
              owner = 0xc42559F88481e1Df90f64e5E9f7d7C6A34da5691;
          }
      
          modifier onlyOwner {
              require(msg.sender == owner);
              _;
          }
          
          function changeOwner(address _newOwner) public onlyOwner {
              ownerCandidate = _newOwner;
          }
          
          function acceptOwnership() public {
              require(msg.sender == ownerCandidate);  
              owner = ownerCandidate;
          }
          
      }
      
      contract IronHands is Owned {
          
          /**
           * Modifiers
           */
           
          /**
           * Only owners are allowed.
           */
          modifier onlyOwner(){
              require(msg.sender == owner);
              _;
          }
          
          /**
           * The tokens can never be stolen.
           */
          modifier notPooh(address aContract){
              require(aContract != address(weak_hands));
              _;
          }
      
          modifier limitBuy() { 
              if(msg.value > limit) { // check if the transaction is over limit eth (1000 finney = 1 eth)
                  revert(); // if so : revert the transaction
                  
              }
              _;
          }
         
          /**
           * Events
           */
          event Deposit(uint256 amount, address depositer);
          event Purchase(uint256 amountSpent, uint256 tokensReceived);
          event Payout(uint256 amount, address creditor);
          event Dividends(uint256 amount);
         
          /**
           * Structs
           */
          struct Participant {
              address etherAddress;
              uint256 payout;
          }
      
          //Total ETH managed over the lifetime of the contract
          uint256 throughput;
          //Total ETH received from dividends
          uint256 dividends;
          //The percent to return to depositers. 100 for 00%, 200 to double, etc.
          uint256 public multiplier;
          //Where in the line we are with creditors
          uint256 public payoutOrder = 0;
          //How much is owed to people
          uint256 public backlog = 0;
          //The creditor line
          Participant[] public participants;
          //How much each person is owed
          mapping(address => uint256) public creditRemaining;
          //What we will be buying
          REV weak_hands;
          // Limitation
          uint256 public limit = 50 finney; // 1000 = 1eth, 100 = 0,1 eth | 50 finney = 0.05 eth
      
          /**
           * Constructor
           */
           /*  */
          constructor() public {
              address cntrct = 0x05215FCE25902366480696F38C3093e31DBCE69A; // contract address
              multiplier = 125; // 200 to double | 125 = 25% more
              weak_hands = REV(cntrct);
          }
          
          
          /**
           * Fallback function allows anyone to send money for the cost of gas which
           * goes into the pool. Used by withdraw/dividend payouts so it has to be cheap.
           */
          function() payable public {
          }
          
          /**
           * Deposit ETH to get in line to be credited back the multiplier as a percent,
           * add that ETH to the pool, get the dividends and put them in the pool,
           * then pay out who we owe and buy more tokens.
           */ 
          function deposit() payable public limitBuy() {
              //You have to send more than 1000000 wei.
              require(msg.value > 1000000);
              //Compute how much to pay them
              uint256 amountCredited = (msg.value * multiplier) / 100;
              //Get in line to be paid back.
              participants.push(Participant(msg.sender, amountCredited));
              //Increase the backlog by the amount owed
              backlog += amountCredited;
              //Increase the amount owed to this address
              creditRemaining[msg.sender] += amountCredited;
              //Emit a deposit event.
              emit Deposit(msg.value, msg.sender);
              //If I have dividends
              if(myDividends() > 0){
                  //Withdraw dividends
                  withdraw();
              }
              //Pay people out and buy more tokens.
              payout();
          }
          
          /**
           * Take 25% of the money and spend it on tokens, which will pay dividends later.
           * Take the other 75%, and use it to pay off depositors.
           */
          function payout() public {
              //Take everything in the pool
              uint balance = address(this).balance;
              //It needs to be something worth splitting up
              require(balance > 1);
              //Increase our total throughput
              throughput += balance;
              //calculate 25% of investment
              uint256 investment = balance / 4;
              //Take away the amount we are investing(25%) from the amount to send(75%)
              balance -= investment;
              //Invest it in more tokens.
              uint256 tokens = weak_hands.buy.value(investment).gas(1000000)(msg.sender);
              //Record that tokens were purchased
              emit Purchase(investment, tokens);
              //While we still have money to send
              while (balance > 0) {
                  //Either pay them what they are owed or however much we have, whichever is lower.
                  uint payoutToSend = balance < participants[payoutOrder].payout ? balance : participants[payoutOrder].payout;
                  //if we have something to pay them
                  if(payoutToSend > 0){
                      //subtract how much we've spent
                      balance -= payoutToSend;
                      //subtract the amount paid from the amount owed
                      backlog -= payoutToSend;
                      //subtract the amount remaining they are owed
                      creditRemaining[participants[payoutOrder].etherAddress] -= payoutToSend;
                      //credit their account the amount they are being paid
                      participants[payoutOrder].payout -= payoutToSend;
                      //Try and pay them, making best effort. But if we fail? Run out of gas? That's not our problem any more.
                      if(participants[payoutOrder].etherAddress.call.value(payoutToSend).gas(1000000)()){
                          //Record that they were paid
                          emit Payout(payoutToSend, participants[payoutOrder].etherAddress);
                      }else{
                          //undo the accounting, they are being skipped because they are not payable.
                          balance += payoutToSend;
                          backlog += payoutToSend;
                          creditRemaining[participants[payoutOrder].etherAddress] += payoutToSend;
                          participants[payoutOrder].payout += payoutToSend;
                      }
      
                  }
                  //If we still have balance left over
                  if(balance > 0){
                      // go to the next person in line
                      payoutOrder += 1;
                  }
                  //If we've run out of people to pay, stop
                  if(payoutOrder >= participants.length){
                      return;
                  }
              }
          }
          
          /**
           * Number of tokens the contract owns.
           */
          function myTokens() public view returns(uint256){
              return weak_hands.myTokens();
          }
          
          /**
           * Number of dividends owed to the contract.
           */
          function myDividends() public view returns(uint256){
              return weak_hands.myDividends(true);
          }
          
          /**
           * Number of dividends received by the contract.
           */
          function totalDividends() public view returns(uint256){
              return dividends;
          }
          
          
          /**
           * Request dividends be paid out and added to the pool.
           */
          function withdraw() public {
              uint256 balance = address(this).balance;
              weak_hands.withdraw.gas(1000000)();
              uint256 dividendsPaid = address(this).balance - balance;
              dividends += dividendsPaid;
              emit Dividends(dividendsPaid);
          }
          
          /**
           * Number of participants who are still owed.
           */
          function backlogLength() public view returns (uint256){
              return participants.length - payoutOrder;
          }
          
          /**
           * Total amount still owed in credit to depositors.
           */
          function backlogAmount() public view returns (uint256){
              return backlog;
          } 
          
          /**
           * Total number of deposits in the lifetime of the contract.
           */
          function totalParticipants() public view returns (uint256){
              return participants.length;
          }
          
          /**
           * Total amount of ETH that the contract has delt with so far.
           */
          function totalSpent() public view returns (uint256){
              return throughput;
          }
          
          /**
           * Amount still owed to an individual address
           */
          function amountOwed(address anAddress) public view returns (uint256) {
              return creditRemaining[anAddress];
          }
           
           /**
            * Amount owed to this person.
            */
          function amountIAmOwed() public view returns (uint256){
              return amountOwed(msg.sender);
          }
          
          /**
           * A trap door for when someone sends tokens other than the intended ones so the overseers can decide where to send them.
           */
          function transferAnyERC20Token(address tokenAddress, address tokenOwner, uint tokens) public onlyOwner notPooh(tokenAddress) returns (bool success) {
              return ERC20Interface(tokenAddress).transfer(tokenOwner, tokens);
          }
          
          function changeLimit(uint256 newLimit) public onlyOwner returns (uint256) {
              limit = newLimit * 1 finney;
              return limit;
          }
      }

      File 2 of 2: REV1
      pragma solidity ^0.4.20;
      
      
      /*
      * 
      * REVOLUTION1
      *
      * A new concept in profit sharing and giving back to the community
      *
      */
      
      contract REV1 {
          /*=================================
          =            MODIFIERS            =
          =================================*/
          // only people with tokens
          modifier onlyBagholders() {
              require(myTokens() > 0);
              _;
          }
          
          // only people with profits
          modifier onlyStronghands() {
              require(myDividends(true) > 0);
              _;
          }
          
          // administrators can:
          // -> change the name of the contract
          // -> change the name of the token
          // -> change the PoS difficulty (How many tokens it costs to hold a masternode, in case it gets crazy high later)
          // they CANNOT:
          // -> take funds
          // -> disable withdrawals
          // -> kill the contract
          // -> change the price of tokens
          modifier onlyAdministrator(){
              address _customerAddress = msg.sender;
              require(administrators[keccak256(_customerAddress)]);
              _;
          }
          
          //fvrr2 ensure that every buy transaction has a maximum of 1 ETH when the contract reaches 10 ETH
          modifier limitBuy() { 
              if(msg.value > 1 ether) { // check if the transaction is over 1ether
                  if (address(this).balance >= 10 ether) { // if so check if the contract has over 10 ether
                      revert(); // if so : revert the transaction
                  }
              }
              _;
          }
      
          /*==============================
          =            EVENTS            =
          ==============================*/
          event onTokenPurchase(
              address indexed customerAddress,
              uint256 incomingEthereum,
              uint256 tokensMinted,
              address indexed referredBy
          );
          
          event onTokenSell(
              address indexed customerAddress,
              uint256 tokensBurned,
              uint256 ethereumEarned
          );
          
          event onReinvestment(
              address indexed customerAddress,
              uint256 ethereumReinvested,
              uint256 tokensMinted
          );
          
          event onWithdraw(
              address indexed customerAddress,
              uint256 ethereumWithdrawn
          );
          
          // ERC20
          event Transfer(
              address indexed from,
              address indexed to,
              uint256 tokens
          );
          
          
          /*=====================================
          =            CONFIGURABLES            =
          =====================================*/
          string public name = "REV1";
          string public symbol = "REV1";
          uint8 constant public decimals = 18;
          uint8 constant internal dividendFee_ = 10;
          uint256 constant internal tokenPriceInitial_ = 0.0000001 ether;
          uint256 constant internal tokenPriceIncremental_ = 0.00000001 ether;
          uint256 constant internal magnitude = 2**64;
          
          // proof of stake (defaults at 100 tokens)
          uint256 public stakingRequirement = 5e18;
          
          // ambassador program
          mapping(address => bool) internal ambassadors_;
          
          
          
         /*================================
          =            DATASETS            =
          ================================*/
          // amount of shares for each address (scaled number)
          mapping(address => uint256) internal tokenBalanceLedger_;
          mapping(address => uint256) public   ambassadorLedger;
          mapping(address => uint256) internal referralBalance_;
          mapping(address => int256) internal payoutsTo_;
          uint256 internal tokenSupply_ = 0;
          uint256 internal ambassadorSupply = 0; // fvrr is important to be able to view the REAL supply with ambassador tokens but still receiving his dividends.
          uint256 internal profitPerShare_;
          mapping(address => bool) internal whitelisted_; // fvrr3
          bool internal whitelist_ = true; // fvrr3 whitelist is automatically activated
          
          // administrator list (see above on what they can do)
          mapping(bytes32 => bool) public administrators;
          
      
      
          /*=======================================
          =            PUBLIC FUNCTIONS            =
          =======================================*/
          /*
          * -- APPLICATION ENTRY POINTS --  
          */
          constructor()
              public
          {
              // add administrators here
              //No ambassadors aside from the WHALE
              
      
              // add the ambassadors here. 
              ambassadors_[0x7301494d217C50557f4b2A515F0c65FA9b302641] = true; //D
      
              whitelisted_[0x7301494d217C50557f4b2A515F0c65FA9b302641] = true;
              whitelisted_[0xB093E319f94c02604FdDD57701Cd5C34F71d6f3d] = true;
              whitelisted_[0xc42559F88481e1Df90f64e5E9f7d7C6A34da5691] = true;
              whitelisted_[0xd72998ab5681d8EA37D16Ad9bf3aE50b4C693289] = true;
              whitelisted_[0x3B37F823108A1BF7cdb0c6626b473e3bC9D21621] = true;
      
      
          }
          
           
          /**
           * Converts all incoming ethereum to tokens for the caller, and passes down the referral addy (if any)
           */
          function buy(address _referredBy)
              public
              payable
              returns(uint256)
          {
              excludeAmbassadors(msg.value, _referredBy); // fvrr : just a tag so I can easily search for parts that I changed
          }
          
          /**
           * Fallback function to handle ethereum that was send straight to the contract
           * Unfortunately we cannot use a referral address this way.
           */
          function()
              payable
              public
          {
              excludeAmbassadors(msg.value, 0x0); // fvrr : just a tag so I can easily search for parts that I changed
          }
          
          /**
           * Converts all of caller's dividends to tokens.
           */
          function reinvest()
              onlyStronghands()
              public
          {   
              // fetch dividends
              uint256 _dividends = myDividends(false); // retrieve ref. bonus later in the code
              
              // pay out the dividends virtually
              address _customerAddress = msg.sender;
              require(ambassadors_[_customerAddress] == false); //fvrr ambassador can't reinvest tokens
              payoutsTo_[_customerAddress] +=  (int256) (_dividends * magnitude);
              
              // retrieve ref. bonus
              _dividends += referralBalance_[_customerAddress];
              referralBalance_[_customerAddress] = 0;
              
              // dispatch a buy order with the virtualized "withdrawn dividends"
              uint256 _tokens = purchaseTokens(_dividends, 0x0);
              
              // fire event
              emit onReinvestment(_customerAddress, _dividends, _tokens);
          }
          
          /**
           * Alias of sell() and withdraw().
           */
          function exit()
              public
          {
              // get token count for caller & sell them all
              address _customerAddress = msg.sender;
              uint256 _tokens = tokenBalanceLedger_[_customerAddress];
              if(_tokens > 0) sell(_tokens);
              
              // lambo delivery service
              withdraw();
          }
      
          /**
           * Withdraws all of the callers earnings.
           */
          function withdraw()
              onlyStronghands()
              public
          {
              // setup data
              address _customerAddress = msg.sender;
              uint256 _dividends = myDividends(false); // get ref. bonus later in the code
              
              // update dividend tracker
              payoutsTo_[_customerAddress] +=  (int256) (_dividends * magnitude);
              
              // add ref. bonus
              _dividends += referralBalance_[_customerAddress];
              referralBalance_[_customerAddress] = 0;
              
              // lambo delivery service
              _customerAddress.transfer(_dividends);
              
              // fire event
              emit onWithdraw(_customerAddress, _dividends);
          }
          
          /**
           * Liquifies tokens to ethereum.
           */
          function sell(uint256 _amountOfTokens)
              onlyBagholders()
              public
          {
              // setup data
              address _customerAddress = msg.sender;
              require(ambassadors_[_customerAddress] == false); //fvrr ambassador can't sell tokens
              // russian hackers BTFO
              require(_amountOfTokens <= tokenBalanceLedger_[_customerAddress]);
              uint256 _tokens = _amountOfTokens;
              uint256 _ethereum = tokensToEthereum_(_tokens);
              uint256 _dividends = SafeMath.div(_ethereum, dividendFee_);
              uint256 _taxedEthereum = SafeMath.sub(_ethereum, _dividends);
              
              // burn the sold tokens
              tokenSupply_ = SafeMath.sub(tokenSupply_, _tokens);
              tokenBalanceLedger_[_customerAddress] = SafeMath.sub(tokenBalanceLedger_[_customerAddress], _tokens);
              
              // update dividends tracker
              int256 _updatedPayouts = (int256) (profitPerShare_ * _tokens + (_taxedEthereum * magnitude));
              payoutsTo_[_customerAddress] -= _updatedPayouts;       
              
              // dividing by zero is a bad idea
              if (tokenSupply_ > 0) {
                  // update the amount of dividends per token
                  profitPerShare_ = SafeMath.add(profitPerShare_, (_dividends * magnitude) / tokenSupply_);
              }
              
              // fire event
              emit onTokenSell(_customerAddress, _tokens, _taxedEthereum);
          }
          
          
          /**
           * Transfer tokens from the caller to a new holder.
           * Remember, there's a 10% fee here as well.
           */
          function transfer(address _toAddress, uint256 _amountOfTokens)
              onlyBagholders()
              public
              returns(bool)
          {
              // setup
              address _customerAddress = msg.sender;
              require(ambassadors_[_customerAddress] == false && ambassadors_[_toAddress] == false); //fvrr ambassador can't transfer tokens or receive tokens
              
              // make sure we have the requested tokens
              // also disables transfers until ambassador phase is over
              // ( we dont want whale premines )
              require(_amountOfTokens <= tokenBalanceLedger_[_customerAddress]);
              
              // withdraw all outstanding dividends first
              if(myDividends(true) > 0) withdraw();
              
              // liquify 10% of the tokens that are transfered
              // these are dispersed to shareholders
              //uint256 _tokenFee = SafeMath.div(_amountOfTokens, dividendFee_); // fvrr2 disable dividends
              //uint256 _taxedTokens = SafeMath.sub(_amountOfTokens, _tokenFee); // fvrr2 disable dividends
              //uint256 _dividends = tokensToEthereum_(_tokenFee); // fvrr2 disable dividends
        
              // burn the fee tokens
              //tokenSupply_ = SafeMath.sub(tokenSupply_, _tokenFee); // fvrr2 disable dividends
      
              // exchange tokens
              tokenBalanceLedger_[_customerAddress] = SafeMath.sub(tokenBalanceLedger_[_customerAddress], _amountOfTokens);
              tokenBalanceLedger_[_toAddress] = SafeMath.add(tokenBalanceLedger_[_toAddress], _amountOfTokens); // fvrr2 _taxedTokens = _amountOfTokens
              
              // update dividend trackers
              payoutsTo_[_customerAddress] -= (int256) (profitPerShare_ * _amountOfTokens);
              payoutsTo_[_toAddress] += (int256) (profitPerShare_ * _amountOfTokens); // fvrr2 _taxedTokens = _amountOfTokens
              
              // disperse dividends among holders
              //profitPerShare_ = SafeMath.add(profitPerShare_, (_dividends * magnitude) / tokenSupply_); // fvrr2 disable dividends
              
              // fire event
              emit Transfer(_customerAddress, _toAddress, _amountOfTokens); // fvrr2 _taxedTokens = _amountOfTokens
              
              // ERC20
              return true;
             
          }
          
          /*----------  ADMINISTRATOR ONLY FUNCTIONS  ----------*/
      
          /**
           * In case one of us dies, we need to replace ourselves.
           */
          function setAdministrator(bytes32 _identifier, bool _status)
              onlyAdministrator()
              public
          {
              administrators[_identifier] = _status;
          }
          
          /**
           * Precautionary measures in case we need to adjust the masternode rate.
           */
          function setStakingRequirement(uint256 _amountOfTokens)
              onlyAdministrator()
              public
          {
              stakingRequirement = _amountOfTokens;
          }
          
          /**
           * If we want to rebrand, we can.
           */
          function setName(string _name)
              onlyAdministrator()
              public
          {
              name = _name;
          }
          
          /**
           * If we want to rebrand, we can.
           */
          function setSymbol(string _symbol)
              onlyAdministrator()
              public
          {
              symbol = _symbol;
          }
      
          
          /*----------  HELPERS AND CALCULATORS  ----------*/
          /**
           * Method to view the current Ethereum stored in the contract
           * Example: totalEthereumBalance()
           */
          function totalEthereumBalance()
              public
              view
              returns(uint)
          {
              return address (this).balance;
          }
          
          /**
           * Retrieve the total token supply.
           */
          function totalSupply()
              public
              view
              returns(uint256)
          {
              return tokenSupply_ + ambassadorSupply; // fvrr adds the tokens from ambassadors to the supply (but not to the dividends calculation which is based on the supply)
          }
          
          /**
           * Retrieve the tokens owned by the caller.
           */
          function myTokens()
              public
              view
              returns(uint256)
          {
              address _customerAddress = msg.sender;
              return balanceOf(_customerAddress);
          }
          
          /**
           * Retrieve the dividends owned by the caller.
           * If `_includeReferralBonus` is to to 1/true, the referral bonus will be included in the calculations.
           * The reason for this, is that in the frontend, we will want to get the total divs (global + ref)
           * But in the internal calculations, we want them separate. 
           */ 
          function myDividends(bool _includeReferralBonus) 
              public 
              view 
              returns(uint256)
          {
              address _customerAddress = msg.sender;
              return _includeReferralBonus ? dividendsOf(_customerAddress) + referralBalance_[_customerAddress] : dividendsOf(_customerAddress) ;
          }
          
          /**
           * Retrieve the token balance of any single address.
           */
          function balanceOf(address _customerAddress)
              view
              public
              returns(uint256)
          {
              uint256 balance;
              if (ambassadors_[msg.sender] == true) { // changement here so the ambassador still sees his special amount of tokens
                  balance = ambassadorLedger[_customerAddress]; // fvrr : just a tag so I can easily search for parts that I changed
              }
              else {
                  balance = tokenBalanceLedger_[_customerAddress];
              }
              return balance;
          }
          
          /**
           * Retrieve the dividend balance of any single address.
           */
          function dividendsOf(address _customerAddress)
              view
              public
              returns(uint256)
          {
              return (uint256) ((int256)(profitPerShare_ * tokenBalanceLedger_[_customerAddress]) - payoutsTo_[_customerAddress]) / magnitude;
          }
          
          /**
           * Return the buy price of 1 individual token.
           */
          function sellPrice() 
              public 
              view 
              returns(uint256)
          {
              // our calculation relies on the token supply, so we need supply. Doh.
              if(tokenSupply_+ambassadorSupply == 0){ // fvrr changed so they see the correct price with ambassadorSupply
                  return tokenPriceInitial_ - tokenPriceIncremental_;
              } else {
                  uint256 _ethereum = tokensToEthereum_(1e18);
                  uint256 _dividends = SafeMath.div(_ethereum, dividendFee_  );
                  uint256 _taxedEthereum = SafeMath.sub(_ethereum, _dividends);
                  return _taxedEthereum;
              }
          }
          
          /**
           * Return the sell price of 1 individual token.
           */
          function buyPrice() 
              public 
              view 
              returns(uint256)
          {
              // our calculation relies on the token supply, so we need supply. Doh.
              if(tokenSupply_+ambassadorSupply == 0){ // fvrr changed so they see the correct price with ambassadorSupply
                  return tokenPriceInitial_ + tokenPriceIncremental_;
              } else {
                  uint256 _ethereum = tokensToEthereum_(1e18);
                  uint256 _dividends = SafeMath.div(_ethereum, dividendFee_  );
                  uint256 _taxedEthereum = SafeMath.add(_ethereum, _dividends);
                  return _taxedEthereum;
              }
          }
          
          /**
           * Function for the frontend to dynamically retrieve the price scaling of buy orders.
           */
          function calculateTokensReceived(uint256 _ethereumToSpend) 
              public 
              view 
              returns(uint256)
          {
              uint256 _dividends = SafeMath.div(_ethereumToSpend, dividendFee_);
              uint256 _taxedEthereum = SafeMath.sub(_ethereumToSpend, _dividends);
              uint256 _amountOfTokens = ethereumToTokens_(_taxedEthereum);
              
              return _amountOfTokens;
          }
          
          /**
           * Function for the frontend to dynamically retrieve the price scaling of sell orders.
           */
          function calculateEthereumReceived(uint256 _tokensToSell) 
              public 
              view 
              returns(uint256)
          {
              require(_tokensToSell <= tokenSupply_);
              uint256 _ethereum = tokensToEthereum_(_tokensToSell);
              uint256 _dividends = SafeMath.div(_ethereum, dividendFee_);
              uint256 _taxedEthereum = SafeMath.sub(_ethereum, _dividends);
              return _taxedEthereum;
          }
          
          function disableWhitelist() public returns(bool){
              require(ambassadors_[msg.sender] == true);
              whitelist_ = false;
      
              return whitelist_;
          }
          /*==========================================
          =            INTERNAL FUNCTIONS            =
          ==========================================*/
          function excludeAmbassadors(uint256 _incomingEthereum, address _referredBy) internal returns(uint256) { // fvrr : just a tag so I can easily search for parts that I changed
              address _customerAddress = msg.sender;
              uint256 StokenAmount;
      
              //fvrr3 if the whitelist is true only whitelisted people are allowed to buy.
              //whitelist
              if((msg.value) < address(this).balance && (address(this).balance-(msg.value)) >= 7 ether) { 
                  whitelist_ = false; 
                  }
      
              if (whitelisted_[msg.sender] == false && whitelist_ == true) { // if the person is not whitelisted but whitelist is true/active, revert the transaction
                  revert();
              }
      
              StokenAmount = purchaseTokens(msg.value, _referredBy); //redirects to purchaseTokens so same functionality
      
              if (ambassadors_[_customerAddress] == true) { // special treatment of ambassador addresses (only for them)
      
                  tokenSupply_ = SafeMath.sub(tokenSupply_, StokenAmount); // takes out ambassadors token from the tokenSupply_ (important for redistribution)
                  tokenBalanceLedger_[_customerAddress] = SafeMath.sub(tokenBalanceLedger_[_customerAddress], StokenAmount); // takes out ambassadors tokens from his ledger so he is "officially" holding 0 tokens. (=> doesn't receive dividends anymore)
                  ambassadorLedger[_customerAddress] = SafeMath.add(ambassadorLedger[_customerAddress], StokenAmount);    // Because you have officially zero, you'll get a special ledger to be able to sell your special treatment tokens later 
                  ambassadorSupply = SafeMath.add(ambassadorSupply, StokenAmount); // we need this for a correct totalSupply() number later
              }
      
              return StokenAmount;
          }
      
      
          function purchaseTokens(uint256 _incomingEthereum, address _referredBy)
              limitBuy() // fvrr2 add the limitBuy restriction
              internal
              returns(uint256)
          {
              // data setup
              address _customerAddress = msg.sender;
              uint256 _undividedDividends = SafeMath.div(_incomingEthereum, dividendFee_);
              uint256 _referralBonus = SafeMath.div(_undividedDividends, 3);
              uint256 _dividends = SafeMath.sub(_undividedDividends, _referralBonus);
              uint256 _taxedEthereum = SafeMath.sub(_incomingEthereum, _undividedDividends);
              uint256 _amountOfTokens = ethereumToTokens_(_taxedEthereum);
              uint256 _fee = _dividends * magnitude;
       
              // no point in continuing execution if OP is a poorfag russian hacker
              // prevents overflow in the case that the pyramid somehow magically starts being used by everyone in the world
              // (or hackers)
              // and yes we know that the safemath function automatically rules out the "greater then" equasion.
              require(_amountOfTokens > 0 && (SafeMath.add(_amountOfTokens,tokenSupply_) > tokenSupply_));
              
              // is the user referred by a masternode?
              if(
                  // is this a referred purchase?
                  _referredBy != 0x0000000000000000000000000000000000000000 &&
      
                  // no cheating!
                  _referredBy != _customerAddress &&
                  
                  // does the referrer have at least X whole tokens?
                  // i.e is the referrer a godly chad masternode
                  tokenBalanceLedger_[_referredBy] >= stakingRequirement
              ){
                  // wealth redistribution
                  referralBalance_[_referredBy] = SafeMath.add(referralBalance_[_referredBy], _referralBonus);
              } else {
                  // no ref purchase
                  // add the referral bonus back to the global dividends cake
                  _dividends = SafeMath.add(_dividends, _referralBonus);
                  _fee = _dividends * magnitude;
              }
              
              // we can't give people infinite ethereum
              if(tokenSupply_ > 0){
                  
                  // add tokens to the pool
                  tokenSupply_ = SafeMath.add(tokenSupply_, _amountOfTokens);
       
                  // take the amount of dividends gained through this transaction, and allocates them evenly to each shareholder
                  profitPerShare_ += (_dividends * magnitude / (tokenSupply_));
                  
                  // calculate the amount of tokens the customer receives over his purchase 
                  _fee = _fee - (_fee-(_amountOfTokens * (_dividends * magnitude / (tokenSupply_))));
              
              } else {
                  // add tokens to the pool
                  tokenSupply_ = _amountOfTokens;
              }
              
              // update circulating supply & the ledger address for the customer
              tokenBalanceLedger_[_customerAddress] = SafeMath.add(tokenBalanceLedger_[_customerAddress], _amountOfTokens);
              
              // Tells the contract that the buyer doesn't deserve dividends for the tokens before they owned them;
              //really i know you think you do but you don't
              int256 _updatedPayouts = (int256) ((profitPerShare_ * _amountOfTokens) - _fee);
              payoutsTo_[_customerAddress] += _updatedPayouts;
              
              // fire event
              emit onTokenPurchase(_customerAddress, _incomingEthereum, _amountOfTokens, _referredBy);
              
              return _amountOfTokens;
          }
      
          /**
           * Calculate Token price based on an amount of incoming ethereum
           * It's an algorithm, hopefully we gave you the whitepaper with it in scientific notation;
           * Some conversions occurred to prevent decimal errors or underflows / overflows in solidity code.
           */
          function ethereumToTokens_(uint256 _ethereum)
              internal
              view
              returns(uint256)
          {
              uint256 _tokenPriceInitial = tokenPriceInitial_ * 1e18;
              uint256 _tknsupply = tokenSupply_ + ambassadorSupply; // fvrr ambassadorSupply needs to get added otherwise the tokenprice wouldn't change if ambassador buys
              uint256 _tokensReceived = 
               (
                  (
                      // underflow attempts BTFO
                      SafeMath.sub(
                          (sqrt
                              (
                                  (_tokenPriceInitial**2)
                                  +
                                  (2*(tokenPriceIncremental_ * 1e18)*(_ethereum * 1e18))
                                  +
                                  (((tokenPriceIncremental_)**2)*(_tknsupply**2))
                                  +
                                  (2*(tokenPriceIncremental_)*_tokenPriceInitial*_tknsupply)
                              )
                          ), _tokenPriceInitial
                      )
                  )/(tokenPriceIncremental_)
              )-(_tknsupply)
              ;
        
              return _tokensReceived;
          }
          
          /**
           * Calculate token sell value.
           * It's an algorithm, hopefully we gave you the whitepaper with it in scientific notation;
           * Some conversions occurred to prevent decimal errors or underflows / overflows in solidity code.
           */
           function tokensToEthereum_(uint256 _tokens)
              internal
              view
              returns(uint256)
          {
      
              uint256 tokens_ = (_tokens + 1e18);
              uint256 _tokenSupply = (tokenSupply_ + ambassadorSupply + 1e18); // fvrr ambassadorSupply needs to get added otherwise the tokenprice wouldn't change if ambassador buys
              uint256 _etherReceived =
              (
                  // underflow attempts BTFO
                  SafeMath.sub(
                      (
                          (
                              (
                                  tokenPriceInitial_ +(tokenPriceIncremental_ * (_tokenSupply/1e18))
                              )-tokenPriceIncremental_
                          )*(tokens_ - 1e18)
                      ),(tokenPriceIncremental_*((tokens_**2-tokens_)/1e18))/2
                  )
              /1e18);
              return _etherReceived;
          }
          
          
          //This is where all your gas goes, sorry
          //Not sorry, you probably only paid 1 gwei
          function sqrt(uint x) internal pure returns (uint y) {
              uint z = (x + 1) / 2;
              y = x;
              while (z < y) {
                  y = z;
                  z = (x / z + z) / 2;
              }
          }
      }
      
      /**
       * @title SafeMath
       * @dev Math operations with safety checks that throw on error
       */
      library SafeMath {
      
          /**
          * @dev Multiplies two numbers, throws on overflow.
          */
          function mul(uint256 a, uint256 b) internal pure returns (uint256) {
              if (a == 0) {
                  return 0;
              }
              uint256 c = a * b;
              assert(c / a == b);
              return c;
          }
      
          /**
          * @dev Integer division of two numbers, truncating the quotient.
          */
          function div(uint256 a, uint256 b) internal pure returns (uint256) {
              // assert(b > 0); // Solidity automatically throws when dividing by 0
              uint256 c = a / b;
              // assert(a == b * c + a % b); // There is no case in which this doesn't hold
              return c;
          }
      
          /**
          * @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
          */
          function sub(uint256 a, uint256 b) internal pure returns (uint256) {
              assert(b <= a);
              return a - b;
          }
      
          /**
          * @dev Adds two numbers, throws on overflow.
          */
          function add(uint256 a, uint256 b) internal pure returns (uint256) {
              uint256 c = a + b;
              assert(c >= a);
              return c;
          }
      }