dgf-prototype/ethereum/contracts/Proposal.sol

82 lines
2.4 KiB
Solidity
Raw Normal View History

// 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
}
}