7

I'm building a staking function and hitting the following error after giving permission to access my token:

"MetaMask - RPC Error: Cannot set properties of undefined (setting 'loadingDefaults')"

Staking function Solidity contract:

    // Staking function
    function depositTokens(uint _amount) public {
        require(_amount > 0, 'Amount has to be > 0');
    // Transfer tether tokens to this contract
    tether.transferFrom(msg.sender, address(this), _amount);

    // Update Staking balance
    stakingBalance[msg.sender] = stakingBalance[msg.sender] + _amount;

    if(!hasStaked[msg.sender]) {
        stakers.push(msg.sender);
    }

    // Update Staking balance
    isStaking[msg.sender] = true;
    hasStaked[msg.sender] = true;
    
    }

Staking Frontend

stakeTokens = (amount) => {
this.setState({loading: true })
this.state.tether.methods.approve(this.state.deBank._address, amount).send({from: this.state.account}).on('transactionHash', (hash) => {
  this.state.deBank.methods.depositTokens(amount).send({from: this.state.account}).on('transactionHash', (hash) => {
    this.setState({loading:false})
  })
}) 

}

enter image description here

What is weird is that in 25-30% of the case, I get to the second approval step and the transaction goes through.

Anyone has an idea what's causing this?

Julien
  • 73
  • 6

7 Answers7

4

Reinstalling modules and recompiling didn't do anything, but it worked out after I changed the function to async await syntax:

stakeTokens = async (amount) => {
  this.setState({ loading: true });

  await this.state.tether.methods
    .approve(this.state.decentralBank._address, amount)
    .send({ from: this.state.account });

  await this.state.decentralBank.methods
    .depositTokens(amount)
    .send({ from: this.state.account });

  this.setState({ loading: false });

};

It should prompt Metamask twice now. 1st for Approve and 2nd for Deposit Tokens.

This error has an open issue on Metamask`s Github: https://github.com/MetaMask/metamask-extension/issues/13197

  • This should be the accepted answer. Worked a treat for me. Definitely a timing error hidden in the original code. whenever i debugged the orginal code - line by line never an error. The above code works every time for me. Thanks. – john blair Jan 14 '22 at 18:20
  • The async/await syntax does fix it... but it's actually waiting for the tx to be confirmed, which adds a lot of waiting. I believe it is equivalent to replacing `.on("transactionHash")` with `.on("receipt")`, but someone should confirm this. – samlaf Jan 18 '22 at 17:05
  • Thank you @Filinto, that solved the issue. – Julien Feb 01 '22 at 21:39
1

changed the function to async await syntax:

stakeTokens = async (amount) => {
await this.setState({ loading: true });
await this.state.tetherToken.methods.approve(this.state.tokenBank._address,amount).send({from : this.state.account });
  this.state.tokenBank.methods.stakeTokens(amount).send({from: this.state.account});
this.setState ({ loading: false });
AmodhGS
  • 11
  • 1
0

Having the same issue while working on the same course as you, maybe try using node 10 and redeploy everything.

Let me know if that works.

Nagasaki
  • 9
  • 3
  • Thank you @Nagasaki, I managed to fix this by uninstalling / reinstalling all the node.js dependencies in the project, deleting the .json contract abi files, and then redeploying the app -truffle compile and truffle migrate. – Julien Dec 21 '21 at 00:18
  • Didn't work for me - any other suggestions? – yesButNotReally Dec 22 '21 at 16:19
0

Try the following, it worked for me:

  1. Go to your Test account in Metamask, Settings > Advanced Settings and then click on "Reset account".
  2. Erase the cache of your browser.

Warning: Make sure you are under your Test account in Metamask.

Julien
  • 73
  • 6
0

i have try to node version 12.18.0 then working successfully

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 06 '22 at 13:03
0

removing .on('transactionHash', (hash) => { and using async await syntax works for me

Slope
  • 7
  • 3
  • Your answer could be improved by adding a code example to show the OP and future readers a working implementation. – Tyler2P Jan 09 '22 at 00:02
0

Changing the parameter value of 'on' function from 'transactionHash' to 'confirmation' fixed the issue. Had to change this while doing approve operation.

sellTokens = (tokenAmount) => { this.setState({ loading: true }) this.state.token.methods.approve(this.state.cryptoExchange.address, tokenAmount).send({ from: this.state.account }).on('confirmation', (confirmation ) => { this.state.cryptoExchange.methods.sellTokens(tokenAmount).send({ from: this.state.account }).on('transactionHash', (hash) => { this.setState({ loading: false }) }) }) }

subin
  • 71
  • 7