interface IUpgradeProxy {
    event OwnershipTransferred(address indexed from, address indexed to);
    event ProxyPaused();
    event ProxyUnpaused();
    event ProxyStartUpgrade(address indexed oldAddress, address indexed newAddress,
                            uint256 fromVersion, uint256 toVersion);
    event ProxyFinishUpgrade(address indexed oldAddress, address indexed newAddress,
                             uint256 fromVersion, uint256 toVersion);
    event ProxyCallMigration(address indexed oldAddress, address indexed newAddress,
                             uint256 fromVersion, uint256 toVersion);
    event ProxyForceVersionBump(address indexed oldAddress, address indexed newAddress,
                                uint256 fromVersion, uint256 toVersion);
    event ProxyCancelUpgrade(address indexed oldAddress, address indexed newAddress,
                             uint256 fromVersion, uint256 toVersion);

    function proxyTransferOwnership(address _newOwner) external;
    function proxyAcceptOwnership() external;
    function proxyPause() external;
    function proxyUnpause() external;
    function proxyStartUpgrade(address newLogicContract, uint256 newVersion) external;
    function proxyFinishUpgrade() external;
    function proxyCallMigration(bytes calldata data) external;

    // Undo proxyStartUpgrade without actually upgrading. Restores the old logic
    // contract. This is only safe to execute before doing a successful call to
    // proxyCallMigration, after which it is UNSAFE. This is meant as a recovery
    // mechanism in case a migration fails.
    function proxyCancelUpgrade() external;

    // Without this function it is possible to reach an unrecoverable state:
    // Call proxyStartUpgrade with a smart contract that does not have a
    // migration function that bumps it to the given version.
    //
    // This can be recovered by calling this function before calling
    // proxyFinishUpgrade, and then initiating a new upgrade before unpause.
    //
    // This is an emergency recovery mechanism that should never be used under
    // normal circumstances.
    function proxyForceVersionBump() external;

    function version() external view returns (uint256);
    function logicContract() external view returns (address);
    function upgradingFromVersion() external view returns (uint256);
    function upgradingToVersion() external view returns (uint256);
}
function proxyCancelUpgrade() external;

// Undo proxyStartUpgrade without actually upgrading. Restores the old logic
// contract. This is only safe to execute before doing a successful call to
// proxyCallMigration, after which it is UNSAFE. This is meant as a recovery
// mechanism in case a migration fails.