# Epoch-based Attestation System ## Overview A system where: - Projects can update once per epoch - Evaluators issue scores with epoch binding - All signatures within epoch are valid - Oracle submits current epoch attestations - Clear freshness verification ## Core Protocol ### 1. Epoch Management ```solidity contract EpochManager { uint256 public currentEpoch; uint256 public epochDuration; // e.g., 1 week in blocks mapping(address => uint256) public projectLastUpdateEpoch; function updateEpoch() external { if (block.number >= currentEpoch + epochDuration) { currentEpoch++; } } // Project can only update once per epoch function updateProject() external { require(projectLastUpdateEpoch[msg.sender] < currentEpoch, "Already updated this epoch"); projectLastUpdateEpoch[msg.sender] = currentEpoch; emit ProjectUpdated(msg.sender, currentEpoch); } } ``` ### 2. Attestations ```solidity struct Attestation { address evaluator; address project; uint256 score; uint256 epoch; bytes signature; // sign(evaluator + project + score + epoch) } contract AttestationVerifier { EpochManager public epochManager; mapping(address => uint256) public weights; function verify( Attestation[] calldata attestations, uint256 claimedWeightedSum ) external view returns (bool) { uint256 currentEpoch = epochManager.currentEpoch(); uint256 computedSum = 0; for (uint i = 0; i < attestations.length; i++) { Attestation calldata att = attestations[i]; // Must be from current epoch require(att.epoch == currentEpoch, "Wrong epoch"); // Project must have updated this epoch require(epochManager.projectLastUpdateEpoch(att.project) == currentEpoch, "Project not updated this epoch"); // Verify signature require(verifySignature(att), "Invalid signature"); // Add weighted score computedSum += att.score * weights[att.evaluator]; } return computedSum == claimedWeightedSum; } } ``` ## Benefits 1. **Clear Freshness** - Current epoch is unambiguous - Old signatures naturally expire - No nonce tracking needed 2. **Rate Limiting** - Projects limited to one update per epoch - Prevents evaluator spamming - Natural cooling-off period 3. **Simple Verification** - Verifier just checks current epoch - No complex state tracking - Easy to check project updated 4. **Independent Evaluators** - Can evaluate anytime within epoch - No coordination needed - Clear validity period ## Example Flow 1. New epoch starts (epoch 10) 2. Project X updates their evidence - Sets projectLastUpdateEpoch[X] = 10 3. Evaluators review & sign ```typescript // Evaluator signing const attestation = { evaluator: myAddress, project: projectX, score: 85, epoch: 10, }; const signature = sign(attestation); ``` 4. Oracle submits attestations - Must all be from epoch 10 - Project must have updated in epoch 10 - Evaluator signatures must be valid 5. Next epoch starts - Old signatures (epoch 10) become invalid - Project must update again for new evaluations ## Security Properties 1. **Temporal Binding** - Signatures bound to specific epoch - Cannot mix old and new scores - Clear expiration of old scores 2. **Rate Limiting** - Projects can't spam updates - Natural evaluation cycles - Predictable load on evaluators 3. **Freshness Guarantee** - All scores from same epoch - Known to be current - No ambiguity about staleness