You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This PR implements a borrow-and-repay feature for the card system, allowing users to borrow USDC against their soUSD savings collateral and repay existing borrows. The implementation integrates with Aave V3 on Fuse network.
✅ Strengths
Good Architecture
Well-structured separation of concerns with dedicated hooks (useAaveBorrowPosition, useRepayAndWithdrawCollateral, useBorrowAndDepositToCard)
Proper state management using Zustand store (useCardRepayStore)
Good use of React Query for contract reads
Comprehensive error handling with Sentry integration
Proper analytics tracking throughout the flow
Security Considerations
Proper approval flows before token transfers
Health factor calculation to prevent liquidation (1.02x target)
Slippage protection on cross-chain bridging (5% tolerance)
Input validation with Zod schemas
🔴 Critical Issues
1. Incorrect Debt Calculation in useAaveBorrowPosition.ts (Lines 162-165)
Issue: Aave's variable debt accrues continuously. This calculation is correct at the current block, but by the time a transaction is submitted, the debt may have increased. This could lead to:
Underpayment when users try to "repay all"
Failed transactions due to insufficient repayment amount
Recommendation: Add a safety buffer (e.g., 0.1%) when calculating repayment amounts, or use type(uint256).max for full repayments.
2. Race Condition Risk in useRepayAndWithdrawCollateral.ts (Lines 92-109)
Issue: No rollback mechanism if the repay succeeds but withdraw fails, or if the transaction is partially executed.
Recommendation: Consider implementing idempotency checks or multi-step confirmation.
6. Hardcoded LTV Value (useBorrowAndDepositToCard.ts Line 47)
constsoUSDLTV=79n;// 80% LTV for soUSD (79% to avoid rounding errors)
Issue: LTV is hardcoded and may become outdated if Aave governance changes this parameter.
Recommendation: Fetch LTV dynamically from the protocol configuration or add monitoring/alerts if this changes.
📊 Medium Priority Issues
7. Type Safety Issues
CardRepayForm.tsx Line 124: resolver: zodResolver(schema) as any - Avoid type assertions
Multiple uses of any type that could be properly typed
Missing null checks in several places
8. Performance Concerns
BorrowSlider.tsx: Multiple re-renders due to refs and state updates. Consider using useMemo more aggressively or throttling the onValueChange callback
useAaveBorrowPosition.ts: Large useMemo dependency array may cause unnecessary recalculations
9. User Experience Issues
No loading state between "Repay" button click and modal transition
Fee amount is hardcoded to 0 (CardRepayForm.tsx Line 36) - users might expect to see actual bridge fees
No confirmation step before submitting large repayments
Missing tooltips explaining health factor, APY calculations, etc.
10. Inconsistent Error Messages
Toast.show({type: 'error',text1: 'Repay failed',text2: 'Please try again or check your wallet balance',});
Generic error messages don't help users understand what went wrong (insufficient balance vs. contract error vs. network issue).
🔵 Low Priority Issues
11. Code Quality
Some repeated calculation logic between useBorrowAndDepositToCard and useRepayAndWithdrawCollateral
Magic numbers (e.g., 95n / 100n for slippage, 30110 for dstEid) should be constants
BorrowSlider.tsx has complex PanResponder logic that could be extracted or use a library
12. Missing Documentation
No JSDoc comments explaining the complex financial calculations
No README or inline comments explaining the borrow flow
Constants like RATE_SCALE, LIQ_THRESHOLD_BPS need explanatory comments
13. Accessibility
BorrowSlider.tsx has no accessibility labels for screen readers
No keyboard navigation support for the slider component
Missing ARIA labels on interactive elements
🧪 Test Coverage
Major Gap: NO TESTS
The PR adds 1,797 lines of complex financial logic with zero test coverage. This is a critical gap for DeFi functionality.
Recommended Tests:
Unit tests for calculation functions:
Health factor calculations
Debt/collateral conversions
Exchange rate applications
Edge cases (zero amounts, max uint, very small amounts)
Integration tests for hooks:
Mock contract responses
Test error scenarios (insufficient balance, rate changes, etc.)
Test multi-step transaction flows
E2E tests:
Complete borrow-to-repay user flow
Error recovery scenarios
Cross-chain bridging
Example test structure:
// hooks/__tests__/useAaveBorrowPosition.test.tsdescribe('useAaveBorrowPosition',()=>{it('calculates total borrowed correctly with accrued interest',()=>{// Test implementation});it('handles zero debt positions',()=>{// Test implementation});it('calculates net APY correctly',()=>{// Test implementation});});
🔒 Security Recommendations
Audit Math Operations: All financial calculations should be audited for overflow/underflow and rounding errors
Rate Staleness Check: Add timestamp checks to ensure exchange rates aren't stale
Maximum Slippage Protection: Consider adding configurable maximum slippage for user protection
Transaction Simulation: Consider simulating transactions before execution (Tenderly/Hardhat fork)
Emergency Pause: Consider adding a circuit breaker if health factor calculations seem off
📝 Additional Recommendations
Add TypeScript strict checks: Enable strictNullChecks and fix all violations
Extract constants: Move all magic numbers to a dedicated constants file with documentation
Add logging: More granular logs for debugging production issues
Monitor health factors: Add analytics to track when users get close to liquidation
Rate limiting: Consider rate limiting borrow/repay actions to prevent abuse
Add transaction previews: Show users exactly what will happen before they confirm
Conclusion
This is a substantial feature with solid architecture, but has critical financial calculation risks that need addressing before production deployment. The lack of tests for DeFi functionality is particularly concerning.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.