Chapter 7. Decentralizing Finance and the Web

The growing popularity of cryptocurrency, blockchain, and smart contracts has ushered in a number of new use cases that provide specialized functionality, from increased privacy to the creation of a stable payments system to entirely new types of blockchain-based applications. This chapter explores the exciting possibilities being revealed in the realms of decentralized finance (DeFi) and decentralized apps (dapps).

Redistribution of Trust

Although they are trying to innovate, banks today are still slow and expensive. Sending money across borders takes more than a day. And for those who don’t have a bank account, sending money to family or friends living in other countries is costly. With a payment layer that uses cryptocurrency, blockchain can remove intermediaries. Over time, it may also allow users to own their data instead of that data being owned by big technology companies.

Identity and the Dangers of Hacking

Why is it important for users to have ownership of their data? Large companies in the technology and finance space have not been great stewards of data. They have repeatedly been breached, hacked, and otherwise compromised. In many cases they have then attempted to downplay or conceal these breaches, though they have often been caught (and fined) later. For example:

  • Yahoo! disclosed 3 billion accounts had been compromised in 2013. It didn’t release information regarding the hack until 2017 and eventually reached a settlement to pay $117.5 million in compensation.

  • Facebook saw 50 million user accounts compromised in 2018. The US Federal Trade Commission (FTC) fined the company $5 billion for mishandling user data.

  • Equifax disclosed that the personal information of 143 million of its customers had been compromised in 2017. The company reached a deal with regulators to pay $700 million in fines and compensation.

  • eBay suffered an attack in 2014 that exposed the personal information (including passwords) of over 145 million users.

  • Uber’s servers were breached in 2016, after two hackers were able to retrieve password information from GitHub. The hackers then accessed the personal information of 57 million riders and 600,000 drivers. Uber hid the breach for over a year and was ultimately fined $148 million.

And these are just technology companies. Well-known hacks at Target, Marriott, Home Depot, and JPMorgan, among others, have taken user data and put it in the hands of those who try to use that information for nefarious purposes.

Blockchain technology is promising in that it has the ability to disintermediate various industries, many perhaps quite quickly. Some experimentation has already begun. Industries including technology, finance, jobs, and gaming are ripe for disruption. The technical “scaffolding” is being built today for users to have more control over their data.

The ultimate realization of this idea is the concept of self-sovereign identity, where individuals generate their own unique identifiers and store and control access to their own personal information, using public/private key pairs. The idea of an identity that is owned by a user instead of large companies and government bureaucracies is something blockchain developers are enthusiastic about, and it could remove the danger of future hacks and thefts that put people’s identities at risk.

A central issue will be how to balance complexity with ease of use. Private key management and transaction broadcasting may be difficult to teach or too cumbersome for mainstream users. However, some early platforms are trying to tackle this problem, as you’ll see in this section.

Wallets

In order to use a number of DeFi services, users must become familiar with wallets. Fortunately, a number of good options are available today. MetaMask is a software wallet that currently works inside the Chrome, Firefox, and Opera browsers. It is also available for Brave, a new type of browser discussed later in this chapter. Hardware wallets like Ledger are another alternative, and Coinbase also offers support for those who don’t want to concern themselves with key storage.

Note

Remember: if you don’t own the keys, you don’t own the asset.

Decentralizing Finance

The ecosystem of financial services without intermediaries is growing quickly. This is a fascinating area of blockchain that is attracting a lot of attention from developers, and a number of platforms are now working to provide decentralized finance.

DeFi services use smart contracts, cryptocurrency, and blockchain to replace some of the services that banking has traditionally provided. Figure 7-2 illustrates.

Figure 7-2. Traditional versus decentralized finance

DeFi has a lot of moving parts, many of which rely on Ethereum and ERC-20 assets. The flexibility of ERC-20 on Ethereum is what makes DeFi possible, since pools of liquidity can be expanded or reduced depending on market conditions.

Important Definitions

Smart contracts are essential to the DeFi model. Many cryptocurrencies are valuable because of the existence of a fixed supply of assets in circulation. However, many DeFi tokens have an elastic supply to make them inflationary or deflationary, depending on the design of the system. This is where some new terminology needs to be defined:

