Mock Ready

This commit is contained in:
2024-08-05 18:07:29 +08:00
parent 3ab5ee37c6
commit 39c2dd760b
12 changed files with 6904 additions and 1052 deletions

View File

@@ -1,7 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol";
//import "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol";
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
// Why is this a library and not abstract?
// Why not an interface?

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
pragma solidity ^0.6.0;
import "@chainlink/contracts/src/v0.8/tests/MockV3Aggregator.sol";
import "@chainlink/contracts/src/v0.6/tests/MockV3Aggregator.sol";
// Direct import from the github, located at local node_modules

View File

@@ -1,6 +1,6 @@
// For Localhost, Hardhat, Ganache Without Price Feed To Get Price Feed
const { ethers, run, network } = require("hardhat");
const { network } = require("hardhat");
const {
developmentChains,
DECIMALS,
@@ -17,14 +17,14 @@ module.exports = async ({ getNamedAccounts, deployments }) => {
// Here can chekc with chainId as well
if (developmentChains.includes(networkName)) {
log("Local network '" + networkName + "', deploying mocks...");
/*
await deploy(MockV3Aggregator, {
await deploy("MockV3Aggregator", {
contract: "MockV3Aggregator",
from: deployer,
log: true,
args: [DECIMALS, INITIAL_ANSWER],
});
*/
log("Mocks deployed!");
log("=====================================");
}

View File

@@ -1,6 +1,9 @@
// import
const { ethers, run, network } = require("hardhat");
const { networkConfig } = require("../helper-hardhat-config");
const {
networkConfig,
developmentChains,
} = require("../helper-hardhat-config");
/* Above same as:
const helperConfig = require("../helper-hardhat-config");
const networkConfig = helperConfig.networkConfig;
@@ -20,23 +23,44 @@ module.exports = async ({ getNamedAccounts, deployments }) => {
const { deploy, log } = deployments;
const { deployer } = await getNamedAccounts(); // Take from hardhat.config.js namedAccounts
const chainId = network.config.chainId;
let ethUsdPriceFeedAddress;
if (networkConfig[chainId] === undefined) {
console.log("Is Not Testnet / Mainnet! No Mock Up...");
console.log(deployments);
const ethUsdAggregator = await deployments.get("MockV3Aggregator");
return;
/*
31337 - Local Hardhat Network
5777 - Local Ganache Network
11155111 - Sepolia Testnet
When going for localhost / hardhat network we want to use a mock
*/
switch (chainId) {
case 31337:
ethUsdAggregator = await deployments.get("MockV3Aggregator");
ethUsdPriceFeedAddress = ethUsdAggregator.address;
break;
case 5777:
ethUsdAggregator = await deployments.get("MockV3Aggregator");
ethUsdPriceFeedAddress = ethUsdAggregator.address;
break;
default:
ethUsdPriceFeedAddress = networkConfig[chainId]["ethUsdPriceFeed"];
}
const ethUsdPriceFeedAddress = networkConfig[chainId]["ethUsdPriceFeed"];
// if contract doest't exist, we deploy a minimal version for our local testing
// When going for localhost / hardhat network we want to use a mock
// Auto Change Chains To Get different Gas
log("----------------------------------------------------");
log("Deploying FundMe Contract and waiting for confirmations...");
const fundMe = await deploy("FundMe", {
from: deployer,
args: [ethUsdPriceFeedAddress], // put price feed address
args: [ethUsdPriceFeedAddress],
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 (
!developmentChains.includes(network.name) &&
process.env.ETHERSCAN_API_KEY
) {
await verify(fundMe.address, [ethUsdPriceFeedAddress]);
}
};
module.exports.tags = ["all", "fundme"];

View File

@@ -0,0 +1 @@
31337

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -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
}
}
}

View File

