3

I create my wallet like this

const wallet = ethers.Wallet.createRandom()

I use metamask to send RIF tokens to the public address. I confirm the new balance of the account and it is accurate, the ERC20 transaction worked.

When I try to send some of the RIF token from that wallet, like this:

const connectedWallet = await wallet.connect(provider)
const contract = new ethers.Contract(
      process.env.CONTRACT_ADDRESS,
      rifContractAbi,
      onlineWallet,
    )

await contract.transfer(to, tokens)

I get the following error:

error: Error: processing response error (body="{\"jsonrpc\":\"2.0\",\"id\":246,\"error\":{\"code\":-32010,\"message\":\"the sender account doesn't exist\"}}\n", error={"code":-32010}, requestBody="{\"method\":\"eth_sendRawTransaction\",\"params\":[\"0xf8a8808403e252e08290999419f64674d8a5b4e652319f5e239efd3bc969a1fe80b844a9059cbb00000000000000000000000010d158b42bfbf39641896ad8b8fd9cf7078d2f4e0000000000000000000000000000000000000000000000000de0b483f7abe82062a0175a2b6e35c1ff301ff45341bf5a63a3895a63404c78b6644cd2f8dee5b9a030a010fbbd608476a555bccd9f3ccf67ceac46183f1be4a82b14a46bbb78ba312fc9\"],\"id\":246,\"jsonrpc\":\"2.0\"}", requestMethod="POST", url="https://public-node.testnet.rsk.co", code=SERVER_ERROR, version=web/5.7.0) 

As soon as I sent some RBTC to that account the transaction works.

bguiz
  • 27,371
  • 47
  • 154
  • 243
Hamady C.
  • 1,205
  • 11
  • 13
  • Hmm, I see 2 possible things to investigate: (1) you seem to have 3 separate wallets in play in your code snippets above... `wallet`, `connectedWallet`, and `onlineWallet`. Which one did you test the balances of? (2) To transact any ERC20 token (including RIF), you need to have the balance of the ERC20 token, and you also need to have have a RBTC of RBTC sufficient to pay for the gas of the smart contract function invocation. Try sending a small amount of RBTC to this address. On RSK Testnet you can use https://faucet.rsk.co/ – bguiz Sep 16 '22 at 04:57
  • Yes , if I send to RBTC to that account, I am able to send RIF out of it – Hamady C. Sep 17 '22 at 05:12
  • As promised, I've expanded this into a more thorough answer --> https://stackoverflow.com/a/73795017/194982 – bguiz Sep 21 '22 at 03:22

1 Answers1

3

Explanation

In order to successfully transfer ERC20 tokens, the EOA performing the transaction will need to satisfy 3 conditions:

  1. Sufficient token balance --> this is what you are transferring
  2. Sufficient RBTC balance --> to pay for gas fees
  3. Submit a valid transaction --> transfers are only effected upon being added to a block, and that block being added to the consensus chain

Reproduce the problem

// assuming that values for `CONTRACT_ADDRESS` and `CONTRACT_ABI` are set

const wallet = ethers.Wallet.createRandom();
const fungibleToken = new ethers.Contract(
      CONTRACT_ADDRESS,
      CONTRACT_ABI,
      wallet,
    );

If you do the above, and then immediately execute the following:

// assuming that values for `toAddress` and `transferAmount` are set

await fungibleToken.transfer(toAddress, transferAmount);

... you have yet to satisfy conditions (1) and (2) above. Therefore (3) will also be rejected as a result.


Solution

To check if you have satisfied condition (1):

const tokenCount = await fungibleToken.balanceOf(wallet.getAddress());
console.log('sufficient token balance:', tokenCount > transferAmount);

If this value is insufficient, and you're on RSK Testnet, can visit faucet.rifos.org to obtain some tRIF tokens.

To check if you have satisfied condition (2):

// assuming value of `ERC20_TRANSFER_GAS_ESTIMATE` is set

const rbtcBalance = await wallet.getBalance();
console.log('sufficient cryptocurrency balance:', rbtcBalance > ERC20_TRANSFER_GAS_ESTIMATE);

Set the value of ERC20_TRANSFER_GAS_ESTIMATE by using a gas estimation method, or even hard-coding its value to a safe overestimate (e.g. 1e6)

If this value is insufficient, and you're on RSK Testnet, can visit faucet.rsk.co to obtain some tRBTC cryptocurrency.

After satisfying the above, and you subsequently execute the following once more:

// assuming that values for `toAddress` and `transferAmount` are set

await fungibleToken.transfer(toAddress, transferAmount);

... the transfer should succeed.

bguiz
  • 27,371
  • 47
  • 154
  • 243