Done auto select price feed based on network & verify on testnet
This commit is contained in:
parent
39c2dd760b
commit
ee8912613c
@ -17,6 +17,9 @@ This project mainly to keep as a reference for future Web 3.0 Developments.
|
||||
|
||||
0xc2022b56eBC140B5FebCf9FBaB14c17db4C315C4
|
||||
https://sepolia.etherscan.io/address/0xc2022b56eBC140B5FebCf9FBaB14c17db4C315C4#code
|
||||
Via deploy.js
|
||||
https://sepolia.etherscan.io/address/0x3a827C119e1D746bb3C7bcbbf95c55246C8CcBdd#code
|
||||
Via yarn hardhat deploy --network sepolia
|
||||
|
||||
### Public Reported Hacked Code References:
|
||||
|
||||
|
@ -6,6 +6,7 @@ const {
|
||||
DECIMALS,
|
||||
INITIAL_ANSWER,
|
||||
} = require("../helper-hardhat-config");
|
||||
const { verify } = require("../utils/verify");
|
||||
|
||||
module.exports = async ({ getNamedAccounts, deployments }) => {
|
||||
const { deploy, log } = deployments;
|
||||
|
@ -8,6 +8,7 @@ const {
|
||||
const helperConfig = require("../helper-hardhat-config");
|
||||
const networkConfig = helperConfig.networkConfig;
|
||||
*/
|
||||
const { verify } = require("../utils/verify");
|
||||
|
||||
/*
|
||||
// main function that auto run via hardhat deploy
|
||||
@ -19,6 +20,14 @@ function deployFunc() {
|
||||
module.exports.default = deployFunc;
|
||||
*/
|
||||
|
||||
/*
|
||||
module.exports = async () => {
|
||||
let contractAddress = "0x3a827C119e1D746bb3C7bcbbf95c55246C8CcBdd";
|
||||
let priceFeedAddress = "0x694AA1769357215DE4FAC081bf1f309aDC325306";
|
||||
await verify(contractAddress, [priceFeedAddress]);
|
||||
};
|
||||
*/
|
||||
|
||||
module.exports = async ({ getNamedAccounts, deployments }) => {
|
||||
const { deploy, log } = deployments;
|
||||
const { deployer } = await getNamedAccounts(); // Take from hardhat.config.js namedAccounts
|
||||
@ -46,20 +55,23 @@ module.exports = async ({ getNamedAccounts, deployments }) => {
|
||||
|
||||
log("----------------------------------------------------");
|
||||
log("Deploying FundMe Contract and waiting for confirmations...");
|
||||
const argsPriceFeed = [ethUsdPriceFeedAddress];
|
||||
const fundMe = await deploy("FundMe", {
|
||||
from: deployer,
|
||||
args: [ethUsdPriceFeedAddress],
|
||||
args: argsPriceFeed,
|
||||
log: true,
|
||||
// we need to wait if on a live network so we can verify properly
|
||||
waitConfirmations: network.config.blockConfirmations || 1,
|
||||
});
|
||||
log(`FundMe deployed at ${fundMe.address}`);
|
||||
|
||||
// If on testnet, then verify smart contract
|
||||
if (
|
||||
!developmentChains.includes(network.name) &&
|
||||
process.env.ETHERSCAN_API_KEY
|
||||
) {
|
||||
await verify(fundMe.address, [ethUsdPriceFeedAddress]);
|
||||
// Verify Code
|
||||
await verify(fundMe.address, argsPriceFeed);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"address": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853",
|
||||
"address": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
|
||||
"abi": [
|
||||
{
|
||||
"inputs": [
|
||||
@ -117,24 +117,24 @@
|
||||
"type": "receive"
|
||||
}
|
||||
],
|
||||
"transactionHash": "0xeabedc2721e71ca9ce643a60e7a60b0534335a0bff995dd4360e134d0ed41e1b",
|
||||
"transactionHash": "0xee5f527d8a195ad5909a2ec516483cb1f62c73dc93c8cc7edf1316380411394c",
|
||||
"receipt": {
|
||||
"to": null,
|
||||
"from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
|
||||
"contractAddress": "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853",
|
||||
"contractAddress": "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
|
||||
"transactionIndex": 0,
|
||||
"gasUsed": "855613",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"blockHash": "0x0c9cb3c9850d403be7b5d7342e9eac86f2ff991f7197d0214eaa0e1a877b9d2f",
|
||||
"transactionHash": "0xeabedc2721e71ca9ce643a60e7a60b0534335a0bff995dd4360e134d0ed41e1b",
|
||||
"blockHash": "0xb4e85c54d81b89dd58a2c11e02935d04b8b3d7d536a33d346ae0d0d207c1f95d",
|
||||
"transactionHash": "0xee5f527d8a195ad5909a2ec516483cb1f62c73dc93c8cc7edf1316380411394c",
|
||||
"logs": [],
|
||||
"blockNumber": 8,
|
||||
"blockNumber": 2,
|
||||
"cumulativeGasUsed": "855613",
|
||||
"status": 1,
|
||||
"byzantium": true
|
||||
},
|
||||
"args": [
|
||||
"0x0165878A594ca255338adfa4d48449f69242Eb8F"
|
||||
"0x5FbDB2315678afecb367f032d93F642f64180aa3"
|
||||
],
|
||||
"numDeployments": 1,
|
||||
"solcInputHash": "2addf7ea1ebec6fe07221842a0f5af20",
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"address": "0x0165878A594ca255338adfa4d48449f69242Eb8F",
|
||||
"address": "0x5FbDB2315678afecb367f032d93F642f64180aa3",
|
||||
"abi": [
|
||||
{
|
||||
"inputs": [
|
||||
@ -297,25 +297,25 @@
|
||||
"type": "function"
|
||||
}
|
||||
],
|
||||
"transactionHash": "0x4e36cc692c0b599533e0ff9149034e753f47f7d986873acb110df44c3dbf67e6",
|
||||
"transactionHash": "0x7e29e8ee3c67b18648f3fe15adcc0ea408e835cac0fee09a37c8a5c296b9ec68",
|
||||
"receipt": {
|
||||
"to": null,
|
||||
"from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
|
||||
"contractAddress": "0x0165878A594ca255338adfa4d48449f69242Eb8F",
|
||||
"contractAddress": "0x5FbDB2315678afecb367f032d93F642f64180aa3",
|
||||
"transactionIndex": 0,
|
||||
"gasUsed": "569759",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"blockHash": "0x14f9c2a5f82fda6c4401839b55d9a1aa8854b8e0d866e6ce8119befa946aee83",
|
||||
"transactionHash": "0x4e36cc692c0b599533e0ff9149034e753f47f7d986873acb110df44c3dbf67e6",
|
||||
"blockHash": "0xbc933db6a5f8e02afe32f6771521a3365ffc45e6361fc7ec758ababbdb9725ca",
|
||||
"transactionHash": "0x7e29e8ee3c67b18648f3fe15adcc0ea408e835cac0fee09a37c8a5c296b9ec68",
|
||||
"logs": [],
|
||||
"blockNumber": 7,
|
||||
"blockNumber": 1,
|
||||
"cumulativeGasUsed": "569759",
|
||||
"status": 1,
|
||||
"byzantium": true
|
||||
},
|
||||
"args": [
|
||||
"8",
|
||||
"200000000000"
|
||||
8,
|
||||
200000000000
|
||||
],
|
||||
"numDeployments": 1,
|
||||
"solcInputHash": "5eac77ba83b4d63fff115dd8269de44a",
|
||||
|
1
deployments/sepolia/.chainId
Normal file
1
deployments/sepolia/.chainId
Normal file
@ -0,0 +1 @@
|
||||
11155111
|
212
deployments/sepolia/FundMe.json
Normal file
212
deployments/sepolia/FundMe.json
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,41 @@
|
||||
{
|
||||
"language": "Solidity",
|
||||
"sources": {
|
||||
"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": {
|
||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(uint80 _roundId)\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n}\n"
|
||||
},
|
||||
"contracts/FundMe.sol": {
|
||||
"content": "// SPDX-License-Identifier: MIT\n/*\n Get funds from users\n Withdraw funds\n Set a minimum funding value in USD\n*/\npragma solidity ^0.8.0;\n\nimport \"./PriceConverter.sol\";\n// Save Gas by using constant, immutable for variables\n\nerror NotOwner();\n\n// 816914\ncontract FundMe {\n /*\n Transaction Fields\n Nonce\n Gas Price\n Gas Limit - Max Gas that this TX can use\n To - Address\n Value - Amount of wei to send\n Data - What to send to the Address (Can Empty)\n v, r, s - components of TX signature\n */\n\n using PriceConverter for uint256;\n uint256 public constant MINIMUM_USD = 50 * 1e18;\n\n address[] public funders;\n mapping(address => uint256) public addressToAmountFunded;\n\n // immutable only can declare 1 time at contructor\n address public immutable i_owner;\n\n AggregatorV3Interface public priceFeed;\n\n constructor(address priceFeedAddress) {\n i_owner = msg.sender;\n priceFeed = AggregatorV3Interface(priceFeedAddress);\n }\n\n function fund() public payable {\n /*\n Want to be able to set a minimum fund amount in USD\n 1. How do we send ETH to this contract\n */\n //require (msg.value >= 1e18, \"Didn't send enough\"); // 1e18 = 1 * 10 * 18 = 1000000000000000000\n require(\n msg.value.getConversionRate(priceFeed) >= MINIMUM_USD,\n \"Didn't send enough\"\n );\n funders.push(msg.sender);\n addressToAmountFunded[msg.sender] = msg.value;\n }\n\n // Owner of this contract only can withdraw\n function withdraw() public onlyOwner {\n // Can use modifier to replace\n // require(msg.sender == owner, \"Sender is not owner\");\n\n /* starting index, eding index, step amount */\n for (\n uint256 funderIndex = 0;\n funderIndex < funders.length;\n funderIndex++\n ) {\n address funder = funders[funderIndex];\n addressToAmountFunded[funder] = 0;\n }\n // reset the array\n funders = new address[](0);\n\n /*\n // transfer - over 2300 gas will cause exception\n payable(msg.sender).transfer(address(this).balance);\n // send - over 2300 gas will not cause exception, only will return true or false\n bool sendSuccess = payable(msg.sender).send(address(this).balance);\n require(sendSuccess, \"Send failed\");\n */\n\n // call - lower level\n (bool callSuccess, ) = payable(msg.sender).call{\n value: address(this).balance\n }(\"\");\n require(callSuccess, \"Call failed\");\n }\n\n modifier onlyOwner() {\n // require(msg.sender == i_owner, \"Sender is not owner!\");\n if (msg.sender != i_owner) {\n revert NotOwner();\n }\n\n _; // doing the rest of the code\n }\n\n // What happens if someone send this contract ETH without calling the fund fucntion\n /*\n receive - people send money / empty money into this contract\n fallback - cannot identify which function to run\n */\n receive() external payable {\n fund();\n }\n\n fallback() external payable {\n fund();\n }\n}\n"
|
||||
},
|
||||
"contracts/PriceConverter.sol": {
|
||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\n//import \"@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\n// Why is this a library and not abstract?\n// Why not an interface?\nlibrary PriceConverter {\n // We could make this public, but then we'd have to deploy it\n function getPrice(\n AggregatorV3Interface priceFeed\n ) internal view returns (uint256) {\n (, int256 answer, , , ) = priceFeed.latestRoundData();\n // ETH/USD rate in 18 digit\n return uint256(answer * 10000000000);\n // or (Both will do the same thing)\n // return uint256(answer * 1e10); // 1* 10 ** 10 == 10000000000\n }\n\n // 1000000000\n function getConversionRate(\n uint256 ethAmount,\n AggregatorV3Interface priceFeed\n ) internal view returns (uint256) {\n uint256 ethPrice = getPrice(priceFeed);\n uint256 ethAmountInUsd = (ethPrice * ethAmount) / 1000000000000000000;\n // or (Both will do the same thing)\n // uint256 ethAmountInUsd = (ethPrice * ethAmount) / 1e18; // 1 * 10 ** 18 == 1000000000000000000\n // the actual ETH/USD conversion rate, after adjusting the extra 0s.\n return ethAmountInUsd;\n }\n}\n"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"optimizer": {
|
||||
"enabled": false,
|
||||
"runs": 200
|
||||
},
|
||||
"outputSelection": {
|
||||
"*": {
|
||||
"*": [
|
||||
"abi",
|
||||
"evm.bytecode",
|
||||
"evm.deployedBytecode",
|
||||
"evm.methodIdentifiers",
|
||||
"metadata",
|
||||
"devdoc",
|
||||
"userdoc",
|
||||
"storageLayout",
|
||||
"evm.gasEstimates"
|
||||
],
|
||||
"": [
|
||||
"ast"
|
||||
]
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"useLiteralContent": true
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +1,15 @@
|
||||
require("@nomicfoundation/hardhat-toolbox");
|
||||
//// Deprecated, below import combined in toolbox import already
|
||||
require("@nomiclabs/hardhat-ethers");
|
||||
//require("@nomiclabs/hardhat-etherscan");
|
||||
//require("@nomicfoundation/hardhat-verify");
|
||||
require("dotenv").config();
|
||||
require("./tasks/block-number");
|
||||
require("@nomiclabs/hardhat-waffle");
|
||||
require("hardhat-gas-reporter");
|
||||
require("@nomiclabs/hardhat-etherscan");
|
||||
require("dotenv").config();
|
||||
require("solidity-coverage");
|
||||
require("hardhat-deploy");
|
||||
require("./tasks/block-number");
|
||||
|
||||
//require("@nomicfoundation/hardhat-toolbox");
|
||||
//// Deprecated, below import combined in toolbox import already
|
||||
//require("@nomiclabs/hardhat-ethers");
|
||||
//require("@nomicfoundation/hardhat-verify");
|
||||
|
||||
const RPC_URL_SEPOLIA = process.env.SEPOLIA_RPC_URL || "https://eth-sepolia";
|
||||
const PRIVATE_KEY_SEPOLIA = process.env.SEPOLIA_PRIVATE_KEY || "0xkey";
|
||||
@ -29,17 +31,20 @@ module.exports = {
|
||||
url: RPC_URL_SEPOLIA,
|
||||
accounts: [PRIVATE_KEY_SEPOLIA],
|
||||
chainId: 11155111,
|
||||
blockConfirmation: 6,
|
||||
},
|
||||
ganache: {
|
||||
url: RPC_URL_GANACHE,
|
||||
accounts: [PRIVATE_KEY_GANACHE],
|
||||
chainId: 5777,
|
||||
blockConfirmation: 1,
|
||||
},
|
||||
localhost: {
|
||||
// Hardhost similar like ganache, can debug the transaction
|
||||
// Start in terminal - yarn hardhat node
|
||||
url: "http://127.0.0.1:8545/",
|
||||
chainId: 31337,
|
||||
blockConfirmation: 1,
|
||||
},
|
||||
},
|
||||
solidity: {
|
||||
@ -54,6 +59,7 @@ module.exports = {
|
||||
},
|
||||
etherscan: {
|
||||
apiKey: ETHERSCAN_API_KEY,
|
||||
customChains: [],
|
||||
},
|
||||
sourcify: {
|
||||
enabled: false,
|
||||
@ -81,11 +87,3 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
|
||||
const accounts = await hre.ethers.getSigners();
|
||||
|
||||
for (const account of accounts) {
|
||||
console.log(account.address);
|
||||
}
|
||||
});
|
||||
|
@ -5,7 +5,7 @@ const { exit } = require("process");
|
||||
// async main
|
||||
async function main() {
|
||||
if (false) {
|
||||
await runVerifyOnly("0xF90F7edF515001CD4293255bfaF7D17ffa415e91");
|
||||
await runVerifyOnly("0x3a827C119e1D746bb3C7bcbbf95c55246C8CcBdd");
|
||||
}
|
||||
|
||||
const simpleStorageFactory =
|
||||
@ -78,7 +78,8 @@ async function runVerifyOnly(address) {
|
||||
console.log("Currently on Sepolia Testnet");
|
||||
if (ETHERSCAN_API_KEY_VERIFY !== undefined) {
|
||||
console.log("Verifying contract...");
|
||||
await verify(address, []);
|
||||
let tmp = await verify(address, []);
|
||||
console.log(tmp);
|
||||
console.log("Verification complete");
|
||||
} else {
|
||||
console.log("ETHERSCAN_API_KEY is undefined");
|
||||
|
@ -1,4 +1,4 @@
|
||||
const { tast, task } = require("hardhat/config");
|
||||
const { task } = require("hardhat/config");
|
||||
|
||||
task("block-number", "Prints current block number").setAction(
|
||||
async (taskArgs, hre) => {
|
||||
@ -6,3 +6,11 @@ task("block-number", "Prints current block number").setAction(
|
||||
console.log("Current block number: " + blockNumber);
|
||||
},
|
||||
);
|
||||
|
||||
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
|
||||
const accounts = await hre.ethers.getSigners();
|
||||
|
||||
for (const account of accounts) {
|
||||
console.log(account.address);
|
||||
}
|
||||
});
|
||||
|
19
utils/verify.js
Normal file
19
utils/verify.js
Normal file
@ -0,0 +1,19 @@
|
||||
const { run } = require("hardhat")
|
||||
|
||||
const verify = async (contractAddress, args) => {
|
||||
console.log("Verifying contract...")
|
||||
try {
|
||||
await run("verify:verify", {
|
||||
address: contractAddress,
|
||||
constructorArguments: args,
|
||||
})
|
||||
} catch (e) {
|
||||
if (e.message.toLowerCase().includes("already verified")) {
|
||||
console.log("Already verified!")
|
||||
} else {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { verify }
|
Loading…
Reference in New Issue
Block a user