Skip to content

WIP: Permission Claims - Voting Mechanics [skip-ci] #1390

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 14 commits into
base: release-candidate
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 140 additions & 0 deletions contracts/interfaces/IPermissionedAssessment.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// SPDX-License-Identifier: GPL-3.0-only

pragma solidity ^0.8.28;

import {EnumerableSet} from "@openzeppelin/contracts-v4/utils/structs/EnumerableSet.sol";

interface IPermissionedAssessment {

/* ========== DATA STRUCTURES ========== */

struct AssessmentData {
uint32 assessingGroupId;
uint32 cooldownPeriod;
}

struct AssessmentGroupView {
uint id;
string ipfsMetadata;
address[] assessors;
}

struct Ballot {
bytes32 ipfsHash;
Vote vote;
uint32 timestamp;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need this timestamp onchain?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, we could probably get the timestamp from the event but since it also packs into slot 1, I've added it in for convenience.

}

struct Assessment {
uint32 start;
uint32 assessorGroupId;
uint32 finalizedAt; // 0, not closed yet else timestamp of closure
uint8 acceptVotes; // 0, if not finalized yet, should only be set onced finalized
uint8 denyVotes; // 0, if not finalized yet, should only be set onced finalized
mapping(uint256 assessorMemberId => Ballot) ballot; // only stores latest choice
}

enum AssessmentResult {
NONE,
ACCEPTED,
DENIED
}

enum Vote {
NONE, // 0 - default
ACCEPT, // 1
DENY // 2
}

/* ========== VIEWS ========== */

// Groups management

// function getGroupsCount() external view returns (uint groupCount);

// function getGroupAssessorCount(uint groupId) external view returns (uint assessorCount);

// function getGroupAssessors(uint groupId) external view returns (address[] memory assessors);

// function isAssessorInGroup(address assessor, uint groupId) external view returns (bool);

// function getGroupsForAssessor(address assessor) external view returns (uint[] memory groupIds);

// function getGroupsData(uint[] calldata groupIds) external view returns (AssessmentGroupView[] memory groups);

// Voting

function minVotingPeriod() external pure returns (uint256);

function payoutCooldown(uint256 productTypeId) external view returns (uint256);

function assessorGroupOf(uint256 claimId) external view returns (uint32);

function getAssessmentInfo(uint256 claimId) external view returns (uint256 acceptVotes, uint256 denyVotes, uint256 groupSize, uint32 end, uint32 finalizedAt);

function isReadyToCloseAfterVote(uint256 claimId, Vote vote) external view returns (bool);

function ballotOf(uint256 claimId, address assessor) external view returns (Ballot memory);

function claimsOpenForVoting(address assessor) external view returns (bytes32[] memory);

/* === MUTATIVE FUNCTIONS ==== */

// Groups management

// function makeNewGroup(address[] calldata assessors, string calldata ipfsMetadata) external returns (uint groupId);

// function addAssessorsToGroup(address[] calldata assessors, uint groupId) external;

// function setGroupMetadata(uint groupId, string calldata ipfsMetadata) external;

// function removeAssessorsFromGroup(address[] calldata assessors, uint groupId) external;

// function removeAssessorsFromAllGroups(address[] calldata assessors) external;

// Voting

function castVote(uint256 claimId, Vote vote, bytes32 ipfsHash) external;

function startAssessment(uint256 claimId, uint16 productTypeId) external;

/* ========= EVENTS ========== */

event SetAssessmentDataForProductTypes(uint[] productTypeIds, uint cooldownPeriod, uint groupId);
event AddAssessorsToGroup(uint indexed groupId, address[] assessors);
event RemoveAssessorsFromGroup(uint indexed groupId, address[] assessors);
event RemoveAssessorsFromAllGroups(address[] assessors);

event AssessmentStarted(
uint256 indexed claimId,
uint32 assessorGroupId,
uint32 start,
uint32 end
);

event VoteCast(
uint256 indexed claimId,
address indexed assessor,
uint256 indexed assessorMemberId,
Vote vote,
bytes32 ipfsHash
);

event AssessmentClosed(uint256 claimId);
event AssessmentExtended(uint256 claimId, uint32 newEnd);


/* ========== ERRORS ========== */

error AssessmentAlreadyExists();
error ClaimIdsEmpty();
error ClaimAssessmentAlreadyClosed();
error ClaimIdsVotesLengthMismatch();
error ClaimIdsCidsLengthMismatch();
error ClaimAssessmentNotFinished();
error EmptyAssessorGroup();
error InvalidAssessor();
error InvalidClaimId();
error InvalidVote();
error InvalidProductType();
}
Loading
Loading