Skip to main content

Overview

The ZKScore Achievement Registry is a sophisticated smart contract that manages on-chain achievements across the ZKScore ecosystem. It handles achievement creation, claiming, progress tracking, and verification, enabling gamified reputation building and milestone recognition.
The Achievement Registry is deployed on multiple networks. Always check the latest deployment addresses in the Deployment section before interacting with the contract.

Contract Architecture

Core Components

The Achievement Registry consists of several key components:
  1. Achievement Management: Creation and configuration of achievements
  2. Progress Tracking: Real-time progress monitoring for each user
  3. Claiming System: Secure achievement claiming with verification
  4. Reward Distribution: Automated reward distribution upon claiming
  5. Badge System: NFT badge minting for earned achievements

Achievement Categories

1. DeFi Achievements

Decentralized finance milestones:
  • Liquidity Provider (LP tokens > $10k)
  • Lending Master (lending volume > $100k)
  • Yield Farmer (3+ protocols)
  • DeFi Pioneer (early adopter)
  • Protocol Veteran (1 year+ active)

2. NFT Achievements

NFT ecosystem achievements:
  • NFT Collector (10+ unique NFTs)
  • Blue Chip Holder (rare NFT owner)
  • Active Trader (50+ trades)
  • Creator Support (support 5+ creators)
  • Community Builder (active participation)

3. Social Achievements

Social platform milestones:
  • Profile Complete (100% completion)
  • Content Creator (10+ posts)
  • Community Leader (100+ followers)
  • Engagement Champion (high interaction)
  • Network Builder (connections)

4. Trading Achievements

Trading performance milestones:
  • Day Trader (20+ trades/month)
  • Profitable Trader (positive ROI)
  • Diamond Hands (long-term holder)
  • Risk Manager (diversified portfolio)
  • Market Maker (liquidity provision)

5. Governance Achievements

Governance participation:
  • Active Voter (voted in 10+ proposals)
  • Proposal Creator (created proposal)
  • Delegate (received delegation)
  • Governance Expert (high participation)
  • Community Advocate (forum activity)

6. Gaming Achievements

Gaming milestones:
  • Game Explorer (played 5+ games)
  • High Scorer (top leaderboard)
  • Tournament Winner (won tournament)
  • Asset Collector (rare in-game items)
  • Gaming Veteran (active player)

7. Identity Achievements

Identity verification milestones:
  • Verified Identity (KYC completed)
  • Multi-Chain User (3+ chains)
  • ENS Holder (owns ENS)
  • Early Adopter (early user)
  • Community Member (active 6+ months)

8. Trust Achievements

Trust layer milestones:
  • Trusted Member (5+ attestations)
  • Attestation Giver (issued attestations)
  • Reputation Builder (high trust score)
  • Verified Credential (verified credentials)
  • Trust Network (trust connections)

Contract Addresses

Mainnet Deployments

// Achievement Registry Contract
address: 0x3456789012345678901234567890123456789012

// Proxy Contract
address: 0x4567890123456789012345678901234567890123

Testnet Deployments

// Achievement Registry Contract
address: 0x9012345678901234567890123456789012345678

// Proxy Contract
address: 0x0123456789012345678901234567890123456789

Achievement Structure

Achievement Data Model

struct Achievement {
    uint256 id;                     // Unique achievement ID
    string name;                    // Achievement name
    string description;             // Achievement description
    string imageURI;                // Achievement image/badge
    uint8 category;                 // Category (0-7)
    Rarity rarity;                  // Rarity level
    uint256 points;                 // Points awarded
    uint256 scoreBoost;             // Score boost percentage
    RequirementType requirementType; // How to verify
    bytes requirementData;          // Verification data
    uint256 totalClaimed;           // Total claims
    uint256 maxClaims;              // Max possible claims (0 = unlimited)
    bool isActive;                  // Achievement active status
    uint256 createdAt;              // Creation timestamp
}

Rarity Levels

enum Rarity {
    COMMON,      // Easy to earn (60% of users)
    UNCOMMON,    // Moderate difficulty (30% of users)
    RARE,        // Challenging (8% of users)
    EPIC,        // Very challenging (1.5% of users)
    LEGENDARY    // Extremely rare (0.5% of users)
}

Requirement Types

enum RequirementType {
    MANUAL,              // Admin verification
    SCORE_THRESHOLD,     // Minimum score required
    CATEGORY_SCORE,      // Category score threshold
    ACTIVITY_COUNT,      // Number of activities
    TIME_BASED,          // Time-based milestone
    COMPOSITE,           // Multiple requirements
    PROOF_BASED          // Zero-knowledge proof
}

Contract Interface

Core Functions

// Achievement Management
function createAchievement(
    string memory name,
    string memory description,
    string memory imageURI,
    uint8 category,
    Rarity rarity,
    uint256 points,
    uint256 scoreBoost,
    RequirementType requirementType,
    bytes memory requirementData
) external returns (uint256);

