# audit-lending

Audits Solidity lending and borrowing protocols for vulnerabilities including premature liquidation before default, collateral manipulation preventing liquidation, loan closure without repayment, asymmetric pause mechanisms, token disallowance blocking operations, missing grace periods, incorrect liquidation share calculations, repayments to zero address, forced loan assignments, loan state manipulation via refinancing, double debt accounting, and dust loan griefing attacks

- **Kind:** skill
- **Source:** https://github.com/auditmos/skills
- **Page:** https://forefy.com/skills/6ede1517-331d-4ef4-b3cf-7c59a9453b38
- **API (JSON + files):** https://forefy.com/api/asr/6ede1517-331d-4ef4-b3cf-7c59a9453b38

---

## SKILL.md

---
name: audit-lending
description: Audits Solidity lending and borrowing protocols for vulnerabilities including premature liquidation before default, collateral manipulation preventing liquidation, loan closure without repayment, asymmetric pause mechanisms, token disallowance blocking operations, missing grace periods, incorrect liquidation share calculations, repayments to zero address, forced loan assignments, loan state manipulation via refinancing, double debt accounting, and dust loan griefing attacks
allowed-tools: Read, Grep, Glob
license: MIT
compatibility: Designed for Claude Code (or similar products)
metadata:
  author: Tomasz Kowalczyk (tom@auditmos.com)
  version: "1.0"
---

# Lending & Borrowing Auditor

## When to Use
- Auditing lending/borrowing protocols, collateral management systems
- User mentions: lending, borrowing, liquidation, collateral, loan, repayment, refinancing, debt, grace period, pause mechanism
- Analyzing loan lifecycle: creation, repayment, liquidation, refinancing
- Reviewing collateral tracking, debt calculations, pause/unpause operations

## Audit Workflow

**IMPORTANT: Announce skill usage at the start of analysis**

Begin with: "I'm using the **audit-lending** skill to analyze this contract for lending and borrowing protocol vulnerabilities..."

1. **Scan for lending operations**
   - Search: `liquidate`, `repay`, `borrow`, `collateral`, `loan`, `refinance`, `close`, `pause`, `unpause`
   - Focus: liquidation conditions, collateral management, debt tracking, pause mechanisms

2. **Check against vulnerability patterns**
   - Reference `reference.md` for complete checklist
   - Compare code against `example.md`

3. **Validate exploitability**
   - **Check access control first** - grep for `onlyOwner|onlyAdmin|onlyGovernance` modifiers
   - Can non-privileged actors exploit lending vulnerabilities?
   - Can borrower avoid liquidation?
   - Can attacker grief lenders/borrowers?
   - Can loan state be corrupted?
   - Verify no compensating protections exist
   - Downgrade severity if admin-only unless direct user fund impact

4. **Generate report**
   - Use deliverable template below
   - Include PoC for each finding
   - Rank by severity

## Core Vulnerability Patterns

See `reference.md` for full checklist. Key patterns:

1. Liquidation before default → borrowers unfairly liquidated early
2. Collateral manipulation → prevents liquidation entirely
3. Loan closure without repayment → debt written off
4. Asymmetric pause mechanism → repayments paused, liquidations active
5. Token disallow blocks existing operations → repayments/liquidations fail
6. No grace period after unpause → immediate unfair liquidations
7. Incorrect liquidation shares → collateral drained with partial repayment
8. Repayments to zero address → funds burned
9. Forced loan assignment → unwilling lenders receive loans
10. Loan state manipulation → auction cancellation extends loans indefinitely
11. Double debt subtraction → pool balance corrupted
12. Dust loan griefing → bypass minLoanSize to force small loans

**Code examples:** See `example.md`

## Severity Criteria

**Critical:** Fund loss, collateral theft, debt erasure without repayment, pool insolvency, **MUST be exploitable by non-privileged actors**
**High:** Unfair liquidation, griefing preventing operations, loan state corruption enabling extended default, **MUST be exploitable by non-privileged actors**
**Medium:** Edge case timing issues, suboptimal pause mechanisms, dust attacks with limited impact, **admin-only lending configuration issues with cascading user impact**
**Low:** Inefficient implementations without security impact, **admin-only parameter issues without immediate user impact**

