Contract ERC1967Upgrade has the following variable with its internal note:
* @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;
Would you say then that when using ERC1967Proxy alongside UUPSUpgradeable, one could remove the ERC1967Upgrade declaration on the inheritance of ERC1967Proxy and _implementation() since it's already being used on UUPSUpgradeable?
If ERC1967Proxy all that it does is call _upgradeToAndCall() from ERC1967Upgrade, wouldn't it be easier to skip this contract altogether, make Proxy non-abstract, inherit from ERC1967Upgrade, use a constructor on Proxy calling _upgradeToAndCall() and checking _IMPLEMENTATION_SLOT, implement _implementation(), and have Proxy is ERC1967Upgrade and UUPSUpgradeable is ERC1967Upgrade + the impl as the two main contracts?