Skip to content

Commit

Permalink
chore(docs): add developer documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
ankurdaharwal committed Jun 5, 2021
1 parent bd6ad46 commit 1385bbd
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 14 deletions.
34 changes: 31 additions & 3 deletions contracts/Lottery.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "./RandomNumberGenerator.sol";

/// @title Lottery smart contract (consumes ChainLink VRF)
/// @author Ankur Daharwal (https://github.com/ankurdaharwal)
/// @notice Ownable Lottery smart contract that announces a lucky draw winner
/// @dev Uses a random number generator based on a VRFConsumerBase contract (https://docs.chain.link/docs/get-a-random-number/)
contract Lottery is Ownable {

using EnumerableSet for EnumerableSet.AddressSet;
Expand All @@ -27,9 +31,19 @@ contract Lottery is Ownable {
address randomNumberGenerator;
bytes32 randomNumberRequestId;

/// @notice Lottery state event emitter
/// @param newState possible states are: Open, Closed or Finished
event LotteryStateChanged(LotteryState newState);
/// @notice New entry event emitter
/// @param player lottery participant's address
/// @param number participant's lottery ticket number
event NewEntry(address player, uint number);
/// @notice Number request event emitter
/// @param requestId request a random number using the RandomNumberGenerator
event NumberRequested(bytes32 requestId);
/// @notice Number drawn event emitter
/// @param requestId unique request identifier
/// @param winningNumber lucky draw winning ticket number
event NumberDrawn(bytes32 requestId, uint winningNumber);

// modifiers
Expand All @@ -39,11 +53,14 @@ contract Lottery is Ownable {
}

modifier onlyRandomGenerator {
require(msg.sender == randomNumberGenerator, "Must be correct generator");
require(msg.sender == randomNumberGenerator, "Must be called by a random number generator");
_;
}

//constructor
/// @dev Lottery contract constuctor
/// @param _entryFee Participant's minimum entry fee
/// @param _ownerCut Owner's fee for organizing the Lottery
/// @param _randomNumberGenerator Random Number Generator contract address (Inherits VRF Consumer)
constructor (uint _entryFee, uint _ownerCut, address _randomNumberGenerator) Ownable() {
require(_entryFee > 0, "Entry fee must be greater than 0");
require(_ownerCut < _entryFee, "Entry fee must be greater than owner cut");
Expand All @@ -55,7 +72,8 @@ contract Lottery is Ownable {
_changeState(LotteryState.Open);
}

//functions
/// @dev Participant submits a ticket number to participate in the lottery
/// @param _number Participant's unique ticket number
function submitNumber(uint _number) public payable isState(LotteryState.Open) {
require(msg.value >= entryFee, "Minimum entry fee required");
require(entries[_number].add(msg.sender), "Cannot submit the same number more than once");
Expand All @@ -65,16 +83,22 @@ contract Lottery is Ownable {
emit NewEntry(msg.sender, _number);
}

/// @dev Draws a random number
function drawNumber() public onlyOwner isState(LotteryState.Open) {
_changeState(LotteryState.Closed);
randomNumberRequestId = RandomNumberGenerator(randomNumberGenerator).request();
emit NumberRequested(randomNumberRequestId);
}

/// @dev Resets the lottery
function rollover() public onlyOwner isState(LotteryState.Finished) {
//rollover new lottery
_changeState(LotteryState.Open);
}

/// @dev Winning ticket number is drawn to announce the winner and lottery comes to an end
/// @param _randomNumberRequestId Unique random number request identifier
/// @param _randomNumber Winning ticket number can be drawn only by the RandomNumberGenerator contract
function numberDrawn(bytes32 _randomNumberRequestId, uint _randomNumber) public onlyRandomGenerator isState(LotteryState.Closed) {
if (_randomNumberRequestId == randomNumberRequestId) {
winningNumber = _randomNumber;
Expand All @@ -84,13 +108,17 @@ contract Lottery is Ownable {
}
}

/// @dev Awards the lottery winners with the winning amounts
/// @param winners Address set of all the winners of the lottery
function _payout(EnumerableSet.AddressSet storage winners) private {
uint balance = address(this).balance;
for (uint index = 0; index < winners.length(); index++) {
payable(winners.at(index)).transfer(balance.div(winners.length()));
}
}

/// @dev Change the lottery's current state
/// @param _newState Changes the state of the lottery
function _changeState(LotteryState _newState) private {
state = _newState;
emit LotteryStateChanged(state);
Expand Down
13 changes: 13 additions & 0 deletions contracts/RandomNumberGenerator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ import "./interfaces/LinkTokenInterface.sol";
import "./VRFConsumerBase.sol";
import "./Lottery.sol";

/// @title Random Number Generator
/// @author Ankur Daharwal (https://github.com/ankurdaharwal)
/// @notice Generates a random number based on the ChainLink VRF consumer implementation (https://docs.chain.link/docs/get-a-random-number/)
/// @dev Inherits VRFConsumerBase (ChainLink VRF)

// Reference ChainLink VRF: https://docs.chain.link/docs/get-a-random-number/

contract RandomNumberGenerator is VRFConsumerBase {

address requester;
Expand All @@ -19,10 +26,16 @@ contract RandomNumberGenerator is VRFConsumerBase {
fee = _fee;
}

/// @dev Fulfills a verifiable random number request and overrides the VRFConsumerBase parent contract function `fulfillRandomness`
/// @param _requestId Unique request identifier
/// @param _randomness Verifiable random number
function fulfillRandomness(bytes32 _requestId, uint256 _randomness) internal override {
Lottery(requester).numberDrawn(_requestId, _randomness);
}

/// @dev Requests a new verifiable random number
/// @return requestId
/// @param requestId Returns the unique requested random number identifier
function request() public returns(bytes32 requestId) {
require(keyHash != bytes32(0), "Must have valid key hash");
requester = msg.sender;
Expand Down
15 changes: 4 additions & 11 deletions scripts/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,13 @@ const main = async () => {
);

/**
* deploy StMaster and link
* - CcyLib
* - TokenLib
* - LedgerLib
* - TransferLib
* - SpotFeeLib
* - Erc20Lib
* - LoadLib
* deploy Lottery contract
*/

console.log(`\nDeploying ${chalk.yellowBright.bold(`Lottery`)}
Player entry fee : ${chalk.magenta(entryFee)}
Owner fee : ${chalk.magenta(ownerFee)}
VRF consumer address : ${chalk.magenta(randomNumberGenerator.address)}
Player entry fee : ${chalk.magenta(entryFee)}
Owner fee : ${chalk.magenta(ownerFee)}
Random Number Generator : ${chalk.magenta(randomNumberGenerator.address)}
`);

const Lottery = await hre.ethers.getContractFactory("Lottery");
Expand Down

0 comments on commit 1385bbd

Please sign in to comment.