Files
hardhat-simple-storage/contracts/FundMe.sol
T
2024-08-05 22:15:23 +08:00

131 lines
3.7 KiB
Solidity

// SPDX-License-Identifier: MIT
/*
Get funds from users
Withdraw funds
Set a minimum funding value in USD
*/
/***** 1. Pragma *****/
pragma solidity ^0.8.0;
/***** 2. Import *****/
import "./PriceConverter.sol";
// Save Gas by using constant, immutable for variables
/***** 3. Error Codes *****/
error FundMe__NotOwner();
/***** 4. Interfaces *****/
/***** 5. Libraries *****/
/***** 6. Contracts *****/
/**
* @title A contract for crowd funding
* @author hoelee
* @notice This contract is to demo a sample funding contract
* @dev This implements price feed as our library
*/
contract FundMe {
/*
Transaction Fields
Nonce
Gas Price
Gas Limit - Max Gas that this TX can use
To - Address
Value - Amount of wei to send
Data - What to send to the Address (Can Empty)
v, r, s - components of TX signature
*/
/***** 6.1 Type Declarations *****/
using PriceConverter for uint256;
uint256 public constant MINIMUM_USD = 50 * 1e18;
address[] public funders;
address public immutable i_owner; // immutable only can declare 1 time at contructor
AggregatorV3Interface public priceFeed;
/***** 6.2 State Variable *****/
mapping(address => uint256) public addressToAmountFunded;
/***** 6.3 Modifier *****/
modifier onlyOwner() {
// require(msg.sender == i_owner, "Sender is not owner!");
if (msg.sender != i_owner) {
revert FundMe__NotOwner();
}
_; // doing the rest of the code
}
/***** Function Orders:
* Constructor
* Receive
* Fallback
* External
* Public Internal
* Private
* View / Pure
* *****/
constructor(address priceFeedAddress) {
i_owner = msg.sender;
priceFeed = AggregatorV3Interface(priceFeedAddress);
}
// What happens if someone send this contract ETH without calling the fund function
receive() external payable {
// people send money / empty money into this contract
fund();
}
fallback() external payable {
// cannot identify which function to run
fund();
}
/**
* @notice Minimum sending USD50, Check Conversion In Real Time
* @dev This implements price feed as our library
*/
function fund() public payable {
//require (msg.value >= 1e18, "Didn't send enough"); // 1e18 = 1 * 10 * 18 = 1000000000000000000
require(
msg.value.getConversionRate(priceFeed) >= MINIMUM_USD,
"Didn't send enough"
);
funders.push(msg.sender);
addressToAmountFunded[msg.sender] = msg.value;
}
// Owner of this contract only can withdraw
function withdraw() public onlyOwner {
// Can use modifier to replace
// require(msg.sender == owner, "Sender is not owner");
/* starting index, eding index, step amount */
for (
uint256 funderIndex = 0;
funderIndex < funders.length;
funderIndex++
) {
address funder = funders[funderIndex];
addressToAmountFunded[funder] = 0;
}
// reset the array
funders = new address[](0);
/*
// transfer - over 2300 gas will cause exception
payable(msg.sender).transfer(address(this).balance);
// send - over 2300 gas will not cause exception, only will return true or false
bool sendSuccess = payable(msg.sender).send(address(this).balance);
require(sendSuccess, "Send failed");
*/
// call - lower level
(bool callSuccess, ) = payable(msg.sender).call{
value: address(this).balance
}("");
require(callSuccess, "Call failed");
}
}