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 type | What it does | Main risk |
|---|---|---|
| Token (ERC-20) | Records balances and transfers | Unsafe mint or admin functions |
| Vault (ERC-4626) | Takes deposits, issues shares and runs a yield strategy | Share 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 liquidity | Price manipulation and rounding errors |
| Lending market | Lends assets against collateral and runs liquidations | Oracle errors and bad debt |
| Staking and rewards | Locks tokens and pays rewards over time | Reward accounting errors |
| Governance and timelock | Lets token holders vote on changes and delays their execution | Vote buying with flash-loaned tokens |
| Oracle adapter | Reads prices from an oracle network and checks them | Stale 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.senderto 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 category | 2025 losses | What goes wrong |
|---|---|---|
| SC09 Integer overflow and underflow | about $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 control | about $220 million (30 incidents) | A privileged function lacks a check, or an admin key is stolen |
| SC02 Business logic | about $189 million (58 incidents) | The code runs as written, but the protocol's own rules let a user take value |
| SC07 Arithmetic errors | about $138 million | Rounding 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
| Practice | What it catches | What to ask for |
|---|---|---|
| Written specification and invariant list | Design flaws before any code exists | The specification, for your review |
| Unit tests | Functional bugs | A branch coverage report |
| Fuzz and invariant tests | Edge cases and broken invariants under random call sequences | Foundry invariant suites, or Echidna or Medusa campaigns |
| Mainnet fork tests | Problems with real tokens, pools and oracles | Tests that run against a copy of live chain state |
| Static analysis | Known bug patterns | Slither or Aderyn output with a note on each finding |
| Formal verification, for critical code | Proof that key properties always hold | The list of proven properties, from tools such as Certora or Halmos |
| Independent audit | Mistakes the authors cannot see in their own code | A 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
| Language | Chains | Notes |
|---|---|---|
| Solidity | Ethereum, Arbitrum, Base, BNB Smart Chain and other EVM chains | Largest set of tools, libraries and auditors |
| Vyper | EVM chains | Python-like syntax with fewer features, used by Curve |
| Rust (often with the Anchor framework) | Solana | Different account model, so EVM experience does not transfer directly |
| Move | Sui and Aptos | Resource 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
- 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.
- Source code in a repository you own, with pinned compiler versions and reproducible builds.
- The full test suite, including fuzz and invariant tests, which runs in continuous integration (CI).
- Deployment scripts and a checklist that covers constructor arguments, role assignments, ownership transfers and source verification on block explorers.
- Audit reports and a log that shows how the team fixed each finding.
- 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.