This document outlines the security architecture, potential vulnerabilities, and mitigation strategies for the Ethos Reputation Launch system. While this is a hackathon project demonstrating reputation-gated NFT launches, it implements professional security patterns and best practices.
- Security Considerations
- Overview
- Table of Contents
- Security Model
- Trust Assumptions
- Security Features
- Known Limitations
- Potential Attack Vectors
- Mitigation Strategies
- Audit Findings
- Emergency Procedures
- Security Best Practices for Users
- Security Best Practices for Administrators
- Code Review Checklist
- Reporting Security Issues
- Security Roadmap
- Additional Resources
The system operates under a trust-minimized but not trustless model:
- Onchain logic is trustless (immutable smart contracts)
- Oracle component requires trust (king/admin sets scores)
- Emergency recovery requires trust (king can transfer NFTs)
This hybrid model balances hackathon simplicity with reasonable security for a demonstration system.
Users must trust:
-
King (Contract Owner)
- Will not set malicious reputation scores
- Will only use emergency NFT transfer for legitimate recovery
- Will not pause contracts arbitrarily
- Will not abuse admin privileges
-
Admin (Score Setter)
- Will accurately fetch scores from Ethos API
- Will not manipulate scores for personal gain
- Will set scores in timely manner
Users do NOT need to trust:
-
Smart Contract Logic
- Minting rules are enforced programmatically
- Tier calculations are deterministic
- Token claims are guaranteed for NFT holders
- Soulbound property is enforced by code
-
Immutability
- Contracts cannot be upgraded
- Rules cannot be changed after deployment
- Tier thresholds are fixed at deployment
Implementation: KingReentrancyGuard module
Protected Functions:
ReputationNFT.mint()ReputationToken.claimTokens()
How it works:
/// @dev Restricts a function from being reentered.
modifier nonReentrant() {
// Revert if locked.
if (s_isLocked) {
revert NoReentrant();
}
// Lock before executing the function.
s_isLocked = true;
_;
// Unlock after the execution.
s_isLocked = false;
}Prevents:
- Recursive calls draining funds
- State manipulation via callback attacks
Test Coverage:
// Tested with malicious contracts attempting reentrancy
// All attempts properly blockedImplementation: Kingable and role-based permissions
Role Hierarchy:
King (Full Control)
├── Can pause/unpause contracts
├── Can set reputation scores
├── Can transfer NFTs (emergency recovery)
├── Can update reward amounts
└── Can assign/revoke admin role
Admin (Limited Control)
├── Can set reputation scores
└── Cannot pause or transfer NFTs
Users (No Admin Rights)
├── Can mint NFTs (if eligible)
├── Can claim tokens (if NFT owner)
└── Cannot transfer NFTs (soulbound)
Function Access Matrix:
| Function | King | Admin | User |
|---|---|---|---|
setEthosScore() |
✓ | ✓ | ✗ |
transferFrom() (NFT) |
✓ | ✗ | ✗ |
pauseContract() |
✓ | ✗ | ✗ |
setTiersClaimableTokens() |
✓ | ✗ | ✗ |
mint() |
✓ | ✓ | ✓ (if eligible) |
claimTokens() |
✓ | ✓ | ✓ (if owner) |
Implementation: KingablePausable module
Pausable Contracts:
ReputationNFT(can pause minting)ReputationToken(can pause claiming)
Usage:
// Pause minting
function pauseContract() external onlyKing {
// Call the internal `_pause` function.
_pause();
}
// Resume minting
function activateContract() external onlyKing {
// Call the internal `_activate` function.
_activate();
}When to use:
- Critical vulnerability discovered
- Oracle compromise detected
- Suspicious activity observed
- Planned maintenance
Important: Pausing does NOT affect:
- NFT ownership (users still own their NFTs)
- Token balances (claimed tokens remain)
- View functions (data still readable)
Zero Address Checks:
// Via KingCheckAddressLib
KingCheckAddressLib.ensureNonZero(address);Applied to:
- Contract constructor parameters
- Function arguments expecting addresses
Array Length Validation:
// In setEthosScoreBatch
if (users.length != scores.length) {
revert EthosIntegration__LengthMisMatch();
}Tier Threshold Validation:
// In TierManager
// Check: silver tier must be greater than the minimum
if (silver_ <= minimum_) {
revert TierManager__InvalidSilverThreshold();
}
// Check: gold tier must be greater than the silver tier
if (gold_ <= silver_) {
revert TierManager__InvalidGoldThreshold();
}Prevents:
- Locking funds in zero address
- Array mismatch attacks
- Invalid configuration states
Implementation: Override all ERC721 transfer functions
Code:
function transferFrom(address from, address to, uint256 tokenId)
public virtual override
{
if(msg.sender == s_king) {
_transfer(from, to, tokenId); // Emergency recovery
} else {
revert ReputationNFT__TokenIsSoulbound();
}
}Security Implications:
- Users cannot sell/transfer NFTs
- Prevents multi-wallet farming
- King maintains emergency transfer capability
- No marketplace compatibility (intentional)
Test Coverage:
// All transfer attempts by non-king addresses revert
// King transfers succeed (for emergency recovery)Implementation: Mapping tracks claim status
Code:
mapping(address => bool) public s_hasClaimed;
function claimTokens(uint256 nftId) external {
// Check: One-time claim only.
if (s_hasClaimed[msg.sender]) {
revert ReputationToken__AlreadyClaimed();
}
// ... mint tokens
}Prevents:
- Double-spending tokens
- Infinite minting exploits
Edge Case Handling:
- NFT transfer after claim doesn't grant new claim
- New owner of transferred NFT cannot claim (original minter already claimed)
-
Centralized Oracle
⚠️ - Issue: King/admin manually sets scores
- Risk: Malicious/incorrect score setting
- Mitigation: Trust assumption on king/admin
- Production Fix: Chainlink Functions or UMA oracle
-
No Score Refresh
⚠️ - Issue: Tier locked at mint, never updates
- Risk: Users keep tier even if reputation drops
- Mitigation: Snapshot-based design (intentional)
- Production Fix: Optional tier refresh mechanism
-
No Burning
⚠️ - Issue: NFTs cannot be destroyed
- Risk: Permanent association with wallet
- Mitigation: Emergency transfer by king
- Production Fix: Add burning function
-
Single Admin
⚠️ - Issue: Admin is single point of failure
- Risk: Admin key compromise or loss
- Mitigation: Trust assumption
- Production Fix: Multi-sig for admin operations
-
No Upgrade Path
⚠️ - Issue: Contracts are immutable
- Risk: Cannot fix bugs post-deployment
- Mitigation: Thorough testing pre-deployment
- Production Fix: UUPS proxy pattern
Attack: Malicious admin sets fake high scores for accomplices.
Impact:
- Undeserving users mint NFTs
- Illegitimate token claims
- System integrity compromised
Likelihood: Medium (requires admin compromise)
Mitigations:
- Trust assumption on admin
- Event emissions allow public monitoring
- Production: Multi-sig required for score setting
- Production: Delay + dispute period
Detection:
// Monitor ScoreUpdated events
event ScoreUpdated(address indexed user, uint256 score);Attack: King's private key is stolen.
Impact:
- Attacker can pause contracts
- Attacker can transfer all NFTs
- Attacker can set arbitrary scores
- Complete system takeover
Likelihood: Low (depends on key security)
Mitigations:
- Hardware wallet for king
- Multi-sig wallet in production
- Time-locks on critical operations
- Emergency recovery procedures
If Detected:
- Deploy new contracts immediately
- Announce compromise publicly
- Assist users with migration
- Investigate root cause
Attack: User temporarily boosts Ethos score, mints NFT, then drops score.
Impact:
- User gains tier benefits without maintaining reputation
- Undermines system fairness
Likelihood: Medium (depends on Ethos score mechanics)
Mitigations:
- Current: Snapshot-based design (tier locked at mint)
- Production: Time-weighted average scores
- Production: Reputation decay mechanism
- Production: Periodic tier verification
Attack: Attacker observes score-setting transaction in mempool, frontruns mint.
Impact:
- Minimal (score must be set anyway)
- User still gets NFT
- No financial loss
Likelihood: Low (no real incentive)
Mitigations:
- Public minting (no advantage to frontrun)
- No price discovery (fixed tiers)
- Mempool privacy in production (Flashbots)
Attack: Malicious admin sets score = 799 for victim (just below minimum).
Impact:
- Victim cannot mint NFT
- Requires legitimate score update
Likelihood: Low (requires malicious admin)
Mitigations:
- Trust assumption on admin
- Event monitoring detects suspicious scores
- King can override admin score
- Production: Multi-sig prevents single admin grief
Attack: Manipulate arithmetic to overflow/underflow variables.
Impact:
- Could bypass checks
- Could mint incorrect amounts
Likelihood: Very Low (Solidity ^0.8.0 has built-in checks)
Mitigations:
- Solidity ^0.8.30 (automatic checks)
- Unchecked only where safe (loop increments)
- Extensive test coverage
Test Coverage:
// All arithmetic operations tested
// Boundary conditions verified
// No unchecked blocks except safe loop increments- Custom Errors - Gas-efficient, clear error messages
- Reentrancy Guards - On all state-changing functions
- Access Control - Role-based permissions
- Pausability - Emergency stop mechanism
- Input Validation - Comprehensive checks
- Event Emission - Transparent on-chain logging
- Immutability - No upgrade risk
- Test Coverage - 98.71% line coverage
-
Multi-Sig Governance
// Use Gnosis Safe or similar address king = 0xGnosisSafeAddress;
-
Chainlink Oracle Integration
// Decentralized score fetching function requestScore(address user) external { bytes32 requestId = sendChainlinkRequest(...); }
-
Time-Locks
// Add delay to critical operations function setEthosScore(...) external onlyKing { require(block.timestamp >= unlockTime, "Timelocked"); // ... }
-
Rate Limiting
// Prevent spam attacks mapping(address => uint256) lastMintTime; require(block.timestamp - lastMintTime[user] >= COOLDOWN);
-
Professional Audit
- Trail of Bits
- OpenZeppelin
- Consensys Diligence
Status: No professional audit conducted (hackathon project)
Self-Audit Results:
- ✅ No critical vulnerabilities found
- ✅ All reentrancy risks mitigated
- ✅ Access control properly implemented
- ✅ Input validation comprehensive
⚠️ Centralization risks documented
Test Coverage: 98.71%
Recommended Actions:
- Professional audit before mainnet
- Bug bounty program
- Formal verification for critical functions
Immediate Actions:
- Pause all contracts (
pauseContract()) - Announce on official channels
- Document the vulnerability
- Develop fix
- Test extensively
- Deploy new contracts
- Assist with migration
Communication Template:
CRITICAL SECURITY UPDATE
We have discovered a vulnerability in [contract name].
All operations have been paused.
User funds are SAFE.
Migration plan will be announced within 24 hours.
Updates: [link]
Immediate Actions:
- Revoke admin permissions (
assignAdmin(newAdmin)) - Pause score-dependent operations
- Audit recent score updates
- Identify affected users
- Deploy new EthosIntegration contract
- Re-set legitimate scores
- Resume operations
Recovery Steps:
// 1. Remove compromised admin
ethosIntegration.assignAdmin(newAdmin);
// 2. Deploy new integration
EthosIntegration newIntegration = new EthosIntegration(king, newAdmin);
// 3. Deploy new NFT pointing to new integration
ReputationNFT newNFT = new ReputationNFT(..., address(newIntegration), ...);Immediate Actions:
- Verify legitimate wallet loss (not theft)
- Confirm new wallet ownership
- Use king emergency transfer
- Document all transfers
- Announce publicly
Transfer Process:
// King transfers NFT from lost wallet to new wallet
function transferFrom(address from, address to, uint256 tokenId) public virtual override {
// Check if the caller is the king.
if (msg.sender == s_king) {
_transfer(from, to, tokenId);
} else {
revert ReputationNFT__TokenIsSoulbound();
}-
Wallet Security
- Use hardware wallet if possible
- Never share private keys
- Backup seed phrases securely
- Verify contract addresses
-
Transaction Safety
- Always verify contract address before interacting
- Check transaction details before signing
- Start with small test transactions
- Confirm on block explorer
-
Awareness
- Understand soulbound property (cannot transfer)
- Know that tier is locked at mint
- Recognize official communication channels
- Report suspicious activity
-
Key Management
- Use hardware wallet for king/admin
- Never expose private keys
- Rotate keys periodically
- Use multi-sig in production
-
Score Setting
- Verify scores from official Ethos API
- Double-check addresses before setting
- Use batch operations when possible
- Monitor for anomalies
-
Monitoring
- Watch for unusual mint patterns
- Monitor score update events
- Track contract interactions
- Alert on suspicious activity
-
Incident Response
- Have pause procedures ready
- Document all emergency actions
- Communicate transparently
- Preserve evidence for investigation
Before deployment, verify:
- All functions have appropriate access control
- All state-changing functions have reentrancy guards
- All inputs are validated
- All addresses are checked for zero
- All events are emitted correctly
- All errors are handled properly
- No hardcoded addresses
- No TODO comments in production code
- Test coverage above 95%
- No unchecked arithmetic except safe cases
- All dependencies are latest stable versions
- Deployment scripts are tested
- Emergency procedures documented
Please DO NOT open public GitHub issues for security vulnerabilities.
Instead, report via:
- Email: buildswithking@gmail.com
- Discord: @BuildsWithKing
Include:
- Description of vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if any)
Response Time:
- Critical: < 24 hours
- High: < 48 hours
- Medium: < 1 week
- Low: < 2 weeks
Bug Bounty Not Available
- Comprehensive test suite
- Self-audit completed
- Known limitations documented
- Community review period
- Final security checklist
- External code review
- Formal verification of critical functions
- Bug bounty program
- Incident response plan
- Monitoring infrastructure
- Professional security audit
- Multi-sig implementation
- Chainlink oracle integration
- Time-locks on critical functions
- Upgrade mechanism (if needed)
- OpenZeppelin Security Best Practices
- Consensys Smart Contract Best Practices
- Trail of Bits Security Checklists
- OWASP Smart Contract Top 10
Remember: Security is a continuous process, not a one-time check. Stay vigilant, keep learning, and always prioritize user safety.