Proxy forwarding delegatecall

I have an ERC721 contract that is deployed via an UUPS proxy.

I have a proxy contract that forwards calls to the UUPS proxy via the _delegate method.

For all methods besides one, I am getting:

> await thinContractWithProviderNoProxy.symbol()
Uncaught:
Error: call revert exception [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (method="symbol()", data="0x", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.6.4)
    at step (/Users/pw/Documents/coding/contracts/node_modules/@ethersproject/contracts/lib/index.js:48:23)
    at Contract.<anonymous> (/Users/pw/Documents/coding/contracts/node_modules/@ethersproject/contracts/src.ts/index.ts:400:44)
    at Interface.decodeFunctionResult (/Users/pw/Documents/coding/contracts/node_modules/@ethersproject/abi/src.ts/interface.ts:427:23)
    at Logger.throwError (/Users/pw/Documents/coding/contracts/node_modules/@ethersproject/logger/src.ts/index.ts:273:20)
    at Logger.makeError (/Users/pw/Documents/coding/contracts/node_modules/@ethersproject/logger/src.ts/index.ts:261:28) {
  reason: null

The call that works is:

function setMintPrice(uint256 val) public payable {
    mintPrice = val;
}

from:

contract ERC721 is
    Initializable,
    ERC721Upgradeable,
    ERC721EnumerableUpgradeable,
    ERC721URIStorageUpgradeable,
    UUPSUpgradeable
{
    using CountersUpgradeable for CountersUpgradeable.Counter;

    uint256 mintPrice;
    CountersUpgradeable.Counter private _tokenIdCounter;

    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {}

    function initialize() public initializer {
        __ERC721_init("Pluto ERC721", "PLUTO");
        __ERC721Enumerable_init();
        __ERC721URIStorage_init();
        __UUPSUpgradeable_init();
    }

    function setMintPrice(uint256 val) public payable {
        mintPrice = val;
    }

    function safeMint(address to, string memory uri) public {
        uint256 tokenId = _tokenIdCounter.current();
        _tokenIdCounter.increment();
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal override(ERC721Upgradeable, ERC721EnumerableUpgradeable) {
        super._beforeTokenTransfer(from, to, tokenId);
    }

    // The following functions are overrides required by Solidity.

    function _burn(uint256 tokenId)
        internal
        override(ERC721Upgradeable, ERC721URIStorageUpgradeable)
    {
        super._burn(tokenId);
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721Upgradeable, ERC721URIStorageUpgradeable)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        override(ERC721Upgradeable, ERC721EnumerableUpgradeable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }

    function _authorizeUpgrade(address newImplementation) internal override {}
}

The error call revert exception means that:

1/ Method reverts during its execution.
2/ Method is not present in your contract.
3/ Contract not deployed on the network you're connected to (or address put is incorrect).
4/ Your network has some temporary outages.

3 and 4 aren't true since setMintPrice() call should work. 2 shouldn't be true either given .symbol() method does exist.

Why is my contract reverting in this case?

The proxy forwarding to the UUPS proxy looks like:

contract ThinContract is Proxy {
    constructor(address addr) {
        assert(
            _IMPLEMENTATION_SLOT ==
                bytes32(uint256(keccak256("eip1967.proxy.implementations")))
        );
        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = addr;
        Address.functionDelegateCall(
            addr,
            abi.encodeWithSignature("initialize()")
        );
    }

    bytes32 internal constant _IMPLEMENTATION_SLOT =
        0x4f87f1e9c3bae405811ebf6eb673f2ac9deccca180b85510b910593bd47872ca;

    /**
     * @dev Returns the current implementation address.
     */
    function implementation() public view returns (address) {
        return _implementation();
    }

    function _implementation() internal view override returns (address) {
        console.log("calling _implementation");
        return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
}

I'm not entirely sure why your contract is reverting, I think more info is needed. However, this is not how proxies are meant to be used. The proxy contracts that we offer should be used without modification. Ideally, through our Upgrades Plugins.