MinimalForwarder: signature does not match request

I've skimmed through other similar topics but couldn't figure out a solution.

I'm getting the error 'MinimalForwarder': signature does not match request. This happens when I send my transaction without verifying signature.

It's worth noting that when I use

// const signature = await signer._signTypedData(TypedData.domain, types, request);

ethers.utils.verifyTypedData returns correct address, however the valid check(verify) returns false.

On the contrary if I use

const signature = await signer.provider.send('eth_signTypedData_v4',
                    [address, JSON.stringify(toSign)]);

ethers.utils.verifyTypedData returns wrong address and valid returns true.

Can someone point to me where I'm messing up?

                const EIP712DomainType = [
                    { name: 'name', type: 'string' },
                    { name: 'version', type: 'string' },
                    { name: 'chainId', type: 'uint256' },
                    { name: 'verifyingContract', type: 'address' }
                ]

                const ForwardRequestType = [
                    { name: 'from', type: 'address' },
                    { name: 'to', type: 'address' },
                    { name: 'value', type: 'uint256' },
                    { name: 'gas', type: 'uint256' },
                    { name: 'nonce', type: 'uint256' },
                    { name: 'data', type: 'bytes' }
                ]

                const types = { ForwardRequestType };
                const provider= new ethers.providers.Web3Provider(window.ethereum)
                // Forwarder Contract
                const forwarderContract = new ethers.Contract(forwarder, Forwarder.ForwarderAbi, 
                 provider);
                // gets nonce and chainID
                const nonce = await forwarderContract.getNonce(address).then(nonce => nonce.toString());
                const chainId = await forwarderContract.provider.getNetwork().then(n => n.chainId);

                // Encode meta-tx request
                const boxesInterface = new ethers.utils.Interface(PayFactory.abi);
                const data = boxesInterface.encodeFunctionData('RedeemPayment', [code]);

                const request = {
                    from: address, // current user address
                    to: contractAddress, 
                    value: 0,
                    gas: 1e6,
                    nonce,
                    data
                };

                const TypedData = {
                    domain: {
                        name: 'MinimalForwarder',
                        version: '0.0.1',
                        chainId: chainId,
                        verifyingContract: forwarder,
                    },
                    primaryType: 'ForwardRequest',
                    types: {
                        EIP712Domain: EIP712DomainType,
                        ForwardRequest: ForwardRequestType
                    },
                    message: {
                        request
                    }
                };
                const toSign = { ...TypedData, message: request };

                const signature = await signer._signTypedData(TypedData.domain, types, request);

                const valid = await forwarderContract.verify(request, signature);

                console.log("valid:", valid)

                let recovered = await ethers.utils.verifyTypedData(TypedData.domain, types, request, signature);

                console.log("recoveredAddress:", recovered)
                if (recovered == address) {
                    console.log('verified TypedData ');
                //  Call server endpoint.            
  }
                else {
                    console.log("Wrong recovered Addy")
                }

UPDATE:

When I use:

const signature = await signer.provider.send('eth_signTypedData_v4',
                    [address, JSON.stringify(toSign)]);

The valid check(verify) method returns true and the recovered address incorrect. I tried sending the transaction and got this error instead:
Although one or more Error Occurred [**execution reverted** ] Contract Execution Completed.

Here is the tx on Mumbai.

Same error as here

Update:

Although one or more Error Occurred [ execution reverted ] Contract Execution Completed

This error means the forwarder executed the call, however the target contract function that I was calling was reverting because I had a revert statement which was triggered accidentally ;).

2 Likes

Hey @Ibrahim96,

Sorry for the late response, now I see you figured it out, but please let me know if you need any other support request around this.

Best!

1 Like

Just to add some insights to this thread, when you see this message:

Although one or more Error Occurred [ execution reverted ] Contract Execution Completed

It means that the signature verification at the Forwarder level succeeded and the smart contract that you are trying to call is being executed. I suggest to go directly to that smart contract and call the function directly (without a meta-tx) to see exactly what is the problem with that contract.

Once you sort that error out, then the meta-tx via the Forwarder should work with no issues.