Skip to content

Commit 7facd80

Browse files
authored
Competition enhance (#710)
* authorizedRepMinter : add burn functionality * add _proposerIsAdmin * rename ReputationAdmin * bump v to 0.0.1-rc.39
1 parent 0aaf2e7 commit 7facd80

File tree

7 files changed

+316
-217
lines changed

7 files changed

+316
-217
lines changed

contracts/schemes/AuthorizedMintRep.sol

Lines changed: 0 additions & 63 deletions
This file was deleted.

contracts/schemes/Competition.sol

Lines changed: 85 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ contract Competition {
1717
uint256 _suggestionsEndTime,
1818
uint256 _endTime,
1919
uint256 _maxNumberOfVotesPerVoter,
20-
address payable _contributionRewardExt //address of the contract to redeem from.
20+
address payable _contributionRewardExt, //address of the contract to redeem from.
21+
address _admin
2122
);
2223

2324
event Redeem(
@@ -30,7 +31,7 @@ contract Competition {
3031
bytes32 indexed _proposalId,
3132
uint256 indexed _suggestionId,
3233
string _descriptionHash,
33-
address payable indexed _suggester
34+
address payable indexed _beneficiary
3435
);
3536

3637
event NewVote(
@@ -61,6 +62,7 @@ contract Competition {
6162
uint256 nativeTokenReward;
6263
uint256 externalTokenReward;
6364
uint256[] topSuggestions;
65+
address admin;
6466
//mapping from suggestions totalVotes to the number of suggestions with the same totalVotes.
6567
mapping(uint256=>uint256) suggestionsPerVote;
6668
mapping(address=>uint256) votesPerVoter;
@@ -69,7 +71,7 @@ contract Competition {
6971
struct Suggestion {
7072
uint256 totalVotes;
7173
bytes32 proposalId;
72-
address payable suggester;
74+
address payable beneficiary;
7375
mapping(address=>uint256) votes;
7476
}
7577

@@ -108,6 +110,10 @@ contract Competition {
108110
* _competitionParams[2] - _endTime competition end time
109111
* _competitionParams[3] - _maxNumberOfVotesPerVoter on how many suggestions a voter can vote
110112
* _competitionParams[4] - _suggestionsEndTime suggestion submition end time
113+
* _proposerIsAdmin -
114+
* true - proposer is an admin.
115+
* false no admin.
116+
* if admin is set, so only admin can suggest on this proposal.
111117
* @return proposalId the proposal id.
112118
*/
113119
function proposeCompetition(
@@ -116,7 +122,8 @@ contract Competition {
116122
uint[3] calldata _rewards,
117123
IERC20 _externalToken,
118124
uint256[] calldata _rewardSplit,
119-
uint256[5] calldata _competitionParams
125+
uint256[5] calldata _competitionParams,
126+
bool _proposerIsAdmin
120127
)
121128
external
122129
returns(bytes32 proposalId) {
@@ -141,12 +148,7 @@ contract Competition {
141148
}
142149
require(totalRewardSplit == 100, "total rewards split is not 100%");
143150
proposalId = ContributionRewardExt(contributionRewardExt).proposeContributionReward(
144-
_descriptionHash,
145-
_reputationChange,
146-
_rewards,
147-
_externalToken,
148-
contributionRewardExt,
149-
msg.sender);
151+
_descriptionHash, _reputationChange, _rewards, _externalToken, contributionRewardExt, msg.sender);
150152
proposals[proposalId].numberOfWinners = numberOfWinners;
151153
proposals[proposalId].rewardSplit = _rewardSplit;
152154
proposals[proposalId].startTime = startTime;
@@ -158,7 +160,9 @@ contract Competition {
158160
proposals[proposalId].nativeTokenReward = _rewards[0];
159161
proposals[proposalId].ethReward = _rewards[1];
160162
proposals[proposalId].externalTokenReward = _rewards[2];
161-
163+
if (_proposerIsAdmin) {
164+
proposals[proposalId].admin = msg.sender;
165+
}
162166
emit NewCompetitionProposal(
163167
proposalId,
164168
numberOfWinners,
@@ -168,31 +172,43 @@ contract Competition {
168172
proposals[proposalId].suggestionsEndTime,
169173
proposals[proposalId].endTime,
170174
proposals[proposalId].maxNumberOfVotesPerVoter,
171-
contributionRewardExt
175+
contributionRewardExt,
176+
proposals[proposalId].admin
172177
);
173178
}
174179

175180
/**
176181
* @dev submit a competion suggestion
177182
* @param _proposalId the proposal id this suggestion is referring to.
178183
* @param _descriptionHash a descriptionHash of the suggestion.
184+
* @param _beneficiary the beneficiary of this suggestion.
179185
* @return suggestionId the suggestionId.
180186
*/
181187
function suggest(
182188
bytes32 _proposalId,
183-
string calldata _descriptionHash
189+
string calldata _descriptionHash,
190+
address payable _beneficiary
184191
)
185192
external
186193
returns(uint256)
187194
{
188-
// solhint-disable-next-line not-rely-on-time
195+
if (proposals[_proposalId].admin != address(0)) {
196+
require(proposals[_proposalId].admin == msg.sender, "only admin can suggest");
197+
}
198+
// solhint-disable-next-line not-rely-on-time
189199
require(proposals[_proposalId].startTime <= now, "competition not started yet");
190200
// solhint-disable-next-line not-rely-on-time
191201
require(proposals[_proposalId].suggestionsEndTime > now, "suggestions submition time is over");
192202
suggestionsCounter = suggestionsCounter.add(1);
193203
suggestions[suggestionsCounter].proposalId = _proposalId;
194-
suggestions[suggestionsCounter].suggester = msg.sender;
195-
emit NewSuggestion(_proposalId, suggestionsCounter, _descriptionHash, msg.sender);
204+
address payable beneficiary;
205+
if (_beneficiary == address(0)) {
206+
beneficiary = msg.sender;
207+
} else {
208+
beneficiary = _beneficiary;
209+
}
210+
suggestions[suggestionsCounter].beneficiary = beneficiary;
211+
emit NewSuggestion(_proposalId, suggestionsCounter, _descriptionHash, beneficiary);
196212
return suggestionsCounter;
197213
}
198214

@@ -231,23 +247,6 @@ contract Competition {
231247
return true;
232248
}
233249

234-
/**
235-
* @dev redeem a winning suggestion reward
236-
* @param _suggestionId suggestionId
237-
* @param _beneficiary - the reward beneficiary.
238-
* this parameter is take into account only if the msg.sender is the suggestion's suggester,
239-
* otherwise the _beneficiary param is ignored and the beneficiary is suggestion's suggester.
240-
*/
241-
function redeem(uint256 _suggestionId, address payable _beneficiary) external {
242-
address payable beneficiary = suggestions[_suggestionId].suggester;
243-
if ((msg.sender == suggestions[_suggestionId].suggester) &&
244-
(_beneficiary != address(0))) {
245-
//only suggester can redeem to other address
246-
beneficiary = _beneficiary;
247-
}
248-
_redeem(_suggestionId, beneficiary);
249-
}
250-
251250
/**
252251
* @dev setSnapshotBlock set the block for the reputaion snapshot
253252
* @param _proposalId the proposal id
@@ -270,7 +269,7 @@ contract Competition {
270269
require(proposals[_proposalId].endTime < now, "competition is still on");
271270
uint256[] memory topSuggestions = proposals[_proposalId].topSuggestions;
272271
for (uint256 i; i < topSuggestions.length; i++) {
273-
require(suggestions[topSuggestions[i]].suggester == address(0), "not all winning suggestions redeemed");
272+
require(suggestions[topSuggestions[i]].beneficiary == address(0), "not all winning suggestions redeemed");
274273
}
275274

276275
(, , , , , ,
@@ -291,6 +290,58 @@ contract Competition {
291290
_proposalId, address(avatar), nativeTokenRewardLeft);
292291
}
293292

293+
/**
294+
* @dev redeem a winning suggestion reward
295+
* @param _suggestionId suggestionId
296+
*/
297+
function redeem(uint256 _suggestionId) public {
298+
bytes32 proposalId = suggestions[_suggestionId].proposalId;
299+
Proposal storage proposal = proposals[proposalId];
300+
// solhint-disable-next-line not-rely-on-time
301+
require(proposal.endTime < now, "competition is still on");
302+
require(suggestions[_suggestionId].beneficiary != address(0),
303+
"suggestion was already redeemed");
304+
address payable beneficiary = suggestions[_suggestionId].beneficiary;
305+
uint256 orderIndex = getOrderedIndexOfSuggestion(_suggestionId);
306+
require(orderIndex < proposal.topSuggestions.length, "suggestion is not in winners list");
307+
suggestions[_suggestionId].beneficiary = address(0);
308+
uint256 rewardPercentage = 0;
309+
uint256 numberOfTieSuggestions = proposal.suggestionsPerVote[suggestions[_suggestionId].totalVotes];
310+
uint256 j;
311+
//calc the reward percentage for this suggestion
312+
for (j = orderIndex; j < (orderIndex+numberOfTieSuggestions) && j < proposal.numberOfWinners; j++) {
313+
rewardPercentage = rewardPercentage.add(proposal.rewardSplit[j]);
314+
}
315+
rewardPercentage = rewardPercentage.div(numberOfTieSuggestions);
316+
uint256 rewardPercentageLeft = 0;
317+
if (proposal.topSuggestions.length < proposal.numberOfWinners) {
318+
//if there are less winners than the proposal number of winners so divide the pre allocated
319+
//left reward equally between the winners
320+
for (j = proposal.topSuggestions.length; j < proposal.numberOfWinners; j++) {
321+
rewardPercentageLeft = rewardPercentageLeft.add(proposal.rewardSplit[j]);
322+
}
323+
rewardPercentage =
324+
rewardPercentage.add(rewardPercentageLeft.div(proposal.topSuggestions.length));
325+
}
326+
uint256 amount;
327+
amount = proposal.externalTokenReward.mul(rewardPercentage).div(100);
328+
ContributionRewardExt(contributionRewardExt).redeemExternalTokenByRewarder(
329+
proposalId, beneficiary, amount);
330+
331+
amount = proposal.reputationReward.mul(rewardPercentage).div(100);
332+
ContributionRewardExt(contributionRewardExt).redeemReputationByRewarder(
333+
proposalId, beneficiary, amount);
334+
335+
amount = proposal.ethReward.mul(rewardPercentage).div(100);
336+
ContributionRewardExt(contributionRewardExt).redeemEtherByRewarder(
337+
proposalId, beneficiary, amount);
338+
339+
amount = proposal.nativeTokenReward.mul(rewardPercentage).div(100);
340+
ContributionRewardExt(contributionRewardExt).redeemNativeTokenByRewarder(
341+
proposalId, beneficiary, amount);
342+
emit Redeem(proposalId, _suggestionId, rewardPercentage);
343+
}
344+
294345
/**
295346
* @dev getOrderedIndexOfSuggestion return the index of specific suggestion in the winners list.
296347
* @param _suggestionId suggestion id
@@ -348,56 +399,4 @@ contract Competition {
348399
}
349400
}
350401

351-
/**
352-
* @dev redeem a winning suggestion reward
353-
* @param _suggestionId suggestionId
354-
* @param _beneficiary - the reward beneficiary
355-
*/
356-
function _redeem(uint256 _suggestionId, address payable _beneficiary) private {
357-
bytes32 proposalId = suggestions[_suggestionId].proposalId;
358-
Proposal storage proposal = proposals[proposalId];
359-
// solhint-disable-next-line not-rely-on-time
360-
require(proposal.endTime < now, "competition is still on");
361-
require(suggestions[_suggestionId].suggester != address(0),
362-
"suggestion was already redeemed");
363-
uint256 orderIndex = getOrderedIndexOfSuggestion(_suggestionId);
364-
require(orderIndex < proposal.topSuggestions.length, "suggestion is not in winners list");
365-
suggestions[_suggestionId].suggester = address(0);
366-
uint256 rewardPercentage = 0;
367-
uint256 numberOfTieSuggestions = proposal.suggestionsPerVote[suggestions[_suggestionId].totalVotes];
368-
uint256 j;
369-
//calc the reward percentage for this suggestion
370-
for (j = orderIndex; j < (orderIndex+numberOfTieSuggestions) && j < proposal.numberOfWinners; j++) {
371-
rewardPercentage = rewardPercentage.add(proposal.rewardSplit[j]);
372-
}
373-
rewardPercentage = rewardPercentage.div(numberOfTieSuggestions);
374-
uint256 rewardPercentageLeft = 0;
375-
if (proposal.topSuggestions.length < proposal.numberOfWinners) {
376-
//if there are less winners than the proposal number of winners so divide the pre allocated
377-
//left reward equally between the winners
378-
for (j = proposal.topSuggestions.length; j < proposal.numberOfWinners; j++) {
379-
rewardPercentageLeft = rewardPercentageLeft.add(proposal.rewardSplit[j]);
380-
}
381-
rewardPercentage =
382-
rewardPercentage.add(rewardPercentageLeft.div(proposal.topSuggestions.length));
383-
}
384-
uint256 amount;
385-
amount = proposal.externalTokenReward.mul(rewardPercentage).div(100);
386-
ContributionRewardExt(contributionRewardExt).redeemExternalTokenByRewarder(
387-
proposalId, _beneficiary, amount);
388-
389-
amount = proposal.reputationReward.mul(rewardPercentage).div(100);
390-
ContributionRewardExt(contributionRewardExt).redeemReputationByRewarder(
391-
proposalId, _beneficiary, amount);
392-
393-
amount = proposal.ethReward.mul(rewardPercentage).div(100);
394-
ContributionRewardExt(contributionRewardExt).redeemEtherByRewarder(
395-
proposalId, _beneficiary, amount);
396-
397-
amount = proposal.nativeTokenReward.mul(rewardPercentage).div(100);
398-
ContributionRewardExt(contributionRewardExt).redeemNativeTokenByRewarder(
399-
proposalId, _beneficiary, amount);
400-
emit Redeem(proposalId, _suggestionId, rewardPercentage);
401-
}
402-
403402
}

0 commit comments

Comments
 (0)