AAVE v3 - POLYGON - TEST <UnrecognizedContract>.<unknown> When running a script to deposit tokens to AAVE using a fork of the polygon mainnet - solidity

I'm testing v3 AAVE contracts on a fork of the polygon mainnet using harhat locally, but when I call de supply() function I get this error:
Error: Transaction reverted without a reason string
at <UnrecognizedContract>.<unknown> (0x794a61358d6845594f94dc1db02a252b5b4814ad)
at <UnrecognizedContract>.<unknown> (0x794a61358d6845594f94dc1db02a252b5b4814ad)
at <UnrecognizedContract>.<unknown> (0x794a61358d6845594f94dc1db02a252b5b4814ad)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at HardhatNode._mineBlockWithPendingTxs (/home/daniel/daniel/dev/chainlink/flowmi/node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:1802:23)
at HardhatNode.mineBlock (/home/daniel/daniel/dev/chainlink/flowmi/node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:491:16)
at EthModule._sendTransactionAndReturnHash (/home/daniel/daniel/dev/chainlink/flowmi/node_modules/hardhat/src/internal/hardhat-network/provider/modules/eth.ts:1522:18)
at HardhatNetworkProvider.request (/home/daniel/daniel/dev/chainlink/flowmi/node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:118:18)
at EthersProviderWrapper.send (/home/daniel/daniel/dev/chainlink/flowmi/node_modules/#nomiclabs/hardhat-ethers/src/internal/ethers-provider-wrapper.ts:13:20)
The script I'm trying to run:
const { getNamedAccounts, ethers } = require("hardhat");
async function main() {
const { deployer } = await getNamedAccounts();
// Mainnet pool adready given by the deployment
// Deposit
// Aprove to get Matic
const AMOUNT = ethers.utils.parseEther("0.11");
//const maticTokenAddress = "0x0000000000000000000000000000000000001010"; //mainnet
const Pool = await getPool(deployer);
const maticTokenAddress = "0xD65d229951E94a7138F47Bd9e0Faff42A7aCe0c6"; // testnet matic address
await approveErc20(maticTokenAddress, Pool.address, AMOUNT, deployer);
console.log("Depositing...");
console.log("Address provided: ", Pool.address);
await Pool.supply(maticTokenAddress, AMOUNT, deployer, 0);
console.log("Deposited!");
}
async function getPool(account) {
const PoolAddressesProvider = await ethers.getContractAt(
"IPoolAddressesProvider",
"0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb", // mainnet pool addresses provider
//"0x5343b5bA672Ae99d627A1C87866b8E53F47Db2E6", // testnet pool addresses provider
account
);
const PoolAddress = await PoolAddressesProvider.getPool();
const Pool = await ethers.getContractAt("IPool", PoolAddress, account);
return Pool;
}
async function approveErc20(
erc20Address,
spenderAddress,
amountToSpend,
account
) {
const erc20Token = await ethers.getContractAt(
"IERC20",
erc20Address,
account
);
const tx = await erc20Token.approve(spenderAddress, amountToSpend);
await tx.wait(1);
console.log("Approved!");
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
When I ask for which address was provided the answer is:
Address provided: 0x794a61358D6845594F94dc1DB02A252b5b4814aD
Which happens to be a polygon mainnet pool address according to documentation. Notice is the same address the error gives.
I'll be most thankful if someone points out my mistake
I've tried different combinations of "mainnet" and "testnet" addresses, for the maticToken, and the pool addresses provider

The problem was the matic address, It seems I misundertood documentation, thought the fact that matic is an ERC20 compliant implied it should not need to be wrapped to deposit.
But the script only works with the address of wrapped matic on mainnet.
Maybe is a problem of the mainnet fork, don't know but I moved on.

Related

Error: unknown account #0 (operation="getAddress", code=UNSUPPORTED_OPERATION, version=providers/5.7.1)

I want to test my function withdraw of my Vuejs app.
If my wallet Metamask is connected, then I can click on a button withdraw to get the money of my contract. The function works. Now I want to test it with Jest.
withdraw: async function(){
if(typeof window.ethereum !== 'undefined') {
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const contract = new ethers.Contract(this.contractAddress, NftContract.abi, signer);
try {
const transaction = await contract.withdraw();
await transaction.wait();
this.setSuccess('The withdrawal is successful');
}
catch(err) {
console.log(err);
this.setError('An error occured to withdraw');
}
}
}
I'm using eth-testing (https://www.npmjs.com/package/eth-testing?activeTab=readme) to mock the interaction with my smart contract. My test with Jest:
let wrapper;
const testingUtils = generateTestingUtils({ providerType: "MetaMask" });
beforeAll(() => {
// use this to check the state of anything in the view
wrapper = shallowMount(NFTMintComponent);
// Manually inject the mocked provider in the window as MetaMask does
global.window.ethereum = testingUtils.getProvider();
})
afterEach(() => {
// Clear all mocks between tests
testingUtils.clearAllMocks();
//jest.restoreAllMocks();
})
it('when the owner withdraw the amount of the contract, the balance of the contract should be 0 and a successful message should appear (withdraw function)', async () => {
// Start with not connected wallet
testingUtils.mockNotConnectedWallet();
// Mock the connection request of MetaMask
const account = testingUtils.mockRequestAccounts(["0xe14d2f7105f759a100eab6559282083e0d5760ff"]);
//allows to mock the chain ID / network to which the provider is connected --> 0x3 Ropsten network
testingUtils.mockChainId("0x3");
// Mock the network to Ethereum main net
testingUtils.mockBlockNumber("0x3");
const abi = NftContract.abi;
// An address may be optionally given as second argument, advised in case of multiple similar contracts
const contractTestingUtils = testingUtils.generateContractUtils(abi);
const transaction = await contractTestingUtils.mockTransaction("withdraw", '0x10Bc587867D87d1Ea1Cd62eac01b6DD027c182E9');
await wrapper.vm.withdraw();
});
I got the error: Error: unknown account #0 (operation="getAddress", code=UNSUPPORTED_OPERATION, version=providers/5.7.1) for my transaction contract.withdraw();
It's like the contract doesn't recognize my account even if I mocked my account at the beginning of the test with const account = testingUtils.mockRequestAccounts(["0xe14d2f7105f759a100eab6559282083e0d5760ff"]);
How can I fix that problem ?

Staging test: Listener not resolving - TimeOut Error ( ChainLink Solidity Course)

Raffle Staging Tests
fulfillRandomWords
Setting up test...
Setting up Listener...
Entering Raffle...
Ok, time to wait...
All Good here!!!
1) works with live Chainlink Keepers and Chainlink VRF, we get a random winner
0 passing (8m)
1 failing
Problem:
Code runs properly until listener tries to listen to raffle.once("WinnerPicked", async () => { }
It fails to resolve the try/catch block
It fails to call upkeep but calls vrf succesfully (transactions for 0.1 ETH registered)
Error:
Error: Timeout of 500000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
================================================================
Code Block:
describe("fulfillRandomWords", function () {
it("works with live Chainlink Keepers and Chainlink VRF, we get a random winner", async function () {
// enter the raffle
console.log("Setting up test...")
const startingTimeStamp = await raffle.getLatestTimeStamp()
const accounts = await ethers.getSigners()
console.log("Setting up Listener...")
await new Promise(async (resolve, reject) => {
// setup listener before we enter the raffle
// Just in case the blockchain moves REALLY fast
raffle.once("WinnerPicked", async () => {
console.log("WinnerPicked event fired!")
try {
// add our asserts here
const recentWinner = await raffle.getRecentWinner()
const raffleState = await raffle.getRaffleState()
const winnerEndingBalance = await accounts[0].getBalance()
const endingTimeStamp = await raffle.getLatestTimeStamp()
await expect(raffle.getPlayer(0)).to.be.reverted
assert.equal(recentWinner.toString(), accounts[0].address)
assert.equal(raffleState, 0)
assert.equal(
winnerEndingBalance.toString(),
winnerStartingBalance.add(raffleEntranceFee).toString()
)
assert(endingTimeStamp > startingTimeStamp)
resolve()
} catch (error) {
console.log(error)
reject(e)
}
})
// Then entering the raffle
console.log("Entering Raffle...")
const tx = await raffle.enterRaffle({ value: raffleEntranceFee })
await tx.wait(1)
console.log("Ok, time to wait...")
const winnerStartingBalance = await accounts[0].getBalance()
console.log("All Good here!!!")
// and this code WONT complete until our listener has finished listening!
})
})
})
})
================================================================
Solutions Attempted:
GitHub conversation: https://github.com/smartcontractkit/full-blockchain-solidity-course-js/discussions/729
| When removed alters the code and functionality & does not fix the problem in my case
(bool upkeepNeeded, ) = checkUpkeep("");
if (!upkeepNeeded) {
revert Raffle__UpkeepNotNeeded(
address(this).balance,
s_players.length,
uint256(s_raffleState)
);
}
GitHub conversation: https://github.com/smartcontractkit/full-blockchain-solidity-course-js/discussions/967
Google search + Forums
| 5 days spent researching a solution but still no success...
================================================================
Steps to reproduce:
GitHub Repo: https://github.com/DorianDaSilva/RaffleStagingDebug
================================================================
Repo:
Chainlink Solidity Course: https://github.com/PatrickAlphaC/hardhat-smartcontract-lottery-fcc
../test/staging/Raffle.staging.test.js
================================================================
I would appreciate if someone could help me figure out how to fix the problem block or code so it runs as originally intended.
Thank you!