Minting
Used to increase a cryptocurrency supply, minting involves the creation of new assets. This is done with the creation of new blocks as rewards are generated for stakers, or users who pool assets for incentives. Minting must be properly controlled in order to limit inflation via some system of governance. Otherwise, the value of a cryptocurrency may fall in relation to other assets, diminishing its purchasing power and store of value properties. Minting is algorithmically fixed, or relegated to authorities within a system.
Burning
Used to decrease a cryptocurrency supply, burning involves the destruction of assets. This destruction is done by system authorities. By reducing circulation and lessening supply, this can cause the price of a cryptocurrency to go up. However, the asset could become deflationary via this process—while the value goes up, prices of other assets may go down. Burning could be a one-time event, or a staggered event triggered by revenue/earnings. Burning is also a way to distribute profits back to token holders by reducing the supply in hopes demand and prices rise.
Wrapped tokens
The Ethereum platform was not designed with the ERC-20 standard in mind. Neither were Bitcoin or any other cryptocurrencies outside of the Ethereum ecosystem. Because of users wanting to trade various cryptocurrencies with ERC-20s in smart contracts, wrapped tokens have become a solution. The original asset is “wrapped,” meaning provably held on-chain as collateral. A smart contract facilitates the processes of depositing (minting) and withdrawing (burning) for these ERC-20 representatives of their external cryptocurrency counterparts. Some level of trust is required to assure that the external tokens remain in custody for the holder of the wrapped token balance. Typically, a multisignature scheme is implemented among disinterested custodians who mutually sign off on withdrawal requests.
DAOs
Decentralized autonomous organizations (DAOs) are projects organized via code, mostly through Ethereum smart contracts. Not controlled by a central authority, DAOs have token holders to provide governance. Because DAOs utilize blockchain-based smart contracts, there are transparent records of transactions and the rules governing a DAO. Although their legal and regulatory status isn’t clear, DAOs have already been used for finance, gaming, and social media.
Oracles
Because blockchains don’t interface well with data sources, such as relational databases, oracles are required to provide outside information. Real-world events that are recorded in centralized databases are still needed for these systems to function, and oracles serve that purpose. Oracles bring off-chain data on-chain, as illustrated in Figure 7-3.
Figure 7-3. How oracles interact with blockchains
Note

Oracles play an important role in the blockchain ecosystem because they provide data smart contracts use to execute code. Any wrong or manipulated feed from an oracle could trigger a smart contract execution that could mean an irretrievable loss of funds. A smart contract might be fully secured and audited, but if the oracle is being manipulated, it would also serve as a weak entry point for hackers to exploit. This is why trust in an oracle system is paramount.

Stablecoins

As blockchain-based assets that peg to the US dollar and other fiat currencies, stablecoins underpin services that don’t require banking intermediaries. Many stablecoins do have some regulatory risk (discussed in Chapter 6). In addition, there are various levels of governance and centralization between different projects. Nevertheless, interesting experiments are being done with stablecoins. We’ll briefly look at a few of them here.

DAI

In the volatile world of cryptocurrencies, DeFi requires a stable asset in order to properly service users. The major stablecoin cryptocurrency used for this today is the Maker project’s DAI. DAI, launched in 2018, was originally a “single-collateral token” backed by Ethereum’s ETH. Now DAI is a multicollateral token backed by several cryptocurrencies, including ETH and BAT (Basic Attention Token, the Ethereum token that powers the Brave browser) and others.

However, the cryptocurrencies that back the DAI stablecoin are inherently volatile. So how does Maker create a stable asset from volatile markets? By locking in assets. Here’s how it works:

  1. A user deposits ETH into the Maker smart contract, called a vault.

  2. Maker then allows the user to withdraw DAI. The amount that can be withdrawn must be collateralized 150%. That means a user who deposits $150 worth of ETH can withdraw up to $100 worth of DAI. This DAI is backed by the ETH a user deposits.

  3. If ETH begins to drop against the value deposited, in this example below $150, the system will begin to close out the position. If, for example, the user only withdraws $50 worth of DAI, the system will not close out until ETH drops to $75, which is the 150% collateralization threshold. The position will close unless the user deposits ETH or DAI to make up for the collateral requirement.

  4. A stability fee is charged to return DAI in order to retrieve ETH or another cryptocurrency used for collateral. Currently the fee is 3%, but it’s subject to change. When DAI is returned to the system, it is burned or destroyed because it is no longer backed by collateral. The stability fee is used by Maker to fund the system’s development.

Maker is a DAO, and it also offers an investment token, MKR. MKR is the cryptocurrency that determines elements inside the MakerDAO system. Those who hold MKR have influence over the system. This includes providing input on collateralization requirements, stability fees, how the stability fees are spent, and the emergency shutdown protocol in the event of a price crash.

For every dollar that is paid in stability fees, the equivalent is bought and removed from the MKR market. In addition, for liquidations that cannot be rectified by a standard collateral auction, a debt auction occurs where the equivalent amount of MKR is also bought and removed from the market.

Because the Maker system is smart contract–based, it does not require users to submit personal Know Your Customer (KYC) information to participate. The only thing required to interact with it is a private key and access to some ether.

USDC

An ERC-20 stablecoin, USD Coin (USDC) is supported by two of the largest and best-known companies in cryptocurrency: Coinbase and Circle. USDC is part of a larger consortium called Centre, whose members collaborate on the stablecoin’s governance and use cases. Grant Thorton, LLP, is the auditor for USDC. The firm provides monthly attestations that there are enough reserves to back the USDC stablecoin. The system requires users acquiring or redeeming USDC from the issuer to submit personal information for KYC checks.

KYC and pseudonymity

As mentioned in the previous sections, although DAI does not require KYC information from users, TUSD and USDC do. Because of banking relationships, TUSD and USDC require users to provide personal information to redeem their stablecoins for fiat. However, inside the blockchain ecosystem, the stablecoins can be used pseudonymously, changing hands while leaving a blockchain record, as Figure 7-4 illustrates.

