Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrieljim committed Jun 3, 2022
0 parents commit 3fa9883
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
cache/
artifacts/
package-lock.json
61 changes: 61 additions & 0 deletions contracts/Lottery.sol
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
)
)
);
}
}
7 changes: 7 additions & 0 deletions hardhat.config.js
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",
};
11 changes: 11 additions & 0 deletions package.json
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"
}
}
75 changes: 75 additions & 0 deletions test/Lottery.test.js
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
});
});
});

0 comments on commit 3fa9883

Please sign in to comment.