QuorumProof is a decentralized credential verification platform built on Stellar Soroban. This threat model identifies attack vectors, mitigations, and operational recommendations for the core contracts and dispute resolution system.
Scope: quorum_proof, sbt_registry, zk_verifier contracts and their interactions.
Last Updated: May 27, 2026
-
Credentials — Soulbound tokens representing verified professional qualifications
- Issued by trusted institutions (universities, licensing bodies)
- Non-transferable, tied to individual identity
- Revocable by issuer
- Value: Enables international hiring, credential portability
-
Quorum Slices — Trust networks defining credential attestation requirements
- Created by credential issuers
- Define threshold for multi-party consensus
- Weighted voting model (FBA-inspired)
- Value: Ensures credential authenticity through distributed trust
-
Attestations — Cryptographic signatures from slice members
- Prove credential holder meets requirements
- Time-windowed (valid for specific period)
- Weighted according to slice definition
- Value: Enables instant verification without contacting original issuer
-
Soulbound Tokens (SBTs) — On-chain representation of credentials
- Minted by
sbt_registryafter credential verification - Non-transferable by design
- Queryable by any third party
- Value: Portable, verifiable proof of qualification
- Minted by
| Actor | Motivation | Capability | Likelihood |
|---|---|---|---|
| Credential Fraudster | Obtain fake credentials to misrepresent qualifications | Medium (social engineering, bribery) | High |
| Slice Member Attacker | Attest false credentials for payment | Medium (insider threat) | Medium |
| Contract Exploiter | Find smart contract vulnerabilities | High (security researcher) | Medium |
| Network Attacker | Disrupt credential verification | Medium (DDoS, network partition) | Low |
| Malicious Issuer | Issue credentials to unqualified individuals | High (institutional access) | Low |
| Actor | Motivation | Capability | Likelihood |
|---|---|---|---|
| Admin Collusion | Bypass verification requirements | High (full contract access) | Low |
| Disgruntled Employee | Sabotage credential system | High (institutional access) | Low |
| Compromised Key | Unauthorized credential issuance | High (key compromise) | Medium |
Attack: Attacker creates fake credentials without authorization.
Vector:
- Call
issue_credentialwithout proper authorization - Bypass issuer authentication
- Forge metadata hash
Mitigation:
- ✅
require_auth()enforced onissue_credential— only issuer can create credentials - ✅ Issuer address stored in credential — cannot be spoofed
- ✅ Metadata hash is immutable after issuance
- ✅ Credential ID is monotonically increasing — no ID collision possible
Residual Risk: Low. Requires compromised issuer key.
Attack: Non-slice-member attests credential, or attests outside time window.
Vector:
- Call
attestwithout being in the slice - Attest outside the time window
- Attest the same credential twice
Mitigation:
- ✅
NotInSliceerror if caller not in attestor list - ✅ Attestation time window enforced (
AttestationTimeWindowstruct) - ✅
DuplicateAttestorerror prevents double-attestation - ✅ Weighted threshold prevents single-member bypass
Residual Risk: Low. Requires slice member compromise.
Attack: Attacker transfers SBT to another address, breaking non-transferability.
Vector:
- Call
transferon SBT - Exploit
approve+transfer_frompattern - Bypass owner check
Mitigation:
- ✅
transferfunction always panics withSoulboundNonTransferable - ✅ No
approveortransfer_fromfunctions exist - ✅ SBT can only be minted or burned, never transferred
- ✅ Owner field is immutable except via admin-gated recovery
Residual Risk: None. Transfer is cryptographically impossible.
Attack: Attester signs a revoked credential, making it appear valid.
Vector:
- Revoke credential after attestation
- Attest revoked credential
- Query
is_attestedon revoked credential
Mitigation:
- ✅
is_attestedcheckscredential.revokedflag - ✅ Revoked credentials cannot be attested (checked in
attest) - ✅ Revocation is irreversible
- ✅ Revocation event is emitted for audit trail
Residual Risk: Low. Requires issuer to revoke after attestation (expected behavior).
Attack: Attacker calls revoke_credential twice, potentially triggering state inconsistency.
Vector:
- Call
revoke_credentialon already-revoked credential - Exploit state machine transition
Mitigation:
- ✅
AlreadyRevokederror on double revocation - ✅ Revocation flag is idempotent
- ✅ Revocation event only emitted once
Residual Risk: None. Double revocation is explicitly rejected.
Attack: Attacker creates slice with threshold = 0 or threshold > attestor count.
Vector:
- Call
create_slicewith invalid threshold - Bypass weighted voting requirement
Mitigation:
- ✅
threshold > 0validated increate_slice - ✅
threshold <= attestors.len()validated - ✅ Weighted threshold prevents single-member bypass
- ✅
MAX_ATTESTORS_PER_SLICE = 20prevents unbounded slices
Residual Risk: None. Threshold validation is enforced.
Attack: Attacker supplies malicious contract address for cross-contract calls.
Vector:
- Call
sbt_registry.mintwith fakequorum_proof_id - Substitute
zk_verifieraddress inverify_claim - Invoke attacker-controlled contract
Mitigation:
- ✅ Contract addresses stored in persistent storage (
DataKey::QuorumProofId, etc.) - ✅ Addresses initialized once and never changed
- ✅ Cross-contract calls use stored addresses, not caller input
- ✅
initializeis guarded against double-initialization
Residual Risk: None. Contract addresses are immutable after initialization.
Attack: Attacker calls verify_claim with invalid proof, bypassing ZK verification.
Vector:
- Call
verify_claimwith empty or malformed proof - Exploit stub implementation (accepts any non-empty proof)
- Bypass claim verification
Mitigation:
⚠️ STUB:verify_claimis admin-gated (only admin can call)⚠️ STUB: Accepts any non-empty byte string as valid proof- ✅ No production credential decision relies on
verify_claimoutput (v1.0) - ✅ README and code comments warn of stub status
- 🔄 Planned (v1.1): Real Groth16/PLONK verification
Residual Risk: Medium (stub only). Mitigated by admin gate and documentation.
Attack: Attacker waits for credential TTL to expire, causing data loss.
Vector:
- Exploit missing
extend_ttl()calls - Ledger entry evicted after TTL expires
- Credential becomes inaccessible
Mitigation:
- ✅ Every storage write followed by
extend_ttl() - ✅
STANDARD_TTL = 16,384ledgers (~2 days) - ✅
EXTENDED_TTL = 524,288ledgers (~60 days) for persistent data - ✅ TTL renewal tested in test suite
Residual Risk: Low. Requires missing TTL extension (code review catches this).
Attack: Admin pauses contract indefinitely, blocking credential issuance.
Vector:
- Call
pauseand never callunpause - Permanently disable credential system
- Cause denial of service
Mitigation:
- ✅
unpauseis always available to admin - ✅ No way to permanently brick contract
- ✅ Read-only functions remain accessible while paused
- ✅ Pause event is emitted for monitoring
Residual Risk: Low. Requires admin compromise (detected by monitoring).
┌─────────────────────────────────────────────────────────────┐
│ Dispute Initiated │
│ - Credential holder challenges attestation │
│ - Provides evidence (metadata, timestamps) │
│ - Dispute enters PENDING state │
└────────────────────┬────────────────────────────────────────┘
│
┌────────────┴────────────┐
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ RESOLVED_VALID │ │ RESOLVED_INVALID │
│ (Attestation OK)│ │ (Attestation Bad)│
└──────────────────┘ └──────────────────┘
│ │
▼ ▼
Attestation Attestation
Remains Valid Revoked
Attack: Attacker files frivolous disputes to harass credential holders.
Vector:
- File dispute for valid credential
- Provide fake or insufficient evidence
- Waste slice member time reviewing disputes
Mitigation:
- ✅ Dispute filing requires
require_auth()from the credential holder — third parties cannot file on their behalf - ✅ Dispute evidence is required at filing time and stored immutably on-chain (cannot be added retroactively)
- ✅ Evidence must include: credential ID, dispute reason, supporting metadata hash, and timestamp
- ✅ Slice members can reject disputes with insufficient evidence before voting begins
- ✅ Dispute history is permanently auditable — repeated frivolous filers are identifiable
- ✅ Dispute filing is rate-limited per credential (one active dispute at a time)
Residual Risk: Low. Requires credential holder compromise; evidence requirements deter frivolous filings.
Attack: Admin and slice members collude to invalidate valid attestations.
Vector:
- Admin marks valid dispute as RESOLVED_INVALID
- Slice members vote to revoke valid attestation
- Credential holder loses qualification
Mitigation:
- ✅ Dispute resolution requires multi-sig approval (threshold-based voting)
- ✅ Dispute evidence is public and auditable on-chain
- ✅ Revocation event is emitted (can be monitored by any party)
- ✅ Credential holder can appeal via new attestation from a different slice
- ✅ Operator requirement: Deploy admin as a multisig account (2-of-3 or 3-of-5 Stellar multisig) — see Section 4.3 recommendations
- 🔄 Planned (v2.0): On-chain multi-sig admin enforcement via contract logic
Residual Risk: Medium. Operators must configure Stellar account-level multisig for admin keys (see Section 4.3).
Attack: Attacker delays dispute resolution indefinitely.
Vector:
- File dispute and never resolve it
- Credential holder left in limbo
- Slice members cannot attest new credentials
Mitigation:
- ✅ Dispute has TTL (expires after 30 days)
- ✅ Expired disputes auto-resolve as RESOLVED_VALID
- ✅ Slice members can force resolution
- ✅ Dispute timeout event is emitted
Residual Risk: Low. Timeout is enforced by contract.
Attack: Attacker modifies dispute evidence after filing.
Vector:
- File dispute with evidence
- Modify evidence on-chain
- Slice members see different evidence
Mitigation:
- ✅ Dispute evidence is immutable (stored as hash)
- ✅ Evidence hash is verified before dispute resolution
- ✅ Tampering causes
InvalidEvidenceerror - ✅ Evidence is stored off-chain (IPFS) with hash verification
Residual Risk: None. Evidence is cryptographically protected.
Attack: Attacker bribes slice member to vote for invalid dispute resolution.
Vector:
- Offer payment to slice member
- Slice member votes to revoke valid attestation
- Attacker gains unfair advantage
Mitigation:
- ✅ Voting is on-chain and auditable
- ✅ Bribery is detectable (pattern analysis)
- ✅ Slice members can be removed by issuer
- ✅ Reputation system tracks voting history (planned v2.0)
Residual Risk: Medium. Requires social engineering (off-chain).
- Multi-Sig Admin (Required): Configure the admin Stellar account as a multisig with at least 2-of-3 signers before deploying to mainnet. Use
stellar account set-options --master-weight 0 --med-threshold 2 --high-threshold 2 --signer <key2>,1 --signer <key3>,1. This prevents single-key compromise from resolving disputes unilaterally. - Dispute Evidence Requirements: Enforce that disputes include a metadata hash pointing to off-chain evidence (IPFS or equivalent). Reject disputes with empty or placeholder evidence hashes at the application layer.
- Monitoring: Alert on unusual dispute patterns — high volume from a single address, rapid resolution (< 1 hour), or disputes filed and resolved by overlapping slice members.
- Audit Trail: Log all dispute decisions with timestamps, voter identities, and evidence hashes. Retain logs for at least 2 years.
- Appeal Process: Allow credential holders to re-attest via a different quorum slice after a dispute resolves against them. Document this process for credential holders.
- Reputation Tracking: Monitor slice member voting patterns. Flag members who consistently vote with the majority on disputed cases for manual review (planned v2.0 on-chain reputation system).
- Evidence Review: Always review dispute evidence before voting
- Conflict of Interest: Recuse yourself from disputes involving your institution
- Documentation: Document your reasoning for each dispute vote
- Escalation: Escalate suspicious disputes to issuer for investigation
- Dispute Monitoring: Monitor your credentials for disputes
- Evidence Preservation: Keep records of your qualifications
- Appeal Rights: Know your right to appeal dispute decisions
- Transparency: Request audit trail of dispute decisions
| Component | Key Type | Storage | Rotation | Backup |
|---|---|---|---|---|
| Admin | Stellar Account | Hardware Wallet | Quarterly | Secure Vault |
| Issuer | Stellar Account | Hardware Wallet | Quarterly | Secure Vault |
| Slice Member | Stellar Account | Hardware Wallet | Quarterly | Secure Vault |
| ZK Prover | Private Key | Secure Enclave | Annually | Encrypted |
Recommendations:
- Use hardware wallets for all admin/issuer keys
- Implement key rotation schedule
- Maintain encrypted backups in geographically distributed locations
- Never store keys in version control or logs
| Event | Severity | Action |
|---|---|---|
Unauthorized issue_credential attempt |
Critical | Immediate investigation |
| Double revocation attempt | High | Review contract logs |
| Unusual dispute volume | High | Investigate slice members |
| TTL expiry (data loss) | Critical | Immediate remediation |
| Cross-contract call failure | High | Review contract state |
| Pause event | Medium | Verify admin action |
- Detection: Monitor contract events and logs
- Containment: Pause contract if necessary
- Investigation: Review transaction history and evidence
- Remediation: Fix vulnerability and redeploy
- Communication: Notify affected parties
- Post-Mortem: Document lessons learned
- GDPR: Credential data may contain PII — ensure compliance with data retention policies
- FERPA: Educational credentials are protected — verify institutional policies
- Professional Licensing: Verify compliance with national licensing board requirements
- Cross-Border: Ensure compliance with international credential recognition agreements
- Issuer Authority: Each issuer controls their own credentials
- Slice Autonomy: Slice members vote independently
- Dispute Resolution: Multi-party consensus required
- Emergency Powers: Admin can pause contract (limited scope)
| Risk | Likelihood | Impact | Mitigation | Status |
|---|---|---|---|---|
| Credential Forgery | Low | Critical | Auth checks, issuer verification | ✅ Mitigated |
| Unauthorized Attestation | Low | High | Slice membership, time windows | ✅ Mitigated |
| SBT Transfer | None | Critical | Non-transferable by design | ✅ Mitigated |
| Revoked Credential Attestation | Low | High | Revocation checks | ✅ Mitigated |
| Double Revocation | None | Low | Idempotent revocation | ✅ Mitigated |
| Slice Threshold Bypass | None | High | Threshold validation | ✅ Mitigated |
| Cross-Contract Substitution | None | Critical | Immutable addresses | ✅ Mitigated |
| ZK Verification Bypass | Medium | High | Admin gate, stub warning | |
| TTL Expiry & Data Loss | Low | High | TTL extension, monitoring | ✅ Mitigated |
| Pause/Unpause Abuse | Low | High | Unpause always available | ✅ Mitigated |
| False Dispute Filing | Low | Medium | Auth requirement, audit trail | ✅ Mitigated |
| Admin Collusion | Medium | Critical | Multi-sig (planned v2.0) | |
| Dispute Timeout Abuse | Low | Medium | TTL enforcement | ✅ Mitigated |
| Evidence Tampering | None | High | Cryptographic hashing | ✅ Mitigated |
| Slice Member Bribery | Medium | High | Monitoring, reputation (planned) |
- Real Groth16/PLONK proof verification
- Claim-specific privacy (selective disclosure)
- Proof generation framework
- Multi-sig admin requirement (2-of-3)
- Reputation system for slice members
- Appeal process for disputed credentials
- Automated evidence verification
- DAO-based dispute resolution
- Credential expiry and renewal
- Institutional rating system
- Revocation registry
| Role | Name | Date | Signature |
|---|---|---|---|
| Security Lead | |||
| Contract Author | |||
| Compliance Officer |
Last Reviewed: April 26, 2026 Next Review: October 26, 2026 (6-month cycle)