// Contract: OwnedUpgradabilityProxy
// Target function: function implementation() public view override returns (address impl)
// SPDX-License-Identifier: UNLICENSED
// This code is taken from https://github.com/OpenZeppelin/openzeppelin-labs
// with minor modifications.
pragma solidity ^0.7.0;


// This code is taken from https://github.com/OpenZeppelin/openzeppelin-labs
// with minor modifications.



// This code is taken from https://github.com/OpenZeppelin/openzeppelin-labs
// with minor modifications.


/**
 * @title Proxy
 * @dev Gives the possibility to delegate any call to a foreign implementation.
 */
abstract contract Proxy {
  /**
  * @dev Tells the address of the implementation where every call will be delegated.
  * @return impl address of the implementation to which it will be delegated
  */
  function implementation() public view virtual returns (address impl);

  receive() payable external {
    _fallback();
  }

  fallback() payable external {
    _fallback();
  }

  function _fallback() private {
    address _impl = implementation();
    require(_impl != address(0));

    assembly {
      let ptr := mload(0x40)
      calldatacopy(ptr, 0, calldatasize())
      let result := delegatecall(gas(), _impl, ptr, calldatasize(), 0, 0)
      let size := returndatasize()
      returndatacopy(ptr, 0, size)

      switch result
      case 0 { revert(ptr, size) }
      default { return(ptr, size) }
    }
  }
}


/**
 * @title UpgradeabilityProxy
 * @dev This contract represents a proxy where the implementation address to which it will delegate can be upgraded
 */
contract UpgradeabilityProxy is Proxy {
  /**
   * @dev This event will be emitted every time the implementation gets upgraded
   * @param implementation representing the address of the upgraded implementation
   */
  event Upgraded(address indexed implementation);

  // Storage position of the address of the current implementation
  bytes32 private constant implementationPosition = keccak256("org.zeppelinos.proxy.implementation");

  /**
   * @dev Constructor function
   */
  constructor() {}