Intro
I am making my first ever smart contract. So please cut me some slack. Basically, I am trying to make a staking contract in which I want the ability to deposit my USDC which should be done by using stakeTokens() function that I have defined in my contract.
I successfully deployed my contract on Avalanche Fuji testnet using truffle.
Objective
I was trying to send 2 USDC from my 0x69e3E27BBA76B8789dB1E0AA0B816bF93570EFdf wallet to my contract 0x0B4ae929F3181815bA8Bd9873ED31b4e75e21aFE using the stakeTokens(2, _from, _to) function defined in my contract. More info, I have 1.9 AVAX and 7 USDC both testnet in my wallet.
Error
Now when I tried to interact with the smart contract I had the following error:
error occured Error: Transaction has been reverted by the EVM:
{
"blockHash": "0xea3a62f9426fcdcbb6e183dc24576e92695c6996fe8573b38614ad86ed4d8938",
"blockNumber": 10313473,
"contractAddress": null,
"cumulativeGasUsed": 154456,
"effectiveGasPrice": 25000000000,
"from": "0x69e3e27bba76b8789db1e0aa0b816bf93570efdf",
"gasUsed": 86686,
"logs": [],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"status": false,
"to": "0x0b4ae929f3181815ba8bd9873ed31b4e75e21afe",
"transactionHash": "0xdd74634fd8496adafa4b9d733e004d13fb4a9ebb746a327b8586e43e4b00bbc6",
"transactionIndex": 2,
"type": "0x0"
}
Receipt:
blockHash: '0xea3a62f9426fcdcbb6e183dc24576e92695c6996fe8573b38614ad86ed4d8938',
blockNumber: 10313473,
contractAddress: null,
cumulativeGasUsed: 154456,
effectiveGasPrice: 25000000000,
from: '0x69e3e27bba76b8789db1e0aa0b816bf93570efdf',
gasUsed: 86686,
logs: [],
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
status: false,
to: '0x0b4ae929f3181815ba8bd9873ed31b4e75e21afe',
transactionHash: '0xdd74634fd8496adafa4b9d733e004d13fb4a9ebb746a327b8586e43e4b00bbc6',
transactionIndex: 2,
type: '0x0'
}
}
usdc_stake.sol
pragma solidity >=0.4.22 <0.9.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract USDC_STAKE {
IERC20 public usdcTokenContract;
address owner;
mapping(address => uint256) public stakingBalance;
/*
Kovan DAI: 0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa on ethereum
Rinkyby USDC: 0xb0Ad46bD50b44cBE47E2d83143E0E415d6A842F6 on arbitrum
Fuji USDC: 0x3E937B4881CBd500d05EeDAB7BA203f2b7B3f74f on avalanche
*/
constructor() {
usdcTokenContract = IERC20(0x3E937B4881CBd500d05EeDAB7BA203f2b7B3f74f);
owner = msg.sender;
}
function stakeTokens(uint256 _amount, address _from, address _to) public payable {
// amount should be > 0
require(_amount > 0, "amount should be > 0");
// usdcTokenContract.approve(_from, 10);
// usdcTokenContract.increaseAllowance(_to, 1000);
// transfer Dai to this contract for staking
usdcTokenContract.transferFrom(_from, _to, _amount);
// // update staking balance
// stakingBalance[msg.sender] = stakingBalance[msg.sender] + _amount;
}
// Unstaking Tokens (Withdraw)
function unstakeTokens() public {
uint256 balance = stakingBalance[msg.sender];
// balance should be > 0
// require(balance > 0, "staking balance cannot be 0");
require(
msg.sender == 0xB89F3c0C82679D6c8cF643e8ef9029f5eF782907,
"Address not match"
);
// Transfer Mock Dai tokens to this contract for staking
usdcTokenContract.transfer(msg.sender, balance);
// // reset staking balance to 0
// stakingBalance[msg.sender] = 0;
}
}
interact_file.js
const Web3 = require('web3')
const web3 = new Web3('https://api.avax-test.network/ext/bc/C/rpc')
const { ethers, BigNumber } = require("ethers");
const contract_addr = '0xEEd3A7F0F29d5ABEF73615D435A0c8d062a2B8e5'
var abi = require('../build/contracts/USDC_STAKE.json');
// USDC testnet contract is a Proxy contract so I've used the abi of the implementation contract of USDC contract and the address of the proxy contract. I hope that's how it is supposed to be done.
var erc20_abi = require('../build/contracts/USDC_Contract.json');
let wallet_private_key='My-Priv-Key'
let contract=new web3.eth.Contract(abi.abi, contract_addr)
const wallet_addr='0x69e3E27BBA76B8789dB1E0AA0B816bF93570EFdf'
let erc20_token=new web3.eth.Contract(erc20_abi, '0x3E937B4881CBd500d05EeDAB7BA203f2b7B3f74f')
const tx_dict={
nonce: web3.eth.getTransactionCount(wallet_addr),
gasPrice: web3.utils.toHex('35000000000'),
gasLimit: web3.utils.toHex('3000000'),
value: web3.utils.toHex(0),
chainId: 43113,
data: erc20_token.methods.approve(contract_addr,1000000000).encodeABI()
};
const sign_Tx=web3.eth.accounts.signTransaction(tx_dict,wallet_private_key)
sign_Tx.then((signedTx)=>{
const sentTx=web3.eth.sendSignedTransaction(signedTx.raw||signedTx.rawTransaction);
sentTx.on("receipt", receipt => {
console.log(receipt)
});
sentTx.on("error", err => {
console.log("error occured", err)
});
}).catch((err) => {
console.log("promise failed", err)
});
console.log("<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>")
const tx={
from: wallet_addr,
to: contract_addr,
nonce: web3.eth.getTransactionCount(wallet_addr),
// gas: ethers.utils.hexlify(25000),
gasPrice: web3.utils.toHex('110000000000'),
gasLimit: web3.utils.toHex('3000000'),
value: web3.utils.toHex(2),
data: contract.methods.stakeTokens(2000000,wallet_addr,contract_addr).encodeABI()
};
const signPromise=web3.eth.accounts.signTransaction(tx, wallet_private_key);
signPromise.then((signedTx)=>{
const sentTx = web3.eth.sendSignedTransaction(signedTx.raw||signedTx.rawTransaction);
sentTx.on("receipt", receipt => {
console.log(receipt)
});
sentTx.on("error", err => {
console.log("error occured", err)
});
}).catch((err) => {
console.log("promise failed", err)
});
ether_gist.js
const ethers = require('ethers');
const provider = new ethers.providers.JsonRpcProvider("https://api.avax-test.network/ext/bc/C/rpc");
const signer = new ethers.Wallet("My-Private-Key");
var contract_abi = require('../build/contracts/USDC_STAKE.json');
var erc20_abi = require('../build/contracts/USDC_coin.json');
const tokenContract = new ethers.Contract("0x3E937B4881CBd500d05EeDAB7BA203f2b7B3f74f", erc20_abi, signer);
const stakeContract = new ethers.Contract("0x7c64ca28A9e14030A19b51D95128d0F9F946EB19", contract_abi.abi, signer);
const approveAndStake = async() => {
const approveTx = await tokenContract.approve("0x7c64ca28A9e14030A19b51D95128d0F9F946EB19", 10000000);
await approveTx.wait();
const stakeTx = await stakeContract.stakeTokens(2, '0x4f5feA23DF8B2c4bbB5aDB8fEAe76142bE8927B7', '0x7c64ca28A9e14030A19b51D95128d0F9F946EB19');
await stakeTx.wait();
}
Error in ethers_gist.js
/home/mohit/aave-v3/aave-fork/node_modules/@ethersproject/logger/lib/index.js:233
var error = new Error(message);
^
Error: missing provider (operation="sendTransaction", code=UNSUPPORTED_OPERATION, version=abstract-signer/5.6.2)
at Logger.makeError (/home/mohit/aave-v3/aave-fork/node_modules/@ethersproject/logger/lib/index.js:233:21)
at Logger.throwError (/home/mohit/aave-v3/aave-fork/node_modules/@ethersproject/logger/lib/index.js:242:20)
at Wallet.Signer._checkProvider (/home/mohit/aave-v3/aave-fork/node_modules/@ethersproject/abstract-signer/lib/index.js:395:20)
at Wallet.<anonymous> (/home/mohit/aave-v3/aave-fork/node_modules/@ethersproject/abstract-signer/lib/index.js:144:30)
at step (/home/mohit/aave-v3/aave-fork/node_modules/@ethersproject/abstract-signer/lib/index.js:48:23)
at Object.next (/home/mohit/aave-v3/aave-fork/node_modules/@ethersproject/abstract-signer/lib/index.js:29:53)
at /home/mohit/aave-v3/aave-fork/node_modules/@ethersproject/abstract-signer/lib/index.js:23:71
at new Promise (<anonymous>)
at __awaiter (/home/mohit/aave-v3/aave-fork/node_modules/@ethersproject/abstract-signer/lib/index.js:19:12)
at Wallet.Signer.sendTransaction (/home/mohit/aave-v3/aave-fork/node_modules/@ethersproject/abstract-signer/lib/index.js:139:16) {
reason: 'missing provider',
code: 'UNSUPPORTED_OPERATION',
operation: 'sendTransaction'
}
Here is testnet block explorer transaction.
Help
Please share whatever mistake you can think of I might be making in this.