Back to blog

DeFi security due diligence: a worked example

A treasury is considering a $250,000 USDC deposit into a vault quoting an 8% annual yield. If that rate holds and USDC stays at $1, the return would be about $20,000 over a year, before any additional fees. The full $250,000 would be exposed to the vault, so I’d want to understand how it handles the money before approving the deposit.

For a fund, treasury or trading team, DeFi security due diligence means reviewing the protocol together with the position it plans to hold. I’d establish where the USDC goes, who can change that path and what could prevent a withdrawal.

I’ll work through the review using Cedar Vault, from the first evidence request to the deposit decision. There’s an audit gap to resolve, a withdrawal limit that affects the exit, and a smaller pilot to consider once the evidence is complete. The blank review template at the end lets you record the same decisions for your own integration.

Cedar’s yield, review findings and operating limits are invented for this example. Dollar figures assume USDC at $1, and transaction limits are set in USDC units. Circle’s risk disclosures explain that its market price can differ from $1.

Start with what the vault does with the money

Cedar accepts USDC on Ethereum and lends it to one pool through a strategy contract. The treasury receives vault shares, tokens representing its interest in the vault. To leave, it returns those shares and withdraws USDC, subject to the vault’s rules and available liquidity.

Cedar Vault funds flow: USDC moves from the treasury wallet through the vault and strategy into the lending pool. Withdrawals reverse that path. Vault shares return from the vault to the treasury wallet on deposit.
The wallet holds vault shares, a claim on the position. Custody controls protect the shares, while the underlying USDC remains exposed to the vault and pool.

For this decision, the treasury won’t borrow against the shares, bridge them or deposit them into another protocol. Each of those would add another dependency. I want the first review to cover a clearly defined position and its route back to custody.

The asset also needs to be identified by its contract address and chain. For USDC, I’d use Circle’s published contract addresses as the starting point. A familiar symbol in a wallet interface isn’t enough to identify the asset being approved.

Before the deposit, the treasury gives the vault a spending allowance. That permission lets the vault transfer approved USDC from the wallet. I’d approve only the next deposit amount, keep unrelated balances elsewhere, and check the remaining allowance after execution. The ERC-20 specification defines allowances and transferFrom, the operation used to spend approved tokens.

Cedar uses ERC-4626, a common interface for tokenized vaults. It gives us standard functions for deposits and withdrawals. We still need to establish what Cedar’s implementation does behind those functions.

The audit is where the first problem appears

The evidence package contains an audit report and verified contract source. That’s useful, but the next step is to connect them to the code actually handling the deposit.

Cedar uses a proxy: the address users interact with forwards execution to a separate implementation contract. An upgrade can change that implementation while leaving the vault address the same. Ethereum’s upgrade documentation explains this arrangement.

Cedar Vault audit coverage: the vault code matches the reviewed deployment, but the new strategy withdrawal path lacks review coverage. Hold deposits.
The withdrawal path is the evidence gap that stops this deposit. A smaller deposit would leave the same question unanswered.

The completed evidence review records three other findings:

  • Deployment: the proxy, implementation, strategy and pool are identified. Verified source and build settings match the deployed code. Initialization and configuration are recorded.
  • Remediation: the previous version’s withdrawal-accounting fix has a documented follow-up review. That evidence covers the earlier version only.
  • Dependencies: the pool deployment matches its separate review scope. The asset is native USDC with issuer controls. Borrower solvency and redemption rights need separate assessment.

Verified source doesn’t close this gap. It establishes a correspondence between published source and deployed bytecode, the code executed on the chain. It doesn’t establish correct behavior or audit coverage. Ethereum’s verification documentation explains the distinction.

The evidence request is specific: provide a review of the changed withdrawal path, identify the reviewed code revision, and map it to the deployed strategy. Include the findings and evidence that any fixes were checked. A general assurance that the protocol is audited would leave the request open.

