# 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