ETH Price: $1,975.77 (-1.99%)

Transaction Decoder

Block:
9010187 at Nov-27-2019 02:05:19 PM +UTC
Transaction Fee:
0.000790635 ETH $1.56
Gas Used:
52,709 Gas / 15 Gwei

Emitted Events:

293 Wallet.Confirmation( owner=[Sender] 0x6effb3f3678689cd70492fbb8b2657bca4e224bc, operation=8F8BC9A432E438A067CD48EDBE411CCDC62AE0C83F9281AC47BA7B38D790D533 )
294 EURSToken.Transfer( _from=[Receiver] Wallet, _to=0x5572Fc1D99De01618dcCE0D078C43527BdCB7faC, _value=5000000 )
295 EURSToken.Transfer( _from=[Receiver] Wallet, _to=0x70250fcFEf983C9b912c8EEFB7021B4b7baE836e, _value=0 )
296 Wallet.MultiTransact( owner=[Sender] 0x6effb3f3678689cd70492fbb8b2657bca4e224bc, operation=8F8BC9A432E438A067CD48EDBE411CCDC62AE0C83F9281AC47BA7B38D790D533, value=0, to=EURSToken, data=0xA9059CBB0000000000000000000000005572FC1D99DE01618DCCE0D078C43527BDCB7FAC00000000000000000000000000000000000000000000000000000000004C4B40 )

Account State Difference:

  Address   Before After State Difference Code
0x6EffB3f3...Ca4e224bC
0.510148911937447291 Eth
Nonce: 147
0.509358276937447291 Eth
Nonce: 148
0.000790635
0xdB25f211...28a807ad8
0xe1EE550d...F0D09a318
(Ethermine)
576.194152233498588002 Eth576.194942868498588002 Eth0.000790635

Execution Trace

Wallet.confirm( _h=8F8BC9A432E438A067CD48EDBE411CCDC62AE0C83F9281AC47BA7B38D790D533 ) => ( True )
  • EURSToken.transfer( _to=0x5572Fc1D99De01618dcCE0D078C43527BdCB7faC, _value=5000000 ) => ( True )
    File 1 of 2: Wallet
    //sol Wallet
    // Multi-sig account proxy/wallet.
    // @authors:
    // Gav Wood <g@ethdev.com>
    // inheritable "property" contract that enables methods to be protected by requiring the acquiescence of either a
    // single, or, crucially, each of a number of, designated owners.
    // usage:
    // use modifiers onlyowner (just own owned) or onlymanyowners(hash), whereby the same hash must be provided by
    // some number (specified in constructor) of the set of owners (specified in the constructor, modifiable) before the
    // interior is executed.
    // 
    // Token/no-daylimit modifications: Dmitry Khovratovich <khovratovich@gmail.com> based on https://github.com/ethereum/dapp-bin/blob/dd5c485359074d49f571693ae064ce78970f3d6d/wallet/wallet.sol
    
    pragma solidity ^0.4.15;
    contract multiowned {
    
    	// TYPES
    
        // struct for the status of a pending operation.
        struct PendingState {
            uint yetNeeded;
            uint ownersDone;
            uint index;
        }
    
    	// EVENTS
    
        // this contract only has six types of events: it can accept a confirmation, in which case
        // we record owner and operation (hash) alongside it.
        event Confirmation(address owner, bytes32 operation);
        event Revoke(address owner, bytes32 operation);
        // some others are in the case of an owner changing.
        event OwnerChanged(address oldOwner, address newOwner);
        event OwnerAdded(address newOwner);
        event OwnerRemoved(address oldOwner);
        // the last one is emitted if the required signatures change
        event RequirementChanged(uint newRequirement);
    
    	// MODIFIERS
    
        // simple single-sig function modifier.
        modifier onlyowner {
            if (isOwner(msg.sender))
    
                _;
        }
        // multi-sig function modifier: the operation must have an intrinsic hash in order
        // that later attempts can be realised as the same underlying operation and
        // thus count as confirmations.
        modifier onlymanyowners(bytes32 _operation) {
            if (confirmAndCheck(_operation))
    
                _;
        }
    
    	// METHODS
    
        // constructor is given number of sigs required to do protected "onlymanyowners" transactions
        // as well as the selection of addresses capable of confirming them.
        function multiowned(address[] _owners, uint _required) {
            m_numOwners = _owners.length;
            for (uint i = 0; i < _owners.length; ++i)
            {
                m_owners[1 + i] = uint(_owners[i]);
                m_ownerIndex[uint(_owners[i])] = 1 + i;
            }
            m_required = _required;
        }
        
        // Revokes a prior confirmation of the given operation
        function revoke(bytes32 _operation) external {
            uint ownerIndex = m_ownerIndex[uint(msg.sender)];
            // make sure they're an owner
            if (ownerIndex == 0) return;
            uint ownerIndexBit = 2**ownerIndex;
            var pending = m_pending[_operation];
            if (pending.ownersDone & ownerIndexBit > 0) {
                pending.yetNeeded++;
                pending.ownersDone -= ownerIndexBit;
                Revoke(msg.sender, _operation);
            }
        }
        
        // Replaces an owner `_from` with another `_to`.
        function changeOwner(address _from, address _to) onlymanyowners(sha3(msg.data)) external {
            if (isOwner(_to)) return;
            uint ownerIndex = m_ownerIndex[uint(_from)];
            if (ownerIndex == 0) return;
    
            clearPending();
            m_owners[ownerIndex] = uint(_to);
            m_ownerIndex[uint(_from)] = 0;
            m_ownerIndex[uint(_to)] = ownerIndex;
            OwnerChanged(_from, _to);
        }
        
        function addOwner(address _owner) onlymanyowners(sha3(msg.data)) external {
            if (isOwner(_owner)) return;
    
            clearPending();
            if (m_numOwners >= c_maxOwners)
                reorganizeOwners();
            if (m_numOwners >= c_maxOwners)
                return;
            m_numOwners++;
            m_owners[m_numOwners] = uint(_owner);
            m_ownerIndex[uint(_owner)] = m_numOwners;
            OwnerAdded(_owner);
        }
        
        function removeOwner(address _owner) onlymanyowners(sha3(msg.data)) external {
            uint ownerIndex = m_ownerIndex[uint(_owner)];
            if (ownerIndex == 0) return;
            if (m_required > m_numOwners - 1) return;
    
            m_owners[ownerIndex] = 0;
            m_ownerIndex[uint(_owner)] = 0;
            clearPending();
            reorganizeOwners(); //make sure m_numOwner is equal to the number of owners and always points to the optimal free slot
            OwnerRemoved(_owner);
        }
        
        function changeRequirement(uint _newRequired) onlymanyowners(sha3(msg.data)) external {
            if (_newRequired > m_numOwners) return;
            m_required = _newRequired;
            clearPending();
            RequirementChanged(_newRequired);
        }
    
    
        // Gets an owner by 0-indexed position (using numOwners as the count)
        function getOwner(uint ownerIndex) external constant returns (address) {
            return address(m_owners[ownerIndex + 1]);
        }
    
        function isOwner(address _addr) constant returns (bool) {
            return m_ownerIndex[uint(_addr)] > 0;
        }
        
        function hasConfirmed(bytes32 _operation, address _owner) constant returns (bool) {
            var pending = m_pending[_operation];
            uint ownerIndex = m_ownerIndex[uint(_owner)];
    
            // make sure they're an owner
            if (ownerIndex == 0) return false;
    
            // determine the bit to set for this owner.
            uint ownerIndexBit = 2**ownerIndex;
            return !(pending.ownersDone & ownerIndexBit == 0);
    
    
    
    
        }
        
        // INTERNAL METHODS
    
        function confirmAndCheck(bytes32 _operation) internal returns (bool) {
            // determine what index the present sender is:
            uint ownerIndex = m_ownerIndex[uint(msg.sender)];
            // make sure they're an owner
            if (ownerIndex == 0) return;
    
            var pending = m_pending[_operation];
            // if we're not yet working on this operation, switch over and reset the confirmation status.
            if (pending.yetNeeded == 0) {
                // reset count of confirmations needed.
                pending.yetNeeded = m_required;
                // reset which owners have confirmed (none) - set our bitmap to 0.
                pending.ownersDone = 0;
                pending.index = m_pendingIndex.length++;
                m_pendingIndex[pending.index] = _operation;
            }
            // determine the bit to set for this owner.
            uint ownerIndexBit = 2**ownerIndex;
            // make sure we (the message sender) haven't confirmed this operation previously.
            if (pending.ownersDone & ownerIndexBit == 0) {
                Confirmation(msg.sender, _operation);
                // ok - check if count is enough to go ahead.
                if (pending.yetNeeded <= 1) {
                    // enough confirmations: reset and run interior.
                    delete m_pendingIndex[m_pending[_operation].index];
                    delete m_pending[_operation];
                    return true;
                }
                else
                {
                    // not enough: record that this owner in particular confirmed.
                    pending.yetNeeded--;
                    pending.ownersDone |= ownerIndexBit;
                }
            }
        }
    
        function reorganizeOwners() private {
            uint free = 1;
            while (free < m_numOwners)
            {
                while (free < m_numOwners && m_owners[free] != 0) free++;
                while (m_numOwners > 1 && m_owners[m_numOwners] == 0) m_numOwners--;
                if (free < m_numOwners && m_owners[m_numOwners] != 0 && m_owners[free] == 0)
                {
                    m_owners[free] = m_owners[m_numOwners];
                    m_ownerIndex[m_owners[free]] = free;
                    m_owners[m_numOwners] = 0;
                }
            }
        }
        
        function clearPending() internal {
            uint length = m_pendingIndex.length;
            for (uint i = 0; i < length; ++i)
                if (m_pendingIndex[i] != 0)
                    delete m_pending[m_pendingIndex[i]];
            delete m_pendingIndex;
        }
            
       	// FIELDS
    
        // the number of owners that must confirm the same operation before it is run.
        uint public m_required;
        // pointer used to find a free slot in m_owners
        uint public m_numOwners;
        
        // list of owners
        uint[256] m_owners;
        uint constant c_maxOwners = 250;
        // index on the list of owners to allow reverse lookup
        mapping(uint => uint) m_ownerIndex;
        // the ongoing operations.
        mapping(bytes32 => PendingState) m_pending;
        bytes32[] m_pendingIndex;
    }
    
    
    
    // interface contract for multisig proxy contracts; see below for docs.
    contract multisig {
    
    	// EVENTS
    
        // logged events:
        // Funds has arrived into the wallet (record how much).
        event Deposit(address _from, uint value);
        // Single transaction going out of the wallet (record who signed for it, how much, and to whom it's going).
        event SingleTransact(address owner, uint value, address to, bytes data);
        // Multi-sig transaction going out of the wallet (record who signed for it last, the operation hash, how much, and to whom it's going).
        event MultiTransact(address owner, bytes32 operation, uint value, address to, bytes data);
        // Confirmation still needed for a transaction.
        event ConfirmationNeeded(bytes32 operation, address initiator, uint value, address to, bytes data);
        
        // FUNCTIONS
        
        // TODO: document
        function changeOwner(address _from, address _to) external;
        function execute(address _to, uint _value, bytes _data) external returns (bytes32);
        function confirm(bytes32 _h) returns (bool);
    }
    
    // usage:
    // bytes32 h = Wallet(w).from(oneOwner).execute(to, value, data);
    // Wallet(w).from(anotherOwner).confirm(h);
    contract Wallet is multisig, multiowned {
    
    
    
    	// TYPES
    
        // Transaction structure to remember details of transaction lest it need be saved for a later call.
        struct Transaction {
            address to;
            uint value;
            bytes data;
        }
    
        // METHODS
    
        // constructor - just pass on the owner array to the multiowned 
        function Wallet(address[] _owners, uint _required)
                multiowned(_owners, _required)  {
        }
        
        
        // gets called when no other function matches
        function() payable{
            // just being sent some cash?
            if (msg.value > 0)
                Deposit(msg.sender, msg.value);
        }
        
        // Outside-visible transact entry point. Executes transaction immediately if below daily spend limit.
        // If not, goes into multisig process. We provide a hash on return to allow the sender to provide
        // shortcuts for the other confirmations (allowing them to avoid replicating the _to, _value
        // and _data arguments). They still get the option of using them if they want, anyways.
        function execute(address _to, uint _value, bytes _data) external onlyowner returns (bytes32 _r) {
            // determine our operation hash.
            _r = sha3(msg.data, block.number);
            if (!confirm(_r) && m_txs[_r].to == 0) {
                m_txs[_r].to = _to;
                m_txs[_r].value = _value;
                m_txs[_r].data = _data;
                ConfirmationNeeded(_r, msg.sender, _value, _to, _data);
            }
        }
        
        // confirm a transaction through just the hash. we use the previous transactions map, m_txs, in order
        // to determine the body of the transaction from the hash provided.
        function confirm(bytes32 _h) onlymanyowners(_h) returns (bool) {
            if (m_txs[_h].to != 0) {
                var x= m_txs[_h].to.call.value(m_txs[_h].value)(m_txs[_h].data);
                MultiTransact(msg.sender, _h, m_txs[_h].value, m_txs[_h].to, m_txs[_h].data);
                delete m_txs[_h];
                return true;
            }
        }
        
        // INTERNAL METHODS
        
        function clearPending() internal {
            uint length = m_pendingIndex.length;
            for (uint i = 0; i < length; ++i)
                delete m_txs[m_pendingIndex[i]];
            super.clearPending();
        }
    
    	// FIELDS
    
        // pending transactions we have at present.
        mapping (bytes32 => Transaction) m_txs;
    }

    File 2 of 2: EURSToken
    /**
     * EURS Token Smart Contract: EIP-20 compatible token smart contract that
     * manages EURS tokens.
     */
    
    /*
     * Safe Math Smart Contract.
     * Copyright (c) 2018 by STSS (Malta) Limited.
     * Contact: <tech@stasis.net>
     */
    pragma solidity ^0.4.20;
    
    /**
     * Provides methods to safely add, subtract and multiply uint256 numbers.
     */
    contract SafeMath {
      uint256 constant private MAX_UINT256 =
        0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
    
      /**
       * Add two uint256 values, throw 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)
      pure internal
      returns (uint256 z) {
        assert (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)
      pure internal
      returns (uint256 z) {
        assert (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)
      pure internal
      returns (uint256 z) {
        if (y == 0) return 0; // Prevent division by zero at the next line
        assert (x <= MAX_UINT256 / y);
        return x * y;
      }
    }
    /*
     * EIP-20 Standard Token Smart Contract Interface.
     * Copyright (c) 2018 by STSS (Malta) Limited.
     * Contact: <tech@stasis.net>
    
     * ERC-20 standard token interface, as defined
     * <a href="https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md">here</a>.
     */
    contract Token {
      /**
       * Get total number of tokens in circulation.
       *
       * @return total number of tokens in circulation
       */
      function totalSupply () public view 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) public view 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)
      public payable 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)
      public payable 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)
      public payable 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)
      public view 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.
     * Copyright (c) 2018 by STSS (Malta) Limited.
     * Contact: <tech@stasis.net>
    
     * Abstract Token Smart Contract that could be used as a base contract for
     * ERC-20 token contracts.
     */
    contract AbstractToken is Token, SafeMath {
      /**
       * Create new Abstract Token contract.
       */
      function AbstractToken () public {
        // 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) public view 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)
      public payable returns (bool success) {
        uint256 fromBalance = accounts [msg.sender];
        if (fromBalance < _value) return false;
        if (_value > 0 && msg.sender != _to) {
          accounts [msg.sender] = safeSub (fromBalance, _value);
          accounts [_to] = safeAdd (accounts [_to], _value);
        }
        Transfer (msg.sender, _to, _value);
        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)
      public payable returns (bool success) {
        uint256 spenderAllowance = allowances [_from][msg.sender];
        if (spenderAllowance < _value) return false;
        uint256 fromBalance = accounts [_from];
        if (fromBalance < _value) return false;
    
        allowances [_from][msg.sender] =
          safeSub (spenderAllowance, _value);
    
        if (_value > 0 && _from != _to) {
          accounts [_from] = safeSub (fromBalance, _value);
          accounts [_to] = safeAdd (accounts [_to], _value);
        }
        Transfer (_from, _to, _value);
        return true;
      }
    
      /**
       * 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)
      public payable 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)
      public view 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) internal 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)) internal allowances;
    }
    
    /*
     * EURS Token Smart Contract.
     * Copyright (c) 2018 by STSS (Malta) Limited.
     * Contact: <tech@stasis.net>
     */
    
    contract EURSToken is AbstractToken {
      /**
       * Fee denominator (0.001%).
       */
      uint256 constant internal FEE_DENOMINATOR = 100000;
    
      /**
       * Maximum fee numerator (100%).
       */
      uint256 constant internal MAX_FEE_NUMERATOR = FEE_DENOMINATOR;
    
      /**
       * Minimum fee numerator (0%).
       */
      uint256 constant internal MIN_FEE_NUMERATIOR = 0;
    
      /**
       * Maximum allowed number of tokens in circulation.
       */
      uint256 constant internal MAX_TOKENS_COUNT =
        0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff /
        MAX_FEE_NUMERATOR;
    
      /**
       * Default transfer fee.
       */
      uint256 constant internal DEFAULT_FEE = 5e2;
    
      /**
       * Address flag that marks black listed addresses.
       */
      uint256 constant internal BLACK_LIST_FLAG = 0x01;
    
      /**
       * Address flag that marks zero fee addresses.
       */
      uint256 constant internal ZERO_FEE_FLAG = 0x02;
    
      modifier delegatable {
        if (delegate == address (0)) {
          require (msg.value == 0); // Non payable if not delegated
          _;
        } else {
          assembly {
            // Save owner
            let oldOwner := sload (owner_slot)
    
            // Save delegate
            let oldDelegate := sload (delegate_slot)
    
            // Solidity stores address of the beginning of free memory at 0x40
            let buffer := mload (0x40)
    
            // Copy message call data into buffer
            calldatacopy (buffer, 0, calldatasize)
    
            // Lets call our delegate
            let result := delegatecall (gas, oldDelegate, buffer, calldatasize, buffer, 0)
    
            // Check, whether owner was changed
            switch eq (oldOwner, sload (owner_slot))
            case 1 {} // Owner was not changed, fine
            default {revert (0, 0) } // Owner was changed, revert!
    
            // Check, whether delegate was changed
            switch eq (oldDelegate, sload (delegate_slot))
            case 1 {} // Delegate was not changed, fine
            default {revert (0, 0) } // Delegate was changed, revert!
    
            // Copy returned value into buffer
            returndatacopy (buffer, 0, returndatasize)
    
            // Check call status
            switch result
            case 0 { revert (buffer, returndatasize) } // Call failed, revert!
            default { return (buffer, returndatasize) } // Call succeeded, return
          }
        }
      }
    
      /**
       * Create EURS Token smart contract with message sender as an owner.
       *
       * @param _feeCollector address fees are sent to
       */
      function EURSToken (address _feeCollector) public {
        fixedFee = DEFAULT_FEE;
        minVariableFee = 0;
        maxVariableFee = 0;
        variableFeeNumerator = 0;
    
        owner = msg.sender;
        feeCollector = _feeCollector;
      }
    
      /**
       * Delegate unrecognized functions.
       */
      function () public delegatable payable {
        revert (); // Revert if not delegated
      }
    
      /**
       * Get name of the token.
       *
       * @return name of the token
       */
      function name () public delegatable view returns (string) {
        return "STASIS EURS Token";
      }
    
      /**
       * Get symbol of the token.
       *
       * @return symbol of the token
       */
      function symbol () public delegatable view returns (string) {
        return "EURS";
      }
    
      /**
       * Get number of decimals for the token.
       *
       * @return number of decimals for the token
       */
      function decimals () public delegatable view returns (uint8) {
        return 2;
      }
    
      /**
       * Get total number of tokens in circulation.
       *
       * @return total number of tokens in circulation
       */
      function totalSupply () public delegatable view returns (uint256) {
        return tokensCount;
      }
    
      /**
       * 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)
        public delegatable view returns (uint256 balance) {
        return AbstractToken.balanceOf (_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)
      public delegatable payable returns (bool) {
        if (frozen) return false;
        else if (
          (addressFlags [msg.sender] | addressFlags [_to]) & BLACK_LIST_FLAG ==
          BLACK_LIST_FLAG)
          return false;
        else {
          uint256 fee =
            (addressFlags [msg.sender] | addressFlags [_to]) & ZERO_FEE_FLAG == ZERO_FEE_FLAG ?
              0 :
              calculateFee (_value);
    
          if (_value <= accounts [msg.sender] &&
              fee <= safeSub (accounts [msg.sender], _value)) {
            require (AbstractToken.transfer (_to, _value));
            require (AbstractToken.transfer (feeCollector, fee));
            return true;
          } else return false;
        }
      }
    
      /**
       * 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)
      public delegatable payable returns (bool) {
        if (frozen) return false;
        else if (
          (addressFlags [_from] | addressFlags [_to]) & BLACK_LIST_FLAG ==
          BLACK_LIST_FLAG)
          return false;
        else {
          uint256 fee =
            (addressFlags [_from] | addressFlags [_to]) & ZERO_FEE_FLAG == ZERO_FEE_FLAG ?
              0 :
              calculateFee (_value);
    
          if (_value <= allowances [_from][msg.sender] &&
              fee <= safeSub (allowances [_from][msg.sender], _value) &&
              _value <= accounts [_from] &&
              fee <= safeSub (accounts [_from], _value)) {
            require (AbstractToken.transferFrom (_from, _to, _value));
            require (AbstractToken.transferFrom (_from, feeCollector, fee));
            return true;
          } else return false;
        }
      }
    
      /**
       * 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)
      public delegatable payable returns (bool success) {
        return AbstractToken.approve (_spender, _value);
      }
    
      /**
       * 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)
      public delegatable view returns (uint256 remaining) {
        return AbstractToken.allowance (_owner, _spender);
      }
    
      /**
       * Transfer given number of token from the signed defined by digital signature
       * to given recipient.
       *
       * @param _to address to transfer token to the owner of
       * @param _value number of tokens to transfer
       * @param _fee number of tokens to give to message sender
       * @param _nonce nonce of the transfer
       * @param _v parameter V of digital signature
       * @param _r parameter R of digital signature
       * @param _s parameter S of digital signature
       */
      function delegatedTransfer (
        address _to, uint256 _value, uint256 _fee,
        uint256 _nonce, uint8 _v, bytes32 _r, bytes32 _s)
      public delegatable payable returns (bool) {
        if (frozen) return false;
        else {
          address _from = ecrecover (
            keccak256 (
              thisAddress (), messageSenderAddress (), _to, _value, _fee, _nonce),
            _v, _r, _s);
    
          if (_nonce != nonces [_from]) return false;
    
          if (
            (addressFlags [_from] | addressFlags [_to]) & BLACK_LIST_FLAG ==
            BLACK_LIST_FLAG)
            return false;
    
          uint256 fee =
            (addressFlags [_from] | addressFlags [_to]) & ZERO_FEE_FLAG == ZERO_FEE_FLAG ?
              0 :
              calculateFee (_value);
    
          uint256 balance = accounts [_from];
          if (_value > balance) return false;
          balance = safeSub (balance, _value);
          if (fee > balance) return false;
          balance = safeSub (balance, fee);
          if (_fee > balance) return false;
          balance = safeSub (balance, _fee);
    
          nonces [_from] = _nonce + 1;
    
          accounts [_from] = balance;
          accounts [_to] = safeAdd (accounts [_to], _value);
          accounts [feeCollector] = safeAdd (accounts [feeCollector], fee);
          accounts [msg.sender] = safeAdd (accounts [msg.sender], _fee);
    
          Transfer (_from, _to, _value);
          Transfer (_from, feeCollector, fee);
          Transfer (_from, msg.sender, _fee);
    
          return true;
        }
      }
    
      /**
       * Create tokens.
       *
       * @param _value number of tokens to be created.
       */
      function createTokens (uint256 _value)
      public delegatable payable returns (bool) {
        require (msg.sender == owner);
    
        if (_value > 0) {
          if (_value <= safeSub (MAX_TOKENS_COUNT, tokensCount)) {
            accounts [msg.sender] = safeAdd (accounts [msg.sender], _value);
            tokensCount = safeAdd (tokensCount, _value);
    
            Transfer (address (0), msg.sender, _value);
    
            return true;
          } else return false;
        } else return true;
      }
    
      /**
       * Burn tokens.
       *
       * @param _value number of tokens to burn
       */
      function burnTokens (uint256 _value)
      public delegatable payable returns (bool) {
        require (msg.sender == owner);
    
        if (_value > 0) {
          if (_value <= accounts [msg.sender]) {
            accounts [msg.sender] = safeSub (accounts [msg.sender], _value);
            tokensCount = safeSub (tokensCount, _value);
    
            Transfer (msg.sender, address (0), _value);
    
            return true;
          } else return false;
        } else return true;
      }
    
      /**
       * Freeze token transfers.
       */
      function freezeTransfers () public delegatable payable {
        require (msg.sender == owner);
    
        if (!frozen) {
          frozen = true;
    
          Freeze ();
        }
      }
    
      /**
       * Unfreeze token transfers.
       */
      function unfreezeTransfers () public delegatable payable {
        require (msg.sender == owner);
    
        if (frozen) {
          frozen = false;
    
          Unfreeze ();
        }
      }
    
      /**
       * Set smart contract owner.
       *
       * @param _newOwner address of the new owner
       */
      function setOwner (address _newOwner) public {
        require (msg.sender == owner);
    
        owner = _newOwner;
      }
    
      /**
       * Set fee collector.
       *
       * @param _newFeeCollector address of the new fee collector
       */
      function setFeeCollector (address _newFeeCollector)
      public delegatable payable {
        require (msg.sender == owner);
    
        feeCollector = _newFeeCollector;
      }
    
      /**
       * Get current nonce for token holder with given address, i.e. nonce this
       * token holder should use for next delegated transfer.
       *
       * @param _owner address of the token holder to get nonce for
       * @return current nonce for token holder with give address
       */
      function nonce (address _owner) public view delegatable returns (uint256) {
        return nonces [_owner];
      }
    
      /**
       * Set fee parameters.
       *
       * @param _fixedFee fixed fee in token units
       * @param _minVariableFee minimum variable fee in token units
       * @param _maxVariableFee maximum variable fee in token units
       * @param _variableFeeNumerator variable fee numerator
       */
      function setFeeParameters (
        uint256 _fixedFee,
        uint256 _minVariableFee,
        uint256 _maxVariableFee,
        uint256 _variableFeeNumerator) public delegatable payable {
        require (msg.sender == owner);
    
        require (_minVariableFee <= _maxVariableFee);
        require (_variableFeeNumerator <= MAX_FEE_NUMERATOR);
    
        fixedFee = _fixedFee;
        minVariableFee = _minVariableFee;
        maxVariableFee = _maxVariableFee;
        variableFeeNumerator = _variableFeeNumerator;
    
        FeeChange (
          _fixedFee, _minVariableFee, _maxVariableFee, _variableFeeNumerator);
      }
    
      /**
       * Get fee parameters.
       *
       * @return fee parameters
       */
      function getFeeParameters () public delegatable view returns (
        uint256 _fixedFee,
        uint256 _minVariableFee,
        uint256 _maxVariableFee,
        uint256 _variableFeeNumnerator) {
        _fixedFee = fixedFee;
        _minVariableFee = minVariableFee;
        _maxVariableFee = maxVariableFee;
        _variableFeeNumnerator = variableFeeNumerator;
      }
    
      /**
       * Calculate fee for transfer of given number of tokens.
       *
       * @param _amount transfer amount to calculate fee for
       * @return fee for transfer of given amount
       */
      function calculateFee (uint256 _amount)
        public delegatable view returns (uint256 _fee) {
        require (_amount <= MAX_TOKENS_COUNT);
    
        _fee = safeMul (_amount, variableFeeNumerator) / FEE_DENOMINATOR;
        if (_fee < minVariableFee) _fee = minVariableFee;
        if (_fee > maxVariableFee) _fee = maxVariableFee;
        _fee = safeAdd (_fee, fixedFee);
      }
    
      /**
       * Set flags for given address.
       *
       * @param _address address to set flags for
       * @param _flags flags to set
       */
      function setFlags (address _address, uint256 _flags)
      public delegatable payable {
        require (msg.sender == owner);
    
        addressFlags [_address] = _flags;
      }
    
      /**
       * Get flags for given address.
       *
       * @param _address address to get flags for
       * @return flags for given address
       */
      function flags (address _address) public delegatable view returns (uint256) {
        return addressFlags [_address];
      }
    
      /**
       * Set address of smart contract to delegate execution of delegatable methods
       * to.
       *
       * @param _delegate address of smart contract to delegate execution of
       * delegatable methods to, or zero to not delegate delegatable methods
       * execution.
       */
      function setDelegate (address _delegate) public {
        require (msg.sender == owner);
    
        if (delegate != _delegate) {
          delegate = _delegate;
          Delegation (delegate);
        }
      }
    
      /**
       * Get address of this smart contract.
       *
       * @return address of this smart contract
       */
      function thisAddress () internal view returns (address) {
        return this;
      }
    
      /**
       * Get address of message sender.
       *
       * @return address of this smart contract
       */
      function messageSenderAddress () internal view returns (address) {
        return msg.sender;
      }
    
      /**
       * Owner of the smart contract.
       */
      address internal owner;
    
      /**
       * Address where fees are sent to.
       */
      address internal feeCollector;
    
      /**
       * Number of tokens in circulation.
       */
      uint256 internal tokensCount;
    
      /**
       * Whether token transfers are currently frozen.
       */
      bool internal frozen;
    
      /**
       * Mapping from sender's address to the next delegated transfer nonce.
       */
      mapping (address => uint256) internal nonces;
    
      /**
       * Fixed fee amount in token units.
       */
      uint256 internal fixedFee;
    
      /**
       * Minimum variable fee in token units.
       */
      uint256 internal minVariableFee;
    
      /**
       * Maximum variable fee in token units.
       */
      uint256 internal maxVariableFee;
    
      /**
       * Variable fee numerator.
       */
      uint256 internal variableFeeNumerator;
    
      /**
       * Maps address to its flags.
       */
      mapping (address => uint256) internal addressFlags;
    
      /**
       * Address of smart contract to delegate execution of delegatable methods to,
       * or zero to not delegate delegatable methods execution.
       */
      address internal delegate;
    
      /**
       * Logged when token transfers were frozen.
       */
      event Freeze ();
    
      /**
       * Logged when token transfers were unfrozen.
       */
      event Unfreeze ();
    
      /**
       * Logged when fee parameters were changed.
       *
       * @param fixedFee fixed fee in token units
       * @param minVariableFee minimum variable fee in token units
       * @param maxVariableFee maximum variable fee in token units
       * @param variableFeeNumerator variable fee numerator
       */
      event FeeChange (
        uint256 fixedFee,
        uint256 minVariableFee,
        uint256 maxVariableFee,
        uint256 variableFeeNumerator);
    
      /**
       * Logged when address of smart contract execution of delegatable methods is
       * delegated to was changed.
       *
       * @param delegate new address of smart contract execution of delegatable
       * methods is delegated to or zero if execution of delegatable methods is
       * oot delegated.
       */
      event Delegation (address delegate);
    }