1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 01:47:00 +01:00

Refactor checking if address is contract into a new module. (#12354)

* Refactor checking if address is contract into a new module.
Tests for new module.

Signed-off-by: Akintayo A. Olusegun <akintayo.segun@gmail.com>

* addressIsContract is an async function, use await when calling it.

Signed-off-by: Akintayo A. Olusegun <akintayo.segun@gmail.com>

* Lint fixes

Signed-off-by: Akintayo A. Olusegun <akintayo.segun@gmail.com>

* Mock ethQuery
change variable names
refactor in transaction.utils.
fix possible boolean destructiring.

Signed-off-by: Akintayo A. Olusegun <akintayo.segun@gmail.com>

* Refactor isContractAddress boolean checks.

Signed-off-by: Akintayo A. Olusegun <akintayo.segun@gmail.com>

* Lint fixes

Signed-off-by: Akintayo A. Olusegun <akintayo.segun@gmail.com>
This commit is contained in:
Akintayo A. Olusegun 2021-10-20 16:12:07 +01:00 committed by GitHub
parent acf52f9be2
commit 03e3edb00c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 63 additions and 23 deletions

View File

@ -39,6 +39,7 @@ import {
CHAIN_ID_TO_GAS_LIMIT_BUFFER_MAP,
} from '../../../../shared/constants/network';
import { isEIP1559Transaction } from '../../../../shared/modules/transaction.utils';
import { readAddressAsContract } from '../../../../shared/modules/contract-utils';
import TransactionStateManager from './tx-state-manager';
import TxGasUtil from './tx-gas-utils';
import PendingTransactionTracker from './pending-tx-tracker';
@ -1234,23 +1235,21 @@ export default class TransactionController extends EventEmitter {
result = TRANSACTION_TYPES.DEPLOY_CONTRACT;
}
let code;
let contractCode;
if (!result) {
try {
code = await this.query.getCode(to);
} catch (e) {
code = null;
log.warn(e);
}
const {
contractCode: resultCode,
isContractAddress,
} = await readAddressAsContract(this.query, to);
const codeIsEmpty = !code || code === '0x' || code === '0x0';
result = codeIsEmpty
? TRANSACTION_TYPES.SIMPLE_SEND
: TRANSACTION_TYPES.CONTRACT_INTERACTION;
contractCode = resultCode;
result = isContractAddress
? TRANSACTION_TYPES.CONTRACT_INTERACTION
: TRANSACTION_TYPES.SIMPLE_SEND;
}
return { type: result, getCodeResponse: code };
return { type: result, getCodeResponse: contractCode };
}
/**

View File

@ -0,0 +1,12 @@
export const readAddressAsContract = async (ethQuery, address) => {
let contractCode;
try {
contractCode = await ethQuery.getCode(address);
} catch (e) {
contractCode = null;
}
const isContractAddress =
contractCode && contractCode !== '0x' && contractCode !== '0x0';
return { contractCode, isContractAddress };
};

View File

@ -0,0 +1,30 @@
const { readAddressAsContract } = require('./contract-utils');
describe('Contract Utils', () => {
it('checks is an address is a contract address or not', async () => {
let mockEthQuery = {
getCode: () => {
return '0xa';
},
};
const { isContractAddress } = await readAddressAsContract(
mockEthQuery,
'0x76B4aa9Fc4d351a0062c6af8d186DF959D564A84',
);
expect(isContractAddress).toStrictEqual(true);
mockEthQuery = {
getCode: () => {
return '0x';
},
};
const {
isContractAddress: isNotContractAddress,
} = await readAddressAsContract(
mockEthQuery,
'0x76B4aa9Fc4d351a0062c6af8d186DF959D564A84',
);
expect(isNotContractAddress).toStrictEqual(false);
});
});

View File

@ -88,6 +88,7 @@ import {
import { CHAIN_ID_TO_GAS_LIMIT_BUFFER_MAP } from '../../../shared/constants/network';
import { ETH, GWEI } from '../../helpers/constants/common';
import { TRANSACTION_ENVELOPE_TYPES } from '../../../shared/constants/transaction';
import { readAddressAsContract } from '../../../shared/modules/contract-utils';
// typedefs
/**
* @typedef {import('@reduxjs/toolkit').PayloadAction} PayloadAction
@ -230,13 +231,12 @@ async function estimateGasLimitForSend({
// address. If this returns 0x, 0x0 or a nullish value then the address
// is an externally owned account (NOT a contract account). For these
// types of transactions the gasLimit will always be 21,000 or 0x5208
const contractCode = Boolean(to) && (await global.eth.getCode(to));
// Geth will return '0x', and ganache-core v2.2.1 will return '0x0'
const contractCodeIsEmpty =
!contractCode || contractCode === '0x' || contractCode === '0x0';
if (contractCodeIsEmpty && !isNonStandardEthChain) {
const { isContractAddress } = to
? await readAddressAsContract(global.eth, to)
: {};
if (!isContractAddress && !isNonStandardEthChain) {
return GAS_LIMITS.SIMPLE;
} else if (contractCodeIsEmpty && isNonStandardEthChain) {
} else if (!isContractAddress && isNonStandardEthChain) {
isSimpleSendOnNonStandardNetwork = true;
}
}

View File

@ -11,6 +11,7 @@ import {
TRANSACTION_ENVELOPE_TYPES,
} from '../../../shared/constants/transaction';
import { addCurrencies } from '../../../shared/modules/conversion.utils';
import { readAddressAsContract } from '../../../shared/modules/contract-utils';
import fetchWithCache from './fetch-with-cache';
const hstInterface = new ethers.utils.Interface(abi);
@ -144,10 +145,8 @@ export function getLatestSubmittedTxWithNonce(
}
export async function isSmartContractAddress(address) {
const code = await global.eth.getCode(address);
// Geth will return '0x', and ganache-core v2.2.1 will return '0x0'
const codeIsEmpty = !code || code === '0x' || code === '0x0';
return !codeIsEmpty;
const { isContractCode } = readAddressAsContract(global.eth, address);
return isContractCode;
}
export function sumHexes(...args) {