**IMPORTANT:** Admin-only lending functions (onlyOwner, onlyAdmin, onlyGovernance) are **MEDIUM or LOW severity** unless:
- Invalid parameters directly enable borrowers to avoid repayment or liquidation
- Missing validation enables admin to steal user collateral or erase debt without authorization
- Pause mechanism asymmetry (admin pauses repayments but not liquidations) directly harms borrowers

## False Positives - Do NOT Flag

- Liquidation timing with documented grace periods
- Admin-only token disallow for new loans (not affecting existing)
- Intentional minimum loan sizes with explicit documentation
- Refinancing with proper accounting checks
- Pause mechanisms affecting both repayment and liquidation symmetrically
- **Admin-only collateral configuration functions** (onlyOwner, onlyAdmin) with documented trust assumptions
- Governance-controlled loan parameter updates with timelock allowing users to exit
- Admin functions for emergency pause where both repayment and liquidation are halted symmetrically

## Deliverable Format

**MANDATORY:** Before deliverable, verify each `checklist.md` item against codebase. Flag violations as findings.

Use template: `templates/report-template.md`

Each finding includes: severity, pattern #, file/lines, description, vulnerable code, impact analysis, PoC showing exploitation, remediation, gas impact.

## Key Principles

- **Grace periods** - borrowers need reasonable time after defaults/unpauses
- **Symmetric pauses** - pause repayments → pause liquidations
- **Collateral integrity** - cannot be zeroed or manipulated post-creation
- **Accurate accounting** - debt tracking must be atomic and correct
- **Minimum viability** - enforce minimums to prevent griefing

## Output Guidelines

**DO:**
- Reference specific lines and functions
- Provide executable PoCs showing fund loss or griefing
- Quantify impact (funds at risk, borrowers affected)
- Show timing calculations for liquidation conditions

**DON'T:**
- Report intentional design choices with documentation
- Flag gas optimizations without exploit path
- Use vague terms ("could be vulnerable")
- Ignore context (grace periods elsewhere, admin controls)

## checklist.md

# Lending & Borrowing Security Checklist

Verify each item before finalizing audit report:

- [ ] **Liquidation timing:** Only possible after `paymentDueDate + gracePeriod`, not during cycle
- [ ] **Collateral integrity:** Records cannot be zeroed/overwritten after loan creation
- [ ] **Loan closure:** Requires full repayment verification (not just counter decrement)
- [ ] **Symmetric pause:** Repayment pause also pauses liquidations
- [ ] **Token restrictions:** Disallow only affects new loans, not existing repayments/liquidations
- [ ] **Grace period:** Exists after repayment resumption (unpause or token re-allow)
- [ ] **Liquidation shares:** Calculated from total debt, not single position
- [ ] **Repayment routing:** Sent to valid lender address (not zero/deleted)
- [ ] **Minimum loan size:** Enforced at creation and all modification points
- [ ] **Maximum loan ratio:** Validated on all loan operations (not just creation)
- [ ] **Interest precision:** Cannot result in zero due to rounding
- [ ] **Pool parameters:** Borrower can specify expected values to prevent front-running
- [ ] **Auction duration:** Has reasonable minimum (not 1 second auctions)
- [ ] **Atomic accounting:** Pool balance updates synchronized with loan state changes
- [ ] **Outstanding loans:** Tracked accurately (no double-counting or missed decrements)

## example.md

# Lending & Borrowing Vulnerability Examples

## Pattern #1: Liquidation Before Default

### VULNERABLE
```solidity
contract VulnerableLending {
    struct Loan {
        uint256 startTime;
        uint256 paymentCycleDuration; // e.g., 30 days
        uint256 paymentDefaultDuration; // e.g., 7 days
    }

    // ISSUE: Can liquidate during payment cycle if paymentDefaultDuration < paymentCycleDuration
    function liquidate(uint256 loanId) external {
        Loan memory loan = loans[loanId];
        require(
            block.timestamp > loan.startTime + loan.paymentDefaultDuration,
            "Not defaulted"
        );
        // Liquidate even though payment not due yet
    }
}
```