How to calculate a smart contract deployment price on RSK?

Say I have an ERC20 smart contract which I'm developing and testing in Hardhat:
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/token/ERC20/ERC20.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
contract Erc20Token is ERC20, Ownable {
constructor(uint initialSupply) ERC20("ERC20 Token", "ETK") {
ERC20._mint(msg.sender, initialSupply);
}
}
I intend to deploy it to the RSK network with the following Hardhat deploy.js script:
async function deploy() {
try {
const initialSupply = 1e6;
const ERC20TokenFactory = await ethers.getContractFactory('Erc20Token');
const erc20Token = await ERC20TokenFactory.deploy(initialSupply);
await erc20Token.deployed();
console.log(
`ERC20 Token was deployed on ${hre.network.name} with an address: ${erc20Token.address} `,
);
process.exit(0);
} catch (error) {
console.error(error);
process.exit(1);
}
}
deploy();
To run this script and deploy my smart contract on RSK mainnet I need to run the following command in terminal:
npx hardhat run scripts/deploy.js --network rskmainnet
However, before deploying the smart contract on a real blockchain, I would really like to know how much this deployment will cost (in EUR)! How to calculate the price of my smart contract deployment transaction on the RSK mainnet, priced in fiat?
For reference, this is the hardhat.config.js file I'm using:
require('#nomiclabs/hardhat-waffle');
const { mnemonic } = require('./.secret.json');
module.exports = {
solidity: '0.8.4',
defaultNetwork: 'rsktestnet',
networks: {
rsktestnet: {
chainId: 31,
url: 'https://public-node.testnet.rsk.co/',
accounts: {
mnemonic,
path: "m/44'/60'/0'/0",
},
},
rskmainnet: {
chainId: 30,
url: 'https://public-node.rsk.co',
accounts: {
mnemonic,
path: "m/44'/60'/0'/0",
},
},
},
};
First you need to estimate the amount of gas which your deploy transaction is going to use. To accomplish this, use ethers.js signer.estimateGas() method.
const deployTx = ERC20TokenFactory.getDeployTransaction(initialSupply);
const estimatedGas = await ERC20TokenFactory.signer.estimateGas(deployTx);
Then you need to know the current gas price in your network:
const gasPrice = await ERC20TokenFactory.signer.getGasPrice();
To get the deployment RBTC price,
multiply gas amount by the gas price:
const deploymentPriceWei = gasPrice.mul(estimatedGas);
const deploymentPriceRBTC =
ethers.utils.formatEther(deploymentPriceWei);
Next you can use the Coingecko API to get current RBTC/EUR rate:
const rbtcEurRate = (
await axios.get('https://api.coingecko.com/api/v3/coins/rootstock')
).data.market_data.current_price.eur;
(Note that CoinGecko uses rootstock to denote the native currency of the RSK network, RBTC.)
And finally, to get the deployment price in EUR, multiply the deployment RBTC price by RBTC/EUR exchange rate:
const deploymentPriceEUR = (deploymentPriceRBTC * rbtcEurRate).toFixed(2);
We can make all of the above repeatable by creating a
hardhat script that combines the above.
To do this create scripts/estimateDeploymentPrice.js,
with the following:
const axios = require('axios').default;
async function estimateDeploymentPrice() {
try {
const initialSupply = 1e6;
const contractFactory = await ethers.getContractFactory('Erc20Token');
const deployTx = contractFactory.getDeployTransaction(initialSupply);
const estimatedGas = await contractFactory.signer.estimateGas(deployTx);
const gasPrice = await contractFactory.signer.getGasPrice();
const deploymentPriceWei = gasPrice.mul(estimatedGas);
const deploymentPriceRBTC = ethers.utils.formatEther(deploymentPriceWei);
const rbtcEurRate = (
await axios.get('https://api.coingecko.com/api/v3/coins/rootstock')
).data.market_data.current_price.eur;
const deploymentPriceEUR = (deploymentPriceRBTC * rbtcEurRate).toFixed(2);
console.log(
`ERC20 token deployment price on ${hre.network.name} is ${deploymentPriceEUR} EUR`,
);
process.exit(0);
} catch (error) {
console.error(error);
process.exit(1);
}
}
estimateDeploymentPrice();
Run the script with a command:
npx hardhat run scripts/estimateDeploymentPrice.js --network rskmainnet
(Note that the script needs to be run through hardhat
in order for hre to be injected.)
The script outputs:
ERC20 token deployment price on rskmainnet is 3.34 EUR

