How to Read Chainlink AggregatorV3Interface in Hardhat Deployment - solidity

Total beginner here apologies in advance.
I'm learning Solidity and using Hardhat and trying to figure out how to return the value of the Chainlink price feed in this tutorial contract after deployment. I know how to return the function output in remix but having trouble figuring out how to use console.log or another method in Hardhat. I am able to use console.log for built in functions like token address but can't figure out how to apply to other functions. This is using the Goerli Testnet btw.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.0;
import "#chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract TestChainlink {
AggregatorV3Interface internal priceFeed;
constructor() {
// ETH / USD
priceFeed = AggregatorV3Interface(0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e);
}
function getLatestPrice() public view returns (int) {
(
uint80 roundID,
int price,
uint startedAt,
uint timeStamp,
uint80 answeredInRound
) = priceFeed.latestRoundData();
// for ETH / USD price is scaled up by 10 ** 8
return price;
}
}
I tried emulating console.log usage that work for built in functions like token address to apply them to the Chainlink getLatestPrice() function.
const Token = await ethers.getContractFactory("TestChainlink");
const token = await Token.deploy();
console.log("Token address:", token.address);
i.e.
I tried a ton of different combinations this was the last one I will spare all the error messages since it probably isn't a complex solve for a non novice.
console.log("ETH Price:", getLatestPrice());

try
let price = await token.getLatestPrice();
console.log(`Eth price is: ${price}`);

Related

Solidity, Wrapping Eth from a contract

I'm trying to wrap Eth from an smart contract as I want to swap weth later in uniswap but I don't know how to import the WETH code from goerli scan WETH = 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6;.
Following internet examples I accomplished wrapping Eth but all influencers just import a ERC20 library to create a new one. I don't understand why they are using this as they are not interacting with the right weth contract.
Here is the code I used but is just creating a new token. Can anyone give me some advice?
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
pragma abicoder v2;
import '#uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol';
import '#uniswap/v3-periphery/contracts/libraries/TransferHelper.sol';
import '#openzeppelin/contracts/token/ERC20/ERC20.sol';
contract SwapExamples is ERC20 {
// For the scope of these swap examples,
// we will detail the design considerations when using `exactInput`, `exactInputSingle`, `exactOutput`, and `exactOutputSingle`.
// It should be noted that for the sake of these examples we pass in the swap router as a constructor argument instead of inheriting it.
// More advanced example contracts will detail how to inherit the swap router safely.
// This example swaps DAI/WETH9 for single path swaps and DAI/USDC/WETH9 for multi path swaps.
ISwapRouter public immutable swapRouter;
address payable [] private s_Wallets;
uint256 public walletA = address(this).balance;
// Router = 0xE592427A0AEce92De3Edee1F18E0157C05861564
address public constant WETH = 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6; //0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
// For this example, we will set the pool fee to 0.3%.
uint24 public constant poolFee = 3000;
uint256 public UsdOut;
constructor(ISwapRouter _swapRouter) ERC20("Wrapped Ether", "WETH") {//ERC20("Wrapped Ether", "WETH")
swapRouter = _swapRouter;
}
function Deposit() public payable {
s_Wallets.push(payable(msg.sender));
}
function Mint() external payable {
_mint(address(this), address(this).balance);
}
}
You need not create a new ERC20 token.
Calling:
WETH.deposit.value(msg.value)();
helps you wrap your ETH and you don't need to import WETH code from anywhere.
After wrapping, you can then move on to swapping WETH for any other token on Uniswap like you said.

Execution is reverted in Solidity and Remix