### FIXED
```solidity
contract FixedLending {
    struct Loan {
        uint256 lastPaymentTime;
        uint256 paymentCycleDuration;
        uint256 gracePeriod;
    }

    function liquidate(uint256 loanId) external {
        Loan memory loan = loans[loanId];
        uint256 paymentDueDate = loan.lastPaymentTime + loan.paymentCycleDuration;
        require(
            block.timestamp > paymentDueDate + loan.gracePeriod,
            "Not defaulted - payment not due or grace period active"
        );
        // Only liquidate after payment due + grace period
    }
}
```

## Pattern #2: Collateral Manipulation Preventing Liquidation

### VULNERABLE
```solidity
contract VulnerableCollateral {
    mapping(address => uint256) public collateral;

    // ISSUE: Borrower can zero out collateral record
    function updateCollateral(uint256 amount) external {
        collateral[msg.sender] = amount; // Can set to 0!
    }

    function liquidate(address borrower) external {
        require(collateral[borrower] > 0, "No collateral");
        // Never executes if borrower set collateral to 0
    }
}
```

### FIXED
```solidity
contract FixedCollateral {
    mapping(address => uint256) public collateral;
    mapping(address => bool) public hasActiveLoan;

    function updateCollateral(uint256 amount) external {
        require(!hasActiveLoan[msg.sender], "Cannot modify with active loan");
        require(amount >= collateral[msg.sender], "Can only increase");
        collateral[msg.sender] = amount;
    }

    function liquidate(address borrower) external {
        require(hasActiveLoan[borrower], "No active loan");
        require(collateral[borrower] > 0, "No collateral");
        // Protected: collateral cannot be zeroed with active loan
    }
}
```

## Pattern #3: Loan Closure Without Repayment

### VULNERABLE
```solidity
contract VulnerableLoanClosure {
    uint256 public outstandingLoans;
    mapping(uint256 => uint256) public loanDebt;

    // ISSUE: Doesn't validate loan exists or is repaid
    function close(uint256 loanId) external {
        outstandingLoans--; // Decrements even for non-existent ID
        delete loanDebt[loanId];
    }
}
```

### FIXED
```solidity
contract FixedLoanClosure {
    uint256 public outstandingLoans;
    mapping(uint256 => uint256) public loanDebt;
    mapping(uint256 => bool) public loanExists;

    function close(uint256 loanId) external {
        require(loanExists[loanId], "Loan does not exist");
        require(loanDebt[loanId] == 0, "Debt not fully repaid");

        outstandingLoans--;
        loanExists[loanId] = false;
        delete loanDebt[loanId];
    }
}
```

## Pattern #4: Asymmetric Pause Mechanism

### VULNERABLE
```solidity
contract VulnerableAsymmetricPause {
    bool public repaymentsPaused;

    function repay(uint256 loanId) external {
        require(!repaymentsPaused, "Repayments paused");
        // Process repayment
    }

    // ISSUE: Liquidations work even when repayments paused
    function liquidate(uint256 loanId) external {
        // No pause check - borrowers can't repay but can be liquidated!
    }
}
```

### FIXED
```solidity
contract FixedSymmetricPause {
    bool public operationsPaused;

    function repay(uint256 loanId) external {
        require(!operationsPaused, "Operations paused");
        // Process repayment
    }

    function liquidate(uint256 loanId) external {
        require(!operationsPaused, "Operations paused");
        // Symmetric: both paused together
    }
}
```

## Pattern #5: Token Disallow Blocks Existing Operations

### VULNERABLE
```solidity
contract VulnerableTokenDisallow {
    mapping(address => bool) public allowedTokens;

    function setTokenAllowed(address token, bool allowed) external onlyOwner {
        allowedTokens[token] = allowed;
    }

    // ISSUE: Disallowing token prevents existing loans from being repaid
    function repay(uint256 loanId) external {
        Loan memory loan = loans[loanId];
        require(allowedTokens[loan.token], "Token not allowed");
        // Existing loans become unrepayable if token disallowed!
    }
}
```

