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 "io.laborx.proxy.implementation", and is
    /// validated in the constructor.
    bytes32 internal constant IMPLEMENTATION_SLOT = 0x00dce392765b11486902ac3a76afbfed3e68464872bbbc647d8773854f05fedb;

    /// @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(LaborxAddressLib.isContract(newImplementation), "PROXY_CANNOT_SET_NON_CONTRACT");

        bytes32 slot = IMPLEMENTATION_SLOT;
        assembly {
            sstore(slot, newImplementation)
        }
    }
}
/// @title BaseUpgradeabilityProxy
/// @notice 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.
function _upgradeTo(address newImplementation) internal {
    _setImplementation(newImplementation);
    emit Upgraded(newImplementation);
}

/// @dev Upgrades the proxy to a new implementation.
/// @param newImplementation Address of the new implementation.