Figure 7-4. How stablecoins can be used pseudonymously

Although DAI is the most used stablecoin in DeFi applications, bank-backed solutions are competitors. The main difference is that TUSD and USDC are backed by fiat, whereas DAI is currently backed by cryptocurrencies.

DeFi Services

With increased stablecoin liquidity, financial services are being built on top of crypto. The website DeFi Pulse is a good barometer for projects that are getting traction. By looking at the number of ETH locked up in smart contracts, it’s easy to tell from DeFi Pulse which projects are gaining users. This is a good way to see what these services are being used for in this nascent market, which is growing every day.

Decentralized Exchanges

Most cryptocurrency exchanges are centralized, hosting wallets and taking fees for every trade. With smart contracts, developers can build decentralized exchanges, also known as DEXes. A DEX allows traders to hold their own private keys and swap cryptocurrencies (usually in the form of wrapped tokens).

Uniswap is one of the most popular DEXes available today. It has many smart contracts that facilitate ETH/ERC-20 exchange. The platform charges 0.3% for each trade, which is placed into a liquidity reserve. This reserve is used to incentivize liquidity providers to maintain a pool of assets for trading. Unlike centralized exchanges that use databases for trading, all trades on DEXes like Uniswap occur on-chain, with no middlemen.

Decentralized Versus Centralized Exchanges

DEXes are designed to work in a very different way than a centralized exchange. The goal of a DEX is that it can provide users with 100% functionality without depending on one centralized authority to power any part of the exchange. This can lead to a more transparent, secure, and trustworthy service that allows users to maintain custody of their funds at all times. The downside of a DEX is that its speed and scalability are limited by the blockchain it runs on. This is because users maintain custody of funds, which adds complexity to the overall experience.

Infrastructure

In a centralized exchange, all of the infrastructure is controlled by a single entity, usually a company, and is delivered to the user through a website. In contrast, all parts of the Uniswap DEX are run by the community, as illustrated in Figure 7-5.

Figure 7-5. High-level view of infrastructure differences between centralized exchanges and DEXes

Table 7-1 compares the frontend code for a centralized and decentralized exchange (in this case, Uniswap).

Table 7-1. Frontend differences between centralized exchanges and Uniswap
Type Centralized exchange Uniswap
Distribution & transparency The frontend code is kept private by the exchange and runs on infrastructure the exchange controls. The frontend code is shared in the Uniswap GitHub repository.
Control The frontend runs on infrastructure the exchange and its hosting provider control. Anyone in the community can launch their own website that interacts with the Uniswap DEX.
Functionality The frontend receives data from the backend, for example to get the exchange rate for the market USD/ETH.
The frontend code also sends instructions to the backend, for example to execute a trade.
The frontend code only receives data from the DEX smart contract. It does not send instructions to the backend.
Instead, the user sends instructions to the smart contract directly from their client device using an Ethereum wallet like MetaMask. The frontend code makes this process more user-friendly by setting up the transaction for the user.
Transaction authorization The transaction authorization is performed in the frontend code, usually with a cookie or an access token stored in the browser. The user authorizes the transaction by generating a transaction signature using their private key, stored in MetaMask. MetaMask then pushes the transaction to the smart contract.

Figure 7-6 is a screenshot of a user executing a trade on Uniswap. Note that the transaction authorization occurs in MetaMask, not in the frontend code.

Figure 7-6. A user executing a trade on Uniswap

Table 7-2 outlines the differences between a centralized exchange and a DEX with regard to the backend and database.

Table 7-2. Backend/database differences between centralized exchanges and Uniswap
Type Centralized exchange Uniswap
Distribution & transparency The backend and database are kept private by the exchange. The public is unable to audit the exchange’s code. The backend logic runs in a smart contract. The code in Uniswap smart contracts can be viewed publicly, so potential users can audit the code before using the DEX. All Uniswap transactions are recorded on the Ethereum blockchain, which is also publicly viewable.
Control The backend runs on infrastructure the exchange and its hosting provider control.
The exchange can make changes to the backend server or database at any time.
In addition, the exchange or hosting provider can shut down the backend or database at any time.
Uniswap smart contracts and transactions are powered by and recorded by thousands of miners.
The smart contracts and transactions are immutable and can never be changed.
The only way to shut down the smart contract or stop transactions from completing is by shutting down the Ethereum network.
Authorizing code execution Before executing any business logic, the backend authorizes API requests using security standards like JWT or OAuth. Smart contract code is run on the Ethereum Virtual Machine (EVM). The smart contract runs on the node of the miner producing the block and everyone in the network running a full node validating the chain.

Figure 7-7 shows part of the Uniswap V1 Exchange Template smart contract, viewable on the blockchain.

Figure 7-7. One of Uniswap’s smart contracts, publicly viewable on the Ethereum blockchain

Custody and counterparty risk

Users of a centralized exchange have to deposit cryptocurrency to begin trading, and the exchange takes custody of their funds. Since the exchange controls users’ funds, there is exposure to counterparty risk. That is, if the exchange gets hacked or shuts down, there is a risk that its users’ funds may be lost.

