-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 3fa9883
Showing
5 changed files
with
158 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
node_modules/ | ||
cache/ | ||
artifacts/ | ||
package-lock.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
//SPDX-License-Identifier: GPL-3.0 | ||
|
||
pragma solidity ^0.8.13; | ||
import "hardhat/console.sol"; | ||
|
||
contract Lottery { | ||
// declaring the state variables | ||
address[] public players; //dynamic array of type address payable | ||
address[] public gameWinners; | ||
address public owner; | ||
|
||
// declaring the constructor | ||
constructor() { | ||
// TODO: initialize the owner to the address that deploys the contract | ||
} | ||
|
||
// declaring the receive() function that is necessary to receive ETH | ||
receive() external payable { | ||
// TODO: require each player to send exactly 0.1 ETH | ||
// TODO: append the new player to the players array | ||
} | ||
|
||
// returning the contract's balance in wei | ||
function getBalance() public view returns (uint256) { | ||
// TODO: restrict this function so only the owner is allowed to call it | ||
// TODO: return the balance of this address | ||
} | ||
|
||
// selecting the winner | ||
function pickWinner() public { | ||
// TODO: only the owner can pick a winner | ||
// TODO: owner can only pick a winner if there are at least 3 players in the lottery | ||
|
||
uint256 r = random(); | ||
address winner; | ||
|
||
// TODO: compute an unsafe random index of the array and assign it to the winner variable | ||
|
||
// TODO: append the winner to the gameWinners array | ||
|
||
// TODO: transfer the entire contract's balance to the winner | ||
|
||
// TODO: reset the lottery for the next round | ||
} | ||
|
||
// helper function that returns a big random integer | ||
// UNSAFE! Don't trust random numbers generated on-chain, they can be exploited! This method is used here for simplicity | ||
// See: https://solidity-by-example.org/hacks/randomness | ||
function random() internal view returns (uint256) { | ||
return | ||
uint256( | ||
keccak256( | ||
abi.encodePacked( | ||
block.difficulty, | ||
block.timestamp, | ||
players.length | ||
) | ||
) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
require("@nomiclabs/hardhat-waffle"); | ||
/** | ||
* @type import('hardhat/config').HardhatUserConfig | ||
*/ | ||
module.exports = { | ||
solidity: "0.8.13", | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"name": "hardhat-project", | ||
"devDependencies": { | ||
"@nomiclabs/hardhat-ethers": "^2.0.6", | ||
"@nomiclabs/hardhat-waffle": "^2.0.3", | ||
"chai": "^4.3.6", | ||
"ethereum-waffle": "^3.4.4", | ||
"ethers": "^5.6.5", | ||
"hardhat": "^2.9.4" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
const { expect, assert } = require("chai"); | ||
const { BigNumber } = require("ethers"); | ||
const { parseEther, formatEther } = require("ethers/lib/utils"); | ||
const { ethers, waffle } = require("hardhat"); | ||
|
||
describe("Lottery Contract", function () { | ||
// Declaring outside of the tests to have access inside them | ||
let owner, addr1, addr2, lottery; | ||
let provider = waffle.provider; | ||
|
||
beforeEach(async () => { | ||
[owner, addr1, addr2, ...addrs] = await ethers.getSigners(); | ||
const Lottery = await ethers.getContractFactory("Lottery"); | ||
|
||
// Hardhat always deploys with the first address from getSigners(), but we'll be explicit here | ||
lottery = await Lottery.connect(owner).deploy(); | ||
}); | ||
|
||
describe("Only owner", () => { | ||
it("Only owner can pick a winner", async () => { | ||
await expect(lottery.connect(addr1).pickWinner()).to.be.revertedWith( | ||
"ONLY_OWNER" | ||
); | ||
}); | ||
|
||
it("Only owner can call getBalance", async () => { | ||
// Delete this line | ||
assert.fail(); | ||
}); | ||
}); | ||
|
||
describe("Playing", () => { | ||
it("Reverts if not exactly 0.1 ETH", async () => { | ||
// Delete this line | ||
assert.fail(); | ||
}); | ||
|
||
it("Allows a player to enter", async () => { | ||
await addr1.sendTransaction({ | ||
to: lottery.address, | ||
// parseEther("0.1") will return "100000000000000000" (which is the equivalent in wei) | ||
value: parseEther("0.1"), | ||
}); | ||
|
||
// TODO: Check if the contract's balance increased | ||
let newBalance; | ||
expect(newBalance).to.be.equal(parseEther("0.1")); | ||
|
||
// TODO: Check if the winner got added to the winners array | ||
// Public getters generated for arrays require an index to be passed, so check the 0 index (where this new player should be) | ||
let newPlayer; | ||
expect(newPlayer).to.be.equal(addr1.address); | ||
}); | ||
|
||
it("Can't pick a winner if less than 4 players", async () => { | ||
// Delete this line | ||
assert.fail(); | ||
}); | ||
|
||
it("Can pick a winner and winner gets paid", async () => { | ||
// Make 4 players enter the game | ||
for (let i = 0; i < 4; i++) {} | ||
|
||
await lottery.pickWinner(); | ||
|
||
// TODO: Get the lottery winner | ||
let winner; | ||
|
||
// TODO: Check if the winner is one of the 4 players | ||
|
||
const winnerBalance = await provider.getBalance(winner); | ||
// TODO: With hardhat, by default, all test signers have 10000 ETH, so check if the winner has more than that | ||
}); | ||
}); | ||
}); |