I've wrote a simple code for fetching ETH price by using Chainlink interfaces as below:
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "#chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";
contract ABI {
AggregatorV3Interface internal priceFeed;
constructor() public {
priceFeed = AggregatorV3Interface(0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c);
}
function latestPrice() public view returns (int256) {
(, int256 answer,,,) = priceFeed.latestRoundData();
return answer;
}
}
The problem is when is being compiled by Remix, it has no problem but after execution it throws the error below:
call to ContractName.FunctionName errored: execution reverted
Do you think what the problem is?
Because your question didn't specify on which network you're running the script, I'm assuming that you're using the Remix VM emulator.
The specified Chainlink contract is available on Ethereum mainnet only. Any other network (including the emulator) does not have this contract deployed on this address.
To use the data feed contract in Remix, you can create a local fork of the mainnet, and then connect to the local network in the IDE.
Change ENVIRONMENT to Injected Web3 in Remix IDE and connect to metamask. For example, if you are using Kovan network use address as mentioned in the docs.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "#chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract PriceConsumerV3 {
AggregatorV3Interface internal priceFeed;
/**
* Network: Kovan
* Aggregator: ETH/USD
* Address: 0x9326BFA02ADD2366b30bacB125260Af641031331
*/
constructor() {
priceFeed = AggregatorV3Interface(0x9326BFA02ADD2366b30bacB125260Af641031331);
}
/**
* Returns the latest price
*/
function getLatestPrice() public view returns (int) {
(
/*uint80 roundID*/,
int price,
/*uint startedAt*/,
/*uint timeStamp*/,
/*uint80 answeredInRound*/
) = priceFeed.latestRoundData();
return price;
}
}

Chainlink- Issue when fetching an API in form of `bytes32`

