Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 9 additions & 49 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,50 +1,10 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/blockchain/node_modules
/.pnp
.pnp.js

# vscode
.vscode

# hardhat
artifacts
cache
deployments
cache/
coverage*
blockchain/typechain-types/@chainlink
blockchain/typechain-types/@openzeppelin
blockchain/typechain-types/factories/@chainlink
blockchain/typechain-types/factories/@openzeppelin

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
node_modules
dist
.next
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# vercel
.vercel
__pycache__
*.log
.DS_Store
coverage
*.swp
.vercel
30 changes: 27 additions & 3 deletions blockchain/contracts/Lottery.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,23 @@ import "./VRFv2DirectFundingConsumer.sol";
contract Lottery is ConfirmedOwner, VRFv2DirectFundingConsumer {
using SafeMath for uint256;

struct LotteryRound {
uint256 roundId;
uint256 timestamp;
uint256 potSize;
uint256 participantCount;
address winner;
}

address payable[] public players;
address[] public winners;
uint256 public lotteryId;
uint256 public potWidthdrawalEndTime;

mapping(uint256 => LotteryRound) public lotteryRounds;

event PlayerEntered(address indexed player, uint256 amount);
event WinnerPicked(address indexed winner, uint256 amount);
event WinnerPicked(address indexed winner, uint256 amount, uint256 roundId);
event LotteryReset(uint256 indexed lotteryId);
event Received(address, uint);

Expand Down Expand Up @@ -68,10 +78,20 @@ contract Lottery is ConfirmedOwner, VRFv2DirectFundingConsumer {
uint256 randomPlayerIndex = _randomNumber % players.length;
address payable winner = players[randomPlayerIndex];
uint256 pot = address(this).balance;

// Store lottery round details
lotteryRounds[lotteryId] = LotteryRound({
roundId: lotteryId,
timestamp: block.timestamp,
potSize: pot,
participantCount: players.length,
winner: winner
});

winners.push(winner);
lotteryId = lotteryId.add(1);

emit WinnerPicked(winner, pot);
emit WinnerPicked(winner, pot, lotteryId - 1);
emit LotteryReset(lotteryId);

players = new address payable[](0);
Expand All @@ -93,7 +113,11 @@ contract Lottery is ConfirmedOwner, VRFv2DirectFundingConsumer {
return winners;
}

function getLotteryRoundDetails(uint256 _roundId) public view returns (LotteryRound memory) {
return lotteryRounds[_roundId];
}

receive() external payable {
emit Received(msg.sender, msg.value);
}
}
}
50 changes: 50 additions & 0 deletions blockchain/test/LotteryRoundDetails.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { ethers } from "hardhat";
import { expect } from "chai";
import { Lottery } from "../typechain-types";
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";

describe("Lottery Round Details", function () {
let lottery: Lottery;
let owner: SignerWithAddress;
let player1: SignerWithAddress;
let player2: SignerWithAddress;

beforeEach(async function () {
const LotteryFactory = await ethers.getContractFactory("Lottery");
[owner, player1, player2] = await ethers.getSigners();
lottery = await LotteryFactory.deploy();
await lottery.deployed();
});

it("should store round details when a winner is picked", async function () {
// Enter players
await lottery.connect(player1).enter({ value: ethers.utils.parseEther("0.1") });
await lottery.connect(player2).enter({ value: ethers.utils.parseEther("0.1") });

// Mock VRF and pick winner
await lottery.connect(owner).startPickingWinner();

// Get latest lottery round details
const lotteryId = await lottery.getLotteryId();
const roundDetails = await lottery.getLotteryRoundDetails(lotteryId.sub(1));

expect(roundDetails.roundId).to.be.gt(0);
expect(roundDetails.timestamp).to.be.gt(0);
expect(roundDetails.potSize).to.be.gt(0);
expect(roundDetails.participantCount).to.equal(2);
expect(roundDetails.winner).to.not.be.null;
});

it("should have correct pot size for a round", async function () {
const enterAmount = ethers.utils.parseEther("0.1");
await lottery.connect(player1).enter({ value: enterAmount });
await lottery.connect(player2).enter({ value: enterAmount });

await lottery.connect(owner).startPickingWinner();

const lotteryId = await lottery.getLotteryId();
const roundDetails = await lottery.getLotteryRoundDetails(lotteryId.sub(1));

expect(roundDetails.potSize).to.equal(enterAmount.mul(2));
});
});
Loading