Keep the original reports and this mapping against a deployment snapshot: chain ID, finalized block number and hash, exact addresses, code hashes and capture time. For an ERC-1967 proxy, inspect the relevant implementation or beacon storage slot as well as the upgrade authority. A beacon is a contract that supplies the implementation address. The ERC-1967 specification defines these slots and related events.

Then work out who can change the position

Even if the strategy receives the missing review, the treasury still needs to understand the administrative powers. Reviewed code can be replaced. A withdrawal that works today can behave differently after an upgrade.

Cedar has a 48-hour timelock for upgrades. Covered changes must wait before execution. That gives the treasury a response window, provided the team detects the proposal and can withdraw in time. I’d inspect who can schedule and execute changes, who can grant those permissions, and whether another route bypasses the delay. OpenZeppelin’s access-control documentation describes these roles.

Power Cedar’s configuration Exposure for the treasury
Upgrade the vault or replace the strategy A protocol wallet needs three of five signers to propose a change through the 48-hour timelock. The timelock controls upgrades and its own administration. No immediate upgrade path is present. Once the delay expires, new code could redirect or take deposited funds.
Pause activity A separate wallet needs two of three signers to stop deposits and new strategy allocations. Current code leaves withdrawals available. Resuming allocations requires the delayed controller. Existing pool positions remain exposed. A later implementation could change withdrawal behavior.
Redirect funds or rescue tokens The current strategy moves USDC only between the vault and the recorded pool. Its rescue function excludes USDC, vault shares and the pool position token. Changing the pool or recipient requires the timelock. Confirm the restrictions in code and tests. They can be replaced by an upgrade.
Withdraw from treasury custody The treasury wallet requires two of three signers. Its signing policy permits withdrawal only to that wallet. No execution module or delegate is enabled. Signer compromise or a policy change can defeat custody restrictions. Record which controls are enforced by the custody system and which depend on written procedures.
Change a dependency The pool has its own upgrade controller with a 24-hour delay. USDC has issuer controls, including address blocklisting. Cedar’s 48-hour delay doesn’t apply to either dependency. A blocked address can be unable to send or receive USDC.

For a multisignature wallet, check execution paths as well as owners and signing thresholds. Safe modules, for example, can execute transactions through their own authorization logic. A two-of-three label doesn’t describe every possible permission.

USDC’s issuer controls belong in the review because they affect the exit. Circle explains the circumstances and effects of address restrictions in its blocklisting documentation. The vault’s own pause settings cannot override a restriction at the asset level.

A 48-hour delay is only useful if we can leave

Now take a $25,000 pilot position. Cedar permits withdrawals of up to 40,000 USDC across all users per rolling 24 hours, subject to pool liquidity. At first glance, that looks like enough room for the treasury to exit.

A $25,000 Cedar Vault position has $8,000 available to exit and $17,000 still exposed after other users consume $32,000 of the shared $40,000 withdrawal limit.
A 48-hour upgrade delay reserves no exit capacity. Here, $17,000 stays exposed until capacity and liquidity become available.

The exit review also needs to establish what happens in these states:

  • Under normal liquidity, a 1,000 USDC deposit returns shares and a full withdrawal returns funds to custody. Record fees, shares burned and the balance recovered.
  • With deposits paused, new deposits fail while withdrawals remain available under the current implementation. Establish the reason for the pause before considering a restart.
  • With pool liquidity exhausted or the vault or pool address blocked from transferring USDC, withdrawal fails. Escalate the remaining exposure and retain the transaction record. There is no separate escape route around the pool or the token’s controls.

For an ERC-4626 vault, check maxWithdraw(owner) alongside a withdrawal preview. maxWithdraw must account for applicable limits. previewWithdraw estimates the shares required and must ignore those limits. A quote can exist when the actual withdrawal is unavailable. These are distinct requirements in ERC-4626.

The exit procedure also needs to work without the protocol’s website. Use the reviewed contract interface, return assets to the existing custody wallet, and have gas and enough available signers to execute. After a partial withdrawal, check transaction state and remaining capacity before retrying.

Revoking unused allowances is part of stopping new activity. It removes unused spending permission. It cannot recover USDC already deposited in the vault.

