ETH Price: $1,985.82 (-3.94%)

Transaction Decoder

Block:
10344510 at Jun-26-2020 11:59:38 PM +UTC
Transaction Fee:
0.012842688 ETH $25.50
Gas Used:
535,112 Gas / 24 Gwei

Emitted Events:

216 AdminUpgradeabilityProxy.0x00fffc2da0b561cae30d9826d37709e9421c4725faebc226cbbb7ef5fc5e7349( 0x00fffc2da0b561cae30d9826d37709e9421c4725faebc226cbbb7ef5fc5e7349, 0x000000000000000000000000abbbcbee1f6b5765e5fbaad660693ead272b168e )
217 AdminUpgradeabilityProxy.0xa428d9b5fb7a9d1de4c1d22e2d087d58c34869e9f4495cad9968027f251d5691( 0xa428d9b5fb7a9d1de4c1d22e2d087d58c34869e9f4495cad9968027f251d5691, 000000000000000000000000abbbcbee1f6b5765e5fbaad660693ead272b168e )
218 0xabbbcbee1f6b5765e5fbaad660693ead272b168e.0x8de0fe8dbe9baa18ba442c3a213a5b6129d2df318c76d08283cbeee2dfb93211( 0x8de0fe8dbe9baa18ba442c3a213a5b6129d2df318c76d08283cbeee2dfb93211, 0x0000000000000000000000001c647c67c1aad0ebff25500f3b3084d3d2872eba, 0000000000000000000000000000000000000000000000000000000000000001 )
219 0xabbbcbee1f6b5765e5fbaad660693ead272b168e.0xd04b9de96b5ba21173fd97c509db394c9e07a59ffb10c26da7f6ce38a8102fcb( 0xd04b9de96b5ba21173fd97c509db394c9e07a59ffb10c26da7f6ce38a8102fcb, 0x0000000000000000000000004e50adfc953551286bbd7fee2b2b846d1d227394, 0x0d8e6e2c00000000000000000000000000000000000000000000000000000000 )
220 0xabbbcbee1f6b5765e5fbaad660693ead272b168e.0x8de0fe8dbe9baa18ba442c3a213a5b6129d2df318c76d08283cbeee2dfb93211( 0x8de0fe8dbe9baa18ba442c3a213a5b6129d2df318c76d08283cbeee2dfb93211, 0x0000000000000000000000004e50adfc953551286bbd7fee2b2b846d1d227394, 0000000000000000000000000000000000000000000000000000000000000001 )
221 AdminUpgradeabilityProxy.0x9fcca3f73f85397e2bf03647abf243c20b753bd54463ff3cae74de2971c112fa( 0x9fcca3f73f85397e2bf03647abf243c20b753bd54463ff3cae74de2971c112fa, 000000000000000000000000abbbcbee1f6b5765e5fbaad660693ead272b168e )
222 0xabbbcbee1f6b5765e5fbaad660693ead272b168e.0x8de0fe8dbe9baa18ba442c3a213a5b6129d2df318c76d08283cbeee2dfb93211( 0x8de0fe8dbe9baa18ba442c3a213a5b6129d2df318c76d08283cbeee2dfb93211, 0x000000000000000000000000f490557d67d934440677a4f16793d5ef319b8ef5, 0000000000000000000000000000000000000000000000000000000000000001 )
223 AdminUpgradeabilityProxy.0x9fcca3f73f85397e2bf03647abf243c20b753bd54463ff3cae74de2971c112fa( 0x9fcca3f73f85397e2bf03647abf243c20b753bd54463ff3cae74de2971c112fa, 000000000000000000000000abbbcbee1f6b5765e5fbaad660693ead272b168e )
224 0xabbbcbee1f6b5765e5fbaad660693ead272b168e.0x8de0fe8dbe9baa18ba442c3a213a5b6129d2df318c76d08283cbeee2dfb93211( 0x8de0fe8dbe9baa18ba442c3a213a5b6129d2df318c76d08283cbeee2dfb93211, 0x000000000000000000000000b5723286a15754874bd3551e4f1ca3e2d7f3327c, 0000000000000000000000000000000000000000000000000000000000000001 )
225 AdminUpgradeabilityProxy.0x9fcca3f73f85397e2bf03647abf243c20b753bd54463ff3cae74de2971c112fa( 0x9fcca3f73f85397e2bf03647abf243c20b753bd54463ff3cae74de2971c112fa, 000000000000000000000000abbbcbee1f6b5765e5fbaad660693ead272b168e )
226 0xabbbcbee1f6b5765e5fbaad660693ead272b168e.0x8de0fe8dbe9baa18ba442c3a213a5b6129d2df318c76d08283cbeee2dfb93211( 0x8de0fe8dbe9baa18ba442c3a213a5b6129d2df318c76d08283cbeee2dfb93211, 0x000000000000000000000000c18810960b0609e59ff05737896dbc565a6e3ff2, 0000000000000000000000000000000000000000000000000000000000000001 )
227 AdminUpgradeabilityProxy.0x9fcca3f73f85397e2bf03647abf243c20b753bd54463ff3cae74de2971c112fa( 0x9fcca3f73f85397e2bf03647abf243c20b753bd54463ff3cae74de2971c112fa, 000000000000000000000000abbbcbee1f6b5765e5fbaad660693ead272b168e )
228 0xabbbcbee1f6b5765e5fbaad660693ead272b168e.0x8de0fe8dbe9baa18ba442c3a213a5b6129d2df318c76d08283cbeee2dfb93211( 0x8de0fe8dbe9baa18ba442c3a213a5b6129d2df318c76d08283cbeee2dfb93211, 0x000000000000000000000000e5b3441873e5beb504392e3c68edda1b6c1f2a9d, 0000000000000000000000000000000000000000000000000000000000000001 )
229 AdminUpgradeabilityProxy.0x9fcca3f73f85397e2bf03647abf243c20b753bd54463ff3cae74de2971c112fa( 0x9fcca3f73f85397e2bf03647abf243c20b753bd54463ff3cae74de2971c112fa, 000000000000000000000000abbbcbee1f6b5765e5fbaad660693ead272b168e )
230 0xabbbcbee1f6b5765e5fbaad660693ead272b168e.0x8de0fe8dbe9baa18ba442c3a213a5b6129d2df318c76d08283cbeee2dfb93211( 0x8de0fe8dbe9baa18ba442c3a213a5b6129d2df318c76d08283cbeee2dfb93211, 0x000000000000000000000000dbb37612dbd5d7a59b49d0affed487e2e728d18d, 0000000000000000000000000000000000000000000000000000000000000001 )
231 AdminUpgradeabilityProxy.0x5b03bfed1c14a02bdeceb5fa582eb1a5765fc0bc64ca0e6af4c20afc9487f081( 0x5b03bfed1c14a02bdeceb5fa582eb1a5765fc0bc64ca0e6af4c20afc9487f081, 0x000000000000000000000000abbbcbee1f6b5765e5fbaad660693ead272b168e, 0x000000000000000000000000ae971808cc420cc998339aec23d0c309c1155127 )