When someone uses a DEX, the smart contracts manage deposits, withdrawals, trades, and maintaining custody of user funds. Before sending funds to the DEX, users can audit the smart contract code to know how their funds will be used.

Here are the important things to look for in the smart contract:

  • What smart contract methods can move the user’s funds?

  • Who can call those methods to move the user’s funds?

  • Where can those funds be moved to?

To clarify how Uniswap manages user funds, we executed a small trade on the DEX and then audited the transaction, as shown in Figure 7-9.

Figure 7-9. Publicly viewable record of a method call to a Uniswap smart contract

As you can see, we traded 0.05 ETH for 8.34 SAI tokens, worth about $8 USD.

In the transaction record, the input data field contains this value:

0xf39b5b9b0000000000000000000000000000000000000000000000007349d8cdf224ded30000000
00000000000000000000000000000000000000000000000005e283df6

Breaking down the input data shows which smart contract function is called and the arguments passed.

The first 10 characters of the input data field specify the function being called. In this transaction, the first 10 characters are 0xf39b5b9b. Using an online directory, you can learn that the function being called is ethToTokenSwapInput(uint256,uint256). The remaining characters in the input data field are the values of the arguments passed into the function:

0000000000000000000000000000000000000000000000007349d8cdf224ded3

000000000000000000000000000000000000000000000000000000005e283df6

Auditing this transaction, we see that the following steps took place:

  1. The transaction sent 0.05 ETH from our address (0x76e55ab64c5e2415a8a6375fef216977de7ea213) to the Uniswap SAI smart contract (0x09cabec1ead1c0ba254b09efb3ee13841712be14). Those funds will remain in the smart contract to be used as liquidity for future trades. It’s similar to a bank account: when a user puts funds in, they still own the funds and can pull them out at any time; however, while the funds are sitting there, the bank can use them too.

  2. The transaction called the function ethToTokenSwapInput in the Uniswap SAI smart contract (0x09ca…be14) with these input values:

Argument name Value
min_tokens 0000000000000000000000000000000000000000000000007349d8cdf224ded3
deadline 000000000000000000000000000000000000000000000000000000005e283df6

These arguments are in hex format because smart contracts are compiled into bytecode. Decoding them into human-readable values gives us this:

Argument name Value Type
min_tokens 8307409366703988435 uint256
deadline 1579695606 uint256

Let’s take a closer look at the ethToTokenSwapInput function defined in the Uniswap V1 Exchange Template smart contract mentioned earlier (Figure 7-10).

Figure 7-10. The ethToTokenSwapInput function from the Uniswap template code

Looking at the method definition, you can see that it calls another method, ethToTokenInput. As Figure 7-11 shows, this method is where the real logic of this transaction takes place.

Figure 7-11. Transaction logic

Line 128 in Figure 7-11 checks to make sure that the following are true:

  • The deadline given is equal to or later than the timestamp of the block in which this transaction is being included.

  • The amount of eth_sold is greater than 0.

  • The number of min_tokens expected is greater than 0.

Line 129 gets the quantity of tokens that the smart contract is currently holding.

Line 130 gets the number of tokens that the user should receive in the trade. This is an important line because it shows how the exchange rate for the trade is calculated. It calls the function getInputPrice, which determines the exchange rate based on the ratio of ETH to SAI currently sitting in the smart contract.

Line 131 checks to make sure the value of tokens_bought is greater than or equal to the min_tokens value, which is the minimum number of tokens the user is willing to receive.

If all the previous checks were valid, line 132 is executed. This line transfers the tokens from the smart contract to the recipient’s address. More technically, it calls the method transfer in the SAI smart contract (0x89d2…0359) with the following arguments:

Argument name Value Type
dst 0x76e55ab64c5e2415a8a6375fef216977de7ea213 address
wad 8342650846452389346 uint

Line 133 broadcasts out to all listeners of the event TokenPurchase that this trade has been executed.

Finally, line 134 returns the value token_bought, which is how many tokens the user received.

Here are the input values passed to the ethToTokenInput method in our example transaction, resulting in the trade of 0.05 ETH for 8.34 SAI tokens:

Argument name Value Type Description
eth_sold 50000000000000000 uit256(wei)a msg.value is passed for this argument, which refers to the amount of ETH that was sent in the transaction (0.05 ETH). The type is uint256(wei), where 1 ETH = 1018 wei, so we multiply 0.05 by 1018.
min_tokens 8307409366703988435 uint256 This value was passed from the original transaction. It specifies the minimum number of tokens that we are willing to receive before executing the transaction.
deadline 1579695606 timestamp This value was passed from the original transaction. It represents the latest possible date that we are OK with for executing the transaction.
buyer 0x76e55ab64c5e2415a
8a6375fef216977de7ea213
address msg.sender was passed for this argument, which refers to the address that executed the transaction. That was our address.
recipient 0x76e55ab64c5e2415a
8a6375fef216977de7ea213
address Same as previous.

a Wei is the smallest denomination of ether. 1 ether = 1,000,000,000,000,000,000 wei. When interacting with the Ethereum blockchain, numbers are in terms of wei.

