Library · Summary & review

Building Full Stack DeFi Applications

By Samuel Zhou. A workshop that rebuilds a Uniswap, an Aave-style lending pool and a price oracle.

FR EN
Building Full Stack DeFi Applications book cover, Samuel Zhou

Building Full Stack DeFi Applications

Building Full Stack DeFi Applications: A practical guide to creating your own decentralized finance projects on blockchain

5.8 /10

« A good workshop to understand how DeFi works, not to ship one. »

  • AuthorSamuel Zhou
  • OriginalPackt, 2024 · course, 126 lessons, 8 h 10
  • LanguageEnglish only
  • This page~15 min read
  • Read it Read on ExpertEdge Code : 50% off the yearly plan. Affiliate link: I earn a commission if you subscribe with this code. My ratings do not depend on it.
Book rating across 5 dimensionsIdeas5/10Practical6/10Readability6/10Aged well5/10Examples7/10

You rebuild a Uniswap v2, an Aave-style lending pool and a price oracle: the Solidity is readable, the tooling and the security coverage have aged.

Why this book

A classic exchange keeps an order book, the list of buy and sell offers to be matched. DeFi, short for decentralized finance, can do without it. Programs running on a blockchain provide the financial services: the program is the marketplace. How does it stand up with nobody at the counter? Samuel Zhou rebuilds it to answer. The thread, as I read it: every financial service comes down to a formula, written into a contract and then tested.

From the book, I keep seven ideas in three questions. How does a program set a price with nobody on the other side (ideas 1 and 2)? How does it lend, at what rate, and who steps in when the collateral no longer covers the loan (ideas 3 to 5)? And why does everything fall apart when the price it reads is wrong (ideas 6 and 7)?

On the centralized platform side, I know the setting: portfolio-management mandates under AMF approval (the French financial regulator), custody of assets with Fireblocks, connectors to five exchanges. I also use Event Sourcing: every change is stored as an event that is never rewritten. The other side escapes me, the one where the program is the marketplace.

These programs are called smart contracts: once deployed on the blockchain, nobody can change them. The book writes them in Solidity, Ethereum's contract language, then plugs them into a React front end. They manage tokens, digital assets whose balances a contract keeps for each holder. Every operation consumes gas, the fee paid to the network.

Before building anything, the course opens with a real introduction (lessons 3 to 8). DeFi gets six traits there: decentralized, transparent, open, non-custodial, anonymous, zero downtime. A caveat follows right away: "a DeFi project could be centralized if the DeFi smart contract doesn't renounce ownership". In other words, if an administrator keeps special powers over the contract, decentralization is only a facade.

The introduction also defines two figures every protocol displays. TVL (total value locked) is the total value deposited in its contracts. APY (annual percentage yield) is the return over a year, compound interest included. The book's example deflates the promises: an offer at 100% APY on a 7-day deposit earns 1.34% for those 7 days. Hence its warning: "Sometimes a high APY is a marketing strategy".

The introduction ends with four contract vulnerabilities, each with its fix:

The ideas that stay

1No seller on the other side, just a formula

First service to rebuild, the swap, and first problem: with no server, who keeps the order book? For the book, "a fully on-chain order book DEX is a challenge in implementation and user experience" (lesson 24). So it builds something else. Picture a currency exchange booth with no teller, just two drawers and a pricing rule. The two drawers form a pool: one of ETH (ether, Ethereum's currency), one of USDT (a token worth one dollar).

The whole thing is called an AMM (Automated Market Maker). It lives in a DEX, a decentralized exchange. The book: "A liquidity pool in a DEX is a smart contract that holds two or more types of tokens" (lesson 23).

The rule of Uniswap v2, one of the best-known DEXs, is the constant product: reserve A times reserve B equals a constant K, which trades do not change. My example, with no fees:

Pool: 5 ETH and 10,000 USDT, so K = 50,000, price = 10,000 / 5 = 2,000 USDT.
I buy 1 ETH: 4 ETH are left, so the USDT must rise to 50,000 / 4 = 12,500.
I pay 2,500 USDT for 1 ETH, and the pool price becomes 12,500 / 4 = 3,125.

That is price impact: with equal reserves, buying 90% of a token multiplies its price by 100 (lesson 25). Slippage (the price moves between your click and the confirmation) is never named, but its safeguard exists: a minimum to receive, below which the trade is cancelled, which the front end sets at "90% of the receiving amount shown on the page" (lesson 57). The maximum to pay follows the same rule, at 110%.

The book sets this principle for swaps, in the contract itself: "We allow users to specify the minimum amount of tokens they want to receive, or the maximum amount of tokens they are willing to pay." (lesson 40). Its own liquidity pages ignore it. To add or remove liquidity, they send 0 and 0 as minimums (lessons 49 and 50): the operation goes through whatever the price at that moment.

A comparison of my own, not from the book: a pool looks like a one-row SQL table with two reserve columns. Every UPDATE must keep one rule: ETH reserve × USDT reserve = K. The price is stored nowhere. It is computed on every read. If you test such a pool, check that rule after every swap, not a price written down in advance.

2Your share of the pool is a token

A formula is not enough: it needs contracts to carry it, and people to fill the drawers. The router is the counter, the factory makes the cash drawers, each pair is a cash drawer. The pair holds the reserves and issues the LP token, which proves you own a share of the pool (lesson 29). This token follows ERC-20, the common standard for tokens: transfer, balance, approval.

Four calls: create a pair, swap, add liquidity (mint) or remove it (burn). Example: 100 BTC and 1,600 ETH in a pool that has issued 400 LP tokens. Whoever holds 40 owns 10% and gets back 10 BTC and 160 ETH (lesson 23).

That share has a hidden cost, impermanent loss: staying in the pool can earn less than simply holding your two tokens. The book's example starts with 1 WETH (ETH in the form of an ERC-20 token) and 100 USDT deposited when ETH is worth 100 USDT. ETH rises to 110. Withdrawing your share, you get back 0.9535 WETH and 104.88 USDT, that is 209.76 USDT. By simply holding the tokens, you would have 210 USDT: the loss is 0.24 (lesson 28).

My explanation of the mechanism, drawn from the formula in idea 1: when the price rises, buyers take ETH out of the pool and leave USDT in it, so the provider sells their ETH along the way, as the price climbs. The loss shows up on the way down as well as up, and vanishes if the price comes back. For the book, it is "inevitable" without another reward. Hence the fees: each pair charges 0.2% on every swap (lesson 40), for the benefit of the providers.

3Lending means holding shares that rise

Those pool shares come back in the second service, lending. Think of a pawnbroker: you leave an item, you get cash, you get the item back by repaying. DeFi lending does the same with tokens, with no paperwork and no credit check. The collateral (the deposit that secures the loan) sets the ceiling: you borrow at most the LTV (loan-to-value) times its value, for example 75% of $1,000 in my example. Nobody borrows more than the pool's funds (lesson 82).

The lender receives pool shares, an ERC-20 like the LP token. Lily deposits 100 USDT for 100 shares at 1 USDT. A share is worth the total liquidity divided by the number of shares: borrowers' interest swells the liquidity, so the share. Six months later it is worth 1.1 and Lily withdraws 110 USDT (lesson 87).

Bob borrows 80 USDT at 5% out of Lily's 100 and repays a year later with 4 USDT of interest, which Lily pockets: she earns 4%. Lending rate = pool utilization (80%) × borrow rate (5%) (lesson 84).

At home, my own idea, not the book's: you do not write interest on each lender's row. You keep two numbers, the total liquidity and the number of shares. The value of a share is computed on read. A thousand lenders, and a single UPDATE when interest comes in. The matching test: deposit, bring in some interest, check that the withdrawal returns more than the deposit.

The book makes the same saving for staking, which it covers before lending. Staking means locking tokens in a contract to earn rewards. The book's example: Tom and Alice each deposited 1 bitcoin in the same staking pool, which pays out in USDT. Tom deposited his a year ago, Alice two years ago. Today, Tom can claim 100 USDT and Alice 200 USDT. Same deposit, but Alice has been waiting twice as long.

To reach those two amounts, the contract pays nobody at each block. Each block hands out a fixed reward among the depositors. The contract keeps a single counter: the reward earned per bitcoin deposited since the pool opened. It computes each share only on deposit or withdrawal. Yet that counter also runs over the year when Tom was not there. So when Tom deposits, the contract records what had already been handed out. The book calls that amount the "reward debt". It "is not the real debt a user owes to the smart contract" (lesson 70), only what gets deducted at withdrawal. Tom's reward debt is larger than Alice's, because more has to be deducted for him.

4Past the kink, borrowing hurts

Bob's rate does not fall from the sky: the emptier a pool gets, the more borrowing must be discouraged. Utilization measures that emptiness: it is the share of the liquidity that is borrowed (80 USDT out of 100, 80%).

The PoolConfiguration contract sets six parameters. Among them are the base rate (baseBorrowRate) and the optimal utilization, from 50 to 90% according to the book. Two increases come on top: optimalSpan, spread up to that threshold, and excessSpan, added beyond it (lessons 84 and 85).

if (utilizationRate > optimalUtilizationRate) {
    return baseBorrowRate + optimalSpan + (excessSpan *
        (utilizationRate - optimalUtilizationRate)) /
        (1e18 - optimalUtilizationRate);
}
return baseBorrowRate + (utilizationRate * optimalSpan) / optimalUtilizationRate;

The book gives a worked example (lesson 85). In it, the rate climbs from 1% to 9% up to the kink, then from 9% to 60% as the pool drains. The second, steeper slope pushes borrowers to repay before the pool runs dry.

My numbers, not the book's (base 2%, optimalSpan 4%, excessSpan 60%, threshold 80%): at 40% utilization borrowing costs 4%, at 80% it costs 6%, at 90% it costs 2 + 4 + 60 × 10 / 20 = 36%.

Solidity has no decimals: every rate is an integer multiplied by 10^18, so 1% is written 10^16. In the book's code, one parameter of the rate function has no type, a typo (lesson 87).

5When the collateral melts, the liquidator earns a bonus

A well-tuned rate does not protect against everything: the price of the collateral from idea 3 can fall. The borrowing ceiling falls with it, and the debt ends up above it. The book admits it: "There is no proactive way to resolve the issue using the crypto loan system." (lesson 86).

The fix is called liquidation. A third party, the liquidator, repays part of the debt on the borrower's behalf. In return, they receive some of the borrower's collateral, for the same value plus a bonus. The book's example: the liquidator pays 1,000 USDT for an account in default. They can leave with 1,100 USDT of collateral (a bonus of 1.1), or take BTC instead if the BTC pool pays a bonus of 1.2.

Two settings frame the operation. The close factor, below 1, caps the share of the debt that can be repaid in one transaction (lesson 94). The bonus, for its part, is set according to the LTV: too high, and liquidators drain the collateral. The code of the liquidate function is not shown, by the author's choice: "The code of the liquidate function is very lengthy and we will not post it here in the course."

Is this the vocabulary of a real protocol? The book holds it up to Aave, one of DeFi's major lending protocols: "The workflows and concepts in the Aave protocol version 2 are consistent with the protocol we will build in this course." (lesson 88). It sets Aave's words against its own:

  • Aave's Max LTV = the course's collateralRate;
  • the reserve factor (the share of interest kept by the protocol) = its reserve rate;
  • Aave's liquidation penalty = the liquidator's bonus.

The book also reads Aave v2's ETH pool: 233.13K ETH supplied, 76,748 borrowed, so 32.92% utilization, borrowing at 2.60%, lending at 0.64%.

v3 is only presented, with two features "we will not implement in this course". Isolation mode sets a debt ceiling for risky assets. E-mode gives an LTV above 90% between stablecoins, tokens pegged to the dollar like USDT. Absent from the text, by search: the "health factor", aTokens, the stable rate.

Liquidation does not trigger itself, and one of the last extracted lessons says so (lesson 113). Unlike the DEX, "running a crypto loan system requires some effort and cost to maintain". Someone has to listen for borrows and withdrawals, check the health of accounts, then liquidate those in default. The book suggests a script, or a public list of accounts so the community can do it. It also advises lending only assets from the top 100 cryptocurrencies, which are harder to manipulate.

6One pool, and the price is for sale

Borrowing ceiling, liquidation: all of lending rests on the price of the collateral. So where does that price come from? A contract knows no price: it asks an oracle, like a pawnbroker asking an appraiser. Reading it from the reserve ratio of a single pool is the book's trap: "this way is extremely dangerous" (lesson 84), since a big order moves it (idea 1).

The attack plays out in four steps (lesson 98). Buy the token to inflate its price. Deposit a little of it as collateral, which the oracle then thinks is precious. Borrow other assets well beyond its true value. Sell the token back. With a collateral rate of 80%, inflating the price by 25% is enough for the borrowing ceiling to equal the true value of the deposit (lesson 98). Beyond that, the attacker keeps the difference.

It takes funds and speed. The funds come from a flash loan, an uncollateralized loan repaid within the same transaction. The speed: chain everything in one transaction from a contract, or in ordered transactions that nobody slips between (lesson 98). The book cites Euler Finance: "The biggest flash loan attack at the time of writing the course happened on Euler Finance in March 2023, which caused a massive loss of 197 million US dollars." (lesson 98).

The book does not stop at theory: it plays the attack in a test (lesson 99). The setting is two small pools, one of them holding 10 BAR (a test token) for 1 ETH. The attacker, a plain test account, buys BAR there with 99 ETH, and the BAR price is multiplied by almost 10,000. They deposit 0.26 BAR as collateral, drain the lending pools, then sell their BAR back. The test checks that the final balance beats the starting one: "the attacker gains over 100 ETH by manipulating the price of BAR".

On the web, my own idea, not the book's: never trust a value you have not checked. A price sent by a shop's form is not taken as is in PHP, you read it again from the database. Here, the value to check comes from a pool anyone can move for the length of one transaction. The test to write is the same in both cases: play the attacker, then check that the operation is refused.

7One rigged block drowns in the average

If a single pool can be manipulated, you need a price that is harder to move. First option, Chainlink, one of the most widely used oracles: it aggregates at least 21 answers for the price of ETH. But, like the other providers, it covers only a few hundred cryptos (lesson 100).

The book takes Uniswap v2's approach. The chain validates transactions in batches, called blocks, about every 12 seconds. At each block, each pair accumulates price × elapsed time, and the oracle derives an average over a window from it, a TWAP (time-weighted average price). It "doesn't rely on multiple oracle sources while keeping the price manipulation resistant" (lesson 100). The reason, according to the rest of the text: the average price flattens the fluctuation (lesson 105). A manipulation fits in one block (12 seconds) within a 720-second window, so it weighs little.

A 720-second window, periods of 12, a script that calls update in a loop (gas on every call, lesson 105). The attack test from idea 6 (99 ETH, BAR price multiplied by almost 10,000) is replayed against this new oracle. This time, the loan is refused:

// The attacker swaps 99 ETH for BAR, deposits all their BAR, borrows 99 WETH (ETH wrapped as an ERC-20)
// revertedWith: the transaction must be cancelled with this reason
await expect(assetPool.connect(user2).borrow(wethToken.address, toWei(99)))
  .to.be.revertedWith("ACCOUNT_UNHEALTHY");

After the manipulation, the v2 oracle gives the BAR token 2.16 ETH, the old oracle, which reads the raw ratio, 723.47 ETH (lesson 105).

My take, honestly

I came looking for DeFi's engine room and found a workshop, not a treatise. How does a program set a price with nobody on the other side? With a formula. How does it lend? With shares, a two-slope rate and liquidators paid to step in. Why does everything fall apart when its price is wrong? Because a single pool can be bought, and the book proves it in code.

Its strength: each service goes from formula to tested contract. The oracle part is the best, because the same attack test succeeds against the bad oracle and then fails against the good one.

Its weaknesses, and what they cost you:

  • Dated tooling, detailed below. Cost: the front end has to be rewritten before it is any use.
  • Security skimmed over. The four vulnerabilities of the introduction are described (lesson 8), but no reentrancy attack is replayed. The extracted lessons include no fuzzing (tests with random inputs) and no audit. Cost: nothing here prepares you for production.
  • A few wrong claims. A loop's gas supposedly "grows exponentially along with the number of iterations" (lesson 8). The book's graph is an image the extraction does not carry. In my view, not the book's, a simple loop costs roughly the same gas on every pass: growth is proportional, not exponential. A higher TVL supposedly "means lower risk" (lesson 5). Again in my view, the size of a deposit says nothing about the quality of the code. Cost: read the introduction with a pencil in hand.
  • An overgrown front end. The React code takes up about a third of the text, in repetitive pages. Cost: hours of reading for few ideas.

My advice: read the introduction, the AMM, the lending up to liquidation and the oracle, skim the staking, skip the front end. My verdict, 5.8 out of 10.

Odilon

Still relevant in 2026?

The substance, yes: constant product, pool shares, kinked rate, liquidation, TWAP. The code, no: Uniswap v3 and v4 and Aave v3 dominate.

The course's tooling has aged. Contracts are compiled and tested with Hardhat 2.12.6, and the wallet connects through the old web3-react API. The front end starts from create-react-app (9 mentions), a React starter tool deprecated since. It talks to the blockchain with Ethers v5, the JavaScript library for that job (84 occurrences of ethers.utils, no BrowserProvider). That front end has to be rewritten in Ethers v6, viem or wagmi, the current libraries.

Who is it for?

Read it if

  • you come from finance or the back end and want to see an AMM, a lending pool and an oracle from the inside;
  • you are looking for the oracle attack explained and tested;
  • you want an introduction to DeFi that does the maths: APY, impermanent loss, rates, liquidation.

Skip it if

  • you are aiming at production: no audit in the extracted lessons, and the liquidation code is not published in the course;
  • you want a modern front end;
  • you are after stablecoins, insurance or DAOs (decentralized autonomous organizations): the course leaves them aside (lesson 7).
Read it on ExpertEdge

This book is part of ExpertEdge, Packt's subscription for technical books. The code ODILON50 takes 50% off the yearly plan: the book on ExpertEdge. Affiliate link: I earn a commission if you subscribe with this code, and my ratings don't depend on it.

For going further

Note based on the ExpertEdge 2024 course version: 114 lessons extracted out of the 126 announced, quizzes included. Source: lessons 3 to 8, 23 to 30, 40, 49, 50, 57, 70, 82 to 88, 94, 98 to 105 and 113 read in detail. Quotes checked word for word against the text. Examples flagged as mine are my own, not the book's.

Comments (0)

Browse the whole library

More book notes coming: one book at a time, the marrow only.