### FIXED
```solidity
contract FixedTokenDisallow {
    mapping(address => bool) public allowedTokens;
    mapping(uint256 => bool) public loanExists;

    function setTokenAllowed(address token, bool allowed) external onlyOwner {
        allowedTokens[token] = allowed;
        // Only affects NEW loans
    }

    function repay(uint256 loanId) external {
        require(loanExists[loanId], "Loan does not exist");
        // No token allowlist check - existing loans always repayable
        Loan memory loan = loans[loanId];
        // Process repayment
    }

    function createLoan(address token, uint256 amount) external {
        require(allowedTokens[token], "Token not allowed");
        // Allowlist only checked at creation
    }
}
```

## Pattern #6: No Grace Period After Unpause

### VULNERABLE
```solidity
contract VulnerableGracePeriod {
    bool public paused;
    uint256 public lastUnpauseTime;

    function liquidate(uint256 loanId) external {
        require(!paused, "Paused");
        // ISSUE: Immediately liquidates after unpause
        Loan memory loan = loans[loanId];
        require(block.timestamp > loan.dueDate, "Not due");
        // Liquidates borrowers who couldn't repay during pause
    }
}
```

### FIXED
```solidity
contract FixedGracePeriod {
    bool public paused;
    uint256 public lastUnpauseTime;
    uint256 public constant UNPAUSE_GRACE_PERIOD = 1 days;

    function liquidate(uint256 loanId) external {
        require(!paused, "Paused");
        require(
            block.timestamp > lastUnpauseTime + UNPAUSE_GRACE_PERIOD,
            "Grace period active"
        );

        Loan memory loan = loans[loanId];
        require(block.timestamp > loan.dueDate, "Not due");
        // Grace period gives borrowers time to repay after unpause
    }
}
```

## Pattern #7: Incorrect Liquidation Share Calculations

### VULNERABLE
```solidity
contract VulnerableLiquidationShares {
    function liquidate(uint256 loanId, uint256 repayAmount) external {
        Loan memory loan = loans[loanId];

        // ISSUE: Share calculated from single loan debt, not total position
        uint256 collateralShare = (repayAmount * loan.collateral) / loan.debt;

        // Attacker repays tiny amount to drain all collateral
        transferCollateral(msg.sender, collateralShare);
    }
}
```

### FIXED
```solidity
contract FixedLiquidationShares {
    function liquidate(uint256 loanId, uint256 repayAmount) external {
        Loan memory loan = loans[loanId];
        uint256 totalDebt = getTotalDebt(loan.borrower); // All loans

        // Share calculated from total outstanding debt
        uint256 collateralShare = (repayAmount * loan.collateral) / totalDebt;

        require(repayAmount >= totalDebt, "Must repay full debt for collateral");
        transferCollateral(msg.sender, collateralShare);
    }
}
```

## Pattern #8: Repayments Sent to Zero Address

### VULNERABLE
```solidity
contract VulnerableRepaymentRouting {
    mapping(uint256 => address) public loanLender;

    function repay(uint256 loanId, uint256 amount) external {
        address lender = loanLender[loanId]; // Could be address(0) if deleted
        // ISSUE: No validation - sends to zero address
        token.transfer(lender, amount);
    }
}
```

### FIXED
```solidity
contract FixedRepaymentRouting {
    mapping(uint256 => address) public loanLender;
    mapping(uint256 => bool) public loanActive;

    function repay(uint256 loanId, uint256 amount) external {
        require(loanActive[loanId], "Loan not active");
        address lender = loanLender[loanId];
        require(lender != address(0), "Invalid lender");

        token.transfer(lender, amount);
    }
}
```

## Pattern #9: Forced Loan Assignment

### VULNERABLE
```solidity
contract VulnerableForcedLoan {
    mapping(uint256 => address) public loanLender;

    // ISSUE: Anyone can force loans onto unwilling lenders
    function buyLoan(uint256 loanId, address newLender) external {
        loanLender[loanId] = newLender; // No consent required!
    }
}
```

