CrediTrust
Your Crypto. Your Credit. Your Control.
Created on 26th June 2025
•
CrediTrust
Your Crypto. Your Credit. Your Control.
The problem CrediTrust solves
📢 Disclosure
This project was developed during the parallel timelines of the Coinbase Agents in Action Hackathon and Chromion: A Chainlink Hackathon.
The Chainlink-powered decentralized lending protocol was enhanced with Coinbase technologies such as:
- 🛡️ CDP Wallet – for secure, programmable wallet integration
- 💸 x402pay – for monetization of on-chain credit-scoring agents
The project satisfies the unique requirements of both hackathons, and all development occurred within their official timeframes.
📊 Chainlink Data Feeds: Dynamic Risk Pricing
- Real-time Asset Pricing: ETH/USD feeds ensure accurate collateral valuations
- Market-driven Rates: Interest rates adjust based on live market conditions
- Automated Liquidations: Chainlink price feeds trigger automatic liquidations when needed
- Cross-asset Support: Support for any asset with Chainlink price feeds
⚡ Chainlink Automation: Self-Managing Loans
- Automatic Interest Calculations: No manual intervention required
- Scheduled Payments: Automated monthly payment processing
- Health Monitoring: Continuous monitoring of loan-to-value ratios
- Emergency Liquidations: Instant liquidation when thresholds are breached
What People Can Use It For
🌍 Global Financial Inclusion
For the Unbanked (2B+ People)
Maria in rural Guatemala has no credit history but owns a small coffee farm.
She can:
- Stake her farm equipment as collateral (tokenized)
- Get matched with global lenders via Chainlink VRF
- Receive USDC loans for seed purchases
- Build on-chain credit history for better future rates
For Cross-Border Business
Ahmed, a textile exporter in Bangladesh needs working capital:
- Uses local assets as collateral
- Gets matched with US/EU lenders automatically
- Receives payments in stablecoins instantly
- Pays competitive rates based on real-time Chainlink data
💰 Superior Investment Opportunities
For Yield Seekers
- Higher Returns: Earn 8-15% APR vs 1-3% in traditional savings
- Automated Portfolio: Chainlink VRF distributes your capital across multiple borrowers
- Risk-Adjusted Pricing: Chainlink data feeds ensure fair compensation for risk
- Global Diversification: Lend to borrowers across multiple countries and sectors
🚀 DeFi Innovation
Leverage Trading
DeFi Trader Scenario:
- Stake 100 ETH as collateral (valued via Chainlink ETH/USD)
- Borrow 80 ETH worth of stablecoins
- Use borrowed funds for yield farming
- Chainlink Automation monitors position health
- Automatic liquidation prevents total loss
Cross-Chain Arbitrage
- Multi-Chain Lending: Deploy on Ethereum, Polygon, Arbitrum simultaneously
- Unified Pricing: Chainlink price feeds ensure consistent rates across chains
- Automated Opportunities: Borrow on cheap chains, lend on expensive chains
How It Makes Things Safer & Easier
🛡️ Safety Through Chainlink Integration
Eliminates Human Error & Bias
- ✅ VRF Randomness: Mathematically provable fair lender selection
- ✅ Automated Pricing: No human manipulation of interest rates
- ✅ Real-time Monitoring: Chainlink Automation prevents manual oversight failures
- ✅ Transparent Liquidations: All actions triggered by verifiable price data
Prevents Market Manipulation
// Example: Chainlink-protected liquidation function checkLiquidation(address borrower) external { int256 ethPrice = chainlinkPriceFeed.latestAnswer(); uint256 collateralValue = (collateralAmount * uint256(ethPrice)) / 1e8; uint256 debtValue = getDebtWithInterest(borrower); if (collateralValue * 100 < debtValue * LIQUIDATION_THRESHOLD) { _liquidate(borrower); // Automatic, no human intervention } }
Cross-Chain Security
- Unified Risk Models: Same Chainlink data across all supported chains
- Consistent Liquidation: Identical protection mechanisms everywhere
- Atomic Cross-Chain Operations: Use Chainlink CCIP for secure cross-chain lending
⚡ Easier User Experience
One-Click Global Lending
- Connect Wallet → Platform detects all your assets across chains
- Set Preferences → Choose risk level, loan duration, geographic preferences
- Stake Assets → Chainlink VRF automatically matches you with borrowers
- Earn Passively → Chainlink Automation handles everything else
Intelligent Loan Management
- Smart Notifications: Get alerted before liquidation thresholds
- Automated Payments: Set up recurring payments that execute via Chainlink Automation
- Dynamic Rates: Your rate improves automatically as your credit score increases
Challenges I ran into
🚨 Major Technical Hurdles
1. Chainlink VRF Integration on Local Networks
Problem: Chainlink VRF requires a subscription and coordinator that doesn't exist on local Hardhat networks.
Error Encountered:
// This would fail on localhost function requestRandomLender() internal { uint256 requestId = COORDINATOR.requestRandomWords( keyHash, s_subscriptionId, requestConfirmations, callbackGasLimit, numWords ); }
Solution Implemented:
// Smart fallback for local testing function openCDP(uint256 _collateralAmount, uint256 _creditScore) external { if (address(COORDINATOR) == address(0)) { // Local testing: direct assignment _assignFirstAvailableLender(msg.sender); } else { // Production: use Chainlink VRF _requestRandomLender(msg.sender); } } function fulfillRandomWords(uint256, uint256[] memory randomWords) internal override { address borrower = s_requests[requestId]; address[] memory availableLenders = getAvailableLenders(); uint256 selectedIndex = randomWords[0] % availableLenders.length; _assignLender(borrower, availableLenders[selectedIndex]); }
Key Learning: Always design smart contracts with testnet/mainnet differences in mind.
2. Chainlink Price Feed Integration Complexity
Problem: Managing multiple price feeds for different collateral types while handling feed failures gracefully.
Challenge: Price feeds can become stale or fail, which could freeze all liquidations.
Solution:
contract ChainlinkPriceManager { mapping(address => AggregatorV3Interface) public priceFeeds; mapping(address => uint256) public heartbeats; // Max staleness allowed function getPrice(address asset) external view returns (uint256) { AggregatorV3Interface feed = priceFeeds[asset]; (uint80 roundId, int256 price, , uint256 updatedAt, ) = feed.latestRoundData(); require(price > 0, "Invalid price"); require(block.timestamp - updatedAt <= heartbeats[asset], "Stale price"); require(roundId > 0, "Round not complete"); return uint256(price); } // Fallback to backup feeds if primary fails function getPriceWithFallback(address asset) external view returns (uint256) { try this.getPrice(asset) returns (uint256 price) { return price; } catch { return getBackupPrice(asset); } } }
3. Cross-Chain State Synchronization
Problem: Keeping lending pools and borrower data synchronized across multiple chains.
Challenge: A borrower could potentially double-spend collateral across chains.
Solution Using Chainlink CCIP:
// Cross-chain borrower registry contract CrossChainBorrowerRegistry is CCIPReceiver { mapping(address => uint256) public globalDebt; mapping(uint64 => bool) public trustedChains; function notifyLoanCreated( uint64 destinationChain, address borrower, uint256 amount ) external { bytes memory data = abi.encode(borrower, amount, "LOAN_CREATED"); Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ receiver: abi.encode(crossChainRegistries[destinationChain]), data: data, tokenAmounts: new Client.EVMTokenAmount[](0), extraArgs: "", feeToken: address(0) }); router.ccipSend(destinationChain, message); } function _ccipReceive(Client.Any2EVMMessage memory message) internal override { (address borrower, uint256 amount, string memory action) = abi.decode(message.data, (address, uint256, string)); if (keccak256(bytes(action)) == keccak256("LOAN_CREATED")) { globalDebt[borrower] += amount; emit CrossChainLoanRegistered(borrower, amount); } } }
4. Chainlink Automation Gas Optimization
Problem: Chainlink Automation costs gas for every execution, making frequent health checks expensive.
Challenge: Balance between safety (frequent checks) and cost (gas fees).
Solution - Smart Trigger Logic:
contract OptimizedAutomation { uint256 private lastCheckBlock; uint256 private constant CHECK_INTERVAL = 100; // blocks function checkUpkeep(bytes calldata) external view override returns ( bool upkeepNeeded, bytes memory performData ) { // Only check if enough blocks have passed if (block.number - lastCheckBlock < CHECK_INTERVAL) { return (false, ""); } // Batch check multiple loans address[] memory loansToLiquidate = new address[](0); uint256 count = 0; for (uint i = 0; i < activeBorrowers.length && count < 10; i++) { address borrower = acti
Tracks Applied (2)
