Lending and Borrowing Protocol Development

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
Lending and Borrowing Protocol Development
Complex
from 2 weeks to 3 months
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1214
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

Developing a lending protocol

Typical situation: a team wants to launch a lending protocol, forks Compound v2, changes collateral factor parameters, deploys — and three weeks later discovers that the oracle works via TWAP with a 30-minute window, and liquidations don't catch up during sharp price movements. Positions go negative, protocol suffers losses. This is not a fork bug — it's an architectural decision that in the original was compensated by other risk parameters.

Developing a lending protocol from scratch or adapting an existing one is primarily work with risk mathematics and liquidation mechanics, not just Solidity writing.

Where lending protocols break

Oracle manipulation via flash loan

The most destructive attack vector in DeFi lending is price oracle manipulation. If the protocol reads price directly from Uniswap v2 pool spot price, the attacker takes a flash loan, moves the price in the pool, gets an under-collateralized loan, returns the flash loan. Protocol loses collateral.

The 2022 Mango Markets attack — $117 million — worked exactly like this. The attacker used their own token as collateral, artificially raised its price through spot purchases, took loans against the inflated collateral.

Protection is built on multiple levels:

  • Chainlink price feeds with updatedAt check — if data is older than N seconds, transaction reverts
  • TWAP from Uniswap v3 as secondary source with window of at least 30 minutes for illiquid assets
  • Deviation check — if Chainlink and TWAP diverge more than X%, accept the lower value
  • Circuit breaker — temporary pause on new borrowing during abnormal price movement
function getPrice(address asset) internal view returns (uint256) {
    (, int256 answer, , uint256 updatedAt, ) = chainlinkFeed.latestRoundData();
    require(block.timestamp - updatedAt <= STALENESS_THRESHOLD, "Stale price");
    require(answer > 0, "Invalid price");
    
    uint256 twapPrice = getTWAP(asset, TWAP_PERIOD);
    uint256 chainlinkPrice = uint256(answer);
    
    // Accept minimum of two — conservative position
    return twapPrice < chainlinkPrice ? twapPrice : chainlinkPrice;
}

Liquidation mechanics and bad debt

The second critical moment is liquidation threshold and health factor. Aave uses healthFactor = (collateralETH * liquidationThreshold) / totalDebtETH. As soon as health factor drops below 1.0, the position is open to liquidators.

The problem occurs with gap risk: an asset falls 30% in one candle (liquidity crisis, exchange collapse), liquidators don't catch up to close positions, protocol accumulates bad debt. Compound faced this during LUNA collapse — some positions went negative.

Architectural solutions:

Mechanism Essence Application
Liquidation bonus Liquidator gets collateral at 5-10% discount Incentive for quick liquidation
Partial liquidation Only part of position is closed Reduces gas cost for liquidators
Dutch auction liquidation Bonus price rises over time Automatic attractiveness during volatility
Insurance fund Reserve from part of interest income Bad debt coverage on gap risk

We implement dutch auction following MakerDAO: if a position is not liquidated within N blocks, liquidation bonus starts to rise. This guarantees that even with low liquidator interest, the position will eventually close.

Interest rate model: kink and utilization

Interest rate in Compound v2 and Aave v3 is calculated via utilization rate: U = totalBorrow / totalSupply. At low utilization rate is low, at high it rises sharply (kink model).

The kink parameter is critical. If utilization reaches 100%, depositors cannot withdraw funds — no liquidity. Classic kink model puts inflection point at 80-90% and sharply raises the rate above to incentivize new deposits or debt repayment.

function getBorrowRate(uint256 cash, uint256 borrows, uint256 reserves) 
    external view returns (uint256) 
{
    uint256 util = utilizationRate(cash, borrows, reserves);
    
    if (util <= kink) {
        return util * multiplierPerBlock / BASE + baseRatePerBlock;
    } else {
        uint256 normalRate = kink * multiplierPerBlock / BASE + baseRatePerBlock;
        uint256 excessUtil = util - kink;
        return excessUtil * jumpMultiplierPerBlock / BASE + normalRate;
    }
}

How we build lending protocols

Architecture and stack

Basic architecture divides logic into several contracts:

  • LendingPool — entry point, routes calls
  • ReserveLogic — index calculation, interest accrual
  • ValidationLogic — checks before operations
  • aToken / debtToken — ERC-20 tokens of positions (Aave v3 style)
  • PriceOracle — price aggregator with fallback logic
  • InterestRateStrategy — pluggable rate strategy

We use Foundry for development and testing. Fork-tests against Ethereum mainnet are mandatory: need to verify integration with real Chainlink feeds, real asset prices.

For upgradability — UUPS proxy (EIP-1822). Transparent proxy at this scale of logic creates storage collision risks during upgrades. ERC-7201 namespaced storage isolates variables for each logical module.

Special attention to reentrancy in cross-contract calls: aToken.mint() on deposit, collateral transfer on liquidation — all external calls after state update, nonReentrant on all entry points.

Testing

Property-based tests via Echidna with invariants:

  • Sum of all debts never exceeds sum of all deposits
  • Health factor of position after liquidation always above 1.0
  • Interest index monotonically increases

Fuzz-tests in Foundry on deposit, borrow, repay functions — parameters: random amounts, random operation sequences, random oracle values.

Working process

Analytics (3-5 days). Determine list of assets, collateral factor for each, liquidation parameters, oracle sources. Model stress scenarios: what happens when the main collateral asset falls 50% in 1 block.

Design (5-7 days). Storage layout, contract interfaces, mathematical rate models. Formal verification for core invariants via Certora Prover or Halmos — for protocols with TVL goal >10M USD this is a mandatory step.

Development (4-8 weeks). Core contracts + tests. Fork-tests on mainnet. Coverage >95%.

Internal security review (1 week). Slither, Mythril, manual review per SWC checklist + DeFi-specific vectors: flash loan attacks, oracle manipulation, liquidation griefing.

External audit. For lending protocol — mandatory. Recommend Trail of Bits, Spearbit, or Code4rena contest depending on budget.

Deployment. First testnet (Sepolia) simulating market conditions, then mainnet via Gnosis Safe multisig. Risk parameters set conservatively with ability to adjust via governance.

Timeline estimates

Minimal protocol version (one asset, basic operations) — 4-6 weeks. Full multi-asset lending with governance and insurance fund — 3-4 months. Audit timeline not included and depends on chosen company (usually 2-6 weeks in queue).

Cost is calculated after detailed discussion of architecture and security requirements.