function updateAchievement(uint256 achievementId, bytes memory updateData) external;
function deactivateAchievement(uint256 achievementId) external;

// User Achievements
function claimAchievement(uint256 achievementId, bytes memory proof) external;
function getUserAchievements(address user) external view returns (uint256[] memory);
function getProgress(address user, uint256 achievementId) external view returns (Progress memory);

// Queries
function getAchievement(uint256 achievementId) external view returns (Achievement memory);
function getAchievementsByCategory(uint8 category) external view returns (uint256[] memory);
function getAchievementsByRarity(Rarity rarity) external view returns (uint256[] memory);

Events

// Achievement Events
event AchievementCreated(uint256 indexed achievementId, string name, uint8 category, Rarity rarity);
event AchievementClaimed(address indexed user, uint256 indexed achievementId, uint256 timestamp);
event AchievementUpdated(uint256 indexed achievementId, bytes updateData);
event AchievementDeactivated(uint256 indexed achievementId, uint256 timestamp);

// Progress Events
event ProgressUpdated(address indexed user, uint256 indexed achievementId, uint256 progress);
event BadgeMinted(address indexed user, uint256 indexed achievementId, uint256 tokenId);

Progress Tracking

Progress Structure

struct Progress {
    uint256 current;        // Current progress value
    uint256 required;       // Required value to claim
    uint256 percentage;     // Completion percentage
    uint256 lastUpdated;    // Last update timestamp
    bool canClaim;          // Ready to claim
}

Automatic Progress Updates

Progress is automatically updated when:
  1. User performs qualifying on-chain action
  2. Score thresholds are met
  3. Time-based milestones are reached
  4. Activity counters increment
  5. Category scores update

Manual Progress Verification

For certain achievements, manual verification is required:
function verifyProgress(
    address user,
    uint256 achievementId,
    uint256 progressValue
) external onlyVerifier {
    _updateProgress(user, achievementId, progressValue);
}

Claiming System

Claim Process

  1. Check Eligibility: Verify user meets requirements
  2. Generate Proof: Create verification proof (if needed)
  3. Submit Claim: Call claimAchievement() with proof
  4. Verification: Contract verifies requirements
  5. Mint Badge: NFT badge minted to user
  6. Distribute Rewards: Points and score boost applied
  7. Emit Events: Claim event emitted

Claim Verification

function claimAchievement(uint256 achievementId, bytes memory proof) external {
    Achievement memory achievement = achievements[achievementId];
    
    require(achievement.isActive, "Achievement not active");
    require(!hasClaimed[msg.sender][achievementId], "Already claimed");
    require(_verifyRequirement(msg.sender, achievement, proof), "Requirements not met");
    
    // Mark as claimed
    hasClaimed[msg.sender][achievementId] = true;
    userAchievements[msg.sender].push(achievementId);
    achievement.totalClaimed++;
    
    // Mint badge
    uint256 tokenId = _mintBadge(msg.sender, achievementId);
    
    // Apply rewards
    _applyRewards(msg.sender, achievement);
    
    emit AchievementClaimed(msg.sender, achievementId, block.timestamp);
    emit BadgeMinted(msg.sender, achievementId, tokenId);
}

Reward System

Points Distribution

// Points awarded by rarity
COMMON: 10-50 points
UNCOMMON: 50-100 points
RARE: 100-250 points
EPIC: 250-500 points
LEGENDARY: 500-1000 points

Score Boost

// Temporary score boost (duration: 30 days)
COMMON: +1% boost
UNCOMMON: +2% boost
RARE: +5% boost
EPIC: +10% boost
LEGENDARY: +20% boost

NFT Badges

Each claimed achievement mints a unique NFT badge:
struct Badge {
    uint256 achievementId;   // Achievement reference
    address owner;           // Badge owner
    uint256 claimedAt;       // Claim timestamp
    string metadata;         // Badge metadata URI
}

Gas Optimization

Efficient Storage

// Packed storage for achievements
struct PackedAchievement {
    uint128 id;              // 16 bytes
    uint64 points;           // 8 bytes
    uint32 scoreBoost;       // 4 bytes
    uint8 category;          // 1 byte
    uint8 rarity;            // 1 byte
    uint8 requirementType;   // 1 byte
    bool isActive;           // 1 byte
    // Total: 32 bytes (1 slot)
}

Batch Operations

// Claim multiple achievements in one transaction
function batchClaimAchievements(
    uint256[] calldata achievementIds,
    bytes[] calldata proofs
) external returns (uint256[] memory);

// Get multiple achievements
function batchGetAchievements(
    uint256[] calldata achievementIds
) external view returns (Achievement[] memory);

Gas Estimates