### FIXED
```solidity
contract FixedLoanTransfer {
    mapping(uint256 => address) public loanLender;
    mapping(address => bool) public approvedLenders;

    function buyLoan(uint256 loanId, address newLender) external {
        require(
            approvedLenders[newLender] || msg.sender == newLender,
            "Lender not approved"
        );
        loanLender[loanId] = newLender;
    }

    function approveLender(address lender, bool approved) external {
        approvedLenders[lender] = approved;
    }
}
```

## Pattern #10: Loan State Manipulation via Refinancing

### VULNERABLE
```solidity
contract VulnerableRefinancing {
    enum LoanState { Active, Auction, Defaulted }
    mapping(uint256 => LoanState) public loanState;

    // ISSUE: Can refinance during auction to cancel it
    function refinance(uint256 loanId) external {
        require(loanState[loanId] != LoanState.Defaulted, "Defaulted");
        // Allows refinancing during auction
        loanState[loanId] = LoanState.Active;
        // Auction cancelled, loan extended indefinitely
    }
}
```

### FIXED
```solidity
contract FixedRefinancing {
    enum LoanState { Active, Auction, Defaulted }
    mapping(uint256 => LoanState) public loanState;

    function refinance(uint256 loanId) external {
        LoanState state = loanState[loanId];
        require(
            state == LoanState.Active,
            "Cannot refinance auctioned/defaulted loan"
        );

        // Additional checks
        require(meetsRefinancingCriteria(loanId), "Does not meet criteria");

        // Process refinancing
        loanState[loanId] = LoanState.Active;
    }
}
```

## Pattern #11: Double Debt Subtraction

### VULNERABLE
```solidity
contract VulnerableDebtAccounting {
    uint256 public poolBalance;
    mapping(uint256 => uint256) public loanDebt;

    function refinance(uint256 loanId) external {
        uint256 oldDebt = loanDebt[loanId];

        // ISSUE: Subtracts debt twice
        poolBalance -= oldDebt; // First subtraction

        uint256 newDebt = calculateNewDebt(loanId);
        loanDebt[loanId] = newDebt;

        // Later in the function...
        poolBalance -= oldDebt; // Second subtraction - corrupts balance!
        poolBalance += newDebt;
    }
}
```

### FIXED
```solidity
contract FixedDebtAccounting {
    uint256 public poolBalance;
    mapping(uint256 => uint256) public loanDebt;

    function refinance(uint256 loanId) external {
        uint256 oldDebt = loanDebt[loanId];
        uint256 newDebt = calculateNewDebt(loanId);

        // Atomic update: difference applied once
        if (newDebt > oldDebt) {
            poolBalance += (newDebt - oldDebt);
        } else {
            poolBalance -= (oldDebt - newDebt);
        }

        loanDebt[loanId] = newDebt;
    }
}
```

## Pattern #12: Dust Loan Griefing

### VULNERABLE
```solidity
contract VulnerableDustLoans {
    uint256 public minLoanSize = 1000e18;

    function createLoan(uint256 amount) external {
        require(amount >= minLoanSize, "Too small");
        // Create loan
    }

    // ISSUE: No minimum check on refinancing
    function refinance(uint256 loanId, uint256 newAmount) external {
        // Attacker refinances to dust amount, bypassing minimum
        loans[loanId].amount = newAmount;
    }
}
```

### FIXED
```solidity
contract FixedDustLoans {
    uint256 public minLoanSize = 1000e18;

    function createLoan(uint256 amount) external {
        require(amount >= minLoanSize, "Too small");
        // Create loan
    }

    function refinance(uint256 loanId, uint256 newAmount) external {
        // Minimum enforced on all operations
        require(newAmount >= minLoanSize, "Too small");
        loans[loanId].amount = newAmount;
    }

    function partialRepay(uint256 loanId, uint256 amount) external {
        uint256 remaining = loans[loanId].amount - amount;
        // Prevent leaving dust
        require(
            remaining == 0 || remaining >= minLoanSize,
            "Would leave dust amount"
        );
        loans[loanId].amount = remaining;
    }
}
```

## Summary: Key Protections

