82 lines
2.4 KiB
Solidity
82 lines
2.4 KiB
Solidity
|
// SPDX-License-Identifier: Unlicense
|
||
|
pragma solidity ^0.8.24;
|
||
|
|
||
|
import "./DAO.sol";
|
||
|
|
||
|
contract Proposals is DAOContract {
|
||
|
struct Attestation {
|
||
|
address sender;
|
||
|
uint amount;
|
||
|
}
|
||
|
|
||
|
enum Stage {
|
||
|
Proposal,
|
||
|
Referendum0,
|
||
|
Referendum1,
|
||
|
Referendum100,
|
||
|
Closed
|
||
|
}
|
||
|
struct Proposal {
|
||
|
address sender;
|
||
|
string contentId;
|
||
|
uint startTime;
|
||
|
Stage stage;
|
||
|
mapping(uint => Attestation) attestations;
|
||
|
uint attestationCount;
|
||
|
}
|
||
|
|
||
|
mapping(uint => Proposal) proposals;
|
||
|
uint proposalCount;
|
||
|
|
||
|
constructor(DAO dao) DAOContract(dao) {}
|
||
|
|
||
|
function propose(
|
||
|
string calldata contentId
|
||
|
) external returns (uint proposalIndex) {
|
||
|
proposalIndex = proposalCount++;
|
||
|
Proposal storage proposal = proposals[proposalIndex];
|
||
|
proposal.startTime = block.timestamp;
|
||
|
proposal.contentId = contentId;
|
||
|
}
|
||
|
|
||
|
function attest(uint proposalIndex, uint amount) external {
|
||
|
// Since this is non-binding, non-encumbering, we only need to verify that
|
||
|
// the sender actually has the rep they claim to stake.
|
||
|
require(
|
||
|
dao.balanceOf(msg.sender) >= amount,
|
||
|
"Sender has insufficient REP balance"
|
||
|
);
|
||
|
Proposal storage proposal = proposals[proposalIndex];
|
||
|
uint attestationIndex = proposal.attestationCount++;
|
||
|
Attestation storage attestation = proposal.attestations[
|
||
|
attestationIndex
|
||
|
];
|
||
|
attestation.sender = msg.sender;
|
||
|
attestation.amount = amount;
|
||
|
}
|
||
|
|
||
|
function evaluateAttestation(uint proposalIndex) external returns (bool) {
|
||
|
Proposal storage proposal = proposals[proposalIndex];
|
||
|
require(
|
||
|
proposal.stage == Stage.Proposal,
|
||
|
"Attestation only pertains to Proposal stage"
|
||
|
);
|
||
|
uint totalAttestation;
|
||
|
for (uint i = 0; i < proposal.attestationCount; i++) {
|
||
|
totalAttestation += proposal.attestations[i].amount;
|
||
|
}
|
||
|
bool meetsAttestation = 10 * totalAttestation >= dao.totalSupply();
|
||
|
if (!meetsAttestation) {
|
||
|
if (block.timestamp > proposal.startTime + 365 days) {
|
||
|
proposal.stage = Stage.Closed;
|
||
|
return false;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Initiate validation pool
|
||
|
proposal.stage = Stage.Referendum0;
|
||
|
// TODO: make referendum0 duration a parameter
|
||
|
}
|
||
|
}
|