Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
atenger committed Aug 8, 2022
0 parents commit bb26a8f
Show file tree
Hide file tree
Showing 21 changed files with 7,459 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
node_modules
.env
coverage
coverage.json
typechain
typechain-types
deployments

#Hardhat files
cache
artifacts

10 changes: 10 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
node_modules
package.json
img
artifacts
cache
coverage
.env
.*
README.md
coverage.json
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"tabWidth": 4,
"useTabs": false,
"semi": false,
"singleQuote": false
}
4 changes: 4 additions & 0 deletions .solhint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "solhint:default"
}

Empty file added .solhintignore
Empty file.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Sample Hardhat Project

This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a script that deploys that contract.

Try running some of the following tasks:

```shell
npx hardhat help
npx hardhat test
GAS_REPORT=true npx hardhat test
npx hardhat node
npx hardhat run scripts/deploy.js
```
123 changes: 123 additions & 0 deletions contracts/FundMe.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// SPDX-License-Identifier: MIT
// Pragma
pragma solidity ^0.8.8;

// Imports
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import "./PriceConverter.sol";
import "hardhat/console.sol";

// Error codes
error FundMe__NotOwner();

// Interfaces, Libraries

// Contracts

/** @title A contract for crowd funding
* @author Adrienne
* @notice This contract is to demo a sample funding contract as part of a block chain dev course
* @dev This implements price feeds as our library
*/

contract FundMe {
// Type Declarations
using PriceConverter for uint256;

// State variables
mapping(address => uint256) private s_addressToAmountFunded;
address[] private s_funders;

// Could we make this constant? /* hint: no! We should make it immutable! */
address private immutable i_owner;
uint256 public constant MINIMUM_USD = 50 * 10**18;

AggregatorV3Interface private s_priceFeed;

uint256 SomeVarThatShouldShowUpInLinter; //for some reason sol linter is not working :(

// Modifiers
modifier onlyOwner() {
// require(msg.sender == owner);
if (msg.sender != i_owner) revert FundMe__NotOwner();
_;
}

// Functions
// Order: Constructor, receive, fallback, external, public, internal, private, view/pure

constructor(address priceFeedAddress) {
console.log("testing hardhat console.log in constructor of contract");
i_owner = msg.sender;
s_priceFeed = AggregatorV3Interface(priceFeedAddress);
}

/** @notice This function funds this contract
* @dev
*/

function fund() public payable {
require(
msg.value.getConversionRate(s_priceFeed) >= MINIMUM_USD,
"You need to spend more ETH!"
);
// require(PriceConverter.getConversionRate(msg.value) >= MINIMUM_USD, "You need to spend more ETH!");
s_addressToAmountFunded[msg.sender] += msg.value;
s_funders.push(msg.sender);
}

function withdraw() public payable onlyOwner {
for (
uint256 funderIndex = 0;
funderIndex < s_funders.length;
funderIndex++
) {
address funder = s_funders[funderIndex];
s_addressToAmountFunded[funder] = 0;
}
s_funders = new address[](0);

(bool callSuccess, ) = payable(msg.sender).call{
value: address(this).balance
}("");
require(callSuccess, "Call failed");
}

function cheaperWithdraw() public payable onlyOwner {
address[] memory funders = s_funders;

for (
uint256 funderIndex = 0;
funderIndex < funders.length;
funderIndex++
) {
address funder = funders[funderIndex];
s_addressToAmountFunded[funder] = 0;
}

s_funders = new address[](0);

(bool success, ) = i_owner.call{value: address(this).balance}("");
require(success);
}

function getOwner() public view returns (address) {
return i_owner;
}

function getFunder(uint256 index) public view returns (address) {
return s_funders[index];
}

function getAddressToAmountFunded(address funder)
public
view
returns (uint256)
{
return s_addressToAmountFunded[funder];
}

function getPriceFeed() public view returns (AggregatorV3Interface) {
return s_priceFeed;
}
}
30 changes: 30 additions & 0 deletions contracts/PriceConverter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;

import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";

// Why is this a library and not abstract?
// Why not an interface?
library PriceConverter {
// We could make this public, but then we'd have to deploy it
function getPrice(AggregatorV3Interface priceFeed)
internal
view
returns (uint256)
{
(, int256 answer, , , ) = priceFeed.latestRoundData();
// ETH/USD rate in 18 digit
return uint256(answer * 10000000000);
}

// 1000000000
function getConversionRate(
uint256 ethAmount,
AggregatorV3Interface priceFeed
) internal view returns (uint256) {
uint256 ethPrice = getPrice(priceFeed);
uint256 ethAmountInUsd = (ethPrice * ethAmount) / 1000000000000000000;
// the actual ETH/USD conversion rate, after adjusting the extra 0s.
return ethAmountInUsd;
}
}
4 changes: 4 additions & 0 deletions contracts/test/MockV3Aggregator.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import "@chainlink/contracts/src/v0.6/tests/MockV3Aggregator.sol";
29 changes: 29 additions & 0 deletions deploy/00-deploy-mocks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const { LogDescription } = require("@ethersproject/abi")
const { network } = require("hardhat")

const {
developmentChains,
DECIMALS,
INITIAL_ANSWER,
} = require("../helper-hardhat-config")

module.exports = async ({ getNamedAccounts, deployments }) => {
const { deploy, log } = deployments
const { deployer } = await getNamedAccounts()
const chainId = network.config.chainId

if (developmentChains.includes(network.name)) {
log("Local network detected! deploying mocks")
await deploy("MockV3Aggregator", {
contract: "MockV3Aggregator",
from: deployer,
log: true,
args: [DECIMALS, INITIAL_ANSWER],
})

log("Mocks deployed!")
log("-------------------------------------------------")
}
}

