🛡️ VRAN (Vindex Reputation & Anti-Scam Network)
VRAN is a decentralized trust layer that adds a reputation dimension to PAY.ID payments. It lets you check if a merchant or payer is trustworthy before completing a transaction.
How It Works
| Component | Role |
|---|---|
| VindexRegistry | On-chain contract storing reputation scores and blacklist |
| SentinelApp | Community reporting interface (off-chain) |
| ReputationEngine | AI-driven pattern analysis (off-chain) |
| EAS Bridge | Attestation integration for verified identities |
User ──▶ Check Reputation ──▶ VindexRegistry ──▶ Score / Blacklist?
│
▼
Report (stake + evidence)
Reputation Score
- Range: 0 – 1000
- Default: 500 (neutral)
- Auto-blacklist: When score drops below 100
const { score, isBlacklisted, isTrusted } = useReputation({
registryAddress: '0xVindexRegistry...',
target: merchantAddress,
});
// isTrusted = !isBlacklisted && score >= 700
React Hooks
useReputation
import { useReputation } from 'payid-react';
function MerchantCard({ address }: { address: string }) {
const { data, isLoading } = useReputation({
registryAddress: '0x...',
target: address as `0x${string}`,
});
if (isLoading) return <Spinner />;
return (
<div>
<p>Score: {data?.score ?? 500}/1000</p>
{data?.isBlacklisted && <Badge color="red">Blacklisted</Badge>}
{data?.isTrusted && <Badge color="green">Trusted</Badge>}
</div>
);
}
useCanReport
import { useCanReport } from 'payid-react';
function ReportButton() {
const { canReport } = useCanReport({ registryAddress: '0x...' });
return (
<button disabled={!canReport}>
Report Scam
</button>
);
}
Smart Contract: VindexRegistry
Key Functions
// View reputation (default 500)
function getReputation(address account) external view returns (uint16);
// Check blacklist
function isBlacklisted(address account) external view returns (bool);
// Check if trusted (not blacklisted + score >= threshold)
function isTrusted(address account, uint16 threshold) external view returns (bool);
// Submit staked report with evidence hash
function submitReport(address target, string calldata evidenceHash) external payable;
// Confirm a report (requires minReporterReputation)
function confirmReport(uint256 reportId) external;
// Admin / Engine resolve
function resolveReport(uint256 reportId, bool valid) external;
// Slash false reporter
function slashReporter(uint256 reportId) external;
Parameters
| Parameter | Default | Description |
|---|---|---|
minStake | 0.001 ETH | Minimum stake to submit a report |
consensusThreshold | 3 | Unique high-reputation confirmations needed |
minReporterReputation | 700 | Minimum reputation to count as a valid confirmer |
Reporting Flow
- Reporter submits report with
msg.value >= minStake+ evidence hash (IPFS/Arweave CID) - Sentinels (users with rep ≥ 700) confirm the report
- When confirmations reach
consensusThreshold, report auto-resolves as valid - Target loses reputation (penalty up to 200 points)
- If target rep < 100 → auto-blacklisted
Events
event ReputationUpdated(address indexed account, uint16 oldScore, uint16 newScore, string reason);
event Blacklisted(address indexed account, uint256 reportId, string evidenceHash);
event Unblacklisted(address indexed account, string reason);
event ReportSubmitted(uint256 indexed reportId, address indexed target, address indexed reporter, string evidenceHash, uint256 stake);
event ReportResolved(uint256 indexed reportId, bool valid, uint16 reputationDelta);
Integration with PAY.ID Payments
Gate payments by reputation before evaluation:
import { useReputation } from 'payid-react';
import { usePayIDFlow } from 'payid-react';
function SafePayButton({ merchant }: { merchant: string }) {
const { isBlacklisted } = useReputation({
registryAddress: '0x...',
target: merchant as `0x${string}`,
});
const { execute } = usePayIDFlow();
if (isBlacklisted) {
return <button disabled>🚫 Merchant Blacklisted</button>;
}
return <button onClick={() => execute({ ... })}>Pay</button>;
}
Security Model
- Fail-closed: No reputation data = not trusted
- Staked reporting: False reports cost money (stake can be slashed)
- Consensus: Single reporter cannot blacklist someone; requires multiple high-reputation confirmations
- Engine override: AI/off-chain analysis can resolve reports manually