metamask-mobile
metamask-mobile copied to clipboard
[Bug]: Unexpected characters in signature message
Describe the bug
When trying to deposit at https://bag.win, the site triggers a metatransaction, but the metamask signature is displaying concerning unfamiliar characters.
Expected behavior
It should show a regular metamask signature.
Screenshots/Recordings
Steps to reproduce
- Go to https://bag.win
- Connect Wallet
- Sign the message
- Go to Balance
- Try to deposit USDT
Error messages or log output
No response
Version
11.7.5
Build type
None
Device
Apple iPhone 13 Pro Max
Operating system
iOS
Additional context
Source Code:
function executeMetaTransactionWithSignature(
userAddress: string,
signature: string,
tokenContract: Contract,
functionSignature: string,
gasLimit?: number,
) {
return new Promise(async (resolve, reject) => {
logger.log('User address:', userAddress);
logger.log('Signature:', signature);
logger.log('Token contract:', tokenContract);
logger.log('Function signature:', functionSignature);
try {
if (!signature)
throw new Error("Signature failed.");
let { r, s, v } = getSignatureParameters(signature);
let tx = await tokenContract.executeMetaTransaction(
userAddress,
functionSignature,
r,
s,
v,
(gasLimit ? {gasLimit: gasLimit} : {})
);
logger.log('Transaction hash:', tx.hash);
await tx.wait(1);
logger.log('Transaction successfully confirmed');
resolve(tx.hash);
} catch (error: any) {
logger.log('Execute Meta-Transactions failed:', error);
reject(false);
}
});
}
const getSignatureParameters = (signature: string) => {
if (!ethers.utils.isHexString(signature)) {
throw new Error(
'Given value "'.concat(signature, '" is not a valid hex string.')
);
}
const r = signature.slice(0, 66);
const s = '0x'.concat(signature.slice(66, 130));
let vString = '0x'.concat(signature.slice(130, 132));
let v = ethers.BigNumber.from(vString).toNumber();
if (![27, 28].includes(v)) v += 27;
return {
r: r,
s: s,
v: v,
};
};
function executeMetaTransaction(i: number, functionSignature: any, contractInstance: any, userAddress: string, web3Default: Web3, domainData: any = null) {
return new Promise(async (resolve, reject) => {
let domainType = {};
if (domainData === null) {
domainData = arrayDomainData[i];
domainType = arrayDomainType[i];
} else {
domainType = domainTypeToken;
}
console.log('Execute Biconomy PoS meta-transaction: ' + i);
console.log('Function signature: ' + functionSignature);
console.log('User address: ' + userAddress);
console.log('Verify contract: ' + domainData.verifyingContract);
try {
// console.log('contract instance...');
// console.log(contractInstance);
console.log('nonce: ')
let nonce = await contractInstance.methods.getNonce(userAddress).call();
console.log('noncex: ', nonce)
let message: any = {};
message.nonce = parseInt(nonce);
message.from = userAddress;
message.functionSignature = functionSignature;
const dataToSign = JSON.stringify({
types: {
EIP712Domain: domainType,
MetaTransaction: metaTransactionType
},
domain: domainData,
primaryType: 'MetaTransaction',
message: message
});
console.log('Domain data: ', Object.keys(domainData));
console.log('Web3Provider Info: ', Object.keys(web3Default), web3Default.eth, web3Default.eth.currentProvider);
if(web3Default.eth.currentProvider) {
const provider: any = web3Default.eth.currentProvider;
console.log(provider);
const signedResponse = await provider.sendAsync(
{
jsonrpc: '2.0',
id: 999999999999,
method: 'eth_signTypedData_v4',
params: [userAddress, dataToSign],
fromAddress: userAddress
},
async (error: any, response: any) => {
executeMetaTx(response, dataToSign, functionSignature, contractInstance, userAddress, web3Default, resolve, reject);
}
);
console.log('Signed Response: ', signedResponse);
if (signedResponse) executeMetaTx(signedResponse, dataToSign, functionSignature, contractInstance, userAddress, web3Default, resolve, reject);
}
} catch (error) {
console.log('Execute Meta-Transactions failed: ', error);
reject(false);
}
});
}
async function executeMetaTx(signedResponse: any, dataToSign: string, functionSignature: any, contractInstance: any, userAddress: string, web3Default: Web3, resolve: any, reject: any) {
try {
let { r, s, v } = getSignatureParameters(signedResponse && signedResponse.hasOwnProperty('result') ? signedResponse.result : signedResponse);
const recovered = sigUtil.recoverTypedSignature_v4({
data: JSON.parse(dataToSign),
sig: signedResponse.hasOwnProperty('result') ? signedResponse.result : signedResponse
});
console.log('User signature: ' + signedResponse.hasOwnProperty('result') ? signedResponse.result : signedResponse);
console.log('Recovered address: ' + recovered);
console.log('r: ' + r);
console.log('s: ' + s);
console.log('v: ' + v);
const ret = await contractInstance.methods.executeMetaTransaction(userAddress, functionSignature, r, s, v).send({
from: userAddress
});
console.log('Execute Meta-Transactions done');
console.log(ret);
resolve(ret.transactionHash);
} catch (error) {
console.log('Execute Meta-Transactions failed: ', error);
reject(false);
}
}
Severity
No response