generated from pooltogether/pooltogether-contracts-template
-
Notifications
You must be signed in to change notification settings - Fork 7
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
Showing
6 changed files
with
381 additions
and
10 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
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,135 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity 0.8.6; | ||
import "@pooltogether/owner-manager-contracts/contracts/Manageable.sol"; | ||
import "./interfaces/IPrizeTierHistory.sol"; | ||
|
||
/** | ||
* @title PoolTogether V4 IPrizeTierHistory | ||
* @author PoolTogether Inc Team | ||
* @notice IPrizeTierHistory is the base contract for PrizeTierHistory | ||
*/ | ||
contract PrizeTierHistory is IPrizeTierHistory, Manageable { | ||
|
||
/* ============ Global Variables ============ */ | ||
/** | ||
* @notice History of PrizeTier updates | ||
*/ | ||
PrizeTier[] internal history; | ||
|
||
/* ============ Constructor ============ */ | ||
constructor(address _owner) Ownable(_owner) {} | ||
|
||
/* ============ External Functions ============ */ | ||
|
||
// @inheritdoc IPrizeTierHistory | ||
function push(PrizeTier calldata _nextPrizeTier) | ||
external | ||
override | ||
onlyManagerOrOwner | ||
returns (uint32) | ||
{ | ||
PrizeTier[] memory _history = history; | ||
|
||
if (_history.length > 0) { | ||
// READ the newest PrizeTier struct | ||
PrizeTier memory _newestPrizeTier = history[history.length - 1]; | ||
// New PrizeTier ID must only be 1 greater than the last PrizeTier ID. | ||
require( | ||
_nextPrizeTier.drawId > _newestPrizeTier.drawId, | ||
"PrizeTierHistory/non-sequential-prize-tier" | ||
); | ||
} | ||
|
||
history.push(_nextPrizeTier); | ||
|
||
emit PrizeTierPushed(_nextPrizeTier.drawId, _nextPrizeTier); | ||
} | ||
|
||
/* ============ Setter Functions ============ */ | ||
|
||
// @inheritdoc IPrizeTierHistory | ||
function setPrizeTier(PrizeTier calldata _prizeTier) external override onlyOwner returns (uint32) { | ||
require(history.length > 0, "PrizeTierHistory/history-empty"); | ||
uint32 _idx = _prizeTier.drawId - history[0].drawId; | ||
history[_idx] = _prizeTier; | ||
emit PrizeTierSet(_prizeTier.drawId, _prizeTier); | ||
} | ||
|
||
/* ============ Getter Functions ============ */ | ||
|
||
// @inheritdoc IPrizeTierHistory | ||
function getPrizeTier(uint32 _drawId) external view override returns (PrizeTier memory) { | ||
require(_drawId > 0, "PrizeTierHistory/draw-id-not-zero"); | ||
return _getPrizeTier(_drawId); | ||
} | ||
// @inheritdoc IPrizeTierHistory | ||
function getOldestDrawId() external view override returns (uint32) { | ||
return history[0].drawId; | ||
} | ||
|
||
// @inheritdoc IPrizeTierHistory | ||
function getNewestDrawId() external view override returns (uint32) { | ||
return history[history.length - 1].drawId; | ||
} | ||
|
||
// @inheritdoc IPrizeTierHistory | ||
function getPrizeTierList(uint32[] calldata _drawIds) | ||
external | ||
view | ||
override | ||
returns (PrizeTier[] memory) | ||
{ | ||
PrizeTier[] memory _data = new PrizeTier[](_drawIds.length) ; | ||
for (uint256 index = 0; index < _drawIds.length; index++) { | ||
_data[index] = _getPrizeTier(_drawIds[index]); // SLOAD each struct instead of the whole array before the FOR loop. | ||
} | ||
return _data; | ||
} | ||
|
||
function _getPrizeTier(uint32 _drawId) internal view returns (PrizeTier memory) { | ||
uint256 cardinality = history.length; | ||
uint256 leftSide = 0; | ||
uint256 rightSide = cardinality - 1; | ||
uint32 oldestDrawId = history[leftSide].drawId; | ||
uint32 newestDrawId = history[rightSide].drawId; | ||
|
||
require(_drawId >= oldestDrawId && _drawId <= newestDrawId, "PrizeTierHistory/draw-id-out-of-range"); | ||
|
||
if (_drawId == newestDrawId) return history[rightSide]; | ||
if (_drawId == oldestDrawId) return history[leftSide]; | ||
|
||
return _binarySearch(_drawId, leftSide, rightSide, history); | ||
} | ||
|
||
|
||
function _binarySearch( | ||
uint32 _drawId, | ||
uint256 leftSide, | ||
uint256 rightSide, | ||
PrizeTier[] storage _history | ||
) internal view returns (PrizeTier memory) { | ||
|
||
while (true) { | ||
uint256 center = leftSide + (rightSide - leftSide) / 2; | ||
uint32 centerPrizeTierID = _history[center].drawId; | ||
|
||
if (centerPrizeTierID == _drawId) { | ||
return _history[center]; | ||
} | ||
|
||
if (centerPrizeTierID < _drawId) { | ||
leftSide = center + 1; | ||
} else if (centerPrizeTierID > _drawId) { | ||
rightSide = center - 1; | ||
} | ||
|
||
if (leftSide == rightSide) { | ||
if (centerPrizeTierID >= _drawId) { | ||
return _history[center - 1]; | ||
} else { | ||
return _history[center]; | ||
} | ||
} | ||
} | ||
} | ||
} |
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,77 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity 0.8.6; | ||
import "@pooltogether/v4-core/contracts/DrawBeacon.sol"; | ||
|
||
/** | ||
* @title PoolTogether V4 IPrizeTierHistory | ||
* @author PoolTogether Inc Team | ||
* @notice IPrizeTierHistory is the base contract for PrizeTierHistory | ||
*/ | ||
interface IPrizeTierHistory { | ||
/** | ||
* @notice Linked Draw and PrizeDistribution parameters storage schema | ||
*/ | ||
struct PrizeTier { | ||
uint8 bitRangeSize; | ||
uint32 drawId; | ||
uint32 maxPicksPerUser; | ||
uint256 prize; | ||
uint32[16] tiers; | ||
uint32 validityDuration; | ||
} | ||
|
||
/** | ||
* @notice Emit when new PrizeTier is added to history | ||
* @param drawId Draw ID | ||
* @param prizeTier PrizeTier parameters | ||
*/ | ||
event PrizeTierPushed(uint32 indexed drawId, PrizeTier prizeTier); | ||
|
||
/** | ||
* @notice Emit when existing PrizeTier is updated in history | ||
* @param drawId Draw ID | ||
* @param prizeTier PrizeTier parameters | ||
*/ | ||
event PrizeTierSet(uint32 indexed drawId, PrizeTier prizeTier); | ||
|
||
/** | ||
* @notice Push PrizeTierHistory struct onto history array. | ||
* @dev Callable only by owner or manager, | ||
* @param drawPrizeDistribution New PrizeTierHistory struct | ||
* @return drawId Draw ID linked to PrizeTierHistory | ||
*/ | ||
function push(PrizeTier calldata drawPrizeDistribution) external returns (uint32 drawId); | ||
|
||
/** | ||
* @notice Read PrizeTierHistory struct from history array. | ||
* @param drawId Draw ID | ||
* @return prizeTier | ||
*/ | ||
function getPrizeTier(uint32 drawId) external view returns (PrizeTier memory prizeTier); | ||
|
||
/** | ||
* @notice Read first Draw ID used to initialize history | ||
* @return Draw ID of first PrizeTier record | ||
*/ | ||
function getOldestDrawId() external view returns (uint32); | ||
|
||
function getNewestDrawId() external view returns (uint32); | ||
|
||
/** | ||
* @notice Read PrizeTierHistory List from history array. | ||
* @param drawIds Draw ID array | ||
* @return prizeTierList | ||
*/ | ||
function getPrizeTierList(uint32[] calldata drawIds) | ||
external | ||
view | ||
returns (PrizeTier[] memory prizeTierList); | ||
|
||
/** | ||
* @notice Push PrizeTierHistory struct onto history array. | ||
* @dev Callable only by owner. | ||
* @param prizeTier Updated PrizeTierHistory struct | ||
* @return drawId Draw ID linked to PrizeTierHistory | ||
*/ | ||
function setPrizeTier(PrizeTier calldata prizeTier) external returns (uint32 drawId); | ||
} |
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
Oops, something went wrong.