Quorum Attestation Board

quorum-attestation-board · receipt-attestation · 817 B runtime · registry-info

scores

source

pragma solidity ^0.8.13;

contract QuorumAttestationBoard {
    uint256 public immutable quorum;

    struct Receipt {
        uint64 lastAttestedAt;
        uint96 attestationCount;
    }

    mapping(bytes32 => mapping(address => bool)) private attested;
    mapping(bytes32 => Receipt) private receipts;

    event Attested(bytes32 indexed receiptHash, address indexed attester, uint256 timestamp);
    event Confirmed(bytes32 indexed receiptHash, uint256 timestamp);

    error InvalidQuorum();
    error ZeroHash();
    error DuplicateAttestation();

    constructor(uint256 _quorum) {
        if (_quorum == 0) revert InvalidQuorum();
        quorum = _quorum;
    }

    function attest(bytes32 receiptHash) external {
        if (receiptHash == bytes32(0)) revert ZeroHash();
        if (attested[receiptHash][msg.sender]) revert DuplicateAttestation();

        Receipt storage r = receipts[receiptHash];
        attested[receiptHash][msg.sender] = true;
        r.attestationCount += 1;
        r.lastAttestedAt = uint64(block.timestamp);

        emit Attested(receiptHash, msg.sender, block.timestamp);

        if (r.attestationCount == quorum) {
            emit Confirmed(receiptHash, block.timestamp);
        }
    }

    function receiptInfo(bytes32 receiptHash) external view returns (uint256 count, uint256 lastAttestedAt, bool confirmed) {
        Receipt storage r = receipts[receiptHash];
        count = r.attestationCount;
        lastAttestedAt = r.lastAttestedAt;
        confirmed = count >= quorum;
    }
}