Development of Anti-Sybil Verification System
Sybil attack — creating multiple fake identities to gain unfair advantage. In DeFi: one person creates 1000 addresses and claims airdrop 1000 times. In DAO: accumulating voting power through multiple wallets. Anti-sybil system tries to separate unique real people from bots and fake accounts.
Why This is Hard
Blockchain address — just a pair of keys. Creating 10000 addresses — matter of minutes. No built-in mechanism linking address to real person. Yet you can't require full identification — it contradicts privacy and accessibility.
Balance: sufficient sybil protection with minimal friction for honest users.
Anti-sybil Signals
On-chain Signals (no KYC required)
Transaction history: account with >2 years history, >100 transactions, interaction with >10 protocols — high probability of real person. New address with 3 transactions — questionable.
Asset holdings: minimal ETH balance + diverse portfolio. Sybil farmers economize on gas and hold minimum.
DeFi participation: liquidity provision, borrowing, governance voting — real on-chain patterns.
NFT ownership: verified NFT collections, especially requiring gas-intensive mint.
Proof of Humanity Systems
Proof of Humanity (PoH): video verification. User records video with name and registers in registry. Other users verify recording. Sybil challenge: anyone can challenge + bond.
BrightID: social verification. Users confirm acquaintance in video conferences. Sybil impossible without real social connections.
Worldcoin: biometric iris scan. Strongest uniqueness signal, but most invasive. Uses ZK for privacy.
Core Anti-sybil Contract
contract AntiSybilSystem {
// Different signals with weights
struct SybilScore {
uint256 humanityScore; // 0-100
bool isVerified;
uint256 lastUpdated;
bytes32[] passedChecks;
}
mapping(address => SybilScore) public scores;
// Chainlink-based on-chain activity aggregation
function updateActivityScore(
address user,
uint256 txCount,
uint256 uniqueProtocols,
uint256 accountAgeDays
) external onlyOracle {
uint256 score = 0;
// Account age (max 30 points)
if (accountAgeDays > 730) score += 30; // > 2 years
else if (accountAgeDays > 365) score += 20; // > 1 year
else if (accountAgeDays > 90) score += 10; // > 3 months
// Transaction count (max 30 points)
if (txCount > 500) score += 30;
else if (txCount > 100) score += 20;
else if (txCount > 20) score += 10;
// Protocol diversity (max 40 points)
if (uniqueProtocols > 20) score += 40;
else if (uniqueProtocols > 10) score += 25;
else if (uniqueProtocols > 5) score += 15;
scores[user].humanityScore = score;
scores[user].lastUpdated = block.timestamp;
}
// Check external verifications (PoH, BrightID, Worldcoin)
function registerExternalVerification(
address user,
bytes32 verificationType,
bytes calldata proof
) external onlyVerifier {
require(_verifyProof(verificationType, proof, user), "Invalid proof");
scores[user].passedChecks.push(verificationType);
scores[user].isVerified = true;
// External verification = max humanity score
scores[user].humanityScore = 100;
}
}
Gitcoin Passport Integration
Gitcoin Passport — aggregator of anti-sybil stamps. User collects stamps (Google OAuth, GitHub, BrightID, ENS, PoH, on-chain activity) and gets composite score.
interface IGitcoinPassport {
function getScore(address user) external view returns (uint256);
function hasStamp(address user, bytes32 stampType) external view returns (bool);
function isAboveThreshold(address user, uint256 threshold) external view returns (bool);
}
contract GatedFeature {
IGitcoinPassport passport = IGitcoinPassport(PASSPORT_ADDRESS);
modifier onlyHumans() {
require(
passport.isAboveThreshold(msg.sender, 20), // score >= 20
"Insufficient humanity score"
);
_;
}
}
Quadratic Funding and Anti-sybil
Gitcoin Grants uses quadratic funding: amount of grants proportional to square of number of donors, not sum. This makes sybil especially profitable (1 person with 1000 addresses = sqrt(1000) times larger matching).
Anti-sybil critical for quadratic mechanics. MACI (Minimal Anti-Collusion Infrastructure) + Gitcoin Passport — standard solution.
ZK Anti-sybil
Nullifier pattern: user proves they have unique credential (Worldcoin iris) without revealing identity. Nullifier — unique value derived from credential. Re-registering with same credential → same nullifier → duplicate detection.
ZK Proof:
Input (private): iris_scan_hash, secret
Input (public): world_tree_root, nullifier_hash
Proves: iris_scan_hash is in world_tree_root
Nullifier = hash(iris_scan_hash, secret)
// Cannot register twice — nullifier reveals fact
Development of production anti-sybil system — 6-12 weeks. This is ongoing work: sybil attacks evolve, defenses must too.







