Skip to main content
added 16 characters in body
Source Link

I had an ERC-20ERC-20 token staking project and was looking to migrate from using plain Ethers.js with MetaMask to WagmiWagmi and RainbowKitRainbowKit. As expected, I had to rewrite a large part of the JavaScript code on the page.

The problem occurs when I try to execute the staking step — I can't get it to work, even though the wallet prompts me to confirm the allowance and that confirmation window shows the correct data: the ERC-20 token address, the staking contract address, and the account that's supposed to approve the allowancethe ERC-20 token address, the staking contract address, and the account that's supposed to approve the allowance. I keep getting the error mentioned in the title. In the previous version, when I was using plain ethers.js, I had no issues, but now that I’m using Wagmi functions, I’m really struggling to make staking work.

I had an ERC-20 token staking project and was looking to migrate from using plain Ethers.js with MetaMask to Wagmi and RainbowKit. As expected, I had to rewrite a large part of the JavaScript code on the page.

The problem occurs when I try to execute the staking step — I can't get it to work, even though the wallet prompts me to confirm the allowance and that confirmation window shows the correct data: the ERC-20 token address, the staking contract address, and the account that's supposed to approve the allowance. I keep getting the error mentioned in the title. In the previous version, when I was using plain ethers.js, I had no issues, but now that I’m using Wagmi functions, I’m really struggling to make staking work.

I had an ERC-20 token staking project and was looking to migrate from using plain Ethers.js with MetaMask to Wagmi and RainbowKit. As expected, I had to rewrite a large part of the JavaScript code on the page.

The problem occurs when I try to execute the staking step — I can't get it to work, even though the wallet prompts me to confirm the allowance and that confirmation window shows the correct data: the ERC-20 token address, the staking contract address, and the account that's supposed to approve the allowance. I keep getting the error mentioned in the title. In the previous version, when I was using plain ethers.js, I had no issues, but now that I’m using Wagmi functions, I’m really struggling to make staking work.

Source Link

Error: reverted with reason string 'ERC20: insufficient allowance' with React, Wagmi and local HardHat node

I had an ERC-20 token staking project and was looking to migrate from using plain Ethers.js with MetaMask to Wagmi and RainbowKit. As expected, I had to rewrite a large part of the JavaScript code on the page.

The problem occurs when I try to execute the staking step — I can't get it to work, even though the wallet prompts me to confirm the allowance and that confirmation window shows the correct data: the ERC-20 token address, the staking contract address, and the account that's supposed to approve the allowance. I keep getting the error mentioned in the title. In the previous version, when I was using plain ethers.js, I had no issues, but now that I’m using Wagmi functions, I’m really struggling to make staking work.

I’m comparing the amount of tokens the user wanted to stake with the allowance that was ultimately approved, and the numbers match perfectly.

It doesn’t matter if I approve an absurdly high allowance, I still get the same error. I’m developing with Hardhat, running on a local node, and the test accounts have enough ETH and token balance to test anything.

I’m asking for help here because I don’t know what else to do. Thank you very much.

Form submit code (which calls de staking fuction):

const handleSubmit = async (e: FormEvent) => { e.preventDefault(); if (accountAddress && !tokenAmountErr && !stakeLengthErr) { try { setLoading(true) const tokenAmountParsed = parseUnits(tokenAmount, 18) // 1. Approve const approveTx = await writeContract(config, { abi: iEscrowTokenABI, address: import.meta.env.VITE_UNITYFINANCE_CONTRACT_ADDRESS, functionName: 'approve', args: [import.meta.env.VITE_STAKING_CONTRACT_ADDRESS, tokenAmountParsed], chainId, }) await waitForTransactionReceipt(config, { hash: approveTx, chainId }) console.log('approved: ' + approveTx) // 2. Check allowance const allowance = await readContract(config, { abi: iEscrowTokenABI, functionName: 'allowance', address: import.meta.env.VITE_UNITYFINANCE_CONTRACT_ADDRESS, args: [accountAddress, import.meta.env.VITE_STAKING_CONTRACT_ADDRESS], chainId }) // both match!!!!!!! console.log('Tokens parsed: ' + tokenAmountParsed, 'Allowance: ' + allowance) // 3. Stake const stakeTx = await writeContract(config, { abi: TokenStakingABI, address: import.meta.env.VITE_STAKING_CONTRACT_ADDRESS, functionName: 'stake', args: [parseUnits(tokenAmount, 18), parseInt(stakeLength)], chainId, }) await waitForTransactionReceipt(config, { hash: stakeTx, chainId }) console.log("Stake success!") setData({ status: 'success', message: 'Tokens staked!' }) } catch (err) { console.log("Stake error:", err) setData({ status: 'error', message: 'Error during staking' }) } finally { setLoading(false) } } 

}

TokenStaking contract stake function

function stake(uint256 _amount, uint _days) external nonReentrant { require(!_isStakingPaused, "TokenStaking: staking is paused"); require(_amount <= _maxStakeTokenLimit, "TokenStaking: max staking token limit reached"); require(_amount > 0, "TokenStaking: stake amount must be non-zero"); require(_amount >= _minimumStakingAmount, "TokenStaking: stake amount must be >= minimo"); uint256 currentTime = getCurrentTime(); uint256 endTime = currentTime + _days * 1 days; // *** CAMBIO: Transferimos & quemamos tokens iniciales (igual que antes) IERC20(_tokenAddress).transferFrom(msg.sender, address(this), _amount * 1e18); IERC20(_tokenAddress).transfer(address(0x000000000000000000000000000000000000dEaD), _amount * 1e18); // *** CAMBIO: Creamos un StakeInfo nuevo y lo pusheamos en el array de `_stakes[msg.sender]` StakeInfo memory newStake = StakeInfo({ amount: _amount, start: currentTime, end: endTime, daysStaked: _days, lastRewardCalculation: currentTime, rewardAmount: 0 }); _stakes[msg.sender].push(newStake); // *** CAMBIO: actualizamos contadores if (_stakes[msg.sender].length == 1) { _totalUsers += 1; } _totalStakedTokens += _amount; emit Stake(msg.sender, _amount); }