Deposit payment contract authorization fails in some wallets
Closed this issue · 1 comments
Issue
When attempting to make a deposit into a strategy, the contract call submit payment fails with the error below on some wallets. So far, this appears to occur on: Keystone hardware wallet, Uniswap mobile wallet, sometime on Rabby injected wallet.
Example error message
ContractFunctionExecutionError: The contract function "buySharesOnBehalfUsingTransferWithAuthorizationAndTermsOfService" reverted with the following reason:
GasAbstraction: invalid signature
Contract Call:
address: 0xb71F8d2cd7E6aC4d0C6810a293a1Ea0fCaE9d6a4
function: buySharesOnBehalfUsingTransferWithAuthorizationAndTermsOfService(address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, uint8 v, bytes32 r, bytes32 s, uint256 minSharesQuantity, bytes32 termsOfServiceHash, bytes termsOfServiceSignature)
args: (0x23de77c515aa58A0234B9b4f43dB4FCdB336708E, 0xb71F8d2cd7E6aC4d0C6810a293a1Ea0fCaE9d6a4, 100000, 0, 1712165533, 0x48752137490dd68e41d92e47967daf8e3903c52162ded89f9f2d27bad25f9ef1, 27, 0x099ef0bf8a6e29fe619635cd65e927cf463aa88cc43d1c398a055e7554553d0b, 0x1a8a3086fe35f8172fe7b657c62f84450f8f3d9382ec32656170c6e9703b9313, 1, 0x65cb3999902d514e798a845c52be591f102789e315d58e16940f82fa0df6727b, 0x8ae991159a342312181a187f080ea7b7c6e48783ff19ed979f42c782598736615065aa5cb4de51f793d0c499032e844684ee426c85a1dca4551b38bc35ecaa251c)
sender: 0x23de77c515aa58A0234B9b4f43dB4FCdB336708E
Docs: https://viem.sh/docs/contract/simulateContract
Version: viem@2.5.0
at nh (getContractError.js:26:12)
at A (simulateContract.js:73:15)
at async F (simulateContract.js:23:33)
at async p (+page.svelte:55:11)
This was fixed for Uniswap wallet with #714.
The issue had to do with the non-standard implementation of EIP-3009 on the Polygon bridged USDC token. That token requires a different EIP-712 domain that what is defined in the standard.
The issue for Uniswap wallet had to do with the domain properties that are included with the signature request:
frontend/src/lib/eth-defi/eip-3009.ts
Lines 26 to 41 in f1d00f7
The EIP-712 spec allows for any combination of the following fields to be included: name
, version
, chainId
, verifyingContract
, salt
:
https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator
The fields used by EIP-3009 (transfer with authorization) are the above fields minus salt:
https://eips.ethereum.org/EIPS/eip-3009#use-with-web3-providers
But Polygon bridged USDC doesn't follow the standard – it includes salt but excludes chainId. We have special-case code for this here:
frontend/src/lib/eth-defi/eip-3009.ts
Lines 6 to 22 in f1d00f7
However… we still passed along all of the fields in the domain
object. In theory, the wallet implementation of eth_signTypedData
should ignore any fields that aren't included in the specified EIP712Domain. But apparently some wallet's don't … so they reject a signature request where the domain fields don't match the specified EIP712Domain.
The fix in #714 was to only pass the domain
fields required by the EIP712Domain. This fixed the issue for Uniswap wallet. Unfortunately, the signature still fails in Keystone hardware wallet.