Skip to content
Permalink
Browse files

addressed openzeppelin audit comments excluding changing the tests

  • Loading branch information...
jachai committed Jul 16, 2019
1 parent 1f9c2a4 commit 9ab4ec461759c4a5753f25a45d45d5c1a55c3ad2
@@ -22,7 +22,7 @@ Use node version v8.11.1
$ npm install --global zos
# Install Ganache-cli globally:
$ npm install --global ganache-cli
$ npm install --global ganache-cli@v6.4.1
# Install Truffle globally:
$ npm install --global truffle@v4.1.12
@@ -50,7 +50,8 @@ $ npm run ganache-cli
# Run contracts test suite
$ npm run test
# If fails to bind due to mismatch versions run directly:
$ NODE_ENV=test truffle test ./test/propstoken.test.js --network test
$ NODE_ENV=test truffle test ./test/propstoken-0-rewards.test.js --network test
$ NODE_ENV=test truffle test ./test/propstoken-1-main.test.js --network test
```

### [Test Coverage](https://htmlpreview.github.io/?https://raw.githubusercontent.com/propsproject/props-token-distribution/feature/rewards-contracts/coverage/token/index.html)
@@ -116,7 +116,7 @@ contract PropsRewards is Initializable, ERC20 {
/**
* @dev Set new applications list
* @param _rewardsDay uint256 the rewards day from which this change should take effect
* @param _applications address[] array of validators
* @param _applications address[] array of applications
*/
function setApplications(uint256 _rewardsDay, address[] _applications)
public
@@ -158,19 +158,19 @@ contract PropsRewards is Initializable, ERC20 {
returns (bool)
{
// if submission is for a new day check if previous day validator rewards were given if not give to participating ones
if (_rewardsDay > 0 && (_rewardsDay > rewardsLibData.dailyRewards.lastRewardsDay)) {
if (_rewardsDay > rewardsLibData.dailyRewards.lastApplicationsRewardsDay) {
uint256 previousDayValidatorRewardsAmount = PropsRewardsLib.calculateValidatorRewards(
rewardsLibData,
rewardsLibData.dailyRewards.lastRewardsDay,
rewardsLibData.dailyRewards.lastApplicationsRewardsDay,
rewardsLibData.dailyRewards.lastConfirmedRewardsHash,
false
);
if (previousDayValidatorRewardsAmount > 0) {
_mintDailyRewardsForValidators(rewardsLibData.dailyRewards.lastRewardsDay, rewardsLibData.dailyRewards.lastConfirmedRewardsHash, previousDayValidatorRewardsAmount);
_mintDailyRewardsForValidators(rewardsLibData.dailyRewards.lastApplicationsRewardsDay, rewardsLibData.dailyRewards.lastConfirmedRewardsHash, previousDayValidatorRewardsAmount);
}
}
// check and give application rewards if majority of validators agree
uint256 appRewardsSum = PropsRewardsLib.calculateApplicationRewards(
uint256 appRewardsSum = PropsRewardsLib.calculateAndFinalizeApplicationRewards(
rewardsLibData,
_rewardsDay,
_rewardsHash,
@@ -208,6 +208,7 @@ contract PropsRewards is Initializable, ERC20 {
onlyController
returns (bool)
{
require(_controller != address(0), "Controller cannot be the zero address");
controller = _controller;
emit ControllerUpdated
(
@@ -305,7 +306,7 @@ contract PropsRewards is Initializable, ERC20 {
PropsRewardsLib.updateParameter(rewardsLibData, PropsRewardsLib.ParameterName.ValidatorRewardsPercent, 1829, 0);

// max total supply is 1,000,000,000 PROPS specified in AttoPROPS
rewardsLibData.maxTotalSupply = maxTotalSupply = 1 * 1e9 * (10 ** uint256(_decimals));
rewardsLibData.maxTotalSupply = maxTotalSupply = 1 * 1e9 * (10 ** _decimals);
rewardsLibData.rewardsStartTimestamp = rewardsStartTimestamp = _rewardsStartTimestamp;
rewardsLibData.minSecondsBetweenDays = _minSecondsBetweenDays;

@@ -324,7 +325,7 @@ contract PropsRewards is Initializable, ERC20 {
for (uint256 i = 0; i < validatorsCount; i++) {
_mint(rewardsLibData.validators[rewardsLibData.dailyRewards.submissions[_rewardsHash].validatorsList[i]].rewardsAddress,_amount);
}
PropsRewardsLib._resetDailyRewards(rewardsLibData);
PropsRewardsLib._resetDailyRewards(rewardsLibData, _rewardsHash);
emit DailyRewardsValidatorsMinted(
_rewardsDay,
_rewardsHash,
@@ -50,14 +50,14 @@ library PropsRewardsLib {
bytes32[] submittedRewardsHashes;
uint256 totalSupply;
bytes32 lastConfirmedRewardsHash;
uint256 lastRewardsDay;
uint256 lastApplicationsRewardsDay;
}

struct Submission {
mapping (address => bool) validators;
address[] validatorsList;
uint256 confirmations;
uint256 finalized;
uint256 finalizedStatus; // 0 - initialized, 1 - finalized
bool isInitializedState; // A way to check if there's something in the map and whether it is already added to the list
}

@@ -81,12 +81,12 @@ library PropsRewardsLib {
uint256 minSecondsBetweenDays;
uint256 rewardsStartTimestamp;
uint256 maxTotalSupply;
uint256 lastRewardsDay;
uint256 lastValidatorsRewardsDay;
}
/*
* Modifiers
*/
modifier onlyOneRewardsHashPerValidator(Data storage _self, bytes32 _rewardsHash) {
modifier onlyOneConfirmationPerValidatorPerRewardsHash(Data storage _self, bytes32 _rewardsHash) {
require(
!_self.dailyRewards.submissions[_rewardsHash].validators[msg.sender],
"Must be one submission per validator"
@@ -115,7 +115,7 @@ library PropsRewardsLib {
}

modifier onlySelectedValidators(Data storage _self, uint256 _rewardsDay) {
if (_getSelectedRewardedEntityListType(_self.selectedValidators, _rewardsDay) == 0) {
if (!_usePreviousSelectedRewardsEntityList(_self.selectedValidators, _rewardsDay)) {
require (
_self.selectedValidators.current[msg.sender],
"Must be a current selected validator"
@@ -131,7 +131,7 @@ library PropsRewardsLib {

modifier onlyValidRewardsDay(Data storage _self, uint256 _rewardsDay) {
require(
_currentRewardsDay(_self) > _rewardsDay && _rewardsDay > _self.lastRewardsDay,
_currentRewardsDay(_self) > _rewardsDay && _rewardsDay > _self.lastValidatorsRewardsDay,
"Must be for a previous day but after the last rewards day"
);
_;
@@ -172,7 +172,7 @@ library PropsRewardsLib {
returns (uint256)
{
uint256 numOfValidators;
if (_self.dailyRewards.submissions[_rewardsHash].finalized == 1)
if (_self.dailyRewards.submissions[_rewardsHash].finalizedStatus == 1)
{
if (_allValidators) {
numOfValidators = _requiredValidatorsForValidatorsRewards(_self, _rewardsDay);
@@ -195,7 +195,7 @@ library PropsRewardsLib {
* @param _amounts uint256[] array of amounts each app should get
* @param _currentTotalSupply uint256 current total supply
*/
function calculateApplicationRewards(
function calculateAndFinalizeApplicationRewards(
Data storage _self,
uint256 _rewardsDay,
bytes32 _rewardsHash,
@@ -205,12 +205,12 @@ library PropsRewardsLib {
)
public
onlyValidRewardsDay(_self, _rewardsDay)
onlyOneRewardsHashPerValidator(_self, _rewardsHash)
onlyOneConfirmationPerValidatorPerRewardsHash(_self, _rewardsHash)
onlySelectedValidators(_self, _rewardsDay)
returns (uint256)
{
require(
_rewardsHashIsValid(_rewardsDay, _rewardsHash, _applications, _amounts),
_rewardsHashIsValid(_self, _rewardsDay, _rewardsHash, _applications, _amounts),
"Rewards Hash is invalid"
);
if (!_self.dailyRewards.submissions[_rewardsHash].isInitializedState) {
@@ -242,13 +242,11 @@ library PropsRewardsLib {
*/
function _finalizeDailyApplicationRewards(Data storage _self, uint256 _rewardsDay, bytes32 _rewardsHash, uint256 _currentTotalSupply)
public
returns (bool)
{
_self.dailyRewards.totalSupply = _currentTotalSupply;
_self.dailyRewards.lastConfirmedRewardsHash = _rewardsHash;
_self.dailyRewards.lastRewardsDay = _rewardsDay;
_self.dailyRewards.submissions[_rewardsHash].finalized = 1;
return true;
_self.dailyRewards.lastApplicationsRewardsDay = _rewardsDay;
_self.dailyRewards.submissions[_rewardsHash].finalizedStatus = 1;
}

/**
@@ -447,13 +445,13 @@ library PropsRewardsLib {
returns (address[])
{
if (_entityType == RewardedEntityType.Application) {
if (_getSelectedRewardedEntityListType(_self.selectedApplications, _rewardsDay) == 0) {
if (!_usePreviousSelectedRewardsEntityList(_self.selectedApplications, _rewardsDay)) {
return _self.selectedApplications.currentList;
} else {
return _self.selectedApplications.previousList;
}
} else {
if (_getSelectedRewardedEntityListType(_self.selectedValidators, _rewardsDay) == 0) {
if (!_usePreviousSelectedRewardsEntityList(_self.selectedValidators, _rewardsDay)) {
return _self.selectedValidators.currentList;
} else {
return _self.selectedValidators.previousList;
@@ -462,19 +460,19 @@ library PropsRewardsLib {
}

/**
* @dev Get which entity list to use. Current = 0, previous = 1
* @dev Get which entity list to use. If true use previous if false use current
* @param _rewardedEntitylist RewardedEntityList pointer to storage
* @param _rewardsDay uint256 the rewards day to determine which list to get
*/
function _getSelectedRewardedEntityListType(RewardedEntityList _rewardedEntitylist, uint256 _rewardsDay)
function _usePreviousSelectedRewardsEntityList(RewardedEntityList _rewardedEntitylist, uint256 _rewardsDay)
internal
pure
returns (uint256)
returns (bool)
{
if (_rewardsDay >= _rewardedEntitylist.rewardsDay) {
return 0;
return false;
} else {
return 1;
return true;
}
}

@@ -554,18 +552,34 @@ library PropsRewardsLib {
* @param _amounts uint256[] array of amounts each app should get
*/
function _rewardsHashIsValid(
Data storage _self,
uint256 _rewardsDay,
bytes32 _rewardsHash,
address[] _applications,
uint256[] _amounts
)
public
pure
view
returns (bool)
{
bool nonActiveApplication = false;
if (!_usePreviousSelectedRewardsEntityList(_self.selectedApplications, _rewardsDay)) {
for (uint256 i = 0; i < _applications.length; i++) {
if (!_self.selectedApplications.current[_applications[i]]) {
nonActiveApplication = true;
}
}
} else {
for (uint256 j = 0; j < _applications.length; i++) {
if (!_self.selectedApplications.previous[_applications[i]]) {
nonActiveApplication = true;
}
}
}
return
_applications.length > 0 &&
_applications.length == _amounts.length &&
!nonActiveApplication &&
keccak256(abi.encodePacked(_rewardsDay, _applications.length, _amounts.length, _applications, _amounts)) == _rewardsHash;
}

@@ -579,7 +593,7 @@ library PropsRewardsLib {
view
returns (uint256)
{
if (_getSelectedRewardedEntityListType(_self.selectedValidators, _rewardsDay) == 0) {
if (!_usePreviousSelectedRewardsEntityList(_self.selectedValidators, _rewardsDay)) {
return _self.selectedValidators.currentList.length;
} else {
return _self.selectedValidators.previousList.length;
@@ -596,7 +610,7 @@ library PropsRewardsLib {
view
returns (uint256)
{
if (_getSelectedRewardedEntityListType(_self.selectedValidators, _rewardsDay) == 0) {
if (!_usePreviousSelectedRewardsEntityList(_self.selectedValidators, _rewardsDay)) {
return ((_self.selectedValidators.currentList.length.mul(getParameterValue(_self, ParameterName.ValidatorMajorityPercent, _rewardsDay))).div(1e8)).add(1);
} else {
return ((_self.selectedValidators.previousList.length.mul(getParameterValue(_self, ParameterName.ValidatorMajorityPercent, _rewardsDay))).div(1e8)).add(1);
@@ -713,26 +727,24 @@ library PropsRewardsLib {
/**
* @dev Deletes rewards day submission data
* @param _self Data pointer to storage
* @param _rewardsHash bytes32 rewardsHash
*/
function _resetDailyRewards(
Data storage _self
Data storage _self,
bytes32 _rewardsHash
)
public
returns (bool)
{
_self.lastRewardsDay = _self.dailyRewards.lastRewardsDay;
bytes32[] memory rewardsHashes = _self.dailyRewards.submittedRewardsHashes;
for (uint256 i = 0; i < rewardsHashes.length; i++) {
for (uint256 j = 0; j < _self.dailyRewards.submissions[rewardsHashes[i]].validatorsList.length; j++) {
delete(
_self.dailyRewards.submissions[rewardsHashes[i]].validators[_self.dailyRewards.submissions[rewardsHashes[i]].validatorsList[j]]
);
}
delete _self.dailyRewards.submissions[rewardsHashes[i]].validatorsList;
_self.dailyRewards.submissions[rewardsHashes[i]].confirmations = 0;
_self.dailyRewards.submissions[rewardsHashes[i]].finalized = 0;
_self.dailyRewards.submissions[rewardsHashes[i]].isInitializedState = false;
_self.lastValidatorsRewardsDay = _self.dailyRewards.lastApplicationsRewardsDay;
for (uint256 j = 0; j < _self.dailyRewards.submissions[_rewardsHash].validatorsList.length; j++) {
delete(
_self.dailyRewards.submissions[_rewardsHash].validators[_self.dailyRewards.submissions[_rewardsHash].validatorsList[j]]
);
}
delete _self.dailyRewards.submittedRewardsHashes;
delete _self.dailyRewards.submissions[_rewardsHash].validatorsList;
_self.dailyRewards.submissions[_rewardsHash].confirmations = 0;
_self.dailyRewards.submissions[_rewardsHash].finalizedStatus = 0;
_self.dailyRewards.submissions[_rewardsHash].isInitializedState = false;
}
}
@@ -4,7 +4,7 @@
"description": "PROPS ERC20 token contract and distribution helpers",
"scripts": {
"tdd": "nodemon --watch contracts --watch test --exec 'truffle test --network test'",
"ganache-cli": "ganache-cli -p 8545 -m \"asset member awake bring mosquito lab sustain muscle elephant equip someone obvious\" > /dev/null &",
"ganache-cli": "ganache-cli -a 50 -p 8545 -m \"asset member awake bring mosquito lab sustain muscle elephant equip someone obvious\" > /dev/null &",
"compile": "truffle compile",
"test": "NODE_ENV=test truffle test ./test/*.test.js --network test --exit",
"testrewards": "NODE_ENV=test truffle test ./test/propstoken-0-rewards.test.js --network test --exit",
@@ -126,7 +126,7 @@ async function main() {
upgradeToEncoded,
).send({
from: DevOps1MultiSigOwnerAddress,
gas: utils.gasLimit('deployJurisdiction'),
gas: utils.gasLimit('setEntitiesViaMultisig'),
gasPrice: utils.gasPrice(),
// eslint-disable-next-line no-loop-func
}).then((receipt) => {
@@ -91,8 +91,7 @@ async function main() {
const currentTimestamp = Math.floor(Date.now()/1000);
// return (block.timestamp.sub(_self.rewardsStartTimestamp)).div(_self.minSecondsBetweenDays).add(1);
const rewardsDay = Math.floor((currentTimestamp - rewardsTimestamp) / secondsInDay) + 1;
console.log(`Got rewardsTimestamp=${rewardsTimestamp}, secondsInDay=${secondsInDay}, currentTimestamp=${currentTimestamp}, rewardsDay=${rewardsDay}`);

console.log(`Got rewardsTimestamp=${rewardsTimestamp}, secondsInDay=${secondsInDay}, currentTimestamp=${currentTimestamp}, rewardsDay=${rewardsDay}`);
const upgradeToEncoded = zos.encodeCall('setApplications', ['uint256','address[]'], [rewardsDay,applications]);

const encodedData = await propsContractInstance.methods.setApplications(
@@ -126,7 +125,7 @@ async function main() {
upgradeToEncoded,
).send({
from: DevOps1MultiSigOwnerAddress,
gas: utils.gasLimit('multisig'),
gas: utils.gasLimit('setEntitiesViaMultisig'),
gasPrice: utils.gasPrice(),
// eslint-disable-next-line no-loop-func
}).then((receipt) => {
@@ -12,6 +12,8 @@ const gasLimit = (type) => {
return 70000;
case 'multisig':
return 250000;
case 'setEntitiesViaMultisig':
return 600000;
case 'deployJurisdiction':
return 7473430;
case 'addAttribute': // add attribute to jurisdiction contract

0 comments on commit 9ab4ec4

Please sign in to comment.
You can’t perform that action at this time.