I've been learning the chainlink API and trying to modify the example from the Chainlin's documentation to get a byets32 value from an API. The original code of the example works well, but since the API I was hitting is returning a byets32 foem, the Chainlink job need to be configured to handle this type of return. The node is given here with Kovan testnet. Here is my code
pragma solidity ^0.8.7;
import "#chainlink/contracts/src/v0.8/ChainlinkClient.sol";
/**
* Request testnet LINK and ETH here: https://faucets.chain.link/
* Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/
*/
/**
* THIS IS AN EXAMPLE CONTRACT WHICH USES HARDCODED VALUES FOR CLARITY.
* PLEASE DO NOT USE THIS CODE IN PRODUCTION.
*/
contract APIConsumer is ChainlinkClient {
using Chainlink for Chainlink.Request;
//Result of the api
bytes32 public martket;
address private oracle;
bytes32 private jobId;
uint256 private fee;
/**
* Get -> bytes32
* Network: Kovan
* Oracle: 0xc57B33452b4F7BB189bB5AfaE9cc4aBa1f7a4FD8 (Chainlink Devrel
* Node)
* Job ID: 7401f318127148a894c00c292e486ffd
* Fee: 0.1 LINK
*/
constructor() {
setPublicChainlinkToken();
// Get -> bytes32 node taken from documentation
oracle = 0xc57B33452b4F7BB189bB5AfaE9cc4aBa1f7a4FD8;
jobId = "7401f318127148a894c00c292e486ffd";
fee = 0.1 * 10 ** 18; // (Varies by network and job)
}
/**
* Create a Chainlink request to retrieve API response, find the target
* data, then multiply by 1000000000000000000 (to remove decimal places from data).
*/
function requestVolumeData() public returns (bytes32 requestId)
{
Chainlink.Request memory request = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);
// Set the URL to perform the GET request on
request.add("get", "https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD");
// Set the path to find the desired data in the API response, where the response format is:
// {"RAW":
// {"ETH":
// {"USD":
// {
// "MARKET": "CCCAGG",
// }
// }
// }
// }
//Get the MARKET field of API
request.add("path", "RAW,ETH,USD,MARKET"); // Chainlink nodes 1.0.0 and later support this format
// Sends the request
return sendChainlinkRequestTo(oracle, request, fee);
}
/**
* Receive the response in the form of bytes32
*/
function fulfill(bytes32 _requestId, bytes32 _market) public recordChainlinkFulfillment(_requestId)
{
martket = _market;
}
// function withdrawLink() external {} - Implement a withdraw function to avoid locking your LINK in the contract
}
The value of market should be a byets32 reprsenting "CCCAGG" as shown in the API. But what I got was just 0x0...00 all the time, which means market has not been modified yet. I've checked this various ways and found out that the fulfill function never get rans. Then same thing happens when I changed the jobId and oracle to handle get-> int256, get -> bool (of course I did change the return type of the variable such that it's consistent with the returning form of API). I also noticed that only the job get -> uint256 works well (the example from documentation also used this job). Does anyon know why? Was my code wrong or the problem came from the node/job? Since I was able the get the example right, I don't think the problem cam from my wallet.
Any help would be appreciated!
You can test with a GET>STRING JOB
Go to this link: https://docs.chain.link/docs/any-api-testnet-oracles/
Take the Oracle contract address relevant to your network. For instance: 0xCC79157eb46F5624204f47AB42b3906cAA40eaB7 for Goerli
Use a Get>String job: 7d80a6386ef543a3abb52817f6707e3b
Make sure that your callback function expects to receive a string. (see a full example here: https://docs.chain.link/docs/api-array-response/)

Token balance check is not working in Solidity smart contract

here is my code snippet and i have no idea why its not working
function Testdeposit(address _assetAddress) public returns (uint256 status)
{
//IERC20 erc20 = IERC20(_assetAddress);
//erc20.transferFrom(senderAddress, address(this), _amount));
//uint256 amount = erc20.allowance(senderAddress, address(this));
uint256 amount = IERC20(_assetAddress).balanceOf(address(this));
return amount;
}
i am using a standard IERC20 interface. just it dsnt have an event to emit. i assume it to return me 0 if there is no balance but its gvng me erro. Transcation not going through.
Any suggestions??
It is not working because you may have not overridden the IERC20 functions. At least as they should. I would highly recommend using the ERC20 standard instead, just for how easy it is to implement.

“Out of Gas” while transferring ethereum from account to contract

I am using ganache to create 10 ethereum accounts. I want to transfer ethereum from one account to a smart contract. I am doing this by writing two following smart contracts in solidity;
pragma solidity >=0.4.0 <0.6.0;
contract Ether_Transfer_To{
function () external payable { //fallback function
}
function get_balance() public returns(uint){
return address(this).balance;
}
}
contract Ether_Transfer_From{
Ether_Transfer_To private the_instance;
constructor() public{
//the_instance=Ether_Transfer_To(address(this));
the_instance=new Ether_Transfer_To();
}
function get_balance() public returns(uint){
return address(this).balance;
}
function get_balance_of_instance() public returns(uint){
//return address(the_instance).balance;
return the_instance.get_balance();
}
function () external payable {
// msg.sender.send(msg.value)
address(the_instance).send(msg.value);
}
}
When I deploy the contract Ether_Transfer_From smart contract then I get its three-member functions as follows in remix;
But when I sent one 1 Wei from account to smart contract by writing 1 in the text box and clicking on a (fallback) button, then I get the following error;
transact to Ether_Transfer_From. (fallback) errored: VM Exception while
processing transaction: out of gas
I followed the answer of the same question by installing Ganache-cli 7.0.0 beta.0 by using following command;
npm install -g ganache-cli#7.0.0-beta.0
But I still get the same error. I think I am using older Ganache cli instead of Ganache-cli 7.0.0 beta.0 as it goes to C drive and I installed ganache 2.1.1 in D drive previously.
I just want to send ethereum from one account to other but I am really stuck in this out of gas Error. If there is any way to remove this error or transfer ethereum from one account to another then please let me know.
So this is what I did for one of my projects.
This snippet, deploys the compiles the solidity file and then deploys it and gets the address of the deployed contract address
const input = fs.readFileSync('Migrations.sol');
const output = solc.compile(input.toString(), 1);
const bytecode = output.contracts[':Migrations']['bytecode'];
const abi = JSON.parse(output.contracts[':Migrations'].interface);
var contract = new web3.eth.Contract(abi);
contract.deploy({
data: '0x'+bytecode,
})
.send({
from: chairPerson,
gas: 5500000,
gasPrice: '2000000000000'
})
.on('receipt', (receipt) => {
add=receipt.contractAddress;
})
Now using contract's abi, I can call methods of the deployed contract and use the following code to transfer '1.5' ether from one address to another.
contract.methods.registerRequest(fromAddress,toAddress,requestNumber).send({from:fromAddress,value : web3.utils.toWei('1.5', 'ether')}).on('transactionHash', (hashResult) => {-- some code--})
And also make the method in the solidity as payable to allow it to transfer ether, like :
function registerRequest(address requestedBy,address requestedTo,uint requestNumber) payable public{}
Refer : https://web3js.readthedocs.io/en/v1.2.0/web3-eth-contract.html#id12
Basically I used web3 api itself to transfer ether from one account
to another by calling my solidity method.
Also, check the following things :
1. While deploying, are you deploying with enough gas ? I faced this error when I was deploying the contract with less gas quantity
2. Your method in solidity should be payable