Error: No arguments passed to the base constructor. Specify the arguments or mark "Raffle" as abstract.
Fausi89 opened this issue · comments
Hey,
I did not have this issue before, but suddenly today I get this error when I try to run (forge build),
I don't get it why I have to mark the contract as abstract.
It seems it has to do with importing VRFConsumerBaseV2, because it is an abstract contract.
Error:
Compiler run failed:
Error (3415): No arguments passed to the base constructor. Specify the arguments or mark "Raffle" as abstract.
--> src/Raffle.sol:34:1:
|
34 | contract Raffle is VRFConsumerBaseV2 {
| ^ (Relevant source part starts here and spans across multiple lines).
Note: Base constructor parameters:
--> lib/chainlink-brownie-contracts/contracts/src/v0.8/VRFConsumerBaseV2.sol:104:14:
|
104 | constructor(address _vrfCoordinator) {
This is the code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
import {VRFCoordinatorV2Interface} from "lib/chainlink-brownie-contracts/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import {VRFConsumerBaseV2} from "lib/chainlink-brownie-contracts/contracts/src/v0.8/VRFConsumerBaseV2.sol";
/**
* @title A sample Raffle Contract
* @author Fouzi Matar
* @notice This contract is for creating a sample raffle
* @dev Implements Chainlink VRF v2.0
*/
contract Raffle is VRFConsumerBaseV2 {
error Raffle__NotEnoughEthSent(); // 2 underscores -- custom error
error Raffle__TransferFailed();
error Raffle__RaffleNotOpen();
/** Type Declaration */
enum RaffleState {
OPEN, // 0
CALCULATING // 1
}
/** State Variables */
uint16 private constant REQUEST_CONFIRMATIONS = 3; // all upper case because it is a constant
uint256 private constant CALLBACK_GAS_LIMIT = 200000;
uint32 private constant NUM_WORDS = 1;
uint256 private immutable i_entranceFee;
uint256 private immutable i_interval; // @dev interval is the duration of the raffle in seconds
VRFCoordinatorV2Interface private immutable i_vrfCoordinator; // Chainlink VRF Coordinator
bytes32 private immutable i_keyHash;
uint64 private immutable i_subscriptionId;
uint32 private immutable i_callbackGasLimit;
address payable[] private s_players; // storage variable because it is going to change over time
uint256 private s_lastTimeStamp;
address private s_recentWinner;
RaffleState private s_raffleState;
/** Events */
event EnteredRaffle(address indexed player);
event PickedWinner(address indexed winner);
// we use a dynamic array to keep track of all players
constructor(uint256 entranceFee, uint256 interval, address vrfCoordinator, bytes32 keyHash, uint64 subscriptionId, uint32 callbackGasLimit) {
i_entranceFee = entranceFee;
i_interval = interval;
i_vrfCoordinator = VRFCoordinatorV2Interface(vrfCoordinator);
i_keyHash = keyHash;
i_subscriptionId = subscriptionId;
i_callbackGasLimit = callbackGasLimit;
s_raffleState = RaffleState.OPEN;
s_lastTimeStamp = block.timestamp; // here we set the starting time at the moment we launch the contract
}
function enterRaffle() external payable {
// require(msg.value >= i_entranceFee, "Not enough ETH to enter the raffle"); using custom error with if statement is gas efficient
if(msg.value < i_entranceFee) {
revert Raffle__NotEnoughEthSent();
}
if (s_raffleState != RaffleState.OPEN) {
revert Raffle__RaffleNotOpen();
}
s_players.push(payable(msg.sender));
// whenever we update storage we need to emit an event
// 1. makes migration easier 2. makes front end indexing easier
emit EnteredRaffle(msg.sender);
}
// 1. Get a random number
// 2. use the random number to pick a winner
// 3. be automatically called when the raffle is over
function pickWinner() external {
// check to see if enough time has passed
if ((block.timestamp - s_lastTimeStamp) < i_interval) {
revert();
}
s_raffleState = RaffleState.CALCULATING;
// how to get a random number from chainlink VRF
// 1. Request the RNG
// 2. Get the random number
// Will revert if subscription is not set and funded.
uint256 requestId = i_vrfCoordinator.requestRandomWords(
i_keyHash, // gas lane
i_subscriptionId,
REQUEST_CONFIRMATIONS,
i_callbackGasLimit,
NUM_WORDS
);
}
function fulfillRandomWords(
uint256 _requestId,
uint256[] memory randomWords
) internal override {
//we will use modular arithmetic to get a random index
uint256 indexOfWinner = randomWords[0] % s_players.length;
address payable winner = s_players[indexOfWinner];
s_recentWinner = winner;
s_raffleState = RaffleState.OPEN; // then we have to reset the array
s_players = new address payable[](0); // reset the array
s_lastTimeStamp = block.timestamp; // reset the timestamp
(bool success,) = winner.call{value: address(this).balance}("");
if (!success) {
revert Raffle__TransferFailed();
}
emit PickedWinner(winner);
}
/** Getter Function */
function getEntranceFee() external view returns(uint256) {
return i_entranceFee;
}
}
Thanks
Check out this line, it looks like you're missing it!