A fully on-chain reputation protocol built on ERC-5484 Soulbound Tokens.
Wallet behaviour tracked on-chain. Score evolves. Medal art upgrades automatically. No IPFS dependency.
🌐 Live Demo • 💻 Source Code • 🔗 ReputationToken • 🔗 Engine Proxy • 🔗 ReputationVault
On-chain identity is broken. Wallets are anonymous. There is no way to distinguish a DeFi power user from a fresh wallet. This protocol fixes that.
The ERC-5484 Reputation System assigns every wallet a Soulbound Token, non-transferable and non-mintable by the holder, that reflects their on-chain behaviour score. As the wallet performs positive actions (DAO votes, loan repayments, airdrop holding), their score rises and their medal art upgrades automatically with no re-mint required.
The scoring engine is UUPS upgradeable so logic can evolve as the protocol matures. The token contract is intentionally immutable because SBT ownership records are the ground truth of on-chain identity and must be permanent.
- 🌐 Frontend App
- 🏛️ Architecture
- ✅ Deployed Contracts
- 🎖️ Reputation Tiers & Medal System
- ⚙️ Scoring Actions
- 🧩 Smart Contract Breakdown
- 🧪 Testing Strategy
- 🚀 Local Setup
Live reputation dashboard pulls real-time score, tier, voting power, and loan access directly from contracts. Dynamic SBT medal display decodes and renders on-chain SVG from tokenURI() with no IPFS involved. All vault actions are wired up: castVote, submitProposal, mintNFT, takeLoan, repayLoan, claimAirdrop, settleAirdrop, all executable from the UI. Live cooldown bars show per-action countdown timers updating every second. A 30-day airdrop progress bar gives a visual hold tracker with early-settle warning. The animated tier showcase auto-cycles through all 5 tiers with cinematic morph transitions. Scroll-reveal sections use intersection observer based animations, and the particle canvas background carries comet trails matching the landing page.
| Decision | Rationale |
|---|---|
| Token is immutable | SBT ownership is ground truth. Upgradeability would allow silent record tampering |
| Engine is UUPS upgradeable | Scoring logic must evolve; token state must not |
| On-chain SVG medals | Zero IPFS dependency. Token lives as long as Ethereum |
| Dynamic metadata | tokenURI() reads live score from engine. Medal upgrades on score change, no re-mint |
_mint not _safeMint |
SBTs have no receiver contract. onERC721Received is meaningless and adds reentrancy surface |
_update() override |
Exhaustively blocks all OZ transfer paths in one hook |
All contracts deployed and verified on Ethereum Sepolia Testnet.
| Contract | Address | Etherscan |
|---|---|---|
| ReputationToken | 0x9c77Ce31a110e360d62e4eF8B1F4cf8576F70F46 |
🔎 View |
| ReputationEngine (Impl) | 0xC81532619d5fB4728932A43A77Bfea04c3df5957 |
🔎 View |
| ReputationEngine (Proxy) | 0x4eFC1adc7Dd594C4bB04865B6dCc5101392FaBD8 |
🔎 View |
| ReputationVault | 0xd53320CDEF6f3DfA54436D2806e765d6d6bD98b6 |
🔎 View |
Interact with the proxy address only, never the implementation directly.
Every wallet's SBT displays a dynamic on-chain SVG medal that reflects their current tier. No IPFS. No centralized server. The medal art is generated entirely in Solidity and upgrades automatically as score increases.
| Tier | Score Range | Medal Design | Voting Power | Loan Limit |
|---|---|---|---|---|
| Unranked | 0 – 99 | Grey hexagon + ? |
0.5× | None |
| Bronze 🥉 | 100 – 299 | Copper circle + 6-point star | 1× | 20% of collateral |
| Silver 🥈 | 300 – 599 | Silver circle + 5-point star | 1.5× | 40% of collateral |
| Gold 🥇 | 600 – 849 | Gold circle + crown + gems | 2× | 60% of collateral |
| Platinum 💎 | 850 – 1000 | Platinum ring + diamond | 3× | 80% of collateral |
Actions are recorded through the ReputationVault. Each action maps to a signed score delta enforced by the ReputationMath library. Raw deltas are never exposed, only the Action enum is accessible to callers.
| Action | Function | Score Delta | Cooldown |
|---|---|---|---|
| DAO Vote | castVote() |
+10 | 12 hours |
| DAO Proposal | submitProposal() |
+25 | 24 hours |
| Loan Repaid | repayLoan() |
+30 | None (natural gate) |
| Loan Defaulted | markDefault() |
−50 | None (owner only) |
| Airdrop Held 30d | settleAirdrop() |
+15 | None (natural gate) |
| Airdrop Dumped | settleAirdrop() |
−20 | None (natural gate) |
| NFT Minted | mintNFT() |
+5 | 12 hours |
Score is always clamped to [0, 1000]. Underflow and overflow are impossible by design.
src/
├── ReputationToken.sol # ERC-5484 SBT — immutable, transfer-locked
├── ReputationEngine.sol # UUPS scoring engine — issues SBTs, tracks scores
├── ReputationVault.sol # Action simulator — user entry point
├── interfaces/
│ ├── IReputationToken.sol # Full error + event surface for callers
│ └── IReputationEngine.sol # CEI order + reentrancy requirements documented
└── libraries/
├── ReputationMath.sol # Pure math — Action enum, score clamping, tier resolution
└── ReputationSVG.sol # On-chain SVG medal generator — 5 tier designs
Enum-gated deltas mean arbitrary int256 deltas are never exposed, only Action enum variants can mutate scores. Overflow guards in _applyDelta() have early-exit checks for extreme deltas, future-proofing against new high-magnitude actions. The single guard pattern calls _assertValidScore() once per public entry point, while _resolveTierUnchecked() avoids a double-guard in tierName(). Being a pure library, there is zero reentrancy surface.
| Invariant | Enforced By |
|---|---|
| One SBT per wallet | s_walletToToken[to] != 0 check in issue() |
| Engine address immutable post-deploy | setEngine() reverts with EngineAlreadySet on second call |
| Transfer always reverts | _update() override catches all OZ paths |
| Score always in [0, 1000] | ReputationMath.applyAction() clamped by design |
| All storage writes before external calls | Strict CEI in recordAction() and all Vault functions |
| No re-entrancy | nonReentrant on all state-changing engine and vault functions |
| SBT auto-issued on first action | token.issue() called last in CEI after all storage writes |
The project uses a 4-layer testing approach with Foundry.
test/
├── unit/
│ ├── ReputationMathTest.t.sol # Score math, tier resolution, delta clamping
│ ├── ReputationTokenTest.t.sol # SBT issuance, transfer lock, burn, ERC-5484
│ ├── ReputationEngineTest.t.sol # recordAction CEI, auth, score updates
│ └── ReputationVaultTest.t.sol # All actions, cooldowns, loan/airdrop lifecycle
├── integration/
│ └── ReputationFlowTest.t.sol # Full lifecycle: Unranked → Bronze → Gold
└── fuzz/
└── FuzzReputation.t.sol # Score bounds, loan math, SBT uniqueness
cd web3-app
npm install
npm run dev
# → http://localhost:3000Engineered by NexTech Architect
Smart Contract Developer · Solidity · Foundry · Web3 Engineering