Why is ethers trying to convert a string prop to a BigNumber? It's giving me an overflow error in the UI

544 views Asked by At

My solidity contract returns an array of this:

    struct Project {
        uint256 projectId;
        string name;
        string projectType;
        string location;
        bool sdgZeroHunger;
        bool sdgWaterBenefit;
        bool sdgGenderEqImpacts;
        string registry;
        string registryProjectId;
        string url;
    }

Method to return the projects:

    function allProjects() public view returns (Project[] memory) {
        return projects;
    }

This was working perfectly fine until I added the url property on the end. Now when I try to read the url property from the returned contract call I get this error:

Uncaught (in promise) url: overflow (fault="overflow", operation="toNumber", value="5192296858534827628530496329220096", code=NUMERIC_FAULT, version=bignumber/5.5.0)
    at Logger.makeError (http://localhost:3000/static/js/bundle.js:9668:19)
    at Logger.throwError (http://localhost:3000/static/js/bundle.js:9678:16)
    at throwFault (http://localhost:3000/static/js/bundle.js:6749:17)
    at BigNumber.toNumber (http://localhost:3000/static/js/bundle.js:6559:7)
    at StringCoder.decode (http://localhost:3000/static/js/bundle.js:3223:48)
    at StringCoder.decode (http://localhost:3000/static/js/bundle.js:3428:87)
    at http://localhost:3000/static/js/bundle.js:2987:23
    at Array.forEach (<anonymous>)
    at unpack (http://localhost:3000/static/js/bundle.js:2979:10)
    at TupleCoder.decode (http://localhost:3000/static/js/bundle.js:3513:83)

Looking at the stack trace ethers is trying to convert the value into a BigNumber:

    toNumber(): number {
        try {
            return toBN(this).toNumber();
        } catch (error) {
            throwFault("overflow", "toNumber", this.toString());
        }
        return null;
    }

I'm using the outputted typechain definitions in the frontend so I can have a strongly typed experience when talking to the contract. I instaniate the contract like this:

        const projectRegistryFactory = new ProjectRegistry__factory()

        const projectRegistryContract: ProjectRegistry = new ethers.Contract(
            '0x5FbDB2315678afecb367f032d93F642f64180aa3',
            projectRegistryFactory.interface.fragments,
            provider
        ) as ProjectRegistry

Perhaps that's the issue?

1

There are 1 answers

0
Force Hero On

This was because url is a new field but MetaMask was caching the response from the hardhat node so it had old bytes that didn't include the url field but ehters was trying to decode the bytes anyway into the url field and it got very confused.