ERC20 transfer vulnerabilities

My project moved from its own eth node to Infura.
So I removed “web3.eth.personal.unlockAccount” method from source code.
I use signTransaction by refer to the tutorials(Use web3.js - Infura Docs)
but I wonder that I still can use “contract.methods.transfer(receiverAddress, wei)”
and what kind of security vulnerabilities do I keep in mind using Infura instead of my own node?

Here is the main source code of erc20 transfer
-. add pk
-. estimates gas price and gas limit
-. transfer ETH to senderAccount for gas
-. transfer erc token to main_addr for gathering tokens to main wallet.

exports.depositERCToken = async (privateKey) => {
	const senderAccount = web3.eth.accounts.wallet.add(privateKey)
	const mainAddr = web3.eth.accounts.wallet.add(main_addr_pk);
	const weiValue = await this.getERCBalance(senderAccount.address)

	if (weiValue.isZero()) {
		log('No funds in %o', senderAccount.address)
		return false
	}

	// get the estimation of gas
	const gasLimit = parseInt(await contracts.ercToken.methods.transfer(mainAddr.address, weiValue.toString()).estimateGas({
		from: senderAccount.address
	}))
	const gasPrice = parseInt(await web3.eth.getGasPrice() )

	const gas = gasLimit * gasPrice

	// Creating the transaction object
	const tx = {
		from: mainAddr.address,
		to: senderAccount.address,
		value: gas,
		gas: 21000,
		gasPrice: gasPrice
	};

	const signedTx = await web3.eth.accounts.signTransaction(tx, mainAddr.privateKey)

	web3.eth.sendSignedTransaction(signedTx.rawTransaction)	
		.then(receipt => {
			if (receipt.status) {
				log('Fill Gas for deposit Tx: ', receipt)
				return contracts.ercToken.methods.transfer(mainAddr.address, weiValue.toString())
					.send({
						from: senderAccount.address,
						to: contracts.ercToken.options.address,
						value: 0,
						gas: gasLimit,
						gasPrice: gasPrice
					})
			}

			log('Error: Send Ether Transaction was reverted')
		})
		.then(receipt => {
			log('Deposit Tx: ', receipt.transactionHash)
		})
		.catch(error => {
			log(error)
		})
		.finally(() => {
			web3.eth.accounts.wallet.remove(senderAccount.index)
			web3.eth.accounts.wallet.remove(mainAddr.index)
		})

	return true
}

Thanks in advance.

1 Like

Hi @dooba202,

welcome to the Infura community.

I can’t see any issues with your code. I guess web3 is a global that holds the provider?

const web3 = new Web3(
    new Web3.providers.HttpProvider(
        `https://${network}.infura.io/v3/${process.env.INFURA_API_KEY}`
    )

The main difference between a local node and a service like Infura is that Infura does not own any accounts for you to use. A local node can own a set of accounts, with their private keys, and can sign tx’s for you, etc. When using Infura you must sign your tx using a key you hold locally and then sent it as a raw tx.

Infura not holding your private keys means that you need manage them. The most common way to do this in backend code is to keep them in a .env file, being very careful not to commit it to github or otherwise leak it.

For browser base JavaScript, then using a wallet (like Metamask but the choice is up to the user) you are able to have it keep the users keys secure and will sign tx’s for you, i.e. act as the provider in this case.

So the only consideration I can think of when moving to Infura is to keep private keys secure and sign tx locally (web3js, working with a provider, does this well as you know) and send the signed tx to Infura.

I hope this makes things clear, thanks for the question.

Warm regards,
Chris | Infura | ConsenSys

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.