# uWu Attestation Specification v1

## What is an Attestation?
A signed message from a verification oracle proving an off-chain fiat payment occurred.
Any smart contract can verify this independently using the library.

## Attestation Struct

| Field | Type | Description |
|-------|------|-------------|
| tradeId | bytes32 | Unique trade identifier |
| inrAmount | uint256 | INR amount in paisa (₹100 = 10000) |
| usdAmount | uint256 | USDC amount in 6-decimal wei (100 USDC = 100000000) |
| payerHash | bytes32 | keccak256(abi.encodePacked(payerUpiVpa)) |
| payeeHash | bytes32 | keccak256(abi.encodePacked(payeeUpiVpa)) |
| rail | string | Payment rail: "UPI", "IMPS", "NEFT", "RTGS" |
| timestamp | uint256 | Unix timestamp when payment was detected |
| expiresAt | uint256 | Unix timestamp when attestation becomes invalid |
| evidenceHash | bytes32 | keccak256(abi.encodePacked(utrNumber)) |
| riskScore | uint8 | 0-100 risk assessment |
| oracleId | address | Address of the signing oracle |

## EIP-712 Signing

Domain:
  name: "uWu Protocol"
  version: "1"
  chainId: [chain id where escrow is deployed]
  verifyingContract: [escrow contract address]

Type:
  Attestation(
    bytes32 tradeId,
    uint256 inrAmount,
    uint256 usdAmount,
    bytes32 payerHash,
    bytes32 payeeHash,
    string rail,
    uint256 timestamp,
    uint256 expiresAt,
    bytes32 evidenceHash,
    uint8 riskScore,
    address oracleId
  )

## Verification Steps
1. Compute EIP-712 typed data hash of the attestation
2. Recover signer address from the signature using ecrecover
3. Compare recovered address to att.oracleId
4. Check att.oracleId is in authorizedOracles mapping
5. Check att.expiresAt > block.timestamp
6. Check attestation hash not in usedAttestations mapping
7. Check att.riskScore < riskThreshold

## Risk Score Ranges
| Range | Label | Behavior |
|-------|-------|----------|
| 0-29 | Low | Auto-release allowed |
| 30-69 | Medium | Proceed with caution, may require confirmation |
| 70-100 | High/Blocked | Contract rejects, requires manual review |

## Replay Protection
- Every attestation produces a unique hash
- Once used, hash is stored in usedAttestations mapping
- Same attestation cannot release funds twice

## Expiry
- Default attestation validity: 10 minutes from signing
- Contract rejects expired attestations
- Oracle should refuse to re-sign for same trade without new evidence