module.exports.tags = ["all", "mocks"]
45 changes: 45 additions & 0 deletions deploy/01-deploy-fund-me.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// import

//main function

//calling of main function
const { networkConfig, developmentChains } = require("../helper-hardhat-config")
const { network } = require("hardhat")
const { verify } = require("../utils/verify")

module.exports = async ({ getNamedAccounts, deployments }) => {
const { deploy, log } = deployments
const { deployer } = await getNamedAccounts()
const chainId = network.config.chainId

let ethUsdPriceFeedAddress
if (developmentChains.includes(network.name)) {
const ethUsdAggregator = await deployments.get("MockV3Aggregator")
ethUsdPriceFeedAddress = ethUsdAggregator.address
} else {
ethUsdPriceFeedAddress = networkConfig[chainId]["ethUsdPriceFeed"]
}
//const ethUsdPriceFeedAddress = networkConfig[chainId]["ethUsdPriceFeed"]

const args = [ethUsdPriceFeedAddress]

const fundMe = await deploy("FundMe", {
from: deployer,
args: args, // price feed
log: true,
waitConfirmations: network.config.blockConfirmations || 1,
})

//verify if not on a dev chain!
if (
!developmentChains.includes(network.name) &&
process.env.ETHERSCAN_API_KEY
) {
log("adding auto verify now")
await verify(fundMe.address, args)
}

log("---------------------------------------------")
}

module.exports.tags = ["all", "fundme"]
19 changes: 19 additions & 0 deletions gas-report.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
·--------------------------------|----------------------------|-------------|-----------------------------·
| Solc version: 0.8.9 · Optimizer enabled: false · Runs: 200 · Block limit: 30000000 gas │
·································|····························|·············|······························
| Methods · 17 gwei/gas · 1775.21 usd/eth │
·············|···················|·············|··············|·············|···············|··············
| Contract · Method · Min · Max · Avg · # calls · usd (avg) │
·············|···················|·············|··············|·············|···············|··············
| FundMe · cheaperWithdraw · 35708 · 77708 · 56708 · 4 · 1.71 │
·············|···················|·············|··············|·············|···············|··············
| FundMe · fund · 87344 · 104444 · 94385 · 17 · 2.85 │
·············|···················|·············|··············|·············|···············|··············
| FundMe · withdraw · 35603 · 78311 · 56957 · 4 · 1.72 │
·············|···················|·············|··············|·············|···············|··············
| Deployments · · % of limit · │
·································|·············|··············|·············|···············|··············
| FundMe · - · - · 1117842 · 3.7 % · 33.73 │
·································|·············|··············|·············|···············|··············
| MockV3Aggregator · - · - · 569635 · 1.9 % · 17.19 │
·--------------------------------|-------------|--------------|-------------|---------------|-------------·
55 changes: 55 additions & 0 deletions hardhat.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
require("dotenv").config()
require("@nomiclabs/hardhat-etherscan")
require("hardhat-gas-reporter")
require("solidity-coverage")
require("@nomiclabs/hardhat-waffle")
require("@nomicfoundation/hardhat-toolbox")

require("hardhat-deploy")

/** @type import('hardhat/config').HardhatUserConfig */

const RINKEBY_RPC_URL =
process.env.RINKEBY_RPC_URL || "https://eth-rinkeby/example"
const PRIVATE_KEY = process.env.PRIVATE_KEY || "Oxkey"
const ETHERSCAN_API_KEY = process.env.ETHERSCAN_API_KEY || "key"
const COINMARKETCAP_API_KEY = process.env.COINMARKETCAP_API_KEY || "key"

module.exports = {
defaultNetwork: "hardhat",
networks: {
rinkeby: {
url: RINKEBY_RPC_URL,
accounts: [PRIVATE_KEY],
chainId: 4,
blockConfirmations: 6,
},
localhost: {
url: "http://127.0.0.1:8545/",
chainId: 31337, // accounts aren't needed b/c hardhat will default them
},
},
solidity: {
compilers: [{ version: "0.8.9" }, { version: "0.6.6" }],
},

etherscan: {
apiKey: ETHERSCAN_API_KEY,
},

namedAccounts: {
deployer: {
default: 0, // here this will by default take the first account as deployer
1: 0, // similarly on mainnet it will take the first account as deployer. Note though that depending on how hardhat network are configured, the account 0 on one network can be different than on another
},
},

gasReporter: {
enabled: true,
outputFile: "gas-report.txt",
noColors: true,
currency: "USD",
coinmarketcap: COINMARKETCAP_API_KEY,
token: "ETH",
},
}
22 changes: 22 additions & 0 deletions helper-hardhat-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const networkConfig = {
4: {
name: "rinkeby",
ethUsdPriceFeed: "0x8A753747A1Fa494EC906cE90E9f37563A8AF630e",
},

137: {
name: "polygon",
ethUsdPriceFeed: "0xF9680D99D6C9589e2a93a78A04A279e509205945",
},
}

const developmentChains = ["hardhat", "localhost"]
const DECIMALS = 9
const INITIAL_ANSWER = 200000000000

module.exports = {
networkConfig,
developmentChains,
DECIMALS,
INITIAL_ANSWER,
}
Loading

0 comments on commit bb26a8f

Please sign in to comment.