Account State Difference:

  Address   Before After State Difference Code
0x1c647c67...3D2872eBa
0x5822d3be...Cb78c207D
(Spark Pool)
84.819567373289000069 Eth84.832410061289000069 Eth0.012842688
0xaBbbCBEe...D272B168e
0 Eth
Nonce: 0
0 Eth
Nonce: 1
From: 0 To: 35800214812274454912345297936569589621355224239284390646605141798930939368431610235308855955678257571648176883259215270803818998859795682478350234027841577435838599734526345659473505331487529767486617877730854373254573754735708061641624424320768410084799812587408324970624204590898353465991588399239624835813954890945472518669663106340934522329416033547610798665015931102694797017235099488617985411687789498334479457044967624833629186266843289343142386836157198716531842955903271083091170851806591091734031844375904726692452231372931763405558289438543053403973477622714221985833
0xC28aB29d...2d4642886
0xFdCAb1B4...D879aA78a
0.6389319526 Eth
Nonce: 4248
0.6260892646 Eth
Nonce: 4249
0.012842688

Execution Trace

AdminUpgradeabilityProxy.64d9f9fd( )
  • 0x110cfb1ce63b0db60faf2d9902bead4bb23d0b01.64d9f9fd( )
    • 0xabbbcbee1f6b5765e5fbaad660693ead272b168e.60806040( )
    • 0xabbbcbee1f6b5765e5fbaad660693ead272b168e.4589fd16( )
      • 0x66a3d4a9e456224ac6527f5b049908c27c318f59.4589fd16( )
        • AdminUpgradeabilityProxy.19ab453c( )
          • 0x110cfb1ce63b0db60faf2d9902bead4bb23d0b01.19ab453c( )
          • AdminUpgradeabilityProxy.19ab453c( )
            • 0xa0654ac5deee814ef04354425c51a9ee27260dba.19ab453c( )
              • 0xabbbcbee1f6b5765e5fbaad660693ead272b168e.13da30b2( )
              • AdminUpgradeabilityProxy.19ab453c( )
                • 0xd56d4f9e19897b94d68938fe8ad1a5ff975f112f.19ab453c( )
                • AdminUpgradeabilityProxy.19ab453c( )
                  • 0xd969179c28c9661ac3e57479092870410899853b.19ab453c( )
                  • AdminUpgradeabilityProxy.19ab453c( )
                    • 0x91010d844ecae44f397da8fb41627428ed49ab43.19ab453c( )
                    • AdminUpgradeabilityProxy.19ab453c( )
                      • 0x011e4477c8336d9cafce7fc069747280f95ccefd.19ab453c( )
                      • AdminUpgradeabilityProxy.19ab453c( )
                        • 0x59aa2e2f5a4dc4d43c0d76b742cf30b350e5c02c.19ab453c( )
                        • 0x5822d3be26db5cd342b488412ef942ecb78c207d.c6845210( )
                          • 0xabbbcbee1f6b5765e5fbaad660693ead272b168e.b9181611( )
                            • 0x66a3d4a9e456224ac6527f5b049908c27c318f59.b9181611( )
                            • AdminUpgradeabilityProxy.55aa98c9( )
                              • 0x0e301ffdb44e84c043d58b782eb8d2f820c1acf4.55aa98c9( )
                                File 1 of 8: AdminUpgradeabilityProxy
                                // File: @openzeppelin/upgrades/contracts/upgradeability/Proxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                /**
                                 * @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/upgrades/contracts/utils/Address.sol
                                
                                pragma solidity ^0.5.0;
                                
                                /**
                                 * Utility library of inline functions on addresses
                                 *
                                 * Source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/v2.1.3/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 OpenZeppelinUpgradesAddress {
                                    /**
                                     * 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.
                                        // solhint-disable-next-line no-inline-assembly
                                        assembly { size := extcodesize(account) }
                                        return size > 0;
                                    }
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/BaseUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                
                                /**
                                 * @title BaseUpgradeabilityProxy
                                 * @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 BaseUpgradeabilityProxy 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 "eip1967.proxy.implementation" subtracted by 1, and is
                                   * validated in the constructor.
                                   */
                                  bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
                                
                                  /**
                                   * @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) internal {
                                    require(OpenZeppelinUpgradesAddress.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address");
                                
                                    bytes32 slot = IMPLEMENTATION_SLOT;
                                
                                    assembly {
                                      sstore(slot, newImplementation)
                                    }
                                  }
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/UpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title UpgradeabilityProxy
                                 * @dev Extends BaseUpgradeabilityProxy with a constructor for initializing
                                 * implementation and init data.
                                 */
                                contract UpgradeabilityProxy is BaseUpgradeabilityProxy {
                                  /**
                                   * @dev Contract constructor.
                                   * @param _logic 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 _logic, bytes memory _data) public payable {
                                    assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1));
                                    _setImplementation(_logic);
                                    if(_data.length > 0) {
                                      (bool success,) = _logic.delegatecall(_data);
                                      require(success);
                                    }
                                  }  
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/BaseAdminUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title BaseAdminUpgradeabilityProxy
                                 * @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 BaseAdminUpgradeabilityProxy is BaseUpgradeabilityProxy {
                                  /**
                                   * @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 "eip1967.proxy.admin" subtracted by 1, and is
                                   * validated in the constructor.
                                   */
                                
                                  bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
                                
                                  /**
                                   * @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();
                                    }
                                  }
                                
                                  /**
                                   * @return The address of the proxy admin.
                                   */
                                  function admin() external ifAdmin returns (address) {
                                    return _admin();
                                  }
                                
                                  /**
                                   * @return The address of the implementation.
                                   */
                                  function implementation() external 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 calldata data) payable external ifAdmin {
                                    _upgradeTo(newImplementation);
                                    (bool success,) = newImplementation.delegatecall(data);
                                    require(success);
                                  }
                                
                                  /**
                                   * @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: @openzeppelin/upgrades/contracts/upgradeability/AdminUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title AdminUpgradeabilityProxy
                                 * @dev Extends from BaseAdminUpgradeabilityProxy with a constructor for 
                                 * initializing the implementation, admin, and init data.
                                 */
                                contract AdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, UpgradeabilityProxy {
                                  /**
                                   * Contract constructor.
                                   * @param _logic 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 _logic, address _admin, bytes memory _data) UpgradeabilityProxy(_logic, _data) public payable {
                                    assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1));
                                    _setAdmin(_admin);
                                  }
                                }

                                File 2 of 8: AdminUpgradeabilityProxy
                                // File: @openzeppelin/upgrades/contracts/upgradeability/Proxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                /**
                                 * @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/upgrades/contracts/utils/Address.sol
                                
                                pragma solidity ^0.5.0;
                                
                                /**
                                 * Utility library of inline functions on addresses
                                 *
                                 * Source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/v2.1.3/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 OpenZeppelinUpgradesAddress {
                                    /**
                                     * 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.
                                        // solhint-disable-next-line no-inline-assembly
                                        assembly { size := extcodesize(account) }
                                        return size > 0;
                                    }
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/BaseUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                
                                /**
                                 * @title BaseUpgradeabilityProxy
                                 * @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 BaseUpgradeabilityProxy 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 "eip1967.proxy.implementation" subtracted by 1, and is
                                   * validated in the constructor.
                                   */
                                  bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
                                
                                  /**
                                   * @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) internal {
                                    require(OpenZeppelinUpgradesAddress.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address");
                                
                                    bytes32 slot = IMPLEMENTATION_SLOT;
                                
                                    assembly {
                                      sstore(slot, newImplementation)
                                    }
                                  }
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/UpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title UpgradeabilityProxy
                                 * @dev Extends BaseUpgradeabilityProxy with a constructor for initializing
                                 * implementation and init data.
                                 */
                                contract UpgradeabilityProxy is BaseUpgradeabilityProxy {
                                  /**
                                   * @dev Contract constructor.
                                   * @param _logic 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 _logic, bytes memory _data) public payable {
                                    assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1));
                                    _setImplementation(_logic);
                                    if(_data.length > 0) {
                                      (bool success,) = _logic.delegatecall(_data);
                                      require(success);
                                    }
                                  }  
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/BaseAdminUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title BaseAdminUpgradeabilityProxy
                                 * @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 BaseAdminUpgradeabilityProxy is BaseUpgradeabilityProxy {
                                  /**
                                   * @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 "eip1967.proxy.admin" subtracted by 1, and is
                                   * validated in the constructor.
                                   */
                                
                                  bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
                                
                                  /**
                                   * @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();
                                    }
                                  }
                                
                                  /**
                                   * @return The address of the proxy admin.
                                   */
                                  function admin() external ifAdmin returns (address) {
                                    return _admin();
                                  }
                                
                                  /**
                                   * @return The address of the implementation.
                                   */
                                  function implementation() external 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 calldata data) payable external ifAdmin {
                                    _upgradeTo(newImplementation);
                                    (bool success,) = newImplementation.delegatecall(data);
                                    require(success);
                                  }
                                
                                  /**
                                   * @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: @openzeppelin/upgrades/contracts/upgradeability/AdminUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title AdminUpgradeabilityProxy
                                 * @dev Extends from BaseAdminUpgradeabilityProxy with a constructor for 
                                 * initializing the implementation, admin, and init data.
                                 */
                                contract AdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, UpgradeabilityProxy {
                                  /**
                                   * Contract constructor.
                                   * @param _logic 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 _logic, address _admin, bytes memory _data) UpgradeabilityProxy(_logic, _data) public payable {
                                    assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1));
                                    _setAdmin(_admin);
                                  }
                                }

                                File 3 of 8: AdminUpgradeabilityProxy
                                // File: @openzeppelin/upgrades/contracts/upgradeability/Proxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                /**
                                 * @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/upgrades/contracts/utils/Address.sol
                                
                                pragma solidity ^0.5.0;
                                
                                /**
                                 * Utility library of inline functions on addresses
                                 *
                                 * Source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/v2.1.3/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 OpenZeppelinUpgradesAddress {
                                    /**
                                     * 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.
                                        // solhint-disable-next-line no-inline-assembly
                                        assembly { size := extcodesize(account) }
                                        return size > 0;
                                    }
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/BaseUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                
                                /**
                                 * @title BaseUpgradeabilityProxy
                                 * @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 BaseUpgradeabilityProxy 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 "eip1967.proxy.implementation" subtracted by 1, and is
                                   * validated in the constructor.
                                   */
                                  bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
                                
                                  /**
                                   * @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) internal {
                                    require(OpenZeppelinUpgradesAddress.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address");
                                
                                    bytes32 slot = IMPLEMENTATION_SLOT;
                                
                                    assembly {
                                      sstore(slot, newImplementation)
                                    }
                                  }
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/UpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title UpgradeabilityProxy
                                 * @dev Extends BaseUpgradeabilityProxy with a constructor for initializing
                                 * implementation and init data.
                                 */
                                contract UpgradeabilityProxy is BaseUpgradeabilityProxy {
                                  /**
                                   * @dev Contract constructor.
                                   * @param _logic 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 _logic, bytes memory _data) public payable {
                                    assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1));
                                    _setImplementation(_logic);
                                    if(_data.length > 0) {
                                      (bool success,) = _logic.delegatecall(_data);
                                      require(success);
                                    }
                                  }  
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/BaseAdminUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title BaseAdminUpgradeabilityProxy
                                 * @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 BaseAdminUpgradeabilityProxy is BaseUpgradeabilityProxy {
                                  /**
                                   * @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 "eip1967.proxy.admin" subtracted by 1, and is
                                   * validated in the constructor.
                                   */
                                
                                  bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
                                
                                  /**
                                   * @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();
                                    }
                                  }
                                
                                  /**
                                   * @return The address of the proxy admin.
                                   */
                                  function admin() external ifAdmin returns (address) {
                                    return _admin();
                                  }
                                
                                  /**
                                   * @return The address of the implementation.
                                   */
                                  function implementation() external 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 calldata data) payable external ifAdmin {
                                    _upgradeTo(newImplementation);
                                    (bool success,) = newImplementation.delegatecall(data);
                                    require(success);
                                  }
                                
                                  /**
                                   * @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: @openzeppelin/upgrades/contracts/upgradeability/AdminUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title AdminUpgradeabilityProxy
                                 * @dev Extends from BaseAdminUpgradeabilityProxy with a constructor for 
                                 * initializing the implementation, admin, and init data.
                                 */
                                contract AdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, UpgradeabilityProxy {
                                  /**
                                   * Contract constructor.
                                   * @param _logic 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 _logic, address _admin, bytes memory _data) UpgradeabilityProxy(_logic, _data) public payable {
                                    assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1));
                                    _setAdmin(_admin);
                                  }
                                }

                                File 4 of 8: AdminUpgradeabilityProxy
                                // File: @openzeppelin/upgrades/contracts/upgradeability/Proxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                /**
                                 * @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/upgrades/contracts/utils/Address.sol
                                
                                pragma solidity ^0.5.0;
                                
                                /**
                                 * Utility library of inline functions on addresses
                                 *
                                 * Source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/v2.1.3/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 OpenZeppelinUpgradesAddress {
                                    /**
                                     * 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.
                                        // solhint-disable-next-line no-inline-assembly
                                        assembly { size := extcodesize(account) }
                                        return size > 0;
                                    }
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/BaseUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                
                                /**
                                 * @title BaseUpgradeabilityProxy
                                 * @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 BaseUpgradeabilityProxy 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 "eip1967.proxy.implementation" subtracted by 1, and is
                                   * validated in the constructor.
                                   */
                                  bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
                                
                                  /**
                                   * @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) internal {
                                    require(OpenZeppelinUpgradesAddress.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address");
                                
                                    bytes32 slot = IMPLEMENTATION_SLOT;
                                
                                    assembly {
                                      sstore(slot, newImplementation)
                                    }
                                  }
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/UpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title UpgradeabilityProxy
                                 * @dev Extends BaseUpgradeabilityProxy with a constructor for initializing
                                 * implementation and init data.
                                 */
                                contract UpgradeabilityProxy is BaseUpgradeabilityProxy {
                                  /**
                                   * @dev Contract constructor.
                                   * @param _logic 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 _logic, bytes memory _data) public payable {
                                    assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1));
                                    _setImplementation(_logic);
                                    if(_data.length > 0) {
                                      (bool success,) = _logic.delegatecall(_data);
                                      require(success);
                                    }
                                  }  
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/BaseAdminUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title BaseAdminUpgradeabilityProxy
                                 * @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 BaseAdminUpgradeabilityProxy is BaseUpgradeabilityProxy {
                                  /**
                                   * @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 "eip1967.proxy.admin" subtracted by 1, and is
                                   * validated in the constructor.
                                   */
                                
                                  bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
                                
                                  /**
                                   * @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();
                                    }
                                  }
                                
                                  /**
                                   * @return The address of the proxy admin.
                                   */
                                  function admin() external ifAdmin returns (address) {
                                    return _admin();
                                  }
                                
                                  /**
                                   * @return The address of the implementation.
                                   */
                                  function implementation() external 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 calldata data) payable external ifAdmin {
                                    _upgradeTo(newImplementation);
                                    (bool success,) = newImplementation.delegatecall(data);
                                    require(success);
                                  }
                                
                                  /**
                                   * @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: @openzeppelin/upgrades/contracts/upgradeability/AdminUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title AdminUpgradeabilityProxy
                                 * @dev Extends from BaseAdminUpgradeabilityProxy with a constructor for 
                                 * initializing the implementation, admin, and init data.
                                 */
                                contract AdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, UpgradeabilityProxy {
                                  /**
                                   * Contract constructor.
                                   * @param _logic 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 _logic, address _admin, bytes memory _data) UpgradeabilityProxy(_logic, _data) public payable {
                                    assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1));
                                    _setAdmin(_admin);
                                  }
                                }

                                File 5 of 8: AdminUpgradeabilityProxy
                                // File: @openzeppelin/upgrades/contracts/upgradeability/Proxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                /**
                                 * @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/upgrades/contracts/utils/Address.sol
                                
                                pragma solidity ^0.5.0;
                                
                                /**
                                 * Utility library of inline functions on addresses
                                 *
                                 * Source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/v2.1.3/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 OpenZeppelinUpgradesAddress {
                                    /**
                                     * 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.
                                        // solhint-disable-next-line no-inline-assembly
                                        assembly { size := extcodesize(account) }
                                        return size > 0;
                                    }
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/BaseUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                
                                /**
                                 * @title BaseUpgradeabilityProxy
                                 * @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 BaseUpgradeabilityProxy 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 "eip1967.proxy.implementation" subtracted by 1, and is
                                   * validated in the constructor.
                                   */
                                  bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
                                
                                  /**
                                   * @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) internal {
                                    require(OpenZeppelinUpgradesAddress.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address");
                                
                                    bytes32 slot = IMPLEMENTATION_SLOT;
                                
                                    assembly {
                                      sstore(slot, newImplementation)
                                    }
                                  }
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/UpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title UpgradeabilityProxy
                                 * @dev Extends BaseUpgradeabilityProxy with a constructor for initializing
                                 * implementation and init data.
                                 */
                                contract UpgradeabilityProxy is BaseUpgradeabilityProxy {
                                  /**
                                   * @dev Contract constructor.
                                   * @param _logic 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 _logic, bytes memory _data) public payable {
                                    assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1));
                                    _setImplementation(_logic);
                                    if(_data.length > 0) {
                                      (bool success,) = _logic.delegatecall(_data);
                                      require(success);
                                    }
                                  }  
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/BaseAdminUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title BaseAdminUpgradeabilityProxy
                                 * @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 BaseAdminUpgradeabilityProxy is BaseUpgradeabilityProxy {
                                  /**
                                   * @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 "eip1967.proxy.admin" subtracted by 1, and is
                                   * validated in the constructor.
                                   */
                                
                                  bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
                                
                                  /**
                                   * @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();
                                    }
                                  }
                                
                                  /**
                                   * @return The address of the proxy admin.
                                   */
                                  function admin() external ifAdmin returns (address) {
                                    return _admin();
                                  }
                                
                                  /**
                                   * @return The address of the implementation.
                                   */
                                  function implementation() external 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 calldata data) payable external ifAdmin {
                                    _upgradeTo(newImplementation);
                                    (bool success,) = newImplementation.delegatecall(data);
                                    require(success);
                                  }
                                
                                  /**
                                   * @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: @openzeppelin/upgrades/contracts/upgradeability/AdminUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title AdminUpgradeabilityProxy
                                 * @dev Extends from BaseAdminUpgradeabilityProxy with a constructor for 
                                 * initializing the implementation, admin, and init data.
                                 */
                                contract AdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, UpgradeabilityProxy {
                                  /**
                                   * Contract constructor.
                                   * @param _logic 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 _logic, address _admin, bytes memory _data) UpgradeabilityProxy(_logic, _data) public payable {
                                    assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1));
                                    _setAdmin(_admin);
                                  }
                                }

                                File 6 of 8: AdminUpgradeabilityProxy
                                // File: @openzeppelin/upgrades/contracts/upgradeability/Proxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                /**
                                 * @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/upgrades/contracts/utils/Address.sol
                                
                                pragma solidity ^0.5.0;
                                
                                /**
                                 * Utility library of inline functions on addresses
                                 *
                                 * Source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/v2.1.3/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 OpenZeppelinUpgradesAddress {
                                    /**
                                     * 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.
                                        // solhint-disable-next-line no-inline-assembly
                                        assembly { size := extcodesize(account) }
                                        return size > 0;
                                    }
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/BaseUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                
                                /**
                                 * @title BaseUpgradeabilityProxy
                                 * @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 BaseUpgradeabilityProxy 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 "eip1967.proxy.implementation" subtracted by 1, and is
                                   * validated in the constructor.
                                   */
                                  bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
                                
                                  /**
                                   * @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) internal {
                                    require(OpenZeppelinUpgradesAddress.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address");
                                
                                    bytes32 slot = IMPLEMENTATION_SLOT;
                                
                                    assembly {
                                      sstore(slot, newImplementation)
                                    }
                                  }
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/UpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title UpgradeabilityProxy
                                 * @dev Extends BaseUpgradeabilityProxy with a constructor for initializing
                                 * implementation and init data.
                                 */
                                contract UpgradeabilityProxy is BaseUpgradeabilityProxy {
                                  /**
                                   * @dev Contract constructor.
                                   * @param _logic 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 _logic, bytes memory _data) public payable {
                                    assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1));
                                    _setImplementation(_logic);
                                    if(_data.length > 0) {
                                      (bool success,) = _logic.delegatecall(_data);
                                      require(success);
                                    }
                                  }  
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/BaseAdminUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title BaseAdminUpgradeabilityProxy
                                 * @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 BaseAdminUpgradeabilityProxy is BaseUpgradeabilityProxy {
                                  /**
                                   * @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 "eip1967.proxy.admin" subtracted by 1, and is
                                   * validated in the constructor.
                                   */
                                
                                  bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
                                
                                  /**
                                   * @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();
                                    }
                                  }
                                
                                  /**
                                   * @return The address of the proxy admin.
                                   */
                                  function admin() external ifAdmin returns (address) {
                                    return _admin();
                                  }
                                
                                  /**
                                   * @return The address of the implementation.
                                   */
                                  function implementation() external 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 calldata data) payable external ifAdmin {
                                    _upgradeTo(newImplementation);
                                    (bool success,) = newImplementation.delegatecall(data);
                                    require(success);
                                  }
                                
                                  /**
                                   * @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: @openzeppelin/upgrades/contracts/upgradeability/AdminUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title AdminUpgradeabilityProxy
                                 * @dev Extends from BaseAdminUpgradeabilityProxy with a constructor for 
                                 * initializing the implementation, admin, and init data.
                                 */
                                contract AdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, UpgradeabilityProxy {
                                  /**
                                   * Contract constructor.
                                   * @param _logic 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 _logic, address _admin, bytes memory _data) UpgradeabilityProxy(_logic, _data) public payable {
                                    assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1));
                                    _setAdmin(_admin);
                                  }
                                }

                                File 7 of 8: AdminUpgradeabilityProxy
                                // File: @openzeppelin/upgrades/contracts/upgradeability/Proxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                /**
                                 * @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/upgrades/contracts/utils/Address.sol
                                
                                pragma solidity ^0.5.0;
                                
                                /**
                                 * Utility library of inline functions on addresses
                                 *
                                 * Source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/v2.1.3/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 OpenZeppelinUpgradesAddress {
                                    /**
                                     * 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.
                                        // solhint-disable-next-line no-inline-assembly
                                        assembly { size := extcodesize(account) }
                                        return size > 0;
                                    }
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/BaseUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                
                                /**
                                 * @title BaseUpgradeabilityProxy
                                 * @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 BaseUpgradeabilityProxy 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 "eip1967.proxy.implementation" subtracted by 1, and is
                                   * validated in the constructor.
                                   */
                                  bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
                                
                                  /**
                                   * @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) internal {
                                    require(OpenZeppelinUpgradesAddress.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address");
                                
                                    bytes32 slot = IMPLEMENTATION_SLOT;
                                
                                    assembly {
                                      sstore(slot, newImplementation)
                                    }
                                  }
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/UpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title UpgradeabilityProxy
                                 * @dev Extends BaseUpgradeabilityProxy with a constructor for initializing
                                 * implementation and init data.
                                 */
                                contract UpgradeabilityProxy is BaseUpgradeabilityProxy {
                                  /**
                                   * @dev Contract constructor.
                                   * @param _logic 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 _logic, bytes memory _data) public payable {
                                    assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1));
                                    _setImplementation(_logic);
                                    if(_data.length > 0) {
                                      (bool success,) = _logic.delegatecall(_data);
                                      require(success);
                                    }
                                  }  
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/BaseAdminUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title BaseAdminUpgradeabilityProxy
                                 * @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 BaseAdminUpgradeabilityProxy is BaseUpgradeabilityProxy {
                                  /**
                                   * @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 "eip1967.proxy.admin" subtracted by 1, and is
                                   * validated in the constructor.
                                   */
                                
                                  bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
                                
                                  /**
                                   * @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();
                                    }
                                  }
                                
                                  /**
                                   * @return The address of the proxy admin.
                                   */
                                  function admin() external ifAdmin returns (address) {
                                    return _admin();
                                  }
                                
                                  /**
                                   * @return The address of the implementation.
                                   */
                                  function implementation() external 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 calldata data) payable external ifAdmin {
                                    _upgradeTo(newImplementation);
                                    (bool success,) = newImplementation.delegatecall(data);
                                    require(success);
                                  }
                                
                                  /**
                                   * @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: @openzeppelin/upgrades/contracts/upgradeability/AdminUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title AdminUpgradeabilityProxy
                                 * @dev Extends from BaseAdminUpgradeabilityProxy with a constructor for 
                                 * initializing the implementation, admin, and init data.
                                 */
                                contract AdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, UpgradeabilityProxy {
                                  /**
                                   * Contract constructor.
                                   * @param _logic 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 _logic, address _admin, bytes memory _data) UpgradeabilityProxy(_logic, _data) public payable {
                                    assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1));
                                    _setAdmin(_admin);
                                  }
                                }

                                File 8 of 8: AdminUpgradeabilityProxy
                                // File: @openzeppelin/upgrades/contracts/upgradeability/Proxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                /**
                                 * @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/upgrades/contracts/utils/Address.sol
                                
                                pragma solidity ^0.5.0;
                                
                                /**
                                 * Utility library of inline functions on addresses
                                 *
                                 * Source https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-solidity/v2.1.3/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 OpenZeppelinUpgradesAddress {
                                    /**
                                     * 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.
                                        // solhint-disable-next-line no-inline-assembly
                                        assembly { size := extcodesize(account) }
                                        return size > 0;
                                    }
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/BaseUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                
                                /**
                                 * @title BaseUpgradeabilityProxy
                                 * @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 BaseUpgradeabilityProxy 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 "eip1967.proxy.implementation" subtracted by 1, and is
                                   * validated in the constructor.
                                   */
                                  bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
                                
                                  /**
                                   * @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) internal {
                                    require(OpenZeppelinUpgradesAddress.isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address");
                                
                                    bytes32 slot = IMPLEMENTATION_SLOT;
                                
                                    assembly {
                                      sstore(slot, newImplementation)
                                    }
                                  }
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/UpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title UpgradeabilityProxy
                                 * @dev Extends BaseUpgradeabilityProxy with a constructor for initializing
                                 * implementation and init data.
                                 */
                                contract UpgradeabilityProxy is BaseUpgradeabilityProxy {
                                  /**
                                   * @dev Contract constructor.
                                   * @param _logic 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 _logic, bytes memory _data) public payable {
                                    assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1));
                                    _setImplementation(_logic);
                                    if(_data.length > 0) {
                                      (bool success,) = _logic.delegatecall(_data);
                                      require(success);
                                    }
                                  }  
                                }
                                
                                // File: @openzeppelin/upgrades/contracts/upgradeability/BaseAdminUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title BaseAdminUpgradeabilityProxy
                                 * @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 BaseAdminUpgradeabilityProxy is BaseUpgradeabilityProxy {
                                  /**
                                   * @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 "eip1967.proxy.admin" subtracted by 1, and is
                                   * validated in the constructor.
                                   */
                                
                                  bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
                                
                                  /**
                                   * @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();
                                    }
                                  }
                                
                                  /**
                                   * @return The address of the proxy admin.
                                   */
                                  function admin() external ifAdmin returns (address) {
                                    return _admin();
                                  }
                                
                                  /**
                                   * @return The address of the implementation.
                                   */
                                  function implementation() external 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 calldata data) payable external ifAdmin {
                                    _upgradeTo(newImplementation);
                                    (bool success,) = newImplementation.delegatecall(data);
                                    require(success);
                                  }
                                
                                  /**
                                   * @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: @openzeppelin/upgrades/contracts/upgradeability/AdminUpgradeabilityProxy.sol
                                
                                pragma solidity ^0.5.0;
                                
                                
                                /**
                                 * @title AdminUpgradeabilityProxy
                                 * @dev Extends from BaseAdminUpgradeabilityProxy with a constructor for 
                                 * initializing the implementation, admin, and init data.
                                 */
                                contract AdminUpgradeabilityProxy is BaseAdminUpgradeabilityProxy, UpgradeabilityProxy {
                                  /**
                                   * Contract constructor.
                                   * @param _logic 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 _logic, address _admin, bytes memory _data) UpgradeabilityProxy(_logic, _data) public payable {
                                    assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1));
                                    _setAdmin(_admin);
                                  }
                                }