ETH Price: $2,316.21 (+1.57%)

Transaction Decoder

Block:
9472958 at Feb-13-2020 06:07:43 AM +UTC
Transaction Fee:
0.001005525 ETH $2.33
Gas Used:
111,725 Gas / 9 Gwei

Emitted Events:

117 FiatTokenProxy.0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef( 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, 0x0000000000000000000000000a460eaf6e630d62b87a07dd95ccb91d548eebc2, 0x0000000000000000000000006bd7f00fc00b547f4a7aad20f9a6511c8ae13087, 00000000000000000000000000000000000000000000000000000000018e4120 )

Account State Difference:

  Address   Before After State Difference Code
0x0a460eaF...D548eEbC2
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 497590261154554171967157049286663071410493035485686422326730597564482622745594648288772763979226160417299443
0x0cA4c8f0...77BEC82Dd
0.003728 Eth
Nonce: 0
0.002722475 Eth
Nonce: 1
0.001005525
(Spark Pool)
29.060100504427153887 Eth29.061106029427153887 Eth0.001005525
0xA0b86991...E3606eB48
0xf6874c88...336DfBc61
(Coinbase: Coinbase Commerce 2)

Execution Trace

Coinbase: Coinbase Commerce 2.d29dff12( )
  • 0x0a460eaf6e630d62b87a07dd95ccb91d548eebc2.3d602d80( )
  • 0x7fe59e1677afb9df3a0b2135b15fdd040c5936e7.STATICCALL( )
  • 0x0a460eaf6e630d62b87a07dd95ccb91d548eebc2.19ab453c( )
    • 0x7fe59e1677afb9df3a0b2135b15fdd040c5936e7.19ab453c( )
    • 0x0a460eaf6e630d62b87a07dd95ccb91d548eebc2.477523c2( )
      • 0x7fe59e1677afb9df3a0b2135b15fdd040c5936e7.477523c2( )
        • 0xca5faf4c4134bc4f43e910c857723a744b0d2d68.e73b9609( )
          • FiatTokenProxy.70a08231( )
            • FiatTokenV1.balanceOf( account=0x0a460eaF6E630d62b87A07dd95cCb91D548eEbC2 ) => ( 26100000 )
            • FiatTokenProxy.a9059cbb( )
              • FiatTokenV1.transfer( _to=0x6Bd7F00Fc00B547f4a7AaD20f9a6511c8ae13087, _value=26100000 ) => ( True )
                File 1 of 2: FiatTokenProxy
                pragma solidity ^0.4.24;
                
                // File: zos-lib/contracts/upgradeability/Proxy.sol
                
                /**
                 * @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: openzeppelin-solidity/contracts/AddressUtils.sol
                
                /**
                 * Utility library of inline functions on addresses
                 */
                library AddressUtils {
                
                  /**
                   * 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 addr address to check
                   * @return whether the target address is a contract
                   */
                  function isContract(address addr) 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(addr) }
                    return size > 0;
                  }
                
                }
                
                // File: zos-lib/contracts/upgradeability/UpgradeabilityProxy.sol
                
                /**
                 * @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 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.
                   */
                  constructor(address _implementation) public {
                    assert(IMPLEMENTATION_SLOT == keccak256("org.zeppelinos.proxy.implementation"));
                
                    _setImplementation(_implementation);
                  }
                
                  /**
                   * @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(AddressUtils.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
                
                /**
                 * @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.
                   * It sets the `msg.sender` as the proxy administrator.
                   * @param _implementation address of the initial implementation.
                   */
                  constructor(address _implementation) UpgradeabilityProxy(_implementation) public {
                    assert(ADMIN_SLOT == keccak256("org.zeppelinos.proxy.admin"));
                
                    _setAdmin(msg.sender);
                  }
                
                  /**
                   * @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/develop/abi-spec.html#function-selector-and-argument-encoding.
                   */
                  function upgradeToAndCall(address newImplementation, bytes data) payable external ifAdmin {
                    _upgradeTo(newImplementation);
                    require(address(this).call.value(msg.value)(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();
                  }
                }
                
                // File: contracts/FiatTokenProxy.sol
                
                /**
                * Copyright CENTRE SECZ 2018
                *
                * Permission is hereby granted, free of charge, to any person obtaining a copy 
                * of this software and associated documentation files (the "Software"), to deal 
                * in the Software without restriction, including without limitation the rights 
                * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
                * copies of the Software, and to permit persons to whom the Software is furnished to 
                * do so, subject to the following conditions:
                *
                * The above copyright notice and this permission notice shall be included in all 
                * copies or substantial portions of the Software.
                *
                * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
                * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
                * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
                * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
                * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
                * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
                */
                
                pragma solidity ^0.4.24;
                
                
                /**
                 * @title FiatTokenProxy
                 * @dev This contract proxies FiatToken calls and enables FiatToken upgrades
                */ 
                contract FiatTokenProxy is AdminUpgradeabilityProxy {
                    constructor(address _implementation) public AdminUpgradeabilityProxy(_implementation) {
                    }
                }

                File 2 of 2: FiatTokenV1
                pragma solidity ^0.4.24;
                
                // File: contracts/Ownable.sol
                
                /**
                * Copyright CENTRE SECZ 2018
                *
                * Permission is hereby granted, free of charge, to any person obtaining a copy 
                * of this software and associated documentation files (the "Software"), to deal 
                * in the Software without restriction, including without limitation the rights 
                * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
                * copies of the Software, and to permit persons to whom the Software is furnished to 
                * do so, subject to the following conditions:
                *
                * The above copyright notice and this permission notice shall be included in all 
                * copies or substantial portions of the Software.
                *
                * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
                * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
                * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
                * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
                * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
                * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
                */
                
                pragma solidity ^0.4.24;
                
                /**
                 * @title Ownable
                 * @dev The Ownable contract from https://github.com/zeppelinos/labs/blob/master/upgradeability_ownership/contracts/ownership/Ownable.sol 
                 * branch: master commit: 3887ab77b8adafba4a26ace002f3a684c1a3388b modified to:
                 * 1) Add emit prefix to OwnershipTransferred event (7/13/18)
                 * 2) Replace constructor with constructor syntax (7/13/18)
                 * 3) consolidate OwnableStorage into this contract
                 */
                contract Ownable {
                
                  // Owner of the contract
                  address private _owner;
                
                  /**
                  * @dev Event to show ownership has been transferred
                  * @param previousOwner representing the address of the previous owner
                  * @param newOwner representing the address of the new owner
                  */
                  event OwnershipTransferred(address previousOwner, address newOwner);
                
                  /**
                  * @dev The constructor sets the original owner of the contract to the sender account.
                  */
                  constructor() public {
                    setOwner(msg.sender);
                  }
                
                  /**
                 * @dev Tells the address of the owner
                 * @return the address of the owner
                 */
                  function owner() public view returns (address) {
                    return _owner;
                  }
                
                  /**
                   * @dev Sets a new owner address
                   */
                  function setOwner(address newOwner) internal {
                    _owner = newOwner;
                  }
                
                  /**
                  * @dev Throws if called by any account other than the owner.
                  */
                  modifier onlyOwner() {
                    require(msg.sender == owner());
                    _;
                  }
                
                  /**
                   * @dev Allows the current owner to transfer control of the contract to a newOwner.
                   * @param newOwner The address to transfer ownership to.
                   */
                  function transferOwnership(address newOwner) public onlyOwner {
                    require(newOwner != address(0));
                    emit OwnershipTransferred(owner(), newOwner);
                    setOwner(newOwner);
                  }
                }
                
                // File: contracts/Blacklistable.sol
                
                /**
                * Copyright CENTRE SECZ 2018
                *
                * Permission is hereby granted, free of charge, to any person obtaining a copy 
                * of this software and associated documentation files (the "Software"), to deal 
                * in the Software without restriction, including without limitation the rights 
                * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
                * copies of the Software, and to permit persons to whom the Software is furnished to 
                * do so, subject to the following conditions:
                *
                * The above copyright notice and this permission notice shall be included in all 
                * copies or substantial portions of the Software.
                *
                * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
                * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
                * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
                * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
                * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
                * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
                */
                
                pragma solidity ^0.4.24;
                
                
                /**
                 * @title Blacklistable Token
                 * @dev Allows accounts to be blacklisted by a "blacklister" role
                */
                contract Blacklistable is Ownable {
                
                    address public blacklister;
                    mapping(address => bool) internal blacklisted;
                
                    event Blacklisted(address indexed _account);
                    event UnBlacklisted(address indexed _account);
                    event BlacklisterChanged(address indexed newBlacklister);
                
                    /**
                     * @dev Throws if called by any account other than the blacklister
                    */
                    modifier onlyBlacklister() {
                        require(msg.sender == blacklister);
                        _;
                    }
                
                    /**
                     * @dev Throws if argument account is blacklisted
                     * @param _account The address to check
                    */
                    modifier notBlacklisted(address _account) {
                        require(blacklisted[_account] == false);
                        _;
                    }
                
                    /**
                     * @dev Checks if account is blacklisted
                     * @param _account The address to check    
                    */
                    function isBlacklisted(address _account) public view returns (bool) {
                        return blacklisted[_account];
                    }
                
                    /**
                     * @dev Adds account to blacklist
                     * @param _account The address to blacklist
                    */
                    function blacklist(address _account) public onlyBlacklister {
                        blacklisted[_account] = true;
                        emit Blacklisted(_account);
                    }
                
                    /**
                     * @dev Removes account from blacklist
                     * @param _account The address to remove from the blacklist
                    */
                    function unBlacklist(address _account) public onlyBlacklister {
                        blacklisted[_account] = false;
                        emit UnBlacklisted(_account);
                    }
                
                    function updateBlacklister(address _newBlacklister) public onlyOwner {
                        require(_newBlacklister != address(0));
                        blacklister = _newBlacklister;
                        emit BlacklisterChanged(blacklister);
                    }
                }
                
                // File: contracts/Pausable.sol
                
                /**
                * Copyright CENTRE SECZ 2018
                *
                * Permission is hereby granted, free of charge, to any person obtaining a copy 
                * of this software and associated documentation files (the "Software"), to deal 
                * in the Software without restriction, including without limitation the rights 
                * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
                * copies of the Software, and to permit persons to whom the Software is furnished to 
                * do so, subject to the following conditions:
                *
                * The above copyright notice and this permission notice shall be included in all 
                * copies or substantial portions of the Software.
                *
                * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
                * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
                * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
                * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
                * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
                * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
                */
                
                pragma solidity ^0.4.24;
                
                
                /**
                 * @title Pausable
                 * @dev Base contract which allows children to implement an emergency stop mechanism.
                 * Based on openzeppelin tag v1.10.0 commit: feb665136c0dae9912e08397c1a21c4af3651ef3
                 * Modifications:
                 * 1) Added pauser role, switched pause/unpause to be onlyPauser (6/14/2018)
                 * 2) Removed whenNotPause/whenPaused from pause/unpause (6/14/2018)
                 * 3) Removed whenPaused (6/14/2018)
                 * 4) Switches ownable library to use zeppelinos (7/12/18)
                 * 5) Remove constructor (7/13/18)
                 */
                contract Pausable is Ownable {
                  event Pause();
                  event Unpause();
                  event PauserChanged(address indexed newAddress);
                
                
                  address public pauser;
                  bool public paused = false;
                
                  /**
                   * @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);
                  }
                
                }
                
                // File: openzeppelin-solidity/contracts/math/SafeMath.sol
                
                /**
                 * @title SafeMath
                 * @dev Math operations with safety checks that throw on error
                 */
                library SafeMath {
                
                  /**
                  * @dev Multiplies two numbers, throws on overflow.
                  */
                  function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
                    // Gas optimization: this is cheaper than asserting '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;
                    }
                
                    c = a * b;
                    assert(c / a == b);
                    return c;
                  }
                
                  /**
                  * @dev Integer division of two numbers, truncating the quotient.
                  */
                  function div(uint256 a, uint256 b) internal pure returns (uint256) {
                    // assert(b > 0); // Solidity automatically throws when dividing by 0
                    // uint256 c = a / b;
                    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
                    return a / b;
                  }
                
                  /**
                  * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
                  */
                  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                    assert(b <= a);
                    return a - b;
                  }
                
                  /**
                  * @dev Adds two numbers, throws on overflow.
                  */
                  function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
                    c = a + b;
                    assert(c >= a);
                    return c;
                  }
                }
                
                // File: openzeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol
                
                /**
                 * @title ERC20Basic
                 * @dev Simpler version of ERC20 interface
                 * See https://github.com/ethereum/EIPs/issues/179
                 */
                contract ERC20Basic {
                  function totalSupply() public view returns (uint256);
                  function balanceOf(address who) public view returns (uint256);
                  function transfer(address to, uint256 value) public returns (bool);
                  event Transfer(address indexed from, address indexed to, uint256 value);
                }
                
                // File: openzeppelin-solidity/contracts/token/ERC20/ERC20.sol
                
                /**
                 * @title ERC20 interface
                 * @dev see https://github.com/ethereum/EIPs/issues/20
                 */
                contract ERC20 is ERC20Basic {
                  function allowance(address owner, address spender)
                    public view returns (uint256);
                
                  function transferFrom(address from, address to, uint256 value)
                    public returns (bool);
                
                  function approve(address spender, uint256 value) public returns (bool);
                  event Approval(
                    address indexed owner,
                    address indexed spender,
                    uint256 value
                  );
                }
                
                // File: contracts/FiatTokenV1.sol
                
                /**
                * Copyright CENTRE SECZ 2018
                *
                * Permission is hereby granted, free of charge, to any person obtaining a copy 
                * of this software and associated documentation files (the "Software"), to deal 
                * in the Software without restriction, including without limitation the rights 
                * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
                * copies of the Software, and to permit persons to whom the Software is furnished to 
                * do so, subject to the following conditions:
                *
                * The above copyright notice and this permission notice shall be included in all 
                * copies or substantial portions of the Software.
                *
                * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
                * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
                * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
                * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
                * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
                * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
                */
                
                pragma solidity ^0.4.24;
                
                
                
                
                
                
                /**
                 * @title FiatToken
                 * @dev ERC20 Token backed by fiat reserves
                 */
                contract FiatTokenV1 is Ownable, ERC20, Pausable, Blacklistable {
                    using SafeMath for uint256;
                
                    string public name;
                    string public symbol;
                    uint8 public decimals;
                    string public currency;
                    address public masterMinter;
                    bool internal initialized;
                
                    mapping(address => uint256) internal balances;
                    mapping(address => mapping(address => uint256)) internal allowed;
                    uint256 internal totalSupply_ = 0;
                    mapping(address => bool) internal minters;
                    mapping(address => uint256) internal minterAllowed;
                
                    event Mint(address indexed minter, address indexed to, uint256 amount);
                    event Burn(address indexed burner, uint256 amount);
                    event MinterConfigured(address indexed minter, uint256 minterAllowedAmount);
                    event MinterRemoved(address indexed oldMinter);
                    event MasterMinterChanged(address indexed newMasterMinter);
                
                    function initialize(
                        string _name,
                        string _symbol,
                        string _currency,
                        uint8 _decimals,
                        address _masterMinter,
                        address _pauser,
                        address _blacklister,
                        address _owner
                    ) public {
                        require(!initialized);
                        require(_masterMinter != address(0));
                        require(_pauser != address(0));
                        require(_blacklister != address(0));
                        require(_owner != address(0));
                
                        name = _name;
                        symbol = _symbol;
                        currency = _currency;
                        decimals = _decimals;
                        masterMinter = _masterMinter;
                        pauser = _pauser;
                        blacklister = _blacklister;
                        setOwner(_owner);
                        initialized = true;
                    }
                
                    /**
                     * @dev Throws if called by any account other than a minter
                    */
                    modifier onlyMinters() {
                        require(minters[msg.sender] == true);
                        _;
                    }
                
                    /**
                     * @dev Function to mint tokens
                     * @param _to The address that will receive the minted tokens.
                     * @param _amount The amount of tokens to mint. Must be less than or equal to the minterAllowance of the caller.
                     * @return A boolean that indicates if the operation was successful.
                    */
                    function mint(address _to, uint256 _amount) whenNotPaused onlyMinters notBlacklisted(msg.sender) notBlacklisted(_to) public returns (bool) {
                        require(_to != address(0));
                        require(_amount > 0);
                
                        uint256 mintingAllowedAmount = minterAllowed[msg.sender];
                        require(_amount <= mintingAllowedAmount);
                
                        totalSupply_ = totalSupply_.add(_amount);
                        balances[_to] = balances[_to].add(_amount);
                        minterAllowed[msg.sender] = mintingAllowedAmount.sub(_amount);
                        emit Mint(msg.sender, _to, _amount);
                        emit Transfer(0x0, _to, _amount);
                        return true;
                    }
                
                    /**
                     * @dev Throws if called by any account other than the masterMinter
                    */
                    modifier onlyMasterMinter() {
                        require(msg.sender == masterMinter);
                        _;
                    }
                
                    /**
                     * @dev Get minter allowance for an account
                     * @param minter The address of the minter
                    */
                    function minterAllowance(address minter) public view returns (uint256) {
                        return minterAllowed[minter];
                    }
                
                    /**
                     * @dev Checks if account is a minter
                     * @param account The address to check    
                    */
                    function isMinter(address account) public view returns (bool) {
                        return minters[account];
                    }
                
                    /**
                     * @dev Get allowed amount for an account
                     * @param owner address The account owner
                     * @param spender address The account spender
                    */
                    function allowance(address owner, address spender) public view returns (uint256) {
                        return allowed[owner][spender];
                    }
                
                    /**
                     * @dev Get totalSupply of token
                    */
                    function totalSupply() public view returns (uint256) {
                        return totalSupply_;
                    }
                
                    /**
                     * @dev Get token balance of an account
                     * @param account address The account
                    */
                    function balanceOf(address account) public view returns (uint256) {
                        return balances[account];
                    }
                
                    /**
                     * @dev Adds blacklisted check to approve
                     * @return True if the operation was successful.
                    */
                    function approve(address _spender, uint256 _value) whenNotPaused notBlacklisted(msg.sender) notBlacklisted(_spender) public returns (bool) {
                        allowed[msg.sender][_spender] = _value;
                        emit Approval(msg.sender, _spender, _value);
                        return true;
                    }
                
                    /**
                     * @dev Transfer tokens from one address to another.
                     * @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
                     * @return bool success
                    */
                    function transferFrom(address _from, address _to, uint256 _value) whenNotPaused notBlacklisted(_to) notBlacklisted(msg.sender) notBlacklisted(_from) public returns (bool) {
                        require(_to != address(0));
                        require(_value <= balances[_from]);
                        require(_value <= allowed[_from][msg.sender]);
                
                        balances[_from] = balances[_from].sub(_value);
                        balances[_to] = balances[_to].add(_value);
                        allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
                        emit Transfer(_from, _to, _value);
                        return true;
                    }
                
                    /**
                     * @dev transfer token for a specified address
                     * @param _to The address to transfer to.
                     * @param _value The amount to be transferred.
                     * @return bool success
                    */
                    function transfer(address _to, uint256 _value) whenNotPaused notBlacklisted(msg.sender) notBlacklisted(_to) public returns (bool) {
                        require(_to != address(0));
                        require(_value <= balances[msg.sender]);
                
                        balances[msg.sender] = balances[msg.sender].sub(_value);
                        balances[_to] = balances[_to].add(_value);
                        emit Transfer(msg.sender, _to, _value);
                        return true;
                    }
                
                    /**
                     * @dev Function to add/update a new minter
                     * @param minter The address of the minter
                     * @param minterAllowedAmount The minting amount allowed for the minter
                     * @return True if the operation was successful.
                    */
                    function configureMinter(address minter, uint256 minterAllowedAmount) whenNotPaused onlyMasterMinter public returns (bool) {
                        minters[minter] = true;
                        minterAllowed[minter] = minterAllowedAmount;
                        emit MinterConfigured(minter, minterAllowedAmount);
                        return true;
                    }
                
                    /**
                     * @dev Function to remove a minter
                     * @param minter The address of the minter to remove
                     * @return True if the operation was successful.
                    */
                    function removeMinter(address minter) onlyMasterMinter public returns (bool) {
                        minters[minter] = false;
                        minterAllowed[minter] = 0;
                        emit MinterRemoved(minter);
                        return true;
                    }
                
                    /**
                     * @dev allows a minter to burn some of its own tokens
                     * Validates that caller is a minter and that sender is not blacklisted
                     * amount is less than or equal to the minter's account balance
                     * @param _amount uint256 the amount of tokens to be burned
                    */
                    function burn(uint256 _amount) whenNotPaused onlyMinters notBlacklisted(msg.sender) public {
                        uint256 balance = balances[msg.sender];
                        require(_amount > 0);
                        require(balance >= _amount);
                
                        totalSupply_ = totalSupply_.sub(_amount);
                        balances[msg.sender] = balance.sub(_amount);
                        emit Burn(msg.sender, _amount);
                        emit Transfer(msg.sender, address(0), _amount);
                    }
                
                    function updateMasterMinter(address _newMasterMinter) onlyOwner public {
                        require(_newMasterMinter != address(0));
                        masterMinter = _newMasterMinter;
                        emit MasterMinterChanged(masterMinter);
                    }
                }