Skip to content

Commit 74946b8

Browse files
authored
address audit report (#711)
* address audit report test voting machine cannot be zero initilized local vars bump version * spelling
1 parent 7facd80 commit 74946b8

File tree

6 files changed

+125
-60
lines changed

6 files changed

+125
-60
lines changed

contracts/schemes/Competition.sol

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ contract Competition {
109109
* _competitionParams[1] - _votingStartTime competition voting start time
110110
* _competitionParams[2] - _endTime competition end time
111111
* _competitionParams[3] - _maxNumberOfVotesPerVoter on how many suggestions a voter can vote
112-
* _competitionParams[4] - _suggestionsEndTime suggestion submition end time
112+
* _competitionParams[4] - _suggestionsEndTime suggestion submission end time
113113
* _proposerIsAdmin -
114114
* true - proposer is an admin.
115115
* false no admin.
@@ -126,6 +126,7 @@ contract Competition {
126126
bool _proposerIsAdmin
127127
)
128128
external
129+
// solhint-disable-next-line function-max-lines
129130
returns(bytes32 proposalId) {
130131
uint256 numberOfWinners = _rewardSplit.length;
131132
uint256 startTime = _competitionParams[0];
@@ -142,6 +143,10 @@ contract Competition {
142143
require(_competitionParams[4] <= _competitionParams[2],
143144
"suggestionsEndTime should be earlier than proposal end time");
144145
require(_competitionParams[4] > startTime, "suggestionsEndTime should be later than proposal start time");
146+
if (_rewards[2] > 0) {
147+
require(_externalToken != ERC20(0), "extenal token cannot be zero");
148+
}
149+
require(_reputationChange > 0, "only positive rep change(minting) allowed for a competition");
145150
uint256 totalRewardSplit;
146151
for (uint256 i = 0; i < numberOfWinners; i++) {
147152
totalRewardSplit = totalRewardSplit.add(_rewardSplit[i]);
@@ -160,6 +165,7 @@ contract Competition {
160165
proposals[proposalId].nativeTokenReward = _rewards[0];
161166
proposals[proposalId].ethReward = _rewards[1];
162167
proposals[proposalId].externalTokenReward = _rewards[2];
168+
proposals[proposalId].snapshotBlock = 0;
163169
if (_proposerIsAdmin) {
164170
proposals[proposalId].admin = msg.sender;
165171
}
@@ -198,7 +204,7 @@ contract Competition {
198204
// solhint-disable-next-line not-rely-on-time
199205
require(proposals[_proposalId].startTime <= now, "competition not started yet");
200206
// solhint-disable-next-line not-rely-on-time
201-
require(proposals[_proposalId].suggestionsEndTime > now, "suggestions submition time is over");
207+
require(proposals[_proposalId].suggestionsEndTime > now, "suggestions submission time is over");
202208
suggestionsCounter = suggestionsCounter.add(1);
203209
suggestions[suggestionsCounter].proposalId = _proposalId;
204210
address payable beneficiary;
@@ -249,26 +255,30 @@ contract Competition {
249255

250256
/**
251257
* @dev setSnapshotBlock set the block for the reputaion snapshot
258+
* this function is public in order to externaly set snapshot block regardless of the first voting event.
252259
* @param _proposalId the proposal id
253260
*/
254261
function setSnapshotBlock(bytes32 _proposalId) public {
255262
// solhint-disable-next-line not-rely-on-time
256263
require(proposals[_proposalId].votingStartTime < now, "voting period not started yet");
264+
require(proposals[_proposalId].maxNumberOfVotesPerVoter > 0, "proposal does not exist");
257265
if (proposals[_proposalId].snapshotBlock == 0) {
258266
proposals[_proposalId].snapshotBlock = block.number;
259267
emit SnapshotBlock(_proposalId, block.number);
260268
}
261269
}
262270

263271
/**
264-
* @dev sendLeftOverFund send letf over funds back to the dao.
272+
* @dev sendLeftOverFund send leftover funds back to the dao.
265273
* @param _proposalId the proposal id
266274
*/
267275
function sendLeftOverFunds(bytes32 _proposalId) public {
268276
// solhint-disable-next-line not-rely-on-time
269277
require(proposals[_proposalId].endTime < now, "competition is still on");
278+
require(proposals[_proposalId].maxNumberOfVotesPerVoter > 0, "proposal does not exist");
279+
require(_proposalId != bytes32(0), "proposalId is zero");
270280
uint256[] memory topSuggestions = proposals[_proposalId].topSuggestions;
271-
for (uint256 i; i < topSuggestions.length; i++) {
281+
for (uint256 i = 0; i < topSuggestions.length; i++) {
272282
require(suggestions[topSuggestions[i]].beneficiary == address(0), "not all winning suggestions redeemed");
273283
}
274284

@@ -296,9 +306,12 @@ contract Competition {
296306
*/
297307
function redeem(uint256 _suggestionId) public {
298308
bytes32 proposalId = suggestions[_suggestionId].proposalId;
309+
require(proposalId != bytes32(0), "proposalId is zero");
299310
Proposal storage proposal = proposals[proposalId];
311+
require(_suggestionId > 0, "suggestionId is zero");
300312
// solhint-disable-next-line not-rely-on-time
301313
require(proposal.endTime < now, "competition is still on");
314+
require(proposal.maxNumberOfVotesPerVoter > 0, "proposal does not exist");
302315
require(suggestions[_suggestionId].beneficiary != address(0),
303316
"suggestion was already redeemed");
304317
address payable beneficiary = suggestions[_suggestionId].beneficiary;
@@ -344,6 +357,8 @@ contract Competition {
344357

345358
/**
346359
* @dev getOrderedIndexOfSuggestion return the index of specific suggestion in the winners list.
360+
* for the case when the suggestion is NOT in the winners list,
361+
* this method will return topSuggestions.length
347362
* @param _suggestionId suggestion id
348363
*/
349364
function getOrderedIndexOfSuggestion(uint256 _suggestionId)
@@ -354,7 +369,7 @@ contract Competition {
354369
require(proposalId != bytes32(0), "suggestion does not exist");
355370
uint256[] memory topSuggestions = proposals[proposalId].topSuggestions;
356371
/** get how many elements are greater than a given element*/
357-
for (uint256 i; i < topSuggestions.length; i++) {
372+
for (uint256 i = 0; i < topSuggestions.length; i++) {
358373
if (suggestions[topSuggestions[i]].totalVotes > suggestions[_suggestionId].totalVotes) {
359374
index++;
360375
}

contracts/schemes/ContributionRewardExt.sol

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,7 @@ contract ContributionRewardExt is VotingMachineCallbacks, ProposalExecuteInterfa
6969
}
7070

7171
modifier onlyRewarder() {
72-
if (rewarder != address(0)) {
73-
require(msg.sender == rewarder, "msg.sender is not authorized");
74-
}
72+
require(msg.sender == rewarder, "msg.sender is not authorized");
7573
_;
7674
}
7775

@@ -106,6 +104,7 @@ contract ContributionRewardExt is VotingMachineCallbacks, ProposalExecuteInterfa
106104
{
107105
require(avatar == Avatar(0), "can be called only one time");
108106
require(_avatar != Avatar(0), "avatar cannot be zero");
107+
require(_votingMachine != IntVoteInterface(0), "votingMachine cannot be zero");
109108
avatar = _avatar;
110109
votingMachine = _votingMachine;
111110
voteParams = _voteParams;
@@ -162,6 +161,9 @@ contract ContributionRewardExt is VotingMachineCallbacks, ProposalExecuteInterfa
162161
if (beneficiary == address(0)) {
163162
beneficiary = msg.sender;
164163
}
164+
if (beneficiary == address(this)) {
165+
require(_reputationChange > 0, "only positive rep change(minting) allowed for this case");
166+
}
165167

166168
ContributionProposal memory proposal = ContributionProposal({
167169
nativeTokenReward: _rewards[0],
@@ -211,6 +213,7 @@ contract ContributionRewardExt is VotingMachineCallbacks, ProposalExecuteInterfa
211213
if (proposal.beneficiary == address(this)) {
212214
if (proposal.reputationChangeLeft == 0) {//for now only mint(not burn) rep allowed from ext contract.
213215
proposal.reputationChangeLeft = uint256(proposal.reputationChange);
216+
proposal.reputationChange = 0;
214217
}
215218
} else {
216219
reputation = proposal.reputationChange;

contracts/schemes/ReputationAdmin.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ contract ReputationAdmin is Ownable {
4646
* @param _amounts the amounts of reputation to mint for beneficiaries
4747
*/
4848
function reputationMint(address[] calldata _beneficiaries, uint256[] calldata _amounts) external onlyOwner {
49-
require(_beneficiaries.length == _amounts.length, "Arrays length mismuch");
49+
require(_beneficiaries.length == _amounts.length, "Arrays length mismatch");
5050
for (uint256 i=0; i < _beneficiaries.length; i++) {
5151
_reputationMint(_beneficiaries[i], _amounts[i]);
5252
}
@@ -58,7 +58,7 @@ contract ReputationAdmin is Ownable {
5858
* @param _amounts the amounts of reputation to burn for beneficiaries
5959
*/
6060
function reputationBurn(address[] calldata _beneficiaries, uint256[] calldata _amounts) external onlyOwner {
61-
require(_beneficiaries.length == _amounts.length, "Arrays length mismuch");
61+
require(_beneficiaries.length == _amounts.length, "Arrays length mismatch");
6262
for (uint256 i=0; i < _beneficiaries.length; i++) {
6363
_reputationBurn(_beneficiaries[i], _amounts[i]);
6464
}

0 commit comments

Comments
 (0)