ETH Price: $3,640.95 (-2.66%)

Transaction Decoder

Block:
8595708 at Sep-22-2019 12:04:00 AM +UTC
Transaction Fee:
0.00053956 ETH $1.96
Gas Used:
67,445 Gas / 8 Gwei

Emitted Events:

Account State Difference:

  Address   Before After State Difference Code
(Spark Pool)
8.338145617250369348 Eth8.338685177250369348 Eth0.00053956
0x7728dFEF...a501eD29D
0x8d12A197...2A5CC6819
(EtherDelta 2)
0xe427A528...0262D7c61
0.062473532540370479 Eth
Nonce: 635
0.061933972540370479 Eth
Nonce: 636
0.00053956

Execution Trace

EtherDelta.depositToken( token=0x7728dFEF5aBd468669EB7f9b48A7f70a501eD29D, amount=249967000 )
  • ParagonCoinToken.transferFrom( _from=0xe427A52824c5EAb60A163E5d7f4f0970262D7c61, _to=0x8d12A197cB00D4747a1fe03395095ce2A5CC6819, _value=249967000 ) => ( success=True )
    File 1 of 2: EtherDelta
    pragma solidity ^0.4.9;
    
    contract SafeMath {
      function safeMul(uint a, uint b) internal returns (uint) {
        uint c = a * b;
        assert(a == 0 || c / a == b);
        return c;
      }
    
      function safeSub(uint a, uint b) internal returns (uint) {
        assert(b <= a);
        return a - b;
      }
    
      function safeAdd(uint a, uint b) internal returns (uint) {
        uint c = a + b;
        assert(c>=a && c>=b);
        return c;
      }
    
      function assert(bool assertion) internal {
        if (!assertion) throw;
      }
    }
    
    contract Token {
      /// @return total amount of tokens
      function totalSupply() constant returns (uint256 supply) {}
    
      /// @param _owner The address from which the balance will be retrieved
      /// @return The balance
      function balanceOf(address _owner) constant returns (uint256 balance) {}
    
      /// @notice send `_value` token to `_to` from `msg.sender`
      /// @param _to The address of the recipient
      /// @param _value The amount of token to be transferred
      /// @return Whether the transfer was successful or not
      function transfer(address _to, uint256 _value) returns (bool success) {}
    
      /// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
      /// @param _from The address of the sender
      /// @param _to The address of the recipient
      /// @param _value The amount of token to be transferred
      /// @return Whether the transfer was successful or not
      function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {}
    
      /// @notice `msg.sender` approves `_addr` to spend `_value` tokens
      /// @param _spender The address of the account able to transfer the tokens
      /// @param _value The amount of wei to be approved for transfer
      /// @return Whether the approval was successful or not
      function approve(address _spender, uint256 _value) returns (bool success) {}
    
      /// @param _owner The address of the account owning tokens
      /// @param _spender The address of the account able to transfer the tokens
      /// @return Amount of remaining tokens allowed to spent
      function allowance(address _owner, address _spender) constant returns (uint256 remaining) {}
    
      event Transfer(address indexed _from, address indexed _to, uint256 _value);
      event Approval(address indexed _owner, address indexed _spender, uint256 _value);
    
      uint public decimals;
      string public name;
    }
    
    contract StandardToken is Token {
    
      function transfer(address _to, uint256 _value) returns (bool success) {
        //Default assumes totalSupply can't be over max (2^256 - 1).
        //If your token leaves out totalSupply and can issue more tokens as time goes on, you need to check if it doesn't wrap.
        //Replace the if with this one instead.
        if (balances[msg.sender] >= _value && balances[_to] + _value > balances[_to]) {
        //if (balances[msg.sender] >= _value && _value > 0) {
          balances[msg.sender] -= _value;
          balances[_to] += _value;
          Transfer(msg.sender, _to, _value);
          return true;
        } else { return false; }
      }
    
      function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        //same as above. Replace this line with the following if you want to protect against wrapping uints.
        if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && balances[_to] + _value > balances[_to]) {
        //if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0) {
          balances[_to] += _value;
          balances[_from] -= _value;
          allowed[_from][msg.sender] -= _value;
          Transfer(_from, _to, _value);
          return true;
        } else { return false; }
      }
    
      function balanceOf(address _owner) constant returns (uint256 balance) {
        return balances[_owner];
      }
    
      function approve(address _spender, uint256 _value) returns (bool success) {
        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);
        return true;
      }
    
      function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
        return allowed[_owner][_spender];
      }
    
      mapping(address => uint256) balances;
    
      mapping (address => mapping (address => uint256)) allowed;
    
      uint256 public totalSupply;
    }
    
    contract ReserveToken is StandardToken, SafeMath {
      address public minter;
      function ReserveToken() {
        minter = msg.sender;
      }
      function create(address account, uint amount) {
        if (msg.sender != minter) throw;
        balances[account] = safeAdd(balances[account], amount);
        totalSupply = safeAdd(totalSupply, amount);
      }
      function destroy(address account, uint amount) {
        if (msg.sender != minter) throw;
        if (balances[account] < amount) throw;
        balances[account] = safeSub(balances[account], amount);
        totalSupply = safeSub(totalSupply, amount);
      }
    }
    
    contract AccountLevels {
      //given a user, returns an account level
      //0 = regular user (pays take fee and make fee)
      //1 = market maker silver (pays take fee, no make fee, gets rebate)
      //2 = market maker gold (pays take fee, no make fee, gets entire counterparty's take fee as rebate)
      function accountLevel(address user) constant returns(uint) {}
    }
    
    contract AccountLevelsTest is AccountLevels {
      mapping (address => uint) public accountLevels;
    
      function setAccountLevel(address user, uint level) {
        accountLevels[user] = level;
      }
    
      function accountLevel(address user) constant returns(uint) {
        return accountLevels[user];
      }
    }
    
    contract EtherDelta is SafeMath {
      address public admin; //the admin address
      address public feeAccount; //the account that will receive fees
      address public accountLevelsAddr; //the address of the AccountLevels contract
      uint public feeMake; //percentage times (1 ether)
      uint public feeTake; //percentage times (1 ether)
      uint public feeRebate; //percentage times (1 ether)
      mapping (address => mapping (address => uint)) public tokens; //mapping of token addresses to mapping of account balances (token=0 means Ether)
      mapping (address => mapping (bytes32 => bool)) public orders; //mapping of user accounts to mapping of order hashes to booleans (true = submitted by user, equivalent to offchain signature)
      mapping (address => mapping (bytes32 => uint)) public orderFills; //mapping of user accounts to mapping of order hashes to uints (amount of order that has been filled)
    
      event Order(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, address user);
      event Cancel(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, address user, uint8 v, bytes32 r, bytes32 s);
      event Trade(address tokenGet, uint amountGet, address tokenGive, uint amountGive, address get, address give);
      event Deposit(address token, address user, uint amount, uint balance);
      event Withdraw(address token, address user, uint amount, uint balance);
    
      function EtherDelta(address admin_, address feeAccount_, address accountLevelsAddr_, uint feeMake_, uint feeTake_, uint feeRebate_) {
        admin = admin_;
        feeAccount = feeAccount_;
        accountLevelsAddr = accountLevelsAddr_;
        feeMake = feeMake_;
        feeTake = feeTake_;
        feeRebate = feeRebate_;
      }
    
      function() {
        throw;
      }
    
      function changeAdmin(address admin_) {
        if (msg.sender != admin) throw;
        admin = admin_;
      }
    
      function changeAccountLevelsAddr(address accountLevelsAddr_) {
        if (msg.sender != admin) throw;
        accountLevelsAddr = accountLevelsAddr_;
      }
    
      function changeFeeAccount(address feeAccount_) {
        if (msg.sender != admin) throw;
        feeAccount = feeAccount_;
      }
    
      function changeFeeMake(uint feeMake_) {
        if (msg.sender != admin) throw;
        if (feeMake_ > feeMake) throw;
        feeMake = feeMake_;
      }
    
      function changeFeeTake(uint feeTake_) {
        if (msg.sender != admin) throw;
        if (feeTake_ > feeTake || feeTake_ < feeRebate) throw;
        feeTake = feeTake_;
      }
    
      function changeFeeRebate(uint feeRebate_) {
        if (msg.sender != admin) throw;
        if (feeRebate_ < feeRebate || feeRebate_ > feeTake) throw;
        feeRebate = feeRebate_;
      }
    
      function deposit() payable {
        tokens[0][msg.sender] = safeAdd(tokens[0][msg.sender], msg.value);
        Deposit(0, msg.sender, msg.value, tokens[0][msg.sender]);
      }
    
      function withdraw(uint amount) {
        if (tokens[0][msg.sender] < amount) throw;
        tokens[0][msg.sender] = safeSub(tokens[0][msg.sender], amount);
        if (!msg.sender.call.value(amount)()) throw;
        Withdraw(0, msg.sender, amount, tokens[0][msg.sender]);
      }
    
      function depositToken(address token, uint amount) {
        //remember to call Token(address).approve(this, amount) or this contract will not be able to do the transfer on your behalf.
        if (token==0) throw;
        if (!Token(token).transferFrom(msg.sender, this, amount)) throw;
        tokens[token][msg.sender] = safeAdd(tokens[token][msg.sender], amount);
        Deposit(token, msg.sender, amount, tokens[token][msg.sender]);
      }
    
      function withdrawToken(address token, uint amount) {
        if (token==0) throw;
        if (tokens[token][msg.sender] < amount) throw;
        tokens[token][msg.sender] = safeSub(tokens[token][msg.sender], amount);
        if (!Token(token).transfer(msg.sender, amount)) throw;
        Withdraw(token, msg.sender, amount, tokens[token][msg.sender]);
      }
    
      function balanceOf(address token, address user) constant returns (uint) {
        return tokens[token][user];
      }
    
      function order(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce) {
        bytes32 hash = sha256(this, tokenGet, amountGet, tokenGive, amountGive, expires, nonce);
        orders[msg.sender][hash] = true;
        Order(tokenGet, amountGet, tokenGive, amountGive, expires, nonce, msg.sender);
      }
    
      function trade(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, address user, uint8 v, bytes32 r, bytes32 s, uint amount) {
        //amount is in amountGet terms
        bytes32 hash = sha256(this, tokenGet, amountGet, tokenGive, amountGive, expires, nonce);
        if (!(
          (orders[user][hash] || ecrecover(sha3("\x19Ethereum Signed Message:\n32", hash),v,r,s) == user) &&
          block.number <= expires &&
          safeAdd(orderFills[user][hash], amount) <= amountGet
        )) throw;
        tradeBalances(tokenGet, amountGet, tokenGive, amountGive, user, amount);
        orderFills[user][hash] = safeAdd(orderFills[user][hash], amount);
        Trade(tokenGet, amount, tokenGive, amountGive * amount / amountGet, user, msg.sender);
      }
    
      function tradeBalances(address tokenGet, uint amountGet, address tokenGive, uint amountGive, address user, uint amount) private {
        uint feeMakeXfer = safeMul(amount, feeMake) / (1 ether);
        uint feeTakeXfer = safeMul(amount, feeTake) / (1 ether);
        uint feeRebateXfer = 0;
        if (accountLevelsAddr != 0x0) {
          uint accountLevel = AccountLevels(accountLevelsAddr).accountLevel(user);
          if (accountLevel==1) feeRebateXfer = safeMul(amount, feeRebate) / (1 ether);
          if (accountLevel==2) feeRebateXfer = feeTakeXfer;
        }
        tokens[tokenGet][msg.sender] = safeSub(tokens[tokenGet][msg.sender], safeAdd(amount, feeTakeXfer));
        tokens[tokenGet][user] = safeAdd(tokens[tokenGet][user], safeSub(safeAdd(amount, feeRebateXfer), feeMakeXfer));
        tokens[tokenGet][feeAccount] = safeAdd(tokens[tokenGet][feeAccount], safeSub(safeAdd(feeMakeXfer, feeTakeXfer), feeRebateXfer));
        tokens[tokenGive][user] = safeSub(tokens[tokenGive][user], safeMul(amountGive, amount) / amountGet);
        tokens[tokenGive][msg.sender] = safeAdd(tokens[tokenGive][msg.sender], safeMul(amountGive, amount) / amountGet);
      }
    
      function testTrade(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, address user, uint8 v, bytes32 r, bytes32 s, uint amount, address sender) constant returns(bool) {
        if (!(
          tokens[tokenGet][sender] >= amount &&
          availableVolume(tokenGet, amountGet, tokenGive, amountGive, expires, nonce, user, v, r, s) >= amount
        )) return false;
        return true;
      }
    
      function availableVolume(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, address user, uint8 v, bytes32 r, bytes32 s) constant returns(uint) {
        bytes32 hash = sha256(this, tokenGet, amountGet, tokenGive, amountGive, expires, nonce);
        if (!(
          (orders[user][hash] || ecrecover(sha3("\x19Ethereum Signed Message:\n32", hash),v,r,s) == user) &&
          block.number <= expires
        )) return 0;
        uint available1 = safeSub(amountGet, orderFills[user][hash]);
        uint available2 = safeMul(tokens[tokenGive][user], amountGet) / amountGive;
        if (available1<available2) return available1;
        return available2;
      }
    
      function amountFilled(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, address user, uint8 v, bytes32 r, bytes32 s) constant returns(uint) {
        bytes32 hash = sha256(this, tokenGet, amountGet, tokenGive, amountGive, expires, nonce);
        return orderFills[user][hash];
      }
    
      function cancelOrder(address tokenGet, uint amountGet, address tokenGive, uint amountGive, uint expires, uint nonce, uint8 v, bytes32 r, bytes32 s) {
        bytes32 hash = sha256(this, tokenGet, amountGet, tokenGive, amountGive, expires, nonce);
        if (!(orders[msg.sender][hash] || ecrecover(sha3("\x19Ethereum Signed Message:\n32", hash),v,r,s) == msg.sender)) throw;
        orderFills[msg.sender][hash] = amountGet;
        Cancel(tokenGet, amountGet, tokenGive, amountGive, expires, nonce, msg.sender, v, r, s);
      }
    }

    File 2 of 2: ParagonCoinToken
    pragma solidity ^0.4.11;
    
      /**
       * Provides methods to safely add, subtract and multiply uint256 numbers.
       */
      contract SafeMath {
        uint256 constant private MAX_UINT256 =
          0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
    
        /**
         * Add two uint256 values, revert in case of overflow.
         *
         * @param x first value to add
         * @param y second value to add
         * @return x + y
         */
        function safeAdd (uint256 x, uint256 y)
        constant internal
        returns (uint256 z) {
          require (x <= MAX_UINT256 - y);
          return x + y;
        }
    
        /**
         * Subtract one uint256 value from another, throw in case of underflow.
         *
         * @param x value to subtract from
         * @param y value to subtract
         * @return x - y
         */
        function safeSub (uint256 x, uint256 y)
        constant internal
        returns (uint256 z) {
          require(x >= y);
          return x - y;
        }
    
        /**
         * Multiply two uint256 values, throw in case of overflow.
         *
         * @param x first value to multiply
         * @param y second value to multiply
         * @return x * y
         */
        function safeMul (uint256 x, uint256 y)
        constant internal
        returns (uint256 z) {
          if (y == 0) return 0; // Prevent division by zero at the next line
          require (x <= MAX_UINT256 / y);
          return x * y;
        }
      }
    
      /**
       * ERC-20 standard token interface, as defined
       * <a href="http://github.com/ethereum/EIPs/issues/20">here</a>.
       */
      contract Token {
        /**
         * Get total number of tokens in circulation.
         *
         * @return total number of tokens in circulation
         */
        function totalSupply () constant returns (uint256 supply);
    
        /**
         * Get number of tokens currently belonging to given owner.
         *
         * @param _owner address to get number of tokens currently belonging to the
         *        owner of
         * @return number of tokens currently belonging to the owner of given address
         */
        function balanceOf (address _owner) constant returns (uint256 balance);
    
        /**
         * Transfer given number of tokens from message sender to given recipient.
         *
         * @param _to address to transfer tokens to the owner of
         * @param _value number of tokens to transfer to the owner of given address
         * @return true if tokens were transferred successfully, false otherwise
         */
        function transfer (address _to, uint256 _value) returns (bool success);
    
        /**
         * Transfer given number of tokens from given owner to given recipient.
         *
         * @param _from address to transfer tokens from the owner of
         * @param _to address to transfer tokens to the owner of
         * @param _value number of tokens to transfer from given owner to given
         *        recipient
         * @return true if tokens were transferred successfully, false otherwise
         */
        function transferFrom (address _from, address _to, uint256 _value)
        returns (bool success);
    
        /**
         * Allow given spender to transfer given number of tokens from message sender.
         *
         * @param _spender address to allow the owner of to transfer tokens from
         *        message sender
         * @param _value number of tokens to allow to transfer
         * @return true if token transfer was successfully approved, false otherwise
         */
        function approve (address _spender, uint256 _value) returns (bool success);
    
        /**
         * Tell how many tokens given spender is currently allowed to transfer from
         * given owner.
         *
         * @param _owner address to get number of tokens allowed to be transferred
         *        from the owner of
         * @param _spender address to get number of tokens allowed to be transferred
         *        by the owner of
         * @return number of tokens given spender is currently allowed to transfer
         *         from given owner
         */
        function allowance (address _owner, address _spender) constant
        returns (uint256 remaining);
    
        /**
         * Logged when tokens were transferred from one owner to another.
         *
         * @param _from address of the owner, tokens were transferred from
         * @param _to address of the owner, tokens were transferred to
         * @param _value number of tokens transferred
         */
        event Transfer (address indexed _from, address indexed _to, uint256 _value);
    
        /**
         * Logged when owner approved his tokens to be transferred by some spender.
         *
         * @param _owner owner who approved his tokens to be transferred
         * @param _spender spender who were allowed to transfer the tokens belonging
         *        to the owner
         * @param _value number of tokens belonging to the owner, approved to be
         *        transferred by the spender
         */
        event Approval (
          address indexed _owner, address indexed _spender, uint256 _value);
      }
    
      /**
       * Abstract Token Smart Contract that could be used as a base contract for
       * ERC-20 token contracts.
       */
      contract AbstractToken is Token, SafeMath {
    
        /**
         * Address of the fund of this smart contract.
         */
        address fund;
    
        /**
         * Create new Abstract Token contract.
         */
        function AbstractToken () {
          // Do nothing
        }
    
    
        /**
         * Get number of tokens currently belonging to given owner.
         *
         * @param _owner address to get number of tokens currently belonging to the
         *        owner of
         * @return number of tokens currently belonging to the owner of given address
         */
         function balanceOf (address _owner) constant returns (uint256 balance) {
          return accounts [_owner];
        }
    
        /**
         * Transfer given number of tokens from message sender to given recipient.
         *
         * @param _to address to transfer tokens to the owner of
         * @param _value number of tokens to transfer to the owner of given address
         * @return true if tokens were transferred successfully, false otherwise
         */
        function transfer (address _to, uint256 _value) returns (bool success) {
          uint256 feeTotal = fee();
    
          if (accounts [msg.sender] < _value) return false;
          if (_value > feeTotal && msg.sender != _to) {
            accounts [msg.sender] = safeSub (accounts [msg.sender], _value);
            
            accounts [_to] = safeAdd (accounts [_to], safeSub(_value, feeTotal));
    
            processFee(feeTotal);
    
            Transfer (msg.sender, _to, safeSub(_value, feeTotal));
            
          }
          return true;
        }
    
        /**
         * Transfer given number of tokens from given owner to given recipient.
         *
         * @param _from address to transfer tokens from the owner of
         * @param _to address to transfer tokens to the owner of
         * @param _value number of tokens to transfer from given owner to given
         *        recipient
         * @return true if tokens were transferred successfully, false otherwise
         */
        function transferFrom (address _from, address _to, uint256 _value)
        returns (bool success) {
          uint256 feeTotal = fee();
    
          if (allowances [_from][msg.sender] < _value) return false;
          if (accounts [_from] < _value) return false;
    
          allowances [_from][msg.sender] =
            safeSub (allowances [_from][msg.sender], _value);
    
          if (_value > feeTotal && _from != _to) {
            accounts [_from] = safeSub (accounts [_from], _value);
    
            
            accounts [_to] = safeAdd (accounts [_to], safeSub(_value, feeTotal));
    
            processFee(feeTotal);
    
            Transfer (_from, _to, safeSub(_value, feeTotal));
          }
    
          return true;
        }
    
        function fee () constant returns (uint256);
    
        function processFee(uint256 feeTotal) internal returns (bool);
    
        /**
         * Allow given spender to transfer given number of tokens from message sender.
         *
         * @param _spender address to allow the owner of to transfer tokens from
         *        message sender
         * @param _value number of tokens to allow to transfer
         * @return true if token transfer was successfully approved, false otherwise
         */
        function approve (address _spender, uint256 _value) returns (bool success) {
          allowances [msg.sender][_spender] = _value;
          Approval (msg.sender, _spender, _value);
    
          return true;
        }
    
        /**
         * Tell how many tokens given spender is currently allowed to transfer from
         * given owner.
         *
         * @param _owner address to get number of tokens allowed to be transferred
         *        from the owner of
         * @param _spender address to get number of tokens allowed to be transferred
         *        by the owner of
         * @return number of tokens given spender is currently allowed to transfer
         *         from given owner
         */
        function allowance (address _owner, address _spender) constant
        returns (uint256 remaining) {
          return allowances [_owner][_spender];
        }
    
        /**
         * Mapping from addresses of token holders to the numbers of tokens belonging
         * to these token holders.
         */
        mapping (address => uint256) accounts;
    
        /**
         * Mapping from addresses of token holders to the mapping of addresses of
         * spenders to the allowances set by these token holders to these spenders.
         */
        mapping (address => mapping (address => uint256)) allowances;
      }
    
      contract ParagonCoinToken is AbstractToken {
        /**
         * Initial number of tokens.
         */
        uint256 constant INITIAL_TOKENS_COUNT = 200000000e6;
    
        /**
         * Address of the owner of this smart contract.
         */
        address owner;
    
       
    
        /**
         * Total number of tokens ins circulation.
         */
        uint256 tokensCount;
    
        /**
         * Create new ParagonCoin Token Smart Contract, make message sender to be the
         * owner of smart contract, issue given number of tokens and give them to
         * message sender.
         */
        function ParagonCoinToken (address fundAddress) {
          tokensCount = INITIAL_TOKENS_COUNT;
          accounts [msg.sender] = INITIAL_TOKENS_COUNT;
          owner = msg.sender;
          fund = fundAddress;
        }
    
        /**
         * Get name of this token.
         *
         * @return name of this token
         */
        function name () constant returns (string name) {
          return "PRG";
        }
    
        /**
         * Get symbol of this token.
         *
         * @return symbol of this token
         */
        function symbol () constant returns (string symbol) {
          return "PRG";
        }
    
    
        /**
         * Get number of decimals for this token.
         *
         * @return number of decimals for this token
         */
        function decimals () constant returns (uint8 decimals) {
          return 6;
        }
    
        /**
         * Get total number of tokens in circulation.
         *
         * @return total number of tokens in circulation
         */
        function totalSupply () constant returns (uint256 supply) {
          return tokensCount;
        }
    
        
    
        /**
         * Transfer given number of tokens from message sender to given recipient.
         *
         * @param _to address to transfer tokens to the owner of
         * @param _value number of tokens to transfer to the owner of given address
         * @return true if tokens were transferred successfully, false otherwise
         */
        function transfer (address _to, uint256 _value) returns (bool success) {
          return AbstractToken.transfer (_to, _value);
        }
    
        /**
         * Transfer given number of tokens from given owner to given recipient.
         *
         * @param _from address to transfer tokens from the owner of
         * @param _to address to transfer tokens to the owner of
         * @param _value number of tokens to transfer from given owner to given
         *        recipient
         * @return true if tokens were transferred successfully, false otherwise
         */
        function transferFrom (address _from, address _to, uint256 _value)
        returns (bool success) {
          return AbstractToken.transferFrom (_from, _to, _value);
        }
    
        function fee () constant returns (uint256) {
          return safeAdd(safeMul(tokensCount, 5)/1e11, 25000);
        }
    
        function processFee(uint256 feeTotal) internal returns (bool) {
            uint256 burnFee = feeTotal/2;
            uint256 fundFee = safeSub(feeTotal, burnFee);
    
            accounts [fund] = safeAdd (accounts [fund], fundFee);
            tokensCount = safeSub (tokensCount, burnFee); // ledger burned toke
    
            Transfer (msg.sender, fund, fundFee);
    
            return true;
        }
    
        /**
         * Change how many tokens given spender is allowed to transfer from message
         * spender.  In order to prevent double spending of allowance, this method
         * receives assumed current allowance value as an argument.  If actual
         * allowance differs from an assumed one, this method just returns false.
         *
         * @param _spender address to allow the owner of to transfer tokens from
         *        message sender
         * @param _currentValue assumed number of tokens currently allowed to be
         *        transferred
         * @param _newValue number of tokens to allow to transfer
         * @return true if token transfer was successfully approved, false otherwise
         */
        function approve (address _spender, uint256 _currentValue, uint256 _newValue)
        returns (bool success) {
          if (allowance (msg.sender, _spender) == _currentValue)
            return approve (_spender, _newValue);
          else return false;
        }
    
        /**
         * Burn given number of tokens belonging to message sender.
         *
         * @param _value number of tokens to burn
         * @return true on success, false on error
         */
        function burnTokens (uint256 _value) returns (bool success) {
          if (_value > accounts [msg.sender]) return false;
          else if (_value > 0) {
            accounts [msg.sender] = safeSub (accounts [msg.sender], _value);
            tokensCount = safeSub (tokensCount, _value);
            return true;
          } else return true;
        }
    
        /**
         * Set new owner for the smart contract.
         * May only be called by smart contract owner.
         *
         * @param _newOwner address of new owner of the smart contract
         */
        function setOwner (address _newOwner) {
          require (msg.sender == owner);
    
          owner = _newOwner;
        }
    
        
        /**
         * Set new fund address for the smart contract.
         * May only be called by smart contract owner.
         *
         * @param _newFund new fund address of the smart contract
         */
        function setFundAddress (address _newFund) {
          require (msg.sender == owner);
    
          fund = _newFund;
        }
    
      }