1. **Liquidation timing:** `paymentDueDate + gracePeriod`
2. **Collateral locks:** Cannot modify with active loan
3. **Closure validation:** Requires full repayment check
4. **Symmetric pauses:** Both repayment and liquidation
5. **Token restrictions:** New loans only
6. **Grace periods:** After unpause/re-allow
7. **Liquidation shares:** From total debt
8. **Address validation:** No zero addresses
9. **Loan transfers:** Require consent
10. **State constraints:** No refinancing during auctions
11. **Atomic accounting:** Single debt update
12. **Minimum enforcement:** All loan operations

## reference.md

# Lending & Borrowing Vulnerability Patterns

## Pattern #1: Liquidation Before Default
**Risk:** Borrowers liquidated before payment due dates when `paymentDefaultDuration < paymentCycleDuration`
**Detection:** Check liquidation timing logic compares against correct deadline

## Pattern #2: Collateral Manipulation Preventing Liquidation
**Risk:** Attackers overwrite collateral amounts to 0, preventing liquidation entirely
**Detection:** Verify collateral records cannot be zeroed after loan creation

## Pattern #3: Loan Closure Without Repayment
**Risk:** Calling `close()` with non-existent IDs decrements counter, marking loans as repaid without payment
**Detection:** Ensure closure requires full repayment validation

## Pattern #4: Asymmetric Pause Mechanism
**Risk:** Repayments paused while liquidations remain enabled, unfairly preventing borrowers from protecting positions
**Detection:** Verify pause affects both repayment and liquidation symmetrically

## Pattern #5: Token Disallow Blocks Existing Operations
**Risk:** Disallowing tokens prevents existing loans from being repaid/liquidated, trapping funds
**Detection:** Ensure token restrictions only apply to new loans, not existing

## Pattern #6: No Grace Period After Unpause
**Risk:** Borrowers immediately liquidated when repayments resume after pause period
**Detection:** Verify grace period exists after unpause before liquidations resume

## Pattern #7: Incorrect Liquidation Share Calculations
**Risk:** Liquidator takes collateral with insufficient repayment due to calculating shares from single position instead of total debt
**Detection:** Ensure liquidation shares calculated from total outstanding debt

## Pattern #8: Repayments Sent to Zero Address
**Risk:** Deleted loan data causes repayments to be sent to `address(0)`, burning funds
**Detection:** Verify lender address stored and validated before repayment

## Pattern #9: Forced Loan Assignment
**Risk:** Malicious actors force loans onto unwilling lenders via `buyLoan()` or similar mechanisms
**Detection:** Ensure loan transfers require lender consent or whitelist

## Pattern #10: Loan State Manipulation via Refinancing
**Risk:** Borrowers cancel auctions via refinancing to extend loans indefinitely without repayment
**Detection:** Verify refinancing has proper constraints and doesn't bypass auction resolution

## Pattern #11: Double Debt Subtraction
**Risk:** Refinancing incorrectly subtracts debt twice from pool balance, corrupting accounting
**Detection:** Ensure debt updates are atomic and idempotent

## Pattern #12: Dust Loan Griefing
**Risk:** Bypassing `minLoanSize` checks to force small loans onto lenders, making operations unprofitable
**Detection:** Verify minimum loan size enforced at all loan creation/modification points

## templates

```

```

## templates/report-template.md

# Lending & Borrowing Security Audit Report

## Executive Summary

**Contract:** [Contract Name]
**Audit Date:** [Date]
**Auditor:** [Name/Team]

**Findings Overview:**
- Critical: X
- High: X
- Medium: X
- Low: X

## Findings

---

### [SEVERITY] Finding #X: [Vulnerability Title]

**Pattern:** #X - [Pattern Name from reference.md]

**Location:** `[contract_name.sol:line_numbers]`

**Description:**

[Detailed explanation of the vulnerability - what is the flaw in the implementation?]

**Vulnerable Code:**

```solidity
// Highlight the problematic code section
function vulnerableFunction() external {
    // Show the specific issue
}
```

**Impact:**