Flash Loans

Most standard loans have a process for evaluating who can qualify for a loan and the maximum amount they can borrow. Some loans may require the borrower to provide collateral to guarantee a loan. Lenders create and follow these processes to protect themselves from the risk that the borrower may not return the funds, and that risk increases the longer the borrower holds onto the funds.

A flash loan, on the other hand, allows an Ethereum smart contract to borrow a lender’s funds without collateral under the condition that the smart contract return the funds plus a fee within the same Ethereum transaction. This is useful to a smart contract borrowing funds because it can execute multiple calls to other smart contracts within one Ethereum transaction, and therefore can make use of the borrowed funds while still returning the funds at the same instant.

Figure 7-12 illustrates what is possible for a smart contract to do within one transaction.

Figure 7-12. Example flash loan

If the smart contract does not properly return the funds plus the fee (step 3), the DeFi lending platform can produce an error in step 1, because steps 1 and 3 occur in the same transaction. Therefore, the lending platform is not at risk of the loan defaulting. Since there is no risk to the lender, the lender can loan out to smart contracts all the funds it has available in its lending pool.

Smart contracts hold, receive, and send funds. They also keep a record of balances. Essentially, the smart contract and community incentives replace the centralized authority in a traditional financial product.

Creating a Flash Loan Contract

Let’s look at an example of how to perform a flash loan. In this example we will do the following:

  1. Create a smart contract that can execute flash loans.

  2. Execute a simple flash loan.

The flash loan contract will borrow 1 DAI (ERC-20 token) from the Aave (DeFi service) lending pool, and then return 1.0009 DAI. The amount returned is higher because it includes the flash loan fee.

The code for the Flashloan smart contract is as follows:

pragma solidity ^0.6.6;
// Import Aave flashloan code. By importing you are saving resources from
// having to write out this code.
import "https://github.com/aave/flashloan-
  box/blob/Remix/contracts/aave/FlashLoanReceiverBase.sol";
import "https://github.com/aave/flashloan-
  box/blob/Remix/contracts/aave/ILendingPoolAddressesProvider.sol";
import "https://github.com/aave/flashloan-
  box/blob/Remix/contracts/aave/ILendingPool.sol";

contract Flashloan is FlashLoanReceiverBase {

/**
The following constructor method is run when you create this flashloan smart
contract. Make sure to specify the address of the Aave LendingPoolAddressProvider
contract. This argument is different based on the environment you are working in.
Visit the Aave docs to get this address.
*/

    constructor(address _addressProvider) FlashLoanReceiverBase(_addressProvider) 
      public {}
    /**
    The following function is called by Aave to the flashloan contract after the
    contract has received the flash-loaned amount:
     */

    function executeOperation(
        address _reserve,
        uint256 _amount,
        uint256 _fee,
        bytes calldata _params
    )
        external
        override
    {
        require(_amount <= getBalanceInternal(address(this), _reserve), 
                "Invalid balance, was the flashloan successful?");

        // Your logic goes here.
        // !! Ensure that *this contract* has enough `_reserve` funds to
        // pay back the `_fee` !!
       
        uint totalDebt = _amount.add(_fee);
        transferFundsBackToPoolInternal(_reserve, totalDebt);
    }

    /**
    Call the following function when you want to execute a flash loan. The
    parameter _asset is the address of the token you want to borrow in the
    flash loan. In our example the token we will borrow is DAI.
    */

    function flashloan(address _asset) public onlyOwner {
        bytes memory data = "";
        uint amount = 1 ether;

        ILendingPool lendingPool = 
          ILendingPool(addressesProvider.getLendingPool());
        lendingPool.flashLoan(address(this), _asset, amount, data);
    }
}

Deploying the Contract

You can use Remix and MetaMask to deploy this smart contract, as  shown in Figure 7-13.

Figure 7-13. Deploying the Flashloan contract

Here are the steps required to publish the Flashloan smart contract to the Ropsten network:

  1. Copy the smart contract code (you can find it on GitHub) and paste it into Remix.

  2. Compile the code using compiler version 0.6.6+commit.6c089d02 (to check the compiler version, click the third button from the top on the lefthand side of the Remix IDE).

  3. Publish the code to the Ropsten environment. Be sure to enter the address of the Aave LendingPoolAddressProvider contract in the field next to the Deploy button. This argument is passed to the constructor method when creating the Flashloan contract; it essentially tells the Flashloan contract how to communicate with Aave when borrowing funds.

  4. Click Deploy in Remix, then confirm the deployment in MetaMask.

The Flashloan smart contract now has the following address:

0x978e5f2149024D5742476Bc2d3b5B820926537A2

Executing a Flash Loan

To execute a flash loan, perform an Ethereum transaction that calls the function flashloan(address _asset).

In this example, we want to execute a flash loan that borrows 1 DAI. The Flashloan contract is in the Ropsten environment, so the argument we need to pass is the address of the DAI token contract on Ropsten. That address is:

0xf80a32a835f79d7787e8a8ee5721d0feafd78108

