Skip to content

Commit

Permalink
feat: contribution manager (#123)
Browse files Browse the repository at this point in the history
* feat: authorized contributor

* refactor: contributor => contributionManager
  • Loading branch information
pegahcarter authored Oct 9, 2024
1 parent 6882bd7 commit 7aed0e6
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 14 deletions.
57 changes: 46 additions & 11 deletions contracts/tasks/TaskManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {Contribution} from "./interfaces/ITaskFactory.sol";

contract TaskManager is ITaskManager, Initializable, PeriodUtils, AccessUtils {
using EnumerableSet for EnumerableSet.Bytes32Set;
using EnumerableSet for EnumerableSet.AddressSet;

uint128 public pointsActive;
uint128 public periodPointsGiven;
Expand All @@ -22,6 +23,8 @@ contract TaskManager is ITaskManager, Initializable, PeriodUtils, AccessUtils {
mapping(address member => EnumerableSet.Bytes32Set) private memberContributions;
mapping(uint32 periodId => bytes32[] contributionIds) public contributionsGivenInPeriod;

EnumerableSet.AddressSet private _contributionManagers;

constructor() {
_disableInitializers();
}
Expand All @@ -31,6 +34,32 @@ contract TaskManager is ITaskManager, Initializable, PeriodUtils, AccessUtils {
_init_PeriodUtils({_period0Start: _period0Start, _initPeriodId: _initPeriodId});
}

// ContributionManager-management

function addContributionManager(address who) external {
_revertIfNotAdmin();
if (!_contributionManagers.add(who)) revert AlreadyContributionManager();

emit AddContributionManager(who);
}

function removeContributionManager(address who) external {
_revertIfNotAdmin();
if (!_contributionManagers.remove(who)) revert NotContributionManager();

emit RemoveContributionManager(who);
}

function isContributionManager(address who) public view returns (bool) {
return _contributionManagers.contains(who);
}

function contributionManagers() external view returns (address[] memory) {
return _contributionManagers.values();
}

// Contribution-management

function addContribution(bytes32 contributionId, Contribution calldata contribution) public {
_revertIfNotTaskFactory();
writePointSummary();
Expand Down Expand Up @@ -77,28 +106,34 @@ contract TaskManager is ITaskManager, Initializable, PeriodUtils, AccessUtils {
emit RemoveContribution(contributionId, encodeContributionStatus(contributionStatus));
}

function commitContributions(bytes32[] calldata contributionIds, bytes[] calldata datas) external {
_revertIfNotMember(msg.sender);
function commitContributions(
bytes32[] calldata contributionIds,
address[] calldata whos,
bytes[] calldata datas
) external {
uint256 length = contributionIds.length;
if (length != datas.length) revert UnequalLengths();
if (length != whos.length || length != datas.length) revert UnequalLengths();
for (uint256 i = 0; i < length; i++) {
_commitContribution(contributionIds[i], datas[i]);
_commitContribution(contributionIds[i], whos[i], datas[i]);
}
}

function commitContribution(bytes32 contributionId, bytes calldata data) external {
_revertIfNotMember(msg.sender);
_commitContribution(contributionId, data);
function commitContribution(bytes32 contributionId, address who, bytes calldata data) external {
_commitContribution(contributionId, who, data);
}

function _commitContribution(bytes32 contributionId, bytes memory data) internal {
function _commitContribution(bytes32 contributionId, address who, bytes memory data) internal {
if (msg.sender != who && !isContributionManager(msg.sender) && !_isAdmin(msg.sender))
revert UnauthorizedContributionManager();
_revertIfNotMember(who);

ContributionStatus storage contributionStatus = contributionStatuses[contributionId];
if (uint8(contributionStatus.status) != uint8(Status.Open)) revert ContributionNotOpen();
emit CommitContribution(contributionId, msg.sender, data);
emit CommitContribution(contributionId, msg.sender, who, data);
}

function giveContributions(bytes32[] calldata contributionIds, address[] calldata whos) external {
_revertIfNotAdmin();
if (!isContributionManager(msg.sender) && _isAdmin(msg.sender)) revert UnauthorizedContributionManager();
writePointSummary();

uint256 length = contributionIds.length;
Expand All @@ -109,7 +144,7 @@ contract TaskManager is ITaskManager, Initializable, PeriodUtils, AccessUtils {
}

function giveContribution(bytes32 contributionId, address who) external {
_revertIfNotAdmin();
if (!isContributionManager(msg.sender) && _isAdmin(msg.sender)) revert UnauthorizedContributionManager();
writePointSummary();
_giveContribution(contributionId, who);
}
Expand Down
23 changes: 20 additions & 3 deletions contracts/tasks/interfaces/ITaskManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,15 @@ interface ITaskManager {
error UnequalLengths();
error MemberAlreadyContributed();
error ContributionNotOpen();
error AlreadyContributionManager();
error NotContributionManager();
error UnauthorizedContributionManager();

event AddContributionManager(address who);
event RemoveContributionManager(address who);
event AddContribution(bytes32 indexed contributionId, bytes encodedContributionStatus);
event RemoveContribution(bytes32 indexed contributionId, bytes encodedContributionStatus);
event CommitContribution(bytes32 indexed contributionId, address indexed who, bytes data);
event CommitContribution(bytes32 indexed contributionId, address indexed sender, address indexed who, bytes data);
event GiveContribution(
bytes32 indexed contributionId,
address indexed who,
Expand All @@ -51,6 +56,14 @@ interface ITaskManager {
/// @notice Get the amount of contribution points removed for the current period
function periodPointsRemoved() external view returns (uint128);

function addContributionManager(address who) external;

function removeContributionManager(address who) external;

function isContributionManager(address who) external view returns (bool);

function contributionManagers() external view returns (address[] memory);

/// @notice Add a contribution to the manager
/// @dev is called via TaskFactory
function addContribution(bytes32 contributionId, Contribution calldata contribution) external;
Expand All @@ -62,10 +75,14 @@ interface ITaskManager {
function removeContribution(bytes32 contributionId) external;

/// @notice Commit to a set of open contributions with associated data
function commitContributions(bytes32[] calldata contributionIds, bytes[] calldata datas) external;
function commitContributions(
bytes32[] calldata contributionIds,
address[] calldata whos,
bytes[] calldata datas
) external;

/// @notice Commit to an open contribution with associated data
function commitContribution(bytes32 contributionId, bytes calldata data) external;
function commitContribution(bytes32 contributionId, address who, bytes calldata data) external;

/// @notice Give contribution points to members who have completed the contribution requirements
function giveContributions(bytes32[] calldata contributionIds, address[] calldata whos) external;
Expand Down

0 comments on commit 7aed0e6

Please sign in to comment.