BlockchainAppMaker Get a quote

DeFi

DeFi smart contract development: what good work looks like and how to vet a team

DeFi smart contract development is the design, testing and deployment of contracts that hold and move pooled user funds. This guide explains what a good team does on such a project, what you should receive, and how to judge a team before you hire it.

DeFi contracts differ from other contracts because anyone can call them, and a loss caused by a mistake usually cannot be undone. For general contract engineering, see smart contract development.

What DeFi smart contracts do

Most DeFi products combine a few standard contract types:

Contract typeWhat it doesMain risk
Token (ERC-20)Records balances and transfersUnsafe mint or admin functions
Vault (ERC-4626)Takes deposits, issues shares and runs a yield strategyShare price manipulation. In the first-depositor inflation attack, the first depositor inflates the share price so that later depositors receive almost no shares.
Automated market maker (AMM)Swaps tokens against pooled liquidityPrice manipulation and rounding errors
Lending marketLends assets against collateral and runs liquidationsOracle errors and bad debt
Staking and rewardsLocks tokens and pays rewards over timeReward accounting errors
Governance and timelockLets token holders vote on changes and delays their executionVote buying with flash-loaned tokens
Oracle adapterReads prices from an oracle network and checks themStale or manipulated prices

The guides on DeFi lending, staking platforms and decentralized exchanges cover each product in depth.

Why DeFi smart contracts are harder to build

  • Open access. Any other contract can call your contract, in any order, and several calls can happen inside one transaction. With a flash loan, the caller can hold millions of dollars for that one transaction, and your code must stay safe even when a caller controls that much money.
  • Outside dependencies. Your contracts read oracles, call pools in other protocols and handle tokens that behave in unusual ways. Some tokens take a fee on each transfer, some change balances on their own (rebasing tokens), and others return no value from a transfer, block certain addresses, or can pause all transfers.
  • Math precision. Solidity has no decimal numbers, so contracts use fixed-point math, and every rounding step must favor the protocol. A rounding error of one unit can become an attack when someone repeats it many times.
  • Economic invariants. An invariant is a rule that must always be true, such as "total shares match total assets" or "the sum of user balances equals the tokens the contract holds". Each invariant must hold after any sequence of calls.
  • Changes in Ethereum itself. EIP-7702 went live with the Pectra upgrade in May 2025, and since then a normal user account can also run contract code. Some contracts use the check tx.origin == msg.sender to block calls from other contracts. With EIP-7702, a call that passes this check can still run contract code, so the check no longer protects anything.

The most common vulnerabilities

The OWASP Smart Contract Top 10 for 2026 ranks risks from 122 incidents in 2025, which caused about $905 million in losses from contract flaws alone, not counting phishing, exchange hacks or rug pulls. The table shows the four categories with the largest losses.

OWASP category2025 lossesWhat goes wrong
SC09 Integer overflow and underflowabout $260 million (3 incidents)A number grows past the largest value its type can hold and wraps around to a small value. Solidity 0.8 and later stop the transaction instead, except inside unchecked blocks
SC01 Access controlabout $220 million (30 incidents)A privileged function lacks a check, or an admin key is stolen
SC02 Business logicabout $189 million (58 incidents)The code runs as written, but the protocol's own rules let a user take value
SC07 Arithmetic errorsabout $138 millionRounding and precision mistakes

The other six categories include reentrancy, flash loan attacks and oracle manipulation, and the smart contract security article describes all ten categories.

Engineering practices to ask for

PracticeWhat it catchesWhat to ask for
Written specification and invariant listDesign flaws before any code existsThe specification, for your review
Unit testsFunctional bugsA branch coverage report
Fuzz and invariant testsEdge cases and broken invariants under random call sequencesFoundry invariant suites, or Echidna or Medusa campaigns
Mainnet fork testsProblems with real tokens, pools and oraclesTests that run against a copy of live chain state
Static analysisKnown bug patternsSlither or Aderyn output with a note on each finding
Formal verification, for critical codeProof that key properties always holdThe list of proven properties, from tools such as Certora or Halmos
Independent auditMistakes the authors cannot see in their own codeA report from a firm that the developers do not control

Design decisions a good team will raise

Upgradeability

A proxy contract lets a team replace the logic behind a fixed address. Common patterns are transparent proxies, UUPS proxies and beacon proxies. A proxy lets the team fix bugs, but it also lets a stolen admin key replace the logic and take the funds.