What would change the recommendation?

At this stage, the recommendation is to hold deposits. The missing strategy review is the blocker. The permission map and exit analysis tell us what risks would remain after that blocker is resolved.

Now suppose the supplemental review arrives. It covers the new withdrawal path and maps the exact deployed strategy code to the reviewed revision. Findings have documented resolutions. The security reviewer checks the mapping against a fresh deployment snapshot.

I’d then consider a $25,000 pilot, rather than approving the original $250,000 allocation. The smaller amount sets the exposure we’re willing to accept while the treasury exercises its controls. It isn’t a substitute for the evidence we’ve just obtained.

Before any deposit, the treasury team must demonstrate the custody restrictions. The monitoring owner must demonstrate alert delivery and rehearse the exit. The security reviewer must confirm the current code and permissions. Whoever accepts the exposure must acknowledge in writing that the entire pilot could be lost or become inaccessible. The separate investment, legal and credit approvals must also be complete.

The first permitted deposit would be 1,000 USDC, followed by a full withdrawal back to custody. Only after full recovery and balance reconciliation would deposits increase toward the pilot cap. A failed round trip would suspend that permission and reopen the review.

For this pilot, the operating limits would be:

Control Limit or requirement
Aggregate position across treasury wallets 25,000 USDC, including accrued yield. Stop new deposits above the cap.
Total deposits during the pilot 25,000 USDC, including the initial test. A withdrawal doesn’t reset this allowance.
Deposit rate No more than 10,000 USDC per rolling 24 hours. This does not restrict emergency withdrawals.
Treasury wallet Only the allocated USDC and enough ETH for fees. No share approvals or use as collateral elsewhere.
Transaction approval Restrict the chain, asset, vault and functions. Check the spender and receiver. Simulate each deposit and have a second person compare the decoded transaction data with the intended action.
Review expiry 30 days, or sooner if a change or incident triggers another review.

These amounts express the assumed risk tolerance in this example. They aren’t default limits for another treasury. The original $250,000 allocation still needs a separate decision.

Someone needs to own the response

For Cedar, I’d monitor scheduled upgrades, implementation changes, roles, pauses and dependencies. Compare current code identities, allowances, position value and withdrawal capacity with the approved state every five minutes. A missed check must alert too.

The example requires acknowledgment within 15 minutes by a named person, with a backup. Rehearse the response outside normal working hours.

Cedar Vault emergency exit: a scheduled upgrade becomes eligible after 48 hours. Alert the team, prepare signers and attempt withdrawal. Available capacity and liquidity allow USDC to return to custody. A limited or blocked exit leaves the remaining funds exposed.
The 48-hour delay creates a response window. It guarantees neither available liquidity nor a complete withdrawal.

New deposits stop immediately after a code, authority, custody-policy or dependency change. A failed exit, unexplained accounting difference, credible vulnerability report or loss of monitoring also reopens the decision. Follow the exit procedure where possible and record what remains exposed. Restoring deposits requires a new recorded approval.

Keep the security decision within its scope

Even with the pilot controls in place, we haven’t established how much liquidity will be available during a market shock or ruled out a later signer compromise. Those are remaining risks to record and accept. An unidentified administrator or unexplained code change would instead leave the review incomplete and block new deposits.

DeFi due diligence needs separate approvals: security reviews code and controls, investment reviews returns and portfolio fit, legal reviews permission and rights, and credit reviews issuer and borrower risk.
Security approval covers the integration and its controls. The return, legal rights and credit exposure need their own decisions.

Before increasing the allocation, changing strategy or using the shares elsewhere, reopen the review. Record what changed, what evidence supports the new position and who accepts the remaining risk.

Review your next integration

Download the blank DeFi security review template. Use it to record the contracts, evidence gaps and decision conditions for the position you’re considering. No signup is required.

Discuss a DeFi security review

For a review of a vault or protocol your team is considering, see my DeFi technical due diligence service. We can define the scope around your planned interaction and the decision you need to make.