[Explain the consequences:]
- **Borrowers:** [Impact on borrowers - unfair liquidation, trapped funds, etc.]
- **Lenders:** [Impact on lenders - loss of principal, incorrect interest, etc.]
- **Protocol:** [Impact on protocol - insolvency, accounting corruption, etc.]
- **Funds at risk:** [Quantify if possible - e.g., "All collateral in defaulted loans"]

**Proof of Concept:**

```solidity
// Executable test case showing the exploit
contract PoC {
    function testExploit() public {
        // 1. Setup
        // 2. Execute vulnerable operation
        // 3. Demonstrate impact
        // Expected: [Expected behavior]
        // Actual: [Vulnerable behavior]
    }
}
```

**Scenario:**
1. [Step-by-step attack or failure scenario]
2. [What happens at each stage]
3. [Final result showing the vulnerability]

**Remediation:**

```solidity
// Fixed implementation
function fixedFunction() external {
    // Add validation
    require([condition], "Error message");

    // Implement protection
    if ([safety_check]) {
        // Safe path
    }
}
```

**Recommendations:**
1. [Primary fix - specific code change]
2. [Additional protections if needed]
3. [Related checks to add]

**Gas Impact:** [Minimal/Low/Medium/High - estimated gas increase from fix]

---

### [SEVERITY] Finding #X: [Next Vulnerability]

[Repeat above structure for each finding]

---

## Severity Definitions

**Critical:** Direct fund loss, collateral theft, debt erasure without repayment, protocol insolvency. Immediate exploit possible with no preconditions.

**High:** Unfair liquidation enabling value extraction, griefing attacks preventing normal operations, loan state corruption enabling indefinite defaults. Specific but achievable conditions required.

**Medium:** Edge case timing vulnerabilities, suboptimal pause mechanisms, dust loan attacks with limited financial impact. Requires specific market conditions or privileged access.

**Low:** Gas inefficiencies, view function issues, suboptimal implementations without direct security impact.

## Recommendations Summary

### Immediate Actions (Critical/High)
1. [List critical fixes to deploy immediately]

### Short-term Improvements (Medium)
1. [List medium-priority fixes]

### Long-term Enhancements (Low)
1. [List optimization opportunities]

## Checklist Results

Based on `checklist.md`:

- [x] **Liquidation timing:** Only possible after `paymentDueDate + gracePeriod` ✓/✗
- [x] **Collateral integrity:** Records cannot be zeroed after loan creation ✓/✗
- [x] **Loan closure:** Requires full repayment verification ✓/✗
- [x] **Symmetric pause:** Repayment pause also pauses liquidations ✓/✗
- [x] **Token restrictions:** Disallow only affects new loans ✓/✗
- [x] **Grace period:** Exists after repayment resumption ✓/✗
- [x] **Liquidation shares:** Calculated from total debt ✓/✗
- [x] **Repayment routing:** Sent to valid lender address ✓/✗
- [x] **Minimum loan size:** Enforced at all modification points ✓/✗
- [x] **Maximum loan ratio:** Validated on all operations ✓/✗
- [x] **Interest precision:** Cannot result in zero ✓/✗
- [x] **Pool parameters:** Borrower can specify expected values ✓/✗
- [x] **Auction duration:** Has reasonable minimum ✓/✗
- [x] **Atomic accounting:** Balance updates synchronized ✓/✗
- [x] **Outstanding loans:** Tracked accurately ✓/✗

## Testing Recommendations

### Unit Tests
- [ ] Liquidation timing with various grace periods
- [ ] Collateral modification attempts with active loans
- [ ] Loan closure without full repayment
- [ ] Pause/unpause with timing scenarios
- [ ] Token disallow on existing vs new loans

### Integration Tests
- [ ] Multi-loan liquidation share calculations
- [ ] Refinancing state transitions
- [ ] Dust loan creation/modification attempts
- [ ] Cross-contract pause coordination

### Fuzz Tests
- [ ] Liquidation timing edge cases
- [ ] Debt accounting across operations
- [ ] Minimum size enforcement boundaries

## Appendix

### Code Quality Observations
[Non-security observations about code quality, best practices, etc.]

### References
- [Relevant EIPs, standards, or similar protocol implementations]
- [Known exploits or vulnerabilities in similar protocols]