A careful team keeps as little code upgradeable as possible, because a stolen key can change any upgradeable part. Where possible, the contracts that track balances cannot be changed at all. The team uses ERC-7201 namespaced storage so that upgrades do not overwrite stored data. Every upgrade goes through a multisig wallet, which needs several signers, and a timelock, which delays each change.

Admin powers

The team should list every privileged function, who can call it, what it can change and what limits apply. "Owner can set fee" is too open. "Governance can set the fee between 0% and 1% after a 48-hour delay" is a bounded power. An emergency pause should stop new deposits and borrows but still let users with healthy positions withdraw, unless the team states a reason.

Reuse of audited code

Experienced DeFi engineers reuse audited libraries such as OpenZeppelin Contracts and Solady. OpenZeppelin's ERC-4626 vault, for example, includes virtual shares and a decimals offset that make the inflation attack unprofitable. If a team wants to write its own token, math or proxy code instead of using a library, ask for the reason.

Languages and chains

LanguageChainsNotes
SolidityEthereum, Arbitrum, Base, BNB Smart Chain and other EVM chainsLargest set of tools, libraries and auditors
VyperEVM chainsPython-like syntax with fewer features, used by Curve
Rust (often with the Anchor framework)SolanaDifferent account model, so EVM experience does not transfer directly
MoveSui and AptosResource types prevent some token bugs by design

A bug in the compiler can also break a contract. In July 2023, a bug in Vyper versions 0.2.15, 0.2.16 and 0.3.0 broke reentrancy locks, and attackers drained several Curve pools. Losses reached roughly $50 to $70 million, and white-hat hackers later returned part of the funds. Pin the compiler version and track compiler bug notices.

Deliverables you should receive

  1. A specification and a threat model. The threat model lists the attack types the team considered, such as reentrancy, oracle manipulation, rounding, access control, flash-loan governance attacks and denial of service.
  2. Source code in a repository you own, with pinned compiler versions and reproducible builds.
  3. The full test suite, including fuzz and invariant tests, which runs in continuous integration (CI).
  4. Deployment scripts and a checklist that covers constructor arguments, role assignments, ownership transfers and source verification on block explorers.
  5. Audit reports and a log that shows how the team fixed each finding.
  6. Operations documents covering monitoring, keeper bots (scripts that send routine transactions) and emergency steps.

How to vet a DeFi smart contract development team

  • Read code the team has shipped. Ask for deployed, verified contracts and their audit reports. Check the severity of past findings and how the team fixed them.
  • Ask about past incidents. A team should be able to describe a bug it caught or shipped and what it changed afterward. A team that claims it has never had a bug is not credible.
  • Test the team's threat modeling. Ask how the team would protect a vault against the first-depositor inflation attack and how it would price a liquid staking token used as collateral. A vague answer is a warning sign.
  • Check auditor independence. The auditor should not be the same company as the developer or a sister company.
  • Watch for scope growth. A team that agrees to add tokenomics, NFTs and a cross-chain bridge to a first lending release adds risk for your users.

Cost and timeline

These figures are estimates, not quotes. A small contract system with a clear specification, such as a staking contract or a vault with one strategy and a few hundred lines of code, takes one or two senior engineers two to six weeks, including tests. A full protocol takes several months.

Audits add cost and calendar time, so plan time for a second review after fixes. The audit guide explains what drives audit prices, and the DeFi development overview shows where contracts fit in the full product.

Frequently asked questions

Should DeFi smart contracts use Solidity or Vyper?

Most teams use Solidity, because it has more tools, libraries and auditors. Vyper is simpler by design, and Curve uses it. Either language works if the team and the auditors know it well.

How much test coverage is enough?

A high line coverage number does not show that the tests check the important cases. Ask whether the invariants are tested under random call sequences and against forked mainnet state, and ask what the invariant suite checks as well as the coverage percentage.

Should DeFi contracts be upgradeable?

Make only the parts that must change upgradeable, and put them behind a timelock. Many protocols keep core contracts immutable and make only the peripheral contracts replaceable.

Is one audit enough?

One audit can be enough for a small, simple contract. Protocols that hold large sums often use two independent audits, or an audit plus a public audit contest, with a bug bounty after launch.