Skip to content

Commit 2d69f0d

Browse files
authored
Add reputation admin scheme (#768)
* Add reputation admin scheme * Increase test coverage * Bump version
1 parent f916944 commit 2d69f0d

File tree

5 files changed

+364
-2
lines changed

5 files changed

+364
-2
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
pragma solidity 0.6.10;
2+
// SPDX-License-Identifier: GPL-3.0
3+
4+
import "@openzeppelin/contracts-ethereum-package/contracts/access/Ownable.sol";
5+
import "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol";
6+
import "../controller/Controller.sol";
7+
import "./ArcScheme.sol";
8+
9+
/**
10+
* @title A scheme for reputation minting/burning by an authorized account
11+
*/
12+
13+
contract ReputationAdmin is OwnableUpgradeSafe, ArcScheme {
14+
using SafeMath for uint256;
15+
16+
uint256 public activationStartTime;
17+
uint256 public activationEndTime;
18+
uint256 public repRewardLeft;
19+
uint256 public limitRepReward;
20+
21+
/**
22+
* @dev initialize
23+
* @param _avatar the avatar to mint reputation from
24+
* @param _activationStartTime start time for allowing minting
25+
* @param _activationEndTime end time for allowing minting
26+
* @param _maxRepReward maximum reputation mintable by this scheme
27+
*/
28+
function initialize(
29+
Avatar _avatar,
30+
uint256 _activationStartTime,
31+
uint256 _activationEndTime,
32+
uint256 _maxRepReward,
33+
address _owner
34+
) external {
35+
require(_activationStartTime < _activationEndTime, "_activationStartTime < _activationEndTime");
36+
super._initialize(_avatar);
37+
activationStartTime = _activationStartTime;
38+
activationEndTime = _activationEndTime;
39+
repRewardLeft = _maxRepReward;
40+
limitRepReward = _maxRepReward;
41+
__Ownable_init_unchained();
42+
transferOwnership(_owner);
43+
}
44+
45+
/**
46+
* @dev reputationBurn function
47+
* @param _beneficiaries the beneficiaries address to mint reputation from
48+
* @param _amounts the amounts of reputation to mint for beneficiaries
49+
*/
50+
function reputationMint(address[] calldata _beneficiaries, uint256[] calldata _amounts) external onlyOwner {
51+
require(_beneficiaries.length == _amounts.length, "Arrays length mismatch");
52+
for (uint256 i=0; i < _beneficiaries.length; i++) {
53+
_reputationMint(_beneficiaries[i], _amounts[i]);
54+
}
55+
}
56+
57+
/**
58+
* @dev reputationBurn function
59+
* @param _beneficiaries the beneficiaries address to burm reputation from
60+
* @param _amounts the amounts of reputation to burn for beneficiaries
61+
*/
62+
function reputationBurn(address[] calldata _beneficiaries, uint256[] calldata _amounts) external onlyOwner {
63+
require(_beneficiaries.length == _amounts.length, "Arrays length mismatch");
64+
for (uint256 i=0; i < _beneficiaries.length; i++) {
65+
_reputationBurn(_beneficiaries[i], _amounts[i]);
66+
}
67+
}
68+
69+
/**
70+
* @dev reputationMint function
71+
* @param _beneficiary the beneficiary address to mint reputation for
72+
* @param _amount the amount of reputation to mint the the beneficirary
73+
*/
74+
function _reputationMint(address _beneficiary, uint256 _amount) private {
75+
// solhint-disable-next-line not-rely-on-time
76+
require(now >= activationStartTime, "Minting period did not start yet");
77+
// solhint-disable-next-line not-rely-on-time
78+
require(now < activationEndTime, "Minting period ended.");
79+
80+
if (limitRepReward > 0) {
81+
repRewardLeft = repRewardLeft.sub(_amount);
82+
}
83+
84+
require(
85+
Controller(avatar.owner()).mintReputation(_amount, _beneficiary),
86+
"Minting reputation should succeed"
87+
);
88+
}
89+
90+
/**
91+
* @dev reputationBurn function
92+
* @param _beneficiary the beneficiary address to burm reputation from
93+
* @param _amount the amount of reputation to burn for a beneficirary
94+
*/
95+
function _reputationBurn(address _beneficiary, uint256 _amount) private {
96+
// solhint-disable-next-line not-rely-on-time
97+
require(now >= activationStartTime, "Burning period did not start yet");
98+
// solhint-disable-next-line not-rely-on-time
99+
require(now < activationEndTime, "Burning period ended.");
100+
101+
if (limitRepReward > 0) {
102+
require(_amount <= limitRepReward.sub(repRewardLeft), "Cannot burn more than minted");
103+
repRewardLeft = repRewardLeft.add(_amount);
104+
}
105+
106+
require(
107+
Controller(avatar.owner()).burnReputation(_amount, _beneficiary),
108+
"Burn reputation should succeed"
109+
);
110+
}
111+
}

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@daostack/arc-experimental",
3-
"version": "0.1.2-rc.1",
3+
"version": "0.1.2-rc.2",
44
"description": "A platform for building DAOs",
55
"files": [
66
"contracts/",

test/helpers.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const ARCVotingMachineCallbacksMock = artifacts.require("./ARCVotingMachineCallb
3737
const JoinAndQuit = artifacts.require("./JoinAndQuit.sol");
3838
const FundingRequest = artifacts.require("./FundingRequest.sol");
3939
const Dictator = artifacts.require("./Dictator.sol");
40+
const ReputationAdmin = artifacts.require("./ReputationAdmin.sol");
4041

4142

4243
const MAX_UINT_256 = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff';
@@ -157,6 +158,7 @@ const SOME_ADDRESS = '0x1000000000000000000000000000000000000000';
157158
registration.fundingRequest = await FundingRequest.new();
158159
registration.rewarderMock = await RewarderMock.new();
159160
registration.dictator = await Dictator.new();
161+
registration.reputationAdmin = await ReputationAdmin.new();
160162

161163

162164
await implementationDirectory.setImplementation("DAOToken",registration.daoToken.address);
@@ -188,6 +190,7 @@ const SOME_ADDRESS = '0x1000000000000000000000000000000000000000';
188190
await implementationDirectory.setImplementation("JoinAndQuit",registration.joinAndQuit.address);
189191
await implementationDirectory.setImplementation("FundingRequest",registration.fundingRequest.address);
190192
await implementationDirectory.setImplementation("Dictator",registration.dictator.address);
193+
await implementationDirectory.setImplementation("ReputationAdmin",registration.reputationAdmin.address);
191194

192195

193196
registration.implementationDirectory = implementationDirectory;

0 commit comments

Comments
 (0)