2

We're implementing gasless transactions and we need eip3009 transfer With Authorisation call. We're interested in USDC.

I see some mismatches in USDC code on ethereum and polygon. To be accurate in domain separator. So, for ethereum I see this:

 function makeDomainSeparator(string memory name, string memory version)
        internal
        view
        returns (bytes32)
    {
        uint256 chainId;
        assembly {
            chainId := chainid()
        }
        return
            keccak256(
                abi.encode(
                    // keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
                    0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,
                    keccak256(bytes(name)),
                    keccak256(bytes(version)),
                    chainId,
                    address(this)
                )
            );
    }

And for polygon:

    function makeDomainSeparator(string memory name, string memory version)
        internal
        view
        returns (bytes32)
    {
        uint256 chainId;
        assembly {
            chainId := chainid()
        }

        return
            keccak256(
                abi.encode(
                    // keccak256("EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)")
                    0x36c25de3e541d5d970f66e4210d728721220fff5c077cc6cd008b3a0c62adab7,
                    keccak256(bytes(name)),
                    keccak256(bytes(version)),
                    address(this),
                    bytes32(chainId)
                )
            );
    }

I use this code to sign this transaction:

const data = {
  types: {
      TransferWithAuthorization: [
          { name: "from", type: "address" },
          { name: "to", type: "address" },
          { name: "value", type: "uint256" },
          { name: "validAfter", type: "uint256" },
          { name: "validBefore", type: "uint256" },
          { name: "nonce", type: "bytes32" },
      ],
  }
  domain: {
    name: 'MockEIP3009Token',
    version: '0.0.1',
    chainId: 31337,
    verifyingContract: '0x1429859428C0aBc9C2C47C8Ee9FBaf82cFA0F20f'
  },
  primaryType: 'TransferWithAuthorization',
  message: {
    from: '0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc',
    to: '0xfd471836031dc5108809d173a067e8486b9047a3',
    value: 434266,
    validAfter: 0,
    validBefore: 1672224083,
    nonce: '0x16140b6e6c12c7538910d7d08e52620f146518af84281a68576bb679b2c1100a'
  }
}
signer._signTypedData(data.domain, data.types, data.message);

For ethereum code everything works fine, but with polygon code I receive invalid signature error.

Can somebody explain why such difference is required?

Contracts:

Thank you!

2

2 Answers 2

1

Polygon USD Coin (PoS), USDC, or any of bridged Polygon tokens are not EIP-3009 compatible.

They have transferWithAuthorization function, but you need to use a different EIP-712 message for signing. See here for more details.

EIP-3009:

EIP712Domain: [
  { name: 'name', type: 'string' },
  { name: 'version', type: 'string' },
  { name: 'chainId', type: 'uint256' },
  { name: 'verifyingContract', type: 'address' }
]

Polygon:

EIP712Domain: [
  { name: 'name', type: 'string' },
  { name: 'version', type: 'string' },
  { name: 'verifyingContract', type: 'address' },
  { name: 'salt', type: 'bytes32' }
]
1

Where do you include the TRANSFER_AUTHORIZATION_TYPEHASH in the ethers side of things, like for creating the signature.

There's the struct, that contains the relevant data about the user interaction, but before you domain-hash the struct, it also includes the transfer with authorization typehash, right? I never see that as a value inserted into the struct on the ethers.js side of things.

An example is in here, the EIP3009.sol implementation: https://github.com/ethereum/EIPs/issues/3010#:~:text=Implementation-,EIP3009,-.sol

But within the "Use with web3 providers" example, I don't see the TRANSFER_AUTHORIZATION_TYPEHASH bytes32 included? https://github.com/ethereum/EIPs/issues/3010#:~:text=eth_signTypedData%7B_v4%7D%20method.-,Example,-%3A

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.