@@ -0,0 +1,47 @@
{
"language": "Solidity",
"sources": {
"@chainlink/contracts/src/v0.6/interfaces/AggregatorInterface.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.0;\n\ninterface AggregatorInterface {\n function latestAnswer()\n external\n view\n returns (\n int256\n );\n \n function latestTimestamp()\n external\n view\n returns (\n uint256\n );\n\n function latestRound()\n external\n view\n returns (\n uint256\n );\n\n function getAnswer(\n uint256 roundId\n )\n external\n view\n returns (\n int256\n );\n\n function getTimestamp(\n uint256 roundId\n )\n external\n view\n returns (\n uint256\n );\n\n event AnswerUpdated(\n int256 indexed current,\n uint256 indexed roundId,\n uint256 updatedAt\n );\n\n event NewRound(\n uint256 indexed roundId,\n address indexed startedBy,\n uint256 startedAt\n );\n}\n"
},
"@chainlink/contracts/src/v0.6/interfaces/AggregatorV2V3Interface.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.0;\n\nimport \"./AggregatorInterface.sol\";\nimport \"./AggregatorV3Interface.sol\";\n\ninterface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface\n{\n}\n"
},
"@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.0;\n\ninterface AggregatorV3Interface {\n\n function decimals()\n external\n view\n returns (\n uint8\n );\n\n function description()\n external\n view\n returns (\n string memory\n );\n\n function version()\n external\n view\n returns (\n uint256\n );\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(\n uint80 _roundId\n )\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}\n"
},
"@chainlink/contracts/src/v0.6/tests/MockV3Aggregator.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.0;\n\nimport \"../interfaces/AggregatorV2V3Interface.sol\";\n\n/**\n * @title MockV3Aggregator\n * @notice Based on the FluxAggregator contract\n * @notice Use this contract when you need to test\n * other contract's ability to read data from an\n * aggregator contract, but how the aggregator got\n * its answer is unimportant\n */\ncontract MockV3Aggregator is AggregatorV2V3Interface {\n uint256 constant public override version = 0;\n\n uint8 public override decimals;\n int256 public override latestAnswer;\n uint256 public override latestTimestamp;\n uint256 public override latestRound;\n\n mapping(uint256 => int256) public override getAnswer;\n mapping(uint256 => uint256) public override getTimestamp;\n mapping(uint256 => uint256) private getStartedAt;\n\n constructor(\n uint8 _decimals,\n int256 _initialAnswer\n ) public {\n decimals = _decimals;\n updateAnswer(_initialAnswer);\n }\n\n function updateAnswer(\n int256 _answer\n ) public {\n latestAnswer = _answer;\n latestTimestamp = block.timestamp;\n latestRound++;\n getAnswer[latestRound] = _answer;\n getTimestamp[latestRound] = block.timestamp;\n getStartedAt[latestRound] = block.timestamp;\n }\n\n function updateRoundData(\n uint80 _roundId,\n int256 _answer,\n uint256 _timestamp,\n uint256 _startedAt\n ) public {\n latestRound = _roundId;\n latestAnswer = _answer;\n latestTimestamp = _timestamp;\n getAnswer[latestRound] = _answer;\n getTimestamp[latestRound] = _timestamp;\n getStartedAt[latestRound] = _startedAt;\n }\n\n function getRoundData(uint80 _roundId)\n external\n view\n override\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n )\n {\n return (\n _roundId,\n getAnswer[_roundId],\n getStartedAt[_roundId],\n getTimestamp[_roundId],\n _roundId\n );\n }\n\n function latestRoundData()\n external\n view\n override\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n )\n {\n return (\n uint80(latestRound),\n getAnswer[latestRound],\n getStartedAt[latestRound],\n getTimestamp[latestRound],\n uint80(latestRound)\n );\n }\n\n function description()\n external\n view\n override\n returns (string memory)\n {\n return \"v0.6/tests/MockV3Aggregator.sol\";\n }\n}"
},
"contracts/test/MockV3Aggregator.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.6.6;\n\nimport \"@chainlink/contracts/src/v0.6/tests/MockV3Aggregator.sol\";\n\n// Direct import from the github, located at local node_modules\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
}
}
}

View File

@@ -42,7 +42,16 @@ module.exports = {
chainId: 31337,
},
},
solidity: "0.8.8",
solidity: {
compilers: [
{
version: "0.8.8",
},
{
version: "0.6.6",
},
],
},
etherscan: {
apiKey: ETHERSCAN_API_KEY,
},
@@ -65,6 +74,7 @@ module.exports = {
namedAccounts: {
deployer: {
default: 0,
//4: 1,
},
user: {
default: 1,

View File

@@ -7,31 +7,34 @@
"license": "Unlicense",
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
"devDependencies": {
"@chainlink/contracts": "^1.2.0",
"@nomicfoundation/hardhat-toolbox": "^5.0.0",
"@nomicfoundation/hardhat-chai-matchers": "^2.0.0",
"@nomicfoundation/hardhat-ethers": "^3.0.0",
"@nomicfoundation/hardhat-ignition": "^0.15.0",
"@nomicfoundation/hardhat-ignition-ethers": "^0.15.0",
"@nomicfoundation/hardhat-network-helpers": "^1.0.0",
"@nomicfoundation/hardhat-toolbox": "^5.0.0",
"@nomicfoundation/hardhat-verify": "^2.0.0",
"@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers",
"@typechain/ethers-v6": "^0.5.0",
"@typechain/hardhat": "^9.0.0",
"@types/mocha": ">=9.1.0",
"chai": "^4.2.0",
"dotenv": "^16.4.5",
"ethers": "^5.7.2",
"hardhat": "^2.22.7",
"hardhat-deploy": "^0.12.4",
"hardhat-deploy-ethers": "^0.4.2",
"hardhat-gas-reporter": "^1.0.8",
"prettier": "^3.3.3",
"prettier-plugin-solidity": "^1.3.1",
"solhint": "^5.0.2",
"solidity-coverage": "^0.8.12",
"ts-node": ">=8.0.0",
"typechain": "^8.3.0",
"typescript": ">=4.5.0"
"@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13",
"@nomiclabs/hardhat-etherscan": "^3.0.0",
"@nomiclabs/hardhat-waffle": "^2.0.2",
"chai": "^4.3.4",
"ethereum-waffle": "^3.4.0",
"ethers": "^5.5.3",
"hardhat": "^2.8.3",
"hardhat-deploy": "^0.9.29",
"hardhat-gas-reporter": "^1.0.7",
"solidity-coverage": "^0.7.18",
"@chainlink/contracts": "^0.3.1",
"dotenv": "^14.2.0",
"prettier-plugin-solidity": "^1.0.0-beta.19",
"solhint": "^3.3.7"
}
}

7115
yarn.lock

File diff suppressed because it is too large Load Diff