This guide provides security best practices for operators, developers, and users of QuorumCredit.
- Operator Security
- Key Management
- Contract Deployment
- Access Control
- Monitoring & Incident Response
- User Security
- Development Security
Critical: Admin keys control the entire protocol. Compromise of admin keys can lead to:
- Unauthorized contract upgrades
- Configuration changes
- Fund theft
- Protocol shutdown
Best Practices:
-
Use Hardware Wallets: Store admin keys on hardware wallets (Ledger, Trezor)
# Never store keys in plaintext files # Use hardware wallet for signing stellar keys add admin-hw --hw
-
Implement Multisig: Require multiple signatures for admin functions
# Initialize with 3-of-5 multisig stellar contract invoke --id $CONTRACT_ID --fn initialize \ --source $DEPLOYER_SECRET_KEY -- \ --admins '["'$ADMIN1'","'$ADMIN2'","'$ADMIN3'","'$ADMIN4'","'$ADMIN5'"]' \ --admin_threshold 3
-
Separate Roles: Use different keys for different functions
- Deployer key: Only for initial deployment and initialization
- Admin keys: For ongoing governance
- Operator key: For routine operations (pause/unpause)
-
Rotate Keys Regularly: Change admin keys periodically
- Quarterly minimum
- Immediately if compromise is suspected
- After staff changes
-
Secure Key Storage:
- Never commit keys to version control
- Use
.envfiles with.gitignore - Store in secure vaults (HashiCorp Vault, AWS Secrets Manager)
- Encrypt at rest
Recommendation: Use at least 2-of-3 multisig for production
| Scenario | Threshold | Rationale |
|---|---|---|
| Testnet | 1-of-1 | Development only |
| Staging | 2-of-3 | Prevent single-key compromise |
| Mainnet | 3-of-5 | High security, operational flexibility |
Use pause for:
- Emergency response to security issues
- Contract upgrades
- Maintenance windows
- Investigating anomalies
Pause procedure:
# 1. Pause the contract
stellar contract invoke --id $CONTRACT_ID --fn pause --network mainnet \
--source $ADMIN_SECRET_KEY -- --admin_signers '["'$ADMIN1'","'$ADMIN2'","'$ADMIN3'"]'
# 2. Investigate and fix
# ... perform investigation ...
# 3. Unpause when ready
stellar contract invoke --id $CONTRACT_ID --fn unpause --network mainnet \
--source $ADMIN_SECRET_KEY -- --admin_signers '["'$ADMIN1'","'$ADMIN2'","'$ADMIN3'"]'Never:
- Commit secret keys to version control
- Share keys via email or chat
- Store keys in plaintext
- Use the same key for multiple purposes
- Reuse keys across networks (testnet/mainnet)
Always:
- Use environment variables for keys
- Rotate keys regularly
- Use hardware wallets for production
- Implement key access logging
- Backup keys securely
Secure .env setup:
# .env (NEVER commit this)
NETWORK=mainnet
DEPLOYER_SECRET_KEY="SB..."
ADMIN_SECRET_KEY_1="SB..."
ADMIN_SECRET_KEY_2="SB..."
ADMIN_SECRET_KEY_3="SB..."
TOKEN_CONTRACT="CA..."Protect .env:
# Add to .gitignore
echo ".env" >> .gitignore
echo ".env.local" >> .gitignore
# Restrict file permissions
chmod 600 .env
# Use secure vaults in production
# Example: AWS Secrets Manager
aws secretsmanager get-secret-value --secret-id quorum-credit-keysRotation schedule:
- Quarterly: Routine rotation
- Immediately: If compromise suspected
- After staff changes: Remove departing team member's keys
- After security incident: Rotate all keys
Rotation procedure:
- Generate new admin keys
- Update contract configuration with new keys
- Verify new keys work
- Revoke old keys
- Document rotation in audit log
- All tests passing:
cargo test - No clippy warnings:
cargo clippy - Code reviewed by 2+ team members
- Security audit completed (for mainnet)
- Testnet deployment verified
- Deployment script tested
- Rollback plan documented
- Monitoring configured
- Communication plan ready
Critical: Follow this exact sequence to prevent front-running attacks
# Step 1: Build WASM
cargo build --target wasm32-unknown-unknown --release
# Step 2: Deploy contract (deployer signs)
CONTRACT_ID=$(stellar contract deploy \
--wasm target/wasm32-unknown-unknown/release/quorum_credit.wasm \
--network mainnet \
--source $DEPLOYER_SECRET_KEY)
# Step 3: Initialize immediately (SAME deployer key)
stellar contract invoke \
--id $CONTRACT_ID \
--fn initialize \
--network mainnet \
--source $DEPLOYER_SECRET_KEY \
-- \
--deployer $DEPLOYER_ADDRESS \
--admins '["'$ADMIN1'","'$ADMIN2'","'$ADMIN3'"]' \
--admin_threshold 2 \
--token $TOKEN_CONTRACTWhy this matters: If initialization is delayed, an attacker could call initialize first with malicious parameters.
Before mainnet deployment:
- Deploy to testnet: Follow deployment sequence
- Run integration tests: Test all critical paths
- Verify configuration: Check
get_config()returns expected values - Test admin functions: Verify multisig works
- Simulate incident: Test pause/unpause
- Monitor for 24 hours: Watch for anomalies
Before upgrading:
- Pause the contract
- Backup current state (if possible)
- Test new WASM on testnet
- Verify upgrade procedure
- Prepare rollback plan
Upgrade procedure:
# 1. Build new WASM
cargo build --target wasm32-unknown-unknown --release
# 2. Pause contract
stellar contract invoke --id $CONTRACT_ID --fn pause --network mainnet \
--source $ADMIN_SECRET_KEY -- --admin_signers '["'$ADMIN1'","'$ADMIN2'"]'
# 3. Install new WASM
NEW_WASM_HASH=$(stellar contract install \
--wasm target/wasm32-unknown-unknown/release/quorum_credit.wasm \
--network mainnet \
--source $ADMIN_SECRET_KEY)
# 4. Upgrade contract
stellar contract invoke --id $CONTRACT_ID --fn upgrade --network mainnet \
--source $ADMIN_SECRET_KEY -- \
--admin_signers '["'$ADMIN1'","'$ADMIN2'"]' \
--new_wasm_hash $NEW_WASM_HASH
# 5. Unpause contract
stellar contract invoke --id $CONTRACT_ID --fn unpause --network mainnet \
--source $ADMIN_SECRET_KEY -- --admin_signers '["'$ADMIN1'","'$ADMIN2'"]'| Role | Functions | Requirements |
|---|---|---|
| Deployer | initialize |
Must sign deployment tx |
| Admin | pause, unpause, upgrade, set_config |
Must meet admin_threshold |
| Voucher | vouch, increase_stake, decrease_stake, withdraw_vouch |
Must sign tx |
| Borrower | request_loan, repay |
Must sign tx |
| Anyone | get_config, get_loan, get_vouches, is_eligible |
Read-only |
Always verify:
- Caller is authorized for the function
- Caller has required signatures (for multisig)
- Caller has sufficient balance (for token transfers)
- Caller is not blacklisted (for borrowers)
Example:
// Verify caller is the borrower
borrower.require_auth();
// Verify caller is an admin (multisig)
verify_admin_signatures(&env, &admin_signers, &admin_threshold)?;Use blacklist for:
- Repeat defaulters
- Fraudulent borrowers
- Sanctioned addresses
- Compromised accounts
Blacklist procedure:
# Add to blacklist
stellar contract invoke --id $CONTRACT_ID --fn add_to_blacklist \
--network mainnet --source $ADMIN_SECRET_KEY -- \
--admin_signers '["'$ADMIN1'","'$ADMIN2'"]' \
--borrower $BORROWER_ADDRESS
# Remove from blacklist
stellar contract invoke --id $CONTRACT_ID --fn remove_from_blacklist \
--network mainnet --source $ADMIN_SECRET_KEY -- \
--admin_signers '["'$ADMIN1'","'$ADMIN2'"]' \
--borrower $BORROWER_ADDRESSMonitor these metrics:
- Contract balance (should never go negative)
- Loan disbursements (unusual spikes)
- Default rate (should be < 5%)
- Yield distribution (should match calculations)
- Admin actions (all should be logged)
- Contract pause state (should be unpaused normally)
Monitoring tools:
- Stellar Horizon API for transaction history
- Soroban RPC for contract state
- Custom indexer for event tracking
- Alerting system (PagerDuty, Opsgenie)
Incident severity levels:
| Level | Impact | Response Time |
|---|---|---|
| Critical | Funds at risk, contract compromised | Immediate (< 5 min) |
| High | Significant functionality broken | 15 minutes |
| Medium | Minor functionality broken | 1 hour |
| Low | Documentation or UI issues | 24 hours |
Critical incident response:
- Pause contract (< 1 minute)
- Notify stakeholders (< 5 minutes)
- Investigate (ongoing)
- Develop fix (parallel)
- Test fix on testnet (before deploying)
- Deploy fix (multisig approval)
- Unpause contract (after verification)
- Post-mortem (within 24 hours)
Log all:
- Admin actions (pause, unpause, upgrade, config changes)
- Loan disbursements and repayments
- Slash events
- Authorization failures
- Configuration changes
Audit trail:
# Query contract events
stellar events --id $CONTRACT_ID --network mainnet
# Filter by event type
stellar events --id $CONTRACT_ID --network mainnet --type "admin/*"
# Export for analysis
stellar events --id $CONTRACT_ID --network mainnet --format json > audit.jsonBackup procedures:
- Contract state: Snapshot contract storage regularly
- Configuration: Backup
get_config()output - Admin keys: Secure backup of admin keys (encrypted)
- Documentation: Keep deployment and configuration docs updated
Recovery procedures:
- Identify issue: Determine what went wrong
- Pause contract: Stop all operations
- Assess damage: Determine scope of impact
- Develop fix: Create patched WASM
- Deploy fix: Use upgrade procedure
- Verify recovery: Confirm state is correct
- Unpause: Resume operations
This section is for borrowers and vouchers — anyone interacting with QuorumCredit day-to-day, not just protocol operators. The single biggest cause of user fund loss is not a smart contract bug — it's a leaked secret key, a fake website, or a too-good-to-be-true "guaranteed yield" pool. Read this section before you sign your first transaction.
Protect your account:
- Use hardware wallet for loan requests
- Never share your secret key
- Verify contract address before interacting
- Check loan terms before accepting
- Set calendar reminders for repayment deadlines
Repayment security:
- Repay before deadline to avoid default
- Verify repayment amount before sending
- Keep proof of repayment (transaction hash)
- Confirm yield was received
Protect your stake:
- Use hardware wallet for vouching
- Never share your secret key
- Verify borrower identity before vouching
- Start with small stakes to test
- Diversify across multiple borrowers
Vouch responsibly:
- Only vouch for people you trust
- Understand the risks (50% slash on default)
- Monitor borrower's loan status
- Participate in slash votes
- Withdraw vouches when no longer comfortable
Your wallet is the only thing standing between your funds and an attacker. Treat wallet hygiene as seriously as the protocol treats admin key hygiene.
Choosing a wallet:
- Prefer a hardware wallet (Ledger, Trezor) for any meaningful stake or loan amount — keys never leave the device and transactions are signed on-screen.
- If using a software/browser wallet (Freighter, xBull, Lobstr, Rabet), keep it updated and only install extensions from official app store listings.
- Never use a wallet whose seed phrase was generated by, or entered into, a website, Discord bot, or "recovery tool" — legitimate wallets generate seeds locally on your device.
Operating your wallet safely:
- Read every transaction before signing — check the destination contract ID, function name, and amount. Soroban wallets show a simulation; don't blind-sign.
- Use a dedicated wallet for QuorumCredit interactions, separate from wallets holding your long-term savings.
- Lock your wallet/browser session when not in use, and never leave a hardware wallet plugged in and unlocked unattended.
- Disable auto-connect / "always allow" for dApp connections; approve each session explicitly.
- Keep the device and OS your wallet runs on patched — malware that reads clipboards or keystrokes can silently swap a pasted address or exfiltrate a seed phrase.
The same principles that protect protocol admin keys apply to your personal keys — just at individual scale.
Never:
- Type your secret key (starts with
S...) into any website, form, chat, or "support" bot — QuorumCredit staff will never ask for it. - Store your secret key in plaintext notes, screenshots, cloud drives, email drafts, or password managers without encryption.
- Share your seed phrase or secret key with anyone claiming to need it for "verification," "unlocking a stuck transaction," or "syndication approval."
- Reuse the same key across testnet and mainnet, or across unrelated protocols.
Always:
- Write your seed phrase down on paper or a metal backup, store it offline, and never photograph or type it.
- Use a hardware wallet or a passphrase-protected key for anything beyond small test amounts.
- Verify you are on the correct, official domain before connecting a wallet or entering any key material.
- If you ever suspect a key has been exposed, move funds to a new address immediately and treat the old key as burned — do not "wait and see."
Be aware of:
- Fake contract addresses
- Phishing emails claiming to be from QuorumCredit
- Fake websites mimicking QuorumCredit
- Social engineering attacks
- Fake "support" accounts in Discord/Telegram DMs offering to "help" with a stuck transaction
- Malicious browser extensions or fake wallet-connect pop-ups that clone the real signing UI
- Airdrop/giveaway scams asking you to "verify your wallet" by connecting and signing a blank transaction
Verify authenticity:
- Check contract address on GitHub
- Use official website only
- Verify email sender domain
- Never click links in unsolicited emails
- Use hardware wallet for all transactions
- Bookmark the official site rather than following search-engine ads or links shared in chats
- Remember: no legitimate team member will ever DM you first or ask for your secret key/seed phrase
QuorumCredit's social-collateral model reduces (but does not eliminate) rug-pull risk, since vouchers stake real XLM against borrowers. Watch for these warning signs before vouching, borrowing, or interacting with any "QuorumCredit-branded" contract or pool:
Red flags on a contract or deployment:
- Admin key is a single signer with no multisig (
admin_thresholdof 1) on a "mainnet" deployment — one compromised or malicious key can drain or reconfigure everything. - No public audit report, or an audit report that doesn't match the deployed contract's WASM hash.
- Contract is unpausable or the pause function is missing/disabled — legitimate deployments always retain an emergency pause path.
- Upgrade authority held by an anonymous or unverifiable address with no timelock.
- Contract address does not match the one published in this repository or the official website/GitHub.
Red flags on a "deal" or pool:
- Guaranteed or unusually high yield with "no risk" — real yield in this protocol comes from repaid loans; if the return doesn't map to a loan and repayment schedule, question it.
- Pressure to vouch or deposit quickly ("limited slots," "price goes up in 1 hour").
- Anonymous team with no verifiable history, or a team that refuses to answer basic questions about the deployment's admin/multisig configuration.
- Requests to send funds to a wallet address directly instead of interacting with the published contract.
- Clone/fork projects using QuorumCredit's name or branding without a link back to this repository.
Before you vouch or borrow, verify:
- Contract ID matches the address published in this README/GitHub release
-
get_config()shows a multisigadmin_threshold≥ 2 for any mainnet deployment - The deployment has a public audit report, or you're knowingly using an unaudited testnet/beta
- The team/documentation is reachable through the official channels below, not only a Discord DM
Run through this before every session, not just the first time:
- I am on the official website/domain and have verified the contract address
- My wallet is a hardware wallet, or a software wallet I fully control the seed for
- I have never entered my secret key or seed phrase into a website, bot, or form
- I reviewed the transaction (destination, function, amount) before signing — I did not blind-sign
- I am vouching/borrowing only what I can afford to lose, given the slash risk
- I diversified vouches across multiple borrowers rather than concentrating stake in one
- I set a reminder for my loan/vouch deadlines (repayment, cooldown, withdrawal windows)
- I know how to reach official support channels if something looks wrong
- I have not connected my wallet to any unfamiliar dApp claiming to be QuorumCredit
- My device/browser and wallet software are up to date
If you suspect your account is compromised, you've interacted with a phishing site, or you've spotted a likely scam/rug pull impersonating QuorumCredit, act immediately — speed matters more than perfect information.
If you believe your key/seed phrase is exposed:
- Move funds first, ask questions later. If you can still access the wallet, immediately transfer remaining funds to a new address generated on a device you trust.
- Withdraw any active vouches or loan positions you can still control, before the exposed key can be used against them.
- Stop using the exposed key entirely — do not reuse it for anything, even after "cleaning" the device.
- Report it so the team can watch for related on-chain activity and warn other users if it's part of a wider campaign.
If you encounter a phishing site, fake support account, or suspected rug pull:
- Do not engage further, click links, or share any additional information.
- Screenshot the phishing site/message/contract address for evidence.
- Report it through the official channels below.
- Warn others in official community channels only — do not amplify the scam link itself.
Official contact channels (use these, and only these, for security emergencies):
| Situation | Channel |
|---|---|
| Compromised key, active fund-loss risk | Email security@quorumcredit.io with subject [URGENT] Account Compromise |
| Phishing site / fake support / suspected rug pull impersonating QuorumCredit | Email security@quorumcredit.io or file a GitHub Security Advisory |
| Smart contract vulnerability | Follow SECURITY.md — do not open a public GitHub issue |
| General questions / community support | Stellar Developer Discord |
QuorumCredit staff will never DM you first, never ask for your secret key or seed phrase, and never ask you to "verify" your wallet by signing a blind transaction. Any message that does is impersonation — report it using the channels above.
All code changes require:
- 2+ peer reviews
- Security review for sensitive code
- Automated testing (100% coverage for critical paths)
- Clippy checks (no warnings)
- Cargo audit (no vulnerabilities)
Secure dependencies:
# Check for vulnerabilities
cargo audit
# Update dependencies
cargo update
# Pin versions in Cargo.toml
soroban-sdk = "=20.0.0" # Exact versionAvoid:
- Unvetted dependencies
- Dependencies with known vulnerabilities
- Outdated dependencies
- Typosquatting variants
Test coverage:
- Unit tests: 100% for critical functions
- Integration tests: All user flows
- Property-based tests: Invariants
- Fuzz tests: Edge cases
- Security tests: Authorization, overflow, underflow
Test execution:
# Run all tests
cargo test
# Run with output
cargo test -- --nocapture
# Run specific test
cargo test test_vouch_and_loan_disbursed
# Generate coverage
cargo tarpaulin --out HtmlBefore mainnet deployment:
- Internal audit: Team review
- External audit: Third-party security firm
- Formal verification: Mathematical proof of correctness (optional)
- Bug bounty: Incentivize community to find issues
Audit checklist:
- No integer overflow/underflow
- No reentrancy vulnerabilities
- Proper authorization checks
- Correct yield/slash calculations
- State consistency maintained
- Error handling complete
- No hardcoded values
- Proper event logging
Do not:
- Open public GitHub issues
- Post on social media
- Share with unauthorized parties
- Attempt to exploit vulnerabilities
Do:
- Report privately via GitHub Security Advisories
- Include detailed reproduction steps
- Allow time for fix before disclosure
- Follow responsible disclosure timeline
- Day 0: Report vulnerability
- Day 1: Acknowledgment from team
- Day 7: Initial assessment
- Day 30: Fix developed and tested
- Day 45: Fix deployed to mainnet
- Day 60: Public disclosure (if appropriate)
- All tests passing
- No clippy warnings
- No cargo audit vulnerabilities
- Code reviewed by 2+ team members
- Security audit completed
- Testnet deployment verified
- Admin multisig configured
- Monitoring configured
- Incident response plan ready
- Communication plan ready
- Monitor contract balance
- Monitor loan metrics
- Monitor admin actions
- Review audit logs daily
- Rotate admin keys quarterly
- Update security documentation
- Conduct security training
- Test incident response procedures
- Keep dependencies updated
- Monitor security advisories
- Conduct regular security reviews
- Perform penetration testing
- Update threat model
- Review and update this guide
- SECURITY.md - Vulnerability disclosure policy
- Deployment Guide - Deployment procedures
- Monitoring Guide - Monitoring setup
- Threat Model - Security threat analysis
- Stellar Security - Stellar security best practices
- Soroban Security - Soroban security best practices
For security questions or concerns:
- Email: security@quorumcredit.io
- GitHub: Security Advisories
- Discord: Stellar Developer Discord