Can't run test and compile because of deployer error #1740
-
I keep getting this error: Type contract FundMe is not implicitly convertible to expected type tuple(contract FundMe,contract HelperConfig).
// SPDX-License-Identifier: MIT import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; // 3. Interfaces, Libraries, Contracts /**
|
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 8 replies
-
// SPDX-License-Identifier: MIT
// 1. Pragma
pragma solidity ^0.8.19;
// 2. Imports
import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import {PriceConverter} from "./PriceConverter.sol";
// 3. Interfaces, Libraries, Contracts
error FundMe__NotOwner();
/**
@title A sample Funding Contract
https://github.com/author Patrick Collins
@notice This contract is for creating a sample funding contract
@dev This implements price feeds as our library
*/
contract FundMe {
// Type Declarations
using PriceConverter for uint256;
// State variables
uint256 public constant MINIMUM_USD = 5 * 10 ** 18;
address private immutable i_owner;
address[] private s_funders;
mapping(address => uint256) private s_addressToAmountFunded;
AggregatorV3Interface private s_priceFeed;
// Events (we have none!)
// Modifiers
modifier onlyOwner() {
// require(msg.sender == i_owner);
if (msg.sender != i_owner) revert FundMe__NotOwner();
_;
}
// Functions Order:
//// constructor
//// receive
//// fallback
//// external
//// public
//// internal
//// private
//// view / pure
constructor(address priceFeed) {
s_priceFeed = AggregatorV3Interface(priceFeed);
i_owner = msg.sender;
}
/// @notice Funds our contract based on the ETH/USD price
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 onlyOwner {
for (uint256 funderIndex = 0; funderIndex < s_funders.length; funderIndex++) {
address funder = s_funders[funderIndex];
s_addressToAmountFunded[funder] = 0;
}
s_funders = new address;
// Transfer vs call vs Send
// payable(msg.sender).transfer(address(this).balance);
(bool success,) = i_owner.call{value: address(this).balance}("");
require(success);
}
function cheaperWithdraw() public onlyOwner {
address[] memory funders = s_funders;
// mappings can't be in memory, sorry!
for (uint256 funderIndex = 0; funderIndex < funders.length; funderIndex++) {
address funder = funders[funderIndex];
s_addressToAmountFunded[funder] = 0;
}
s_funders = new address;
// payable(msg.sender).transfer(address(this).balance);
(bool success,) = i_owner.call{value: address(this).balance}("");
require(success);
}
/** Getter Functions */
/**
@notice Gets the amount that an address has funded
@param fundingAddress the address of the funder
@return the amount funded
*/
function getAddressToAmountFunded(address fundingAddress) public view returns (uint256) {
return s_addressToAmountFunded[fundingAddress];
}
function getVersion() public view returns (uint256) {
return s_priceFeed.version();
}
function getFunder(uint256 index) public view returns (address) {
return s_funders[index];
}
function getOwner() public view returns (address) {
return i_owner;
}
function getPriceFeed() public view returns (AggregatorV3Interface) {
return s_priceFeed;
}
} |
Beta Was this translation helpful? Give feedback.
-
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import {DeployFundMe} from "../../script/DeployFundMe.s.sol";
import {FundMe} from "../../src/FundMe.sol";
import {HelperConfig} from "../../script/HelperConfig.s.sol";
import {Test, console} from "forge-std/Test.sol";
import {StdCheats} from "forge-std/StdCheats.sol";
contract FundMeTest is StdCheats, Test {
FundMe public fundMe;
HelperConfig public helperConfig;
uint256 public constant SEND_VALUE = 0.1 ether; // just a value to make sure we are sending enough!
uint256 public constant STARTING_USER_BALANCE = 10 ether;
uint256 public constant GAS_PRICE = 1;
address public constant USER = address(1);
// uint256 public constant SEND_VALUE = 1e18;
// uint256 public constant SEND_VALUE = 1_000_000_000_000_000_000;
// uint256 public constant SEND_VALUE = 1000000000000000000;
function setUp() external {
DeployFundMe deployer = new DeployFundMe();
(fundMe, helperConfig) = deployer.run();
vm.deal(USER, STARTING_USER_BALANCE);
}
function testPriceFeedSetCorrectly() public {
address retreivedPriceFeed = address(fundMe.getPriceFeed());
// (address expectedPriceFeed) = helperConfig.activeNetworkConfig();
address expectedPriceFeed = helperConfig.activeNetworkConfig();
assertEq(retreivedPriceFeed, expectedPriceFeed);
}
function testFundFailsWithoutEnoughETH() public {
vm.expectRevert();
fundMe.fund();
}
function testFundUpdatesFundedDataStructure() public {
vm.startPrank(USER);
fundMe.fund{value: SEND_VALUE}();
vm.stopPrank();
uint256 amountFunded = fundMe.getAddressToAmountFunded(USER);
assertEq(amountFunded, SEND_VALUE);
}
function testAddsFunderToArrayOfFunders() public {
vm.startPrank(USER);
fundMe.fund{value: SEND_VALUE}();
vm.stopPrank();
address funder = fundMe.getFunder(0);
assertEq(funder, USER);
}
// https://twitter.com/PaulRBerg/status/1624763320539525121
modifier funded() {
vm.prank(USER);
fundMe.fund{value: SEND_VALUE}();
assert(address(fundMe).balance > 0);
_;
}
function testOnlyOwnerCanWithdraw() public funded {
vm.expectRevert();
fundMe.withdraw();
}
function testWithdrawFromASingleFunder() public funded {
// Arrange
uint256 startingFundMeBalance = address(fundMe).balance;
uint256 startingOwnerBalance = fundMe.getOwner().balance;
// vm.txGasPrice(GAS_PRICE);
// uint256 gasStart = gasleft();
// // Act
vm.startPrank(fundMe.getOwner());
fundMe.withdraw();
vm.stopPrank();
// uint256 gasEnd = gasleft();
// uint256 gasUsed = (gasStart - gasEnd) * tx.gasprice;
// Assert
uint256 endingFundMeBalance = address(fundMe).balance;
uint256 endingOwnerBalance = fundMe.getOwner().balance;
assertEq(endingFundMeBalance, 0);
assertEq(
startingFundMeBalance + startingOwnerBalance,
endingOwnerBalance // + gasUsed
);
}
// Can we do our withdraw function a cheaper way?
function testWithdrawFromMultipleFunders() public funded {
uint160 numberOfFunders = 10;
uint160 startingFunderIndex = 2;
for (uint160 i = startingFunderIndex; i < numberOfFunders + startingFunderIndex; i++) {
// we get hoax from stdcheats
// prank + deal
hoax(address(i), STARTING_USER_BALANCE);
fundMe.fund{value: SEND_VALUE}();
}
uint256 startingFundMeBalance = address(fundMe).balance;
uint256 startingOwnerBalance = fundMe.getOwner().balance;
vm.startPrank(fundMe.getOwner());
fundMe.withdraw();
vm.stopPrank();
assert(address(fundMe).balance == 0);
assert(startingFundMeBalance + startingOwnerBalance == fundMe.getOwner().balance);
assert((numberOfFunders + 1) * SEND_VALUE == fundMe.getOwner().balance - startingOwnerBalance);
}
} |
Beta Was this translation helpful? Give feedback.
-
Just a regular 'forge test' and it returns Error (7407): Type contract FundMe is not implicitly convertible to expected type tuple(contract FundMe,contract HelperConfig). I copied the entire code from the github repo so I am a bit confused on how to fix the error |
Beta Was this translation helpful? Give feedback.
-
Can you share your |
Beta Was this translation helpful? Give feedback.
-
No, I meant your DeployFundMe contract |
Beta Was this translation helpful? Give feedback.
-
// SPDX-License-Identifier: UNLICENSED import {Script} from "forge-std/Script.sol"; contract DeployFundMe is Script {
} |
Beta Was this translation helpful? Give feedback.
All your tests passed, sir. You seem to have no issue, sir.