OperationGas CostDescription
Create Achievement~200,000Create new achievement
Claim Achievement~180,000Claim with badge minting
Update Progress~30,000Update user progress
Get Achievement~3,000View achievement data
Get User Achievements~5,000View user’s achievements
Batch Claim (3)~450,000Claim 3 achievements

Access Control

Roles

// Role definitions
bytes32 public constant CREATOR_ROLE = keccak256("CREATOR_ROLE");
bytes32 public constant VERIFIER_ROLE = keccak256("VERIFIER_ROLE");
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");

// Permission matrix
modifier onlyCreator() {
    require(hasRole(CREATOR_ROLE, msg.sender), "Not authorized creator");
    _;
}

modifier onlyVerifier() {
    require(hasRole(VERIFIER_ROLE, msg.sender), "Not authorized verifier");
    _;
}

Permission Matrix

OperationCREATOR_ROLEVERIFIER_ROLEADMIN_ROLEUser
Create Achievement
Update Achievement
Verify Progress
Claim Achievement
View Achievements
Grant Roles

Integration Examples

Basic Achievement Query

import { ethers } from 'ethers';

// Contract ABI (simplified)
const ACHIEVEMENT_REGISTRY_ABI = [
  "function getAchievement(uint256 achievementId) external view returns (tuple(uint256 id, string name, string description, string imageURI, uint8 category, uint8 rarity, uint256 points, uint256 scoreBoost, uint8 requirementType, bytes requirementData, uint256 totalClaimed, uint256 maxClaims, bool isActive, uint256 createdAt))",
  "function getUserAchievements(address user) external view returns (uint256[])",
  "function getProgress(address user, uint256 achievementId) external view returns (tuple(uint256 current, uint256 required, uint256 percentage, uint256 lastUpdated, bool canClaim))",
  "function claimAchievement(uint256 achievementId, bytes proof) external",
  "event AchievementClaimed(address indexed user, uint256 indexed achievementId, uint256 timestamp)"
];

// Initialize contract
const provider = new ethers.providers.JsonRpcProvider('https://mainnet.infura.io/v3/YOUR_KEY');
const contract = new ethers.Contract(
  '0x3456789012345678901234567890123456789012',
  ACHIEVEMENT_REGISTRY_ABI,
  provider
);

// Get achievement details
async function getAchievementDetails(achievementId) {
  const achievement = await contract.getAchievement(achievementId);
  
  console.log('Achievement:', {
    id: achievement.id.toString(),
    name: achievement.name,
    description: achievement.description,
    category: achievement.category,
    rarity: achievement.rarity,
    points: achievement.points.toString(),
    totalClaimed: achievement.totalClaimed.toString()
  });
  
  return achievement;
}

// Get user's achievements
async function getUserAchievements(userAddress) {
  const achievementIds = await contract.getUserAchievements(userAddress);
  
  console.log(`User has ${achievementIds.length} achievements`);
  return achievementIds;
}

Claim Achievement

// Claim achievement
async function claimAchievement(achievementId, proof) {
  const signer = provider.getSigner();
  const contractWithSigner = contract.connect(signer);
  
  const tx = await contractWithSigner.claimAchievement(achievementId, proof);
  const receipt = await tx.wait();
  
  // Get claim event
  const event = receipt.events.find(e => e.event === 'AchievementClaimed');
  
  console.log('Achievement claimed!');
  console.log('Achievement ID:', event.args.achievementId.toString());
  console.log('Timestamp:', event.args.timestamp.toString());
  
  return receipt;
}

Security Considerations

Claim Verification

All claims are verified before processing:
function _verifyRequirement(
    address user,
    Achievement memory achievement,
    bytes memory proof
) internal view returns (bool) {
    if (achievement.requirementType == RequirementType.SCORE_THRESHOLD) {
        return _verifyScoreThreshold(user, achievement.requirementData);
    } else if (achievement.requirementType == RequirementType.PROOF_BASED) {
        return _verifyProof(user, proof, achievement.requirementData);
    }
    // ... other verification types
}

Double-Claim Prevention

mapping(address => mapping(uint256 => bool)) public hasClaimed;

function claimAchievement(uint256 achievementId, bytes memory proof) external {
    require(!hasClaimed[msg.sender][achievementId], "Already claimed");
    // ... claim logic
    hasClaimed[msg.sender][achievementId] = true;
}

Best Practices

For Developers

  1. Verify Progress: Always check progress before claiming
  2. Handle Errors: Implement comprehensive error handling
  3. Monitor Events: Listen for achievement events
  4. Cache Data: Cache achievement metadata locally
  5. Batch Queries: Use batch functions for multiple queries

For Users

  1. Track Progress: Monitor achievement progress regularly
  2. Claim Promptly: Claim achievements when eligible
  3. Verify Requirements: Understand requirements before attempting
  4. Check Gas: Ensure sufficient gas for claiming
  5. Secure Wallet: Keep wallet secure as badges are valuable