TronWeb to send trc20 usdt

I want to use TronWeb to send trc20 token. Whether I need to use contract().at() to do this? It means I need to treat trc20 token just as smart contract?
first things first, to clarify every token on any network (not just tron) has its own smart contract that has been published to the network
here is the code to get your account balance and another to transfer USDT
don't forget to init the code with your private key and network endpoints
note that you need tron energy and bandwidth to perform a transaction
you can read about them using this link
const CONTRACT = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"
async function getBalance(account) {
const {
abi
} = await tronWeb.trx.getContract(CONTRACT);
const contract = tronWeb.contract(abi.entrys, CONTRACT);
const balance = await contract.methods.balanceOf(account).call();
console.log("balance:", balance.toString());
}
async function transferUSDT(destination, amount) {
const {
abi
} = await tronWeb.trx.getContract(CONTRACT);
const contract = tronWeb.contract(abi.entrys, CONTRACT);
const resp = await contract.methods.transfer(destination, amount).send();
console.log("transfer:", resp);
}
When you init the tronweb compnent with private key ,you could use the contract().at()
tronWeb = new TronWeb(
'https://api.nileex.io/',
'https://api.nileex.io/',
'https://event.nileex.io/',
'your privateKey'
);

Truffle and Ganache-cli test case fails

So I have this setup : truffle and ganache-cli
I'm sending some ether to my contract, here is the related part of my contract:
mapping(address => uint256) public balanceOf;
function () payable public {
uint amount = msg.value;
balanceOf[msg.sender] += amount;
}
In truffle this is how I send the ether.
it("Test if can be payed", function(){
return web3.eth.sendTransaction({
from:fromAddr,
to:MyContract.address,
value:amountToSend
}).then(function(res){
expect(res).to.not.be.an("error"); // test passed
});
});
it("Test if contract received ether", function(){
return web3.eth.getBalance(MyContract.address,
function(err, res){
expect(parseInt(res)).to.be.at.least(1000000000000000000); // test passed
});
});
it("Catch if balanceOf "+fromAddr, function(){
return sale.balanceOf.call(fromAddr).then(function(res){
expect(parseInt(res)).to.be.at.least(1); // fails the test
});
});
Am I doing it right? What could be the reason for failed test?
truffle test output :
AssertionError: expected 0 to be at least 1
+ expected - actual
-0
+1
I can provide more info if needed.
UPDATE :
for clarification on sale which is global variable.
it("Test if MyContract is deployed", function(){
return MyContract.deployed().then(function(instance){
sale = instance;
});
});
I think this is what you are looking for:
File path:
test/vault.js
const Vault = artifacts.require("Vault");
contract("Vault test", async accounts => {
// Rely on one instance for all tests.
let vault;
let fromAccount = accounts[0];
let oneEtherInWei = web3.utils.toWei('1', 'ether');
// Runs before all tests.
// https://mochajs.org/#hooks
before(async () => {
vault = await Vault.deployed();
});
// The `receipt` will return boolean.
// https://web3js.readthedocs.io/en/1.0/web3-eth.html#gettransactionreceipt
it("Test if 1 ether can be paid", async () => {
let receipt = await web3.eth.sendTransaction({
from: fromAccount,
to: vault.address,
value: oneEtherInWei
});
expect(receipt.status).to.equal(true);
});
it("Test if contract received 1 ether", async () => {
let balance = await web3.eth.getBalance(vault.address);
expect(balance).to.equal(oneEtherInWei);
});
// In Web3JS v1.0, `fromWei` will return string.
// In order to use `at.least`, string needs to be parsed to integer.
it("Test if balanceOf fromAccount is at least 1 ether in the contract", async () => {
let balanceOf = await vault.balanceOf.call(fromAccount);
let balanceOfInt = parseInt(web3.utils.fromWei(balanceOf, 'ether'));
expect(balanceOfInt).to.be.at.least(1);
});
});
You can see the full project here. Do note that I'm using Truffle v5 and Ganache v2. See the README file inside that GitLab repository.
Back to your question, there were 2 mistakes:
The sale is not defined. I have a feeling that you were actually referring to MyContract.
In order to use the least method in ChaiJS, you need to make sure you are passing integers. The balanceOf call is returning BigNumber or BN object and you can't use it with .least method.
FYI, Truffle v5 is now using BN by default (previously BigNumber). More about it here.
Let me know if this helps.