Skip to content

Commit

Permalink
Merge fad560a into 954c9c1
Browse files Browse the repository at this point in the history
  • Loading branch information
PierrickGT committed May 17, 2022
2 parents 954c9c1 + fad560a commit 4b85138
Show file tree
Hide file tree
Showing 9 changed files with 2,084 additions and 155 deletions.
85 changes: 45 additions & 40 deletions contracts/DrawCalculatorV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {

/// @notice DrawBuffer address
IDrawBuffer public immutable drawBuffer;


/// @notice PrizeConfigHistory address
IPrizeConfigHistory public immutable prizeConfigHistory;

/// @notice The tiers array length
Expand All @@ -44,20 +45,23 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {
* @notice Emitted when the contract is initialized
* @param gaugeController Address of the GaugeController
* @param drawBuffer Address of the DrawBuffer
* @param prizeConfigHistory Address of the PrizeConfigHistory
*/
event Deployed(
IGaugeController indexed gaugeController,
IDrawBuffer indexed drawBuffer
IDrawBuffer indexed drawBuffer,
IPrizeConfigHistory indexed prizeConfigHistory
);

/* ============ Constructor ============ */

/**
* @notice DrawCalculator constructor
* @param _gaugeController Address of the GaugeController
* @param _drawBuffer Address of the draw buffer to push draws to
* @param _drawBuffer Address of the DrawBuffer to push draws to
* @param _prizeConfigHistory Address of the PrizeConfigHistory
* @param _owner Address of the owner
*/
*/
constructor(
IGaugeController _gaugeController,
IDrawBuffer _drawBuffer,
Expand All @@ -66,13 +70,14 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {
) Ownable(_owner) {
require(address(_gaugeController) != address(0), "DrawCalc/GC-not-zero-address");
require(address(_drawBuffer) != address(0), "DrawCalc/DB-not-zero-address");
require(address(_prizeConfigHistory) != address(0), "DrawCalc/PCH-not-zero-address");
require(_owner != address(0), "DrawCalc/owner-not-zero-address");

gaugeController = _gaugeController;
drawBuffer = _drawBuffer;
prizeConfigHistory = _prizeConfigHistory;

emit Deployed(_gaugeController, _drawBuffer);
emit Deployed(_gaugeController, _drawBuffer, _prizeConfigHistory);
}

/* ============ External Functions ============ */
Expand All @@ -92,7 +97,6 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {

return _calculatePrizesAwardable(
_ticket,
prizeConfigHistory,
_user,
_userRandomNumber,
_drawIds,
Expand All @@ -103,7 +107,6 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {
/// @inheritdoc IDrawCalculatorV3
function calculateUserPicks(
ITicket _ticket,
IPrizeConfigHistory _prizeConfigHistory,
address _user,
uint32[] calldata _drawIds
) external view override returns (uint64[] memory picks) {
Expand All @@ -113,7 +116,7 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {

for (uint32 _drawIndex = 0; _drawIndex < _drawsLength; _drawIndex++) {
IDrawBeacon.Draw memory _draw = _draws[_drawIndex];
IPrizeConfigHistory.PrizeConfig memory _prizeConfig = _prizeConfigHistory.getPrizeConfig(_draw.drawId);
IPrizeConfigHistory.PrizeConfig memory _prizeConfig = prizeConfigHistory.getPrizeConfig(_draw.drawId);

_requireDrawUnexpired(_draw, _prizeConfig);

Expand Down Expand Up @@ -141,6 +144,11 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {
return gaugeController;
}

/// @inheritdoc IDrawCalculatorV3
function getPrizeConfigHistory() external override view returns (IPrizeConfigHistory) {
return prizeConfigHistory;
}

/// @inheritdoc IDrawCalculatorV3
function getTotalPicks(
ITicket _ticket,
Expand All @@ -158,7 +166,7 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {
/**
* @notice Ensure that the draw is not expired.
* @param _draw Draw
* @param _prizeConfig Prize tier
* @param _prizeConfig PrizeConfig
*/
function _requireDrawUnexpired(
IDrawBeacon.Draw memory _draw,
Expand All @@ -170,15 +178,13 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {
/**
* @notice Calculates the prizes awardable for each DrawIds passed.
* @param _ticket Address of the ticket to calculate awardable prizes for
* @param _prizeConfigHistory Address of the prizeConfigHistory associated with the ticket
* @param _user Address of the user for which to calculate awardable prizes for
* @param _userRandomNumber Random number of the user to consider over draws
* @param _drawIds Array of DrawIds for which to calculate awardable prizes for
* @param _pickIndicesForDraws Pick indices for each Draw
*/
function _calculatePrizesAwardable(
ITicket _ticket,
IPrizeConfigHistory _prizeConfigHistory,
address _user,
bytes32 _userRandomNumber,
uint32[] memory _drawIds,
Expand All @@ -193,7 +199,7 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {
// Calculate prizes awardable for each Draw passed
for (uint32 _drawIndex = 0; _drawIndex < _draws.length; _drawIndex++) {
IDrawBeacon.Draw memory _draw = _draws[_drawIndex];
IPrizeConfigHistory.PrizeConfig memory _prizeConfig = _prizeConfigHistory.getPrizeConfig(_draw.drawId);
IPrizeConfigHistory.PrizeConfig memory _prizeConfig = prizeConfigHistory.getPrizeConfig(_draw.drawId);

_requireDrawUnexpired(_draw, _prizeConfig);

Expand Down Expand Up @@ -221,15 +227,15 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {
}

/**
* @notice Calculates the number of picks a user gets for a Draw, considering the normalized user balance and the PrizeDistribution.
* @dev Divided by 1e18 since the normalized user balance is stored as a fixed point 18 number.
* @param _ticket Address of the ticket to get total picks for
* @param _startTimestamp Timestamp at which the prize starts
* @param _endTimestamp Timestamp at which the prize ends
* @param _poolStakeCeiling Globally configured pool stake ceiling
* @param _bitRange Number of bits allocated to each division
* @param _cardinality Number of sub-divisions of a random number
* @return Number of picks a user gets for a Draw
* @notice Calculates the number of picks a user gets for a Draw, considering the normalized user balance and the PrizeConfig.
* @dev Divided by 1e18 since the normalized user balance is stored as a fixed point 18 number.
* @param _ticket Address of the ticket to get total picks for
* @param _startTimestamp Timestamp at which the prize starts
* @param _endTimestamp Timestamp at which the prize ends
* @param _poolStakeCeiling Globally configured pool stake ceiling
* @param _bitRange Number of bits allocated to each division
* @param _cardinality Number of sub-divisions of a random number
* @return Number of picks a user gets for a Draw
*/
function _calculateUserPicks(
ITicket _ticket,
Expand All @@ -242,7 +248,6 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {
) internal view returns (uint64) {
uint256 _numberOfPicks = _getTotalPicks(_ticket, _startTimestamp, _endTimestamp, _poolStakeCeiling, _bitRange, _cardinality);
uint256 _normalizedBalance = _getNormalizedBalanceAt(_ticket, _user, _startTimestamp, _endTimestamp);

return uint64((_normalizedBalance * _numberOfPicks) / 1 ether);
}

Expand Down Expand Up @@ -310,12 +315,12 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {
}

/**
* @notice Calculates the prize amount for a PrizeDistribution over given picks
* @param _winningRandomNumber Draw's winningRandomNumber
* @param _totalUserPicks number of picks the user gets for the Draw
* @param _userRandomNumber users randomNumber for that draw
* @param _picks users picks for that draw
* @param _prizeConfig PrizeConfig for that draw
* @notice Calculates the prize amount for a PrizeConfig over given picks
* @param _winningRandomNumber Draw's winningRandomNumber
* @param _totalUserPicks Number of picks the user gets for the Draw
* @param _userRandomNumber User randomNumber for that draw
* @param _picks User picks for that draw
* @param _prizeConfig PrizeConfig for that draw
* @return prize (if any), prizeCounts (if any)
*/
function _calculate(
Expand All @@ -325,7 +330,7 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {
uint64[] memory _picks,
IPrizeConfigHistory.PrizeConfig memory _prizeConfig
) internal pure returns (uint256 prize, uint256[] memory prizeCounts) {
// Create bitmasks for the PrizeDistribution
// Create bitmasks for the PrizeConfig
uint256[] memory masks = _createBitMasks(_prizeConfig.matchCardinality, _prizeConfig.bitRangeSize);
uint32 picksLength = uint32(_picks.length);
uint256[] memory _prizeCounts = new uint256[](_prizeConfig.tiers.length);
Expand All @@ -337,7 +342,7 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {
"DrawCalc/exceeds-max-user-picks"
);

// for each pick, find number of matching numbers and calculate prize distributions index
// for each pick, find number of matching numbers and calculate prize configs index
for (uint32 index = 0; index < picksLength; index++) {
require(_picks[index] < _totalUserPicks, "DrawCalc/insufficient-user-picks");

Expand Down Expand Up @@ -399,11 +404,11 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {
}

/**
* @notice Calculates the tier index given the random numbers and masks
* @param _randomNumberThisPick User random number for this Pick
* @param _winningRandomNumber The winning number for this draw
* @param _masks The pre-calculated bitmasks for the prizeDistributions
* @return The position within the prize tier array (0 = top prize, 1 = runner-up prize, etc)
* @notice Calculates the tier index given the random numbers and masks
* @param _randomNumberThisPick User random number for this Pick
* @param _winningRandomNumber The winning number for this draw
* @param _masks The pre-calculated bitmasks for the PrizeConfig
* @return The position within the prize tier array (0 = top prize, 1 = runner-up prize, etc)
*/
function _calculateTierIndex(
uint256 _randomNumberThisPick,
Expand Down Expand Up @@ -434,7 +439,7 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {
}

/**
* @notice Creates an array of bitmasks equal to the PrizeDistribution.matchCardinality length
* @notice Creates an array of bitmasks equal to the PrizeConfig.matchCardinality length
* @param _matchCardinality Match cardinality for Draw
* @param _bitRangeSize Bit range size for Draw
* @return Array of bitmasks
Expand All @@ -456,8 +461,8 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {
}

/**
* @notice Calculates the expected prize fraction per PrizeDistributions and distributionIndex
* @param _prizeFraction Prize fraction for this PrizeDistribution
* @notice Calculates the expected prize fraction per PrizeConfig and prize tiers index
* @param _prizeFraction Prize fraction for this PrizeConfig
* @param _bitRangeSize Bit range size for Draw
* @param _prizeConfigIndex Index of the prize tiers array to calculate
* @return returns the fraction of the total prize (fixed point 9 number)
Expand All @@ -477,9 +482,9 @@ contract DrawCalculatorV3 is IDrawCalculatorV3, Manageable {
}

/**
* @notice Calculates the number of prizes for a given prizeDistributionIndex
* @notice Calculates the number of prizes for a given PrizeConfigIndex
* @param _bitRangeSize Bit range size for Draw
* @param _prizeConfigIndex Index of the prize config array to calculate
* @param _prizeConfigIndex Index of the PrizeConfig array to calculate
* @return returns the fraction of the total prize (base 1e18)
*/
function _numberOfPrizesForIndex(uint8 _bitRangeSize, uint256 _prizeConfigIndex)
Expand Down
9 changes: 4 additions & 5 deletions contracts/PrizeConfigHistory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -147,17 +147,16 @@ contract PrizeConfigHistory is IPrizeConfigHistory, Manageable {
* @param _prizeConfig New PrizeConfig struct to push onto history array
*/
function _push(PrizeConfig memory _prizeConfig) internal {
uint32 _historyLength = uint32(history.length);
uint256 _historyLength = history.length;

if (_historyLength > 0) {
// TODO: Check if cheaper in gas to only cast to uint32 below
uint32 _id = history[_historyLength - 1];
uint256 _id = history[uint32(_historyLength - 1)];

require(_prizeConfig.drawId > _id, "PrizeConfHistory/nonsequentialId");
require(_prizeConfig.drawId > uint32(_id), "PrizeConfHistory/nonsequentialId");
}

history.push(_prizeConfig.drawId);
prizeConfigs[_historyLength] = _prizeConfig;
prizeConfigs[uint32(_historyLength)] = _prizeConfig;

emit PrizeConfigPushed(_prizeConfig.drawId, _prizeConfig);
}
Expand Down
8 changes: 6 additions & 2 deletions contracts/interfaces/IDrawCalculatorV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,11 @@ interface IDrawCalculatorV3 {
/**
* @notice Calculates picks for a user for Multiple Draws.
* @param ticket Address of the ticket to calculate picks for
* @param prizeConfigHistory Address of the prizeConfigHistory associated with the ticket
* @param user Address of the user for which to calculate picks for
* @param drawIds Array of DrawIds for which to calculate picks for
*/
function calculateUserPicks(
ITicket ticket,
IPrizeConfigHistory prizeConfigHistory,
address user,
uint32[] calldata drawIds
) external view returns (uint64[] memory);
Expand All @@ -55,6 +53,12 @@ interface IDrawCalculatorV3 {
*/
function getGaugeController() external view returns (IGaugeController);

/**
* @notice Returns PrizeConfigHistory address.
* @return The PrizeConfigHistory address
*/
function getPrizeConfigHistory() external view returns (IPrizeConfigHistory);

/**
* @notice Returns the total number of picks for a prize pool / ticket.
* @param ticket Address of the ticket to get total picks for
Expand Down
Loading

0 comments on commit 4b85138

Please sign in to comment.