Remember that Aave charges a fee, and if the Flashloan contract is unable to pay that fee, it will get an error. To ensure you can pay this fee, make sure the Flashloan contract holds at least 0.0009 DAI. You can use the smart contract tools on Etherscan to mint and then transfer funds to the contract.

Once you’ve identified the DAI token contract address and loaded the Flashloan contract with DAI to pay the fee, the contract is ready to execute a flash loan.

It’s important to set a very high gas limit because a flash loan will perform multiple transactions, using up large amounts of gas—if the gas limit is too low, it will get an “out of gas” error.

In this example, we will send the following transaction to the flash loan contract:

  • Amount: 0 ETH

  • Gas limit: 300,000

  • Data: 0x36c40477000000000000000000000000f80a32a835f79d7787e8a8ee5721d0
    feafd78108

The data field contains two pieces of information:

Data value Description
0x36c40477 Instruction to call the function flashloan(address _asset).
000000000000000000000000f80a32a8
35f79d7787e8a8ee5721d0feafd78108
The _asset argument being passed into the function. In this example, it is the address of the DAI token contract.

Figure 7-14 shows the transaction to be sent to the Flashloan contract, including the input data.

Figure 7-14. Flashloan contract transaction in MetaMask wallet

You can see a successfully executed transaction of the flash loan online. A lot of activity happened in the one transaction (0xc779…1f23), including function calls and token transfers.

Auditing the token transfers in the sample flash loan transaction reveals that three token transactions occurred in the one flash loan (see Table 7-3).

Table 7-3. List of funds transferred in the flash loan transaction
Transaction # Sender Receiver Amount
1 Aave lending pool (0x4295…9472) Flashloan contract (0x978e…37A2) 1 DAI
2 Flashloan contract (0x978e…37A2) Aave lending pool (0x4295…9472) 1.0009 DAI
3 Aave lending pool (0x4295…9472) Aave fee collector
(0xeBA2…fC9C)
0.00027 DAI

Auditing the function calls made in the flash loan transaction reveals a total of 24 function calls made involving 10 different smart contracts and one user account, as shown in Figure 7-15.

Figure 7-15. Flow chart showing the sequence of important function calls made between different smart contracts

The important function calls made in the flash loan transaction are as follows:

  1. Initiate flash loan: The flash loan is initiated using the same user account (0x8319…9949) that created the flash loan contract. This user account calls the function flashloan(address _asset) on the flash loan contract (0x978e…37a2), with sufficient gas.

  2. Request to borrow: The flash loan contract (0x978e…37a2) sends a request for a flash loan from one of the Aave contracts.

  3. Process and send funds: The Aave contract runs through a series of calls and eventually calls the DAI token contract (0xf80a…8108) to transfer 1 DAI to the Flashloan contract (0x978e…37a2). This 1 DAI is the amount borrowed.

  4. Notify funds sent: After the 1 DAI is sent to the flash loan contract (0x987e…37a2), one of Aave’s contracts calls it to notify it that the funds have been sent. At this point, the flash loan contract can use the 1 DAI for any purpose. In this example, the token does not get used, for simplicity.

  5. Repay funds with fee: The flash loan contract (0x987e…37a2) then returns the funds by calling one of Aave’s contracts, which leads it to call the DAI token contract (0xf80a…8108) to transfer 1.0009 DAI to an Aave contract.

Flash Loans for Arbitrage

One of the main use cases for flash loans is to arbitrage between multiple DeFi platforms. The biggest advantage of using a flash loan to execute an arbitrage is that liquidity is no longer required to sit on the exchanges involved in the arbitrage. The requirement for liquidity between crypto exchanges introduces counterparty risk, limits the amount that can be arbitraged, and introduces a large barrier to entry to begin arbitraging. However, arbitraging with a flash loan provides real-time access to multiple large liquidity pools without the need to ask permission.

The lender gives permission for funds to be borrowed when funds are deposited into the smart contract. At any time they can look at the contract balances and see what percentage of the funds have been loaned out. If a transaction stops midloan, the transaction does not complete, and therefore the funds were never lent out. The cost for performing a flash loan is simply the gas required to execute it.

The Fulcrum Exploit

Flash loans have also been used by bad actors to exploit vulnerabilities in DeFi platforms. A well-known example occurred on February 15, 2020, when an attacker used a flash loan to perform an oracle manipulation attack on the Fulcrum margin trading platform.

An oracle provides smart contracts with a trusted view of the outside world. For example, a DeFi smart contract will use an oracle to know what the BTC/USD exchange rate is. On the day of the attack, the Fulcrum platform was listening to multiple oracles for exchange rate data, including Kyber and Uniswap. One reason Fulcrum gathers exchange rate data from these DEXes is that it accesses their liquidity pools to provide margin trades for Fulcrum’s users.

The flash loan contract that performed the oracle manipulation attack has the transaction ID:

0xb5c8bd9430b6cc87a0e2fe110ece6bf527fa4f170a4bc8cd032f768fc5219838

The transaction details can be viewed online. In total, 13 smart contract function calls were made.

In an exploit such as this, the attacking flash loan contract borrows, trades, and repays wrapped tokens. These are ERC-20 tokens that represent the value of a different cryptocurrency. For example, 1 wBTC is a wrapped bitcoin that represents 1 BTC and in theory is worth 1 BTC, but is in the form of an ERC-20 token.

Note

Wrapped tokens allow DeFi platforms to trade cryptocurrencies that are not originally in the form of an ERC-20 token. For simplicity, anytime you see 1 wETH in this discussion, you can assume that it is the equivalent of 1 ETH; the same goes for wBTC and BTC.

We can break down the process of the attack into five distinct steps, which are illustrated in Figure 7-16.

Figure 7-16. Walkthrough of the Fulcrum attack

The steps can be summarized as follows:

  1. Borrow: The attacking flash loan contract borrows 10,000 ETH ($2.81M USD) from the dYdX decentralized trading platform. This action is only valid if it repays the loan plus a fee at the end of this Ethereum transaction.

  2. Hoard: It then borrows 112 wBTC ($1.15M USD) from DeFi lending platform Compound. To secure these funds, it provides 5,500 ETH ($1.5M USD) as collateral. The 112 wBTC will later be dumped onto another market in order to manipulate the oracle rate.

  3. Manipulate oracle rate: Next, it deposits 1,300 ETH onto the Fulcrum margin trading platform and opens a short trading position, which is a bet the price will fall, on the wETH/wBTC market with 5x leverage. This short position creates a domino effect. In order for Fulcrum to service the short position, it swaps 5,637 ETH ($1.58M USD) for 51.34 wBTC ($525,000 USD) from Kyber. Kyber sources the 51.34 wBTC from Uniswap. Significant slippage—when a price moves substantially because of a lack of sufficient liquidity—occurs when Kyber pulls this large amount of wBTC from Uniswap. This changes the exchange rate of wETH/wBTC on Uniswap from 1wBTC = 49 wETH, which is the rate given by Compound in the hoarding stage, to 1wBTC = 109.8 wETH.

  4. Trade under new rate: Now that the wETH/wBTC exchange rate on Uniswap has been pumped, the attacking flash loan contract dumps its 112 wBTC onto the Uniswap market, receiving 6,871 ETH ($1.93M USD) in this trade. In this action, it receives an exchange rate of 1wBTC = 61.3 wETH. This is about 25% higher than the original rate it received on Compound, leading to a profit of 1,371 ETH ($385,000 USD).

  5. Repay loan: After the profit has been gained, the flash loan contract repays the original 10,000 ETH loan from dYdX. This is required, or else an error will be raised and the transaction will not complete. In total, the attacker spent 0.03 ETH ($7.47 USD) to execute the transaction and gained about $385,000 USD worth of cryptocurrency. It then paid back the Compound loan.

Note

Every time there is a big innovation in financial technology, there are always bad actors who look for new ways to exploit the technological shift. For example, in the early days of PayPal, hackers started automatically generating fake PayPal accounts to perform large-scale credit card fraud. Eventually PayPal created an early version of CAPTCHA, a computing test to distinguish human users from machines, to help contain this threat. DeFi is no exception. It’s a fundamental shift in how financial services are provided, and this fluid situation leads to attackers constantly searching for exploits to profit from.

Privacy

Public blockchains like Bitcoin and Ethereum are not great when it comes to privacy. When thinking about decentralizing finance and the web, information security must be carefully considered. To conceal identity, a number of solutions are available. Different implementations will make different uses of these solutions, as privacy is an experimental (yet growing) area of blockchain technology.

With Bitcoin and Ethereum, all transaction information is visible in the public blockchain, including the transaction amount and addresses of the sender and receiver. There are use cases where blockchain transaction information must remain private, however, and different privacy-focused blockchains, such as Zcash and Monero, have been launched to satisfy this need. There are also private blockchain networks such as Corda and Quorum that require either an invitation or automatic vetting before an organization is allowed to participate. This section considers a few aspects of privacy, and we’ll come back to this topic in Chapter 9.

Zero-Knowledge Proof

A zero-knowledge proof is a cryptographic method or protocol where party A (the prover) proves to party B (the verifier) that a statement is true without revealing any information other than that the statement is true.

Suppose a prover needs to prove to the verifier that they found Waldo in a Where’s Waldo? drawing. The easiest approach would be for the prover to point to Waldo, but doing so reveals the secret of where Waldo is, when the point is merely to prove that the prover knows where Waldo is. A zero-knowledge approach might be for the prover to get a large piece of paper, significantly bigger than the Waldo drawing, and cut a hole the shape of Waldo in the center. Out of sight of the verifier, the prover covers the drawing so that only Waldo is visible through the hole in the paper. The prover has demonstrated that they found Waldo without revealing any information that could help the verifier find Waldo.

Let’s consider another example. Say the prover wants to prove to the verifier that they know the correct password for logging in to a website. The current method many websites use is to store a hash of the user’s password in their database. When the user wants to log in, the following sequence takes place:

  1. The user sends the password as plain text to the server.

  2. The server encrypts the password using a standard encryption algorithm, such as MD5.

  3. If the newly generated MD5 hash matches the hash stored in the database, then the password entered is valid.

However, this method makes the user’s password vulnerable to the following:

Man in the middle attacks
If a hacker compromises the communication between the user and the server, it is possible to intercept the plain-text password.
Brute force and dictionary attacks
If a website’s database is breached, a hacker can potentially decrypt the user’s password through various methods, including brute force using trial and error or dictionary attacks using a list of words or phrases.

In a zero-knowledge approach, a user can prove they have a valid password without the need to reveal what it is—the server does not store any variation of the password, not even a hash. This can be done by implementing the Thinbus Secure Remote Password protocol (SRP):

  1. The server stores a randomly generated salt, or random data that is used as an additional input, and a verifier that cannot be decrypted into the password.

  2. When the user logs in to the website, they send a one-time value used only for that particular login. Future messages will look very different. The server receives this one-time value, and through the SRP can verify whether the message received was sent by a user with a valid password. Figure 7-17 illustrates.

Figure 7-17. Flow of actions in the registration action of the SRP

Implementation of a zero-knowledge proof significantly improves the privacy and security of many systems. However, it introduces additional costs in processing power and hard drive space. Another downside is that it requires the two parties (prover and verifier) to interact directly with each other.

These downsides would not matter in the case of a website, but implementing zero-knowledge proofs in a blockchain would have a significant impact, for a few reasons:

  • Blockchain miners maintain a copy of the entire blockchain history, which gets big very fast as network usage scales. Adding more data makes this problem even worse.

  • In a blockchain network, the sender of a transaction wants to prove that the transaction is valid, and the miners each verify that validity. The problem is that the sender does not communicate directly with every miner. Rather, the sender broadcasts out transaction details and miners verify the transaction—a process that does not involve direct, one-to-one interaction.

So, in order for a blockchain to adopt a zero-knowledge proof method, it must be succinct, to allow for better scalability, and noninteractive, so that nodes in the network can verify zero-knowledge statements from nodes they are not communicating with directly. With this method, the sender (prover) of the transaction can broadcast out one piece of data and the miners (verifiers) can verify the transaction’s validity without any additional interaction with the sender. The data that the transaction sender broadcasts to the network must be very small in size, because that data will be stored on the blockchain.

Web 3.0

Blockchain and cryptocurrency with proper levels of privacy could create new platforms for the web, incentivizing new types of development and moving users away from the oligarchical model that has come to dominate over the last decade.

It’s become common to talk about different stages in the evolution of the World Wide Web. Web 1.0 consisted of static pages, form fields, and passive content. Web 2.0 introduced dynamic pages, interactive fields, and user-generated content. Web 3.0 is the next iteration, whereby the data generated from the previous two generations is returned, monetized, and controlled by the user. What that will look like in totality is unclear, but some characteristics are emerging, and scaffolding for Web 3.0 technology is being built today.

Users give away a lot of data, often without realizing it, and much of this occurs within web browsers. Brave is a Chromium-based browser focused on privacy. Although other web browsers make various claims about their privacy features too, Brave is the first to implement blockchain technology. It has built-in ad blockers, replacing advertising with cryptocurrency. The Basic Attention Token (BAT), its ERC-20 cryptocurrency, is used to compensate website owners and content creators in lieu of ad platforms.

Paying independent developers to work on open source code can be a complex process. Cryptocurrency and blockchain are leading to exciting changes in software development. Sites like Gitcoin are embracing and supporting this movement: it pairs developers looking for projects to work on with funders looking for people to implement a bug fix or feature request or do some other work on a project, and all the payments are made in crypto.

File storage is an important part of web-based applications, and decentralizing this aspect is key. Storing and sharing data is what allows many technology providers to take liberties with user information via their terms of service. The Interplanetary File System (IPFS) is a persistent network that enables distributed storage of files as long as a single node keeps running; its aim is to.... Its design is modular, allowing it to be used for a variety of use cases.

Building decentralized web frameworks is a huge task. It requires melding identity, distributed systems, and blockchain into a scaffolding developers can use to create increasingly decentralized applications. Blockstack, which started with identity and then moved into distributed systems, is one of these early frameworks. It uses REST calls to create dapps in a framework similar to what developers have used in the past.

Then there’s gambling. Since the value is being transferred via smart contract in Web 3.0, it is easier to audit whether the rules are fair. In traditional gambling, the house usually has the advantage in terms of odds. In this new framework, newer kinds of games are being invented—for example, no-loss gambling. One example is a DAO pool in which everyone puts in stablecoin, which earns returns. The pool goes through a randomized selection process to pick the winner; the winner gets all the interest earned from the pool, and the losers get back their original amount of stablecoin.

Summary

Web 3.0 technology is based on a disruption of the traditional centralized services model. That model, though it has been successful for some time, is beginning to weaken as numbers of cyberattacks increase. New ideas are being injected into finance and the web, with developers exploring the use of blockchain, cryptocurrencies, and smart contracts to protect user privacy and put control over personal information back in the hands of users.