ETH Price: $2,563.54 (-0.54%)

Transaction Decoder

Block:
10651346 at Aug-13-2020 11:28:01 AM +UTC
Transaction Fee:
0.01581408 ETH $40.54
Gas Used:
43,928 Gas / 360 Gwei

Emitted Events:

226 EURXProxy.0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef( 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x000000000000000000000000ffec0067f5a79cff07527f63d83dd5462ccf8ba4, 00000000000000000000000000000000000000000000032d26d12e980b600000 )
227 EURXProxy.0xab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8( 0xab8530f87dc9b59234c4623bf917212bb2536d647574c8e7e5da92c2ede0c9f8, 0000000000000000000000000031e147a79c45f24319dc02ca860cb6142fcba1, 000000000000000000000000ffec0067f5a79cff07527f63d83dd5462ccf8ba4, 00000000000000000000000000000000000000000000032d26d12e980b600000 )

Account State Difference:

  Address   Before After State Difference Code
0x0031e147...6142FCBA1
(Nexo 3)
90.124166280472063039 Eth
Nonce: 379652
90.108352200472063039 Eth
Nonce: 379653
0.01581408
(Spark Pool)
254.815171524652125909 Eth254.830985604652125909 Eth0.01581408
0xEfa6D996...55E77b553

Execution Trace

EURXProxy.40c10f19( )
  • EURX.mint( to=0xFfec0067F5a79CFf07527f63D83dD5462cCf8BA4, tokens=15000000000000000000000 ) => ( True )
    File 1 of 2: EURXProxy
    // File: zos-lib/contracts/upgradeability/Proxy.sol
    
    pragma solidity ^0.4.24;
    
    /**
     * @title Proxy
     * @dev Implements delegation of calls to other contracts, with proper
     * forwarding of return values and bubbling of failures.
     * It defines a fallback function that delegates all calls to the address
     * returned by the abstract _implementation() internal function.
     */
    contract Proxy {
      /**
       * @dev Fallback function.
       * Implemented entirely in `_fallback`.
       */
      function () payable external {
        _fallback();
      }
    
      /**
       * @return The Address of the implementation.
       */
      function _implementation() internal view returns (address);
    
      /**
       * @dev Delegates execution to an implementation contract.
       * This is a low level function that doesn't return to its internal call site.
       * It will return to the external caller whatever the implementation returns.
       * @param implementation Address to delegate.
       */
      function _delegate(address implementation) internal {
        assembly {
          // Copy msg.data. We take full control of memory in this inline assembly
          // block because it will not return to Solidity code. We overwrite the
          // Solidity scratch pad at memory position 0.
          calldatacopy(0, 0, calldatasize)
    
          // Call the implementation.
          // out and outsize are 0 because we don't know the size yet.
          let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0)
    
          // Copy the returned data.
          returndatacopy(0, 0, returndatasize)
    
          switch result
          // delegatecall returns 0 on error.
          case 0 { revert(0, returndatasize) }
          default { return(0, returndatasize) }
        }
      }
    
      /**
       * @dev Function that is run as the first thing in the fallback function.
       * Can be redefined in derived contracts to add functionality.
       * Redefinitions must call super._willFallback().
       */
      function _willFallback() internal {
      }
    
      /**
       * @dev fallback implementation.
       * Extracted to enable manual triggering.
       */
      function _fallback() internal {
        _willFallback();
        _delegate(_implementation());
      }
    }
    
    // File: zos-lib/contracts/utils/Address.sol
    
    pragma solidity ^0.4.24;
    
    /**
     * Utility library of inline functions on addresses
     *
     * Source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/v2.0.0/contracts/utils/Address.sol
     * This contract is copied here and renamed from the original to avoid clashes in the compiled artifacts
     * when the user imports a zos-lib contract (that transitively causes this contract to be compiled and added to the
     * build/artifacts folder) as well as the vanilla Address implementation from an openzeppelin version.
     */
    library ZOSLibAddress {
    
      /**
       * Returns whether the target address is a contract
       * @dev This function will return false if invoked during the constructor of a contract,
       * as the code is not actually created until after the constructor finishes.
       * @param account address of the account to check
       * @return whether the target address is a contract
       */
      function isContract(address account) internal view returns (bool) {
        uint256 size;
        // XXX Currently there is no better way to check if there is a contract in an address
        // than to check the size of the code at that address.
        // See https://ethereum.stackexchange.com/a/14016/36603
        // for more details about how this works.
        // TODO Check this again before the Serenity release, because all addresses will be
        // contracts then.
        // solium-disable-next-line security/no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
      }
    
    }
    
    // File: zos-lib/contracts/upgradeability/UpgradeabilityProxy.sol
    
    pragma solidity ^0.4.24;
    
    
    
    /**
     * @title UpgradeabilityProxy
     * @dev This contract implements a proxy that allows to change the
     * implementation address to which it will delegate.
     * Such a change is called an implementation upgrade.
     */
    contract UpgradeabilityProxy is Proxy {
      /**
       * @dev Emitted when the implementation is upgraded.
       * @param implementation Address of the new implementation.
       */
      event Upgraded(address indexed implementation);
    
      /**
       * @dev Storage slot with the address of the current implementation.
       * This is the keccak-256 hash of "org.zeppelinos.proxy.implementation", and is
       * validated in the constructor.
       */
      bytes32 private constant IMPLEMENTATION_SLOT = 0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3;
    
      /**
       * @dev Contract constructor.
       * @param _implementation Address of the initial implementation.
       * @param _data Data to send as msg.data to the implementation to initialize the proxied contract.
       * It should include the signature and the parameters of the function to be called, as described in
       * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding.
       * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped.
       */
      constructor(address _implementation, bytes _data) public payable {
        assert(IMPLEMENTATION_SLOT == keccak256("org.zeppelinos.proxy.implementation"));
        _setImplementation(_implementation);
        if(_data.length > 0) {
          require(_implementation.delegatecall(_data));
        }
      }
    
      /**
       * @dev Returns the current implementation.
       * @return Address of the current implementation
       */
      function _implementation() internal view returns (address impl) {
        bytes32 slot = IMPLEMENTATION_SLOT;
        assembly {
          impl := sload(slot)
        }
      }
    
      /**
       * @dev Upgrades the proxy to a new implementation.
       * @param newImplementation Address of the new implementation.
       */
      function _upgradeTo(address newImplementation) internal {
        _setImplementation(newImplementation);
        emit Upgraded(newImplementation);
      }
    
      /**
       * @dev Sets the implementation address of the proxy.
       * @param newImplementation Address of the new implementation.
       */
      function _setImplementation(address newImplementation) private {
        require(ZOSLibAddress.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address");
    
        bytes32 slot = IMPLEMENTATION_SLOT;
    
        assembly {
          sstore(slot, newImplementation)
        }
      }
    }
    
    // File: zos-lib/contracts/upgradeability/AdminUpgradeabilityProxy.sol
    
    pragma solidity ^0.4.24;
    
    
    /**
     * @title AdminUpgradeabilityProxy
     * @dev This contract combines an upgradeability proxy with an authorization
     * mechanism for administrative tasks.
     * All external functions in this contract must be guarded by the
     * `ifAdmin` modifier. See ethereum/solidity#3864 for a Solidity
     * feature proposal that would enable this to be done automatically.
     */
    contract AdminUpgradeabilityProxy is UpgradeabilityProxy {
      /**
       * @dev Emitted when the administration has been transferred.
       * @param previousAdmin Address of the previous admin.
       * @param newAdmin Address of the new admin.
       */
      event AdminChanged(address previousAdmin, address newAdmin);
    
      /**
       * @dev Storage slot with the admin of the contract.
       * This is the keccak-256 hash of "org.zeppelinos.proxy.admin", and is
       * validated in the constructor.
       */
      bytes32 private constant ADMIN_SLOT = 0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b;
    
      /**
       * @dev Modifier to check whether the `msg.sender` is the admin.
       * If it is, it will run the function. Otherwise, it will delegate the call
       * to the implementation.
       */
      modifier ifAdmin() {
        if (msg.sender == _admin()) {
          _;
        } else {
          _fallback();
        }
      }
    
      /**
       * Contract constructor.
       * @param _implementation address of the initial implementation.
       * @param _admin Address of the proxy administrator.
       * @param _data Data to send as msg.data to the implementation to initialize the proxied contract.
       * It should include the signature and the parameters of the function to be called, as described in
       * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding.
       * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped.
       */
      constructor(address _implementation, address _admin, bytes _data) UpgradeabilityProxy(_implementation, _data) public payable {
        assert(ADMIN_SLOT == keccak256("org.zeppelinos.proxy.admin"));
    
        _setAdmin(_admin);
      }
    
      /**
       * @return The address of the proxy admin.
       */
      function admin() external view ifAdmin returns (address) {
        return _admin();
      }
    
      /**
       * @return The address of the implementation.
       */
      function implementation() external view ifAdmin returns (address) {
        return _implementation();
      }
    
      /**
       * @dev Changes the admin of the proxy.
       * Only the current admin can call this function.
       * @param newAdmin Address to transfer proxy administration to.
       */
      function changeAdmin(address newAdmin) external ifAdmin {
        require(newAdmin != address(0), "Cannot change the admin of a proxy to the zero address");
        emit AdminChanged(_admin(), newAdmin);
        _setAdmin(newAdmin);
      }
    
      /**
       * @dev Upgrade the backing implementation of the proxy.
       * Only the admin can call this function.
       * @param newImplementation Address of the new implementation.
       */
      function upgradeTo(address newImplementation) external ifAdmin {
        _upgradeTo(newImplementation);
      }
    
      /**
       * @dev Upgrade the backing implementation of the proxy and call a function
       * on the new implementation.
       * This is useful to initialize the proxied contract.
       * @param newImplementation Address of the new implementation.
       * @param data Data to send as msg.data in the low level call.
       * It should include the signature and the parameters of the function to be called, as described in
       * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding.
       */
      function upgradeToAndCall(address newImplementation, bytes data) payable external ifAdmin {
        _upgradeTo(newImplementation);
        require(newImplementation.delegatecall(data));
      }
    
      /**
       * @return The admin slot.
       */
      function _admin() internal view returns (address adm) {
        bytes32 slot = ADMIN_SLOT;
        assembly {
          adm := sload(slot)
        }
      }
    
      /**
       * @dev Sets the address of the proxy admin.
       * @param newAdmin Address of the new proxy admin.
       */
      function _setAdmin(address newAdmin) internal {
        bytes32 slot = ADMIN_SLOT;
    
        assembly {
          sstore(slot, newAdmin)
        }
      }
    
      /**
       * @dev Only fall back when the sender is not the admin.
       */
      function _willFallback() internal {
        require(msg.sender != _admin(), "Cannot call fallback function from the proxy admin");
        super._willFallback();
      }
    }
    
    
    
    pragma solidity ^0.4.24;
    
    
    contract EURXProxy is AdminUpgradeabilityProxy {
      constructor(address _implementation, address _admin, bytes _data) public AdminUpgradeabilityProxy(_implementation, _admin, _data) {
        
        }
    }

    File 2 of 2: EURX
    // File: openzeppelin-solidity/contracts/token/ERC20/IERC20.sol
    
    pragma solidity ^0.5.2;
    
    /**
     * @title ERC20 interface
     * @dev see https://eips.ethereum.org/EIPS/eip-20
     */
    interface IERC20 {
        function transfer(address to, uint256 value) external returns (bool);
    
        function approve(address spender, uint256 value) external returns (bool);
    
        function transferFrom(address from, address to, uint256 value) external returns (bool);
    
        function totalSupply() external view returns (uint256);
    
        function balanceOf(address who) external view returns (uint256);
    
        function allowance(address owner, address spender) external view returns (uint256);
    
        event Transfer(address indexed from, address indexed to, uint256 value);
    
        event Approval(address indexed owner, address indexed spender, uint256 value);
    }
    
    // File: openzeppelin-solidity/contracts/math/SafeMath.sol
    
    pragma solidity ^0.5.2;
    
    /**
     * @title SafeMath
     * @dev Unsigned math operations with safety checks that revert on error
     */
    library SafeMath {
        /**
         * @dev Multiplies two unsigned integers, reverts on overflow.
         */
        function mul(uint256 a, uint256 b) internal pure returns (uint256) {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
            if (a == 0) {
                return 0;
            }
    
            uint256 c = a * b;
            require(c / a == b);
    
            return c;
        }
    
        /**
         * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
         */
        function div(uint256 a, uint256 b) internal pure returns (uint256) {
            // Solidity only automatically asserts when dividing by 0
            require(b > 0);
            uint256 c = a / b;
            // assert(a == b * c + a % b); // There is no case in which this doesn't hold
    
            return c;
        }
    
        /**
         * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
         */
        function sub(uint256 a, uint256 b) internal pure returns (uint256) {
            require(b <= a);
            uint256 c = a - b;
    
            return c;
        }
    
        /**
         * @dev Adds two unsigned integers, reverts on overflow.
         */
        function add(uint256 a, uint256 b) internal pure returns (uint256) {
            uint256 c = a + b;
            require(c >= a);
    
            return c;
        }
    
        /**
         * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
         * reverts when dividing by zero.
         */
        function mod(uint256 a, uint256 b) internal pure returns (uint256) {
            require(b != 0);
            return a % b;
        }
    }
    
    // File: openzeppelin-solidity/contracts/token/ERC20/ERC20.sol
    
    pragma solidity ^0.5.2;
    
    
    
    /**
     * @title Standard ERC20 token
     *
     * @dev Implementation of the basic standard token.
     * https://eips.ethereum.org/EIPS/eip-20
     * Originally based on code by FirstBlood:
     * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
     *
     * This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for
     * all accounts just by listening to said events. Note that this isn't required by the specification, and other
     * compliant implementations may not do it.
     */
    contract ERC20 is IERC20 {
        using SafeMath for uint256;
    
        mapping (address => uint256) private _balances;
    
        mapping (address => mapping (address => uint256)) private _allowed;
    
        uint256 private _totalSupply;
    
        /**
         * @dev Total number of tokens in existence
         */
        function totalSupply() public view returns (uint256) {
            return _totalSupply;
        }
    
        /**
         * @dev Gets the balance of the specified address.
         * @param owner The address to query the balance of.
         * @return A uint256 representing the amount owned by the passed address.
         */
        function balanceOf(address owner) public view returns (uint256) {
            return _balances[owner];
        }
    
        /**
         * @dev Function to check the amount of tokens that an owner allowed to a spender.
         * @param owner address The address which owns the funds.
         * @param spender address The address which will spend the funds.
         * @return A uint256 specifying the amount of tokens still available for the spender.
         */
        function allowance(address owner, address spender) public view returns (uint256) {
            return _allowed[owner][spender];
        }
    
        /**
         * @dev Transfer token to a specified address
         * @param to The address to transfer to.
         * @param value The amount to be transferred.
         */
        function transfer(address to, uint256 value) public returns (bool) {
            _transfer(msg.sender, to, value);
            return true;
        }
    
        /**
         * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
         * Beware that changing an allowance with this method brings the risk that someone may use both the old
         * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
         * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
         * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
         * @param spender The address which will spend the funds.
         * @param value The amount of tokens to be spent.
         */
        function approve(address spender, uint256 value) public returns (bool) {
            _approve(msg.sender, spender, value);
            return true;
        }
    
        /**
         * @dev Transfer tokens from one address to another.
         * Note that while this function emits an Approval event, this is not required as per the specification,
         * and other compliant implementations may not emit the event.
         * @param from address The address which you want to send tokens from
         * @param to address The address which you want to transfer to
         * @param value uint256 the amount of tokens to be transferred
         */
        function transferFrom(address from, address to, uint256 value) public returns (bool) {
            _transfer(from, to, value);
            _approve(from, msg.sender, _allowed[from][msg.sender].sub(value));
            return true;
        }
    
        /**
         * @dev Increase the amount of tokens that an owner allowed to a spender.
         * approve should be called when _allowed[msg.sender][spender] == 0. To increment
         * allowed value is better to use this function to avoid 2 calls (and wait until
         * the first transaction is mined)
         * From MonolithDAO Token.sol
         * Emits an Approval event.
         * @param spender The address which will spend the funds.
         * @param addedValue The amount of tokens to increase the allowance by.
         */
        function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
            _approve(msg.sender, spender, _allowed[msg.sender][spender].add(addedValue));
            return true;
        }
    
        /**
         * @dev Decrease the amount of tokens that an owner allowed to a spender.
         * approve should be called when _allowed[msg.sender][spender] == 0. To decrement
         * allowed value is better to use this function to avoid 2 calls (and wait until
         * the first transaction is mined)
         * From MonolithDAO Token.sol
         * Emits an Approval event.
         * @param spender The address which will spend the funds.
         * @param subtractedValue The amount of tokens to decrease the allowance by.
         */
        function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
            _approve(msg.sender, spender, _allowed[msg.sender][spender].sub(subtractedValue));
            return true;
        }
    
        /**
         * @dev Transfer token for a specified addresses
         * @param from The address to transfer from.
         * @param to The address to transfer to.
         * @param value The amount to be transferred.
         */
        function _transfer(address from, address to, uint256 value) internal {
            require(to != address(0));
    
            _balances[from] = _balances[from].sub(value);
            _balances[to] = _balances[to].add(value);
            emit Transfer(from, to, value);
        }
    
        /**
         * @dev Internal function that mints an amount of the token and assigns it to
         * an account. This encapsulates the modification of balances such that the
         * proper events are emitted.
         * @param account The account that will receive the created tokens.
         * @param value The amount that will be created.
         */
        function _mint(address account, uint256 value) internal {
            require(account != address(0));
    
            _totalSupply = _totalSupply.add(value);
            _balances[account] = _balances[account].add(value);
            emit Transfer(address(0), account, value);
        }
    
        /**
         * @dev Internal function that burns an amount of the token of a given
         * account.
         * @param account The account whose tokens will be burnt.
         * @param value The amount that will be burnt.
         */
        function _burn(address account, uint256 value) internal {
            require(account != address(0));
    
            _totalSupply = _totalSupply.sub(value);
            _balances[account] = _balances[account].sub(value);
            emit Transfer(account, address(0), value);
        }
    
        /**
         * @dev Approve an address to spend another addresses' tokens.
         * @param owner The address that owns the tokens.
         * @param spender The address that will spend the tokens.
         * @param value The number of tokens that can be spent.
         */
        function _approve(address owner, address spender, uint256 value) internal {
            require(spender != address(0));
            require(owner != address(0));
    
            _allowed[owner][spender] = value;
            emit Approval(owner, spender, value);
        }
    
        /**
         * @dev Internal function that burns an amount of the token of a given
         * account, deducting from the sender's allowance for said account. Uses the
         * internal burn function.
         * Emits an Approval event (reflecting the reduced allowance).
         * @param account The account whose tokens will be burnt.
         * @param value The amount that will be burnt.
         */
        function _burnFrom(address account, uint256 value) internal {
            _burn(account, value);
            _approve(account, msg.sender, _allowed[account][msg.sender].sub(value));
        }
    }
    
    // File: contracts/Ownable.sol
    
    pragma solidity ^0.5.2;
    
    contract Ownable {
    
      // Owner of the contract
      address private _owner;
      // Potential owner of the contract
      address private _potentialOwner;
    
      /**
      * @dev Event to show that a new potential owner has been set
      * @param previousOwner representing the address of the previous owner
      * @param potentialOwner representing the address of the potential owner
      */
      event NewPotentialOwner(address previousOwner, address potentialOwner);
    
      /**
      * @dev Event to show ownership has been claimed
      * Triggered when potentialOwner has claimed his ownership
      * @param previousOwner representing the address of the previous owner
      * @param newOwner representing the address of the new owner
      */
      event OwnershipClaimed(address previousOwner, address newOwner);
      
      /**
      * @return the address of the owner
      */
      function owner() public view returns (address) {
        return _owner;
      }
    
      /**
      * @return the address of the potential owner
      */
      function potentialOwner() public view returns (address) {
        return _potentialOwner;
      }
      
      /**
      * @dev Throws if called by any account other than the owner.
      */
      modifier onlyOwner() {
        require(msg.sender == owner());
        _;
      }
    
      /**
       * @dev Sets a new owner address
       * Called only when initializing the EURX contract
       */
      function setOwner(address newOwner) internal {
        _owner = newOwner;
      }
    
      /**
       * @dev Allows the current owner to transfer control of the contract to a potential owner.
       * @param newOwner The address to transfer ownership to.
       */
      function setPotentialOwner(address newOwner) public onlyOwner {
        require(newOwner != address(0));
        _potentialOwner = newOwner;
        emit NewPotentialOwner(owner(), potentialOwner());
      }
    
      /**
       * @dev Allows the potential owner to claim ownership.
       */
      function claimOwnership() public {
        require(msg.sender == potentialOwner());
        _owner = _potentialOwner;
        _potentialOwner = address(0);
        emit OwnershipClaimed(owner(), potentialOwner());
      }
    }
    
    // File: contracts/Pausable.sol
    
    pragma solidity ^0.5.2;
    
    
    /**
     * @title Pausable
     * @dev Base contract which allows children to implement an emergency stop mechanism.
     * Based on openzeppelin tag v2.2 commit: 9ed1b4486519113ee05fa648acb4ebcecd070cbf
     * https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/lifecycle/Pausable.sol
     * Modifications:
     * 1) Remove address pauser from events Pause and Unpause
     * 2) Added pauser role, switched pause/unpause to be onlyPauser
     * 3) Removed whenNotPaused/whenPaused from pause/unpause
     * 4) Removed whenPaused modifier
     * 5) Inherit from Ownable contract
     * 6) Remove constructor
     */
    contract Pausable is Ownable {
      event Pause();
      event Unpause();
      event PauserChanged(address indexed newAddress);
    
      address private _pauser;
      bool private _paused;
    
      /**
        * @return True if the contract is paused, false otherwise.
        */
      function paused() public view returns (bool) {
          return _paused;
      }
    
      /**
        * @return address of pauser
        */
      function pauser() public view returns (address) {
          return _pauser;
      }
    
      /**
       * @dev Modifier to make a function callable only when the contract is not paused.
       */
      modifier whenNotPaused() {
        require(!_paused);
        _;
      }
    
      /**
       * @dev throws if called by any account other than the pauser
       */
      modifier onlyPauser() {
        require(msg.sender == pauser());
        _;
      }
    
      /**
       * @dev called by the owner to pause, triggers stopped state
       */
      function pause() onlyPauser public {
        _paused = true;
        emit Pause();
      }
    
      /**
       * @dev called by the owner to unpause, returns to normal state
       */
      function unpause() onlyPauser public {
        _paused = false;
        emit Unpause();
      }
    
      /**
       * @dev update the pauser role
       */
      function updatePauser(address _newPauser) onlyOwner public {
        require(_newPauser != address(0));
        _pauser = _newPauser;
        emit PauserChanged(pauser());
      }
    
    }
    
    
    
    pragma solidity ^0.5.2;
    
    
    
    
    contract EURX is ERC20, Ownable, Pausable {
        string constant public name = 'EUR Stablecoin';
        string constant public symbol = 'EURX';
        uint8 constant public decimals = 18;
        
        address public masterMinter;
        address public minter;
    
        bool private initialized;
    
        event Mint(address minter, address to, uint256 amount);
        event Burn(address from, uint256 amount);
    
        // Set initialized state to true to prevent tampering with implementation contract
        constructor() public {
            setOwner(msg.sender);
            initialized = true;
        }
    
        function initialize(address _owner, address _pauser, address _masterMinter, address _minter) public {
            require(!initialized);
            require(_owner != address(0));
            require(_pauser != address(0));
            require(_masterMinter != address(0));
            require(_minter != address(0));
    
            setOwner(_owner);
            updatePauser(_pauser);
            masterMinter = _masterMinter;
            minter = _minter;
            initialized = true;
        }
    
        function transfer(address to, uint256 tokens) public whenNotPaused returns (bool) {
            return super.transfer(to, tokens);
        }
    
        function transferFrom(address from, address to, uint256 tokens) public whenNotPaused returns (bool) {
            return super.transferFrom(from, to, tokens);
        }
    
        function approve(address spender, uint256 tokens) public whenNotPaused returns (bool) {
            return super.approve(spender, tokens);
        }
    
        function increaseAllowance(address spender, uint addedTokens) public whenNotPaused returns (bool success) {
            return super.increaseAllowance(spender, addedTokens);
        }
    
        function decreaseAllowance(address spender, uint subtractedTokens) public whenNotPaused returns (bool success) {
            return super.decreaseAllowance(spender, subtractedTokens);
        }
    
        /**
         * @dev Function to change masterMinter address.
         * @param _masterMinter Address of new masterMinter.
         * @return A boolean that indicates if operation was successful.
        */
        function updateMasterMinter(address _masterMinter) onlyOwner public returns (bool) {
            require(_masterMinter != address(0));
            masterMinter = _masterMinter;
            return true;
        }
    
        /**
         * @dev Function to change minter address.
         * @param _minter Address of new masterMinter.
         * @return A boolean that indicates if operation was successful.
        */
        function updateMinter(address _minter) onlyOwner public returns (bool) {
            require(_minter != address(0));
            minter = _minter;
            return true;
        }
    
        /**
         * @dev Function to mint tokens.
         * @param to The address to mint tokens to.
         * @param tokens The amount of tokens to mint.
         * @return A boolean that indicates if the operation was successful.
        */
        function mint(address to, uint256 tokens) public returns (bool) {
            require(msg.sender == minter || msg.sender == masterMinter);
            require(tokens > 0);
    
            if(msg.sender == minter && minter != masterMinter) {
                require(to == owner());
            }
    
            _mint(to, tokens);
            emit Mint(msg.sender, to, tokens);
            return true;
        }
    
        /**
         * @dev Function to burn tokens.
         *      Tokens are burned from caller address.
         * @param tokens The amount of tokens to burn.
         * @return A boolean that indicates if the operation was successful.
        */
        function burn(uint256 tokens) public returns (bool) {
            require(tokens > 0);
            require(balanceOf(msg.sender) >= tokens);
    
            if(msg.sender != owner()) {
                require(!paused());
            }
    
            _burn(msg.sender, tokens);
            emit Burn(msg.sender, tokens);
            return true;
        }
    
        // Owner can transfer out any accidentally sent ERC20 tokens
    	function transferERC20Token(IERC20 _token, address _to, uint256 _value)
    		public
    		onlyOwner
    		returns (bool success)
    	{
    		require(_token.balanceOf(address(this)) >= _value);
    		uint256 receiverBalance = _token.balanceOf(_to);
    		require(_token.transfer(_to, _value));
    
    		uint256 receiverNewBalance = _token.balanceOf(_to);
    		assert(receiverNewBalance == receiverBalance.add(_value));
    
    		return true;
    	}
    
    }