Smart Contract Development
  • Introduction
    • What is a Transaction
    • Accounts and Signing
    • What is a smart contract
  • Learning Solidity
    • Introduction
    • Module 1
      • Variable Types
      • Variable Scope: State & Local variables
      • Global variables
      • Functions
        • View and Pure
        • Shadowing in Fuctions
      • Mapping
      • Require
      • Events
    • Project #1: Simple Registry
    • Module 2
      • Constructor
      • Data Location: Value & Reference
      • Interface
      • Import
        • Importing in Foundry
      • Inheritance
      • ERC-20
      • Checks-effect-interaction pattern
    • Project #2: Basic Vault
    • Module 3
      • Payable
      • Receive
      • Fallback
      • Returns
    • Project #3: ERC20+ETH Wrapper
    • Module 4
      • Immutable and Constant
      • Fixed-point Math
      • Abstract contracts
      • ERC-4626
      • Modifier + Inheritance +Ownable
      • Type
    • Project #4: Fractional Wrapper
    • Module 5
      • If-else
      • Libraries
        • TransferHelper
      • Chainlink Oracle
    • Project #5: Collateralized Vault
  • Compendium
    • Solidity Basics
      • Variable Types
      • Value Types
        • address
        • enum
      • Reference Types
        • strings
        • mappings
        • struct
        • Arrays
        • Multi-Dimensional arrays
      • Global Objects
      • Functions
        • Function types
        • Constructor Function
        • Transaction vs Call
        • Require, Revert, Assert
      • Function signature + selectors
      • Payable
        • Payable + withdraw
        • msg.value & payable functions
      • Receive
      • Fallback function (sol v 0.8)
        • Fallback function (sol v 0.6)
      • call, staticcall, delegatecall
    • Return & Events
    • Control Variable Visibility
    • Local Variables (Storage v Memory)
    • Data Location and Assignment Behaviors
    • Modifiers & Inheritance & Import
      • import styles
    • Interface & Abstract Contracts
    • ABI & Debugging
    • Libraries
    • Conditional(ternary) operators
    • Smart Contract Life-cycle
      • Pausing Smart Contracts
      • Destroying Smart Contracts
    • Merkle Trie and MPT
    • Merkle Tree Airdrop
  • Try & catch
  • Ethereum Signatures
  • EVM, Storage, Opcodes
    • EVM
    • Wei, Ether, Gas
    • Storage
    • ByteCode and Opcodes
    • Transaction costs & Execution costs
  • Reading txn input data
  • Data Representation
  • Yul
    • Yul
      • Intro
      • Basic operations
      • Storage Slots
      • Storage of Arrays and Mappings
      • Memory Operations
      • Memory: how solidity uses memory
      • Memory: Return, Require, Tuples and Keccak256
      • Memory: Logs and Events
      • Inter-contract calls
      • calldata
      • free memory pointer
    • Yul Exercises
      • read state variable
      • read mapping
      • iterate Array, Return Sum
    • memory-safe
  • Upgradable Contracts
    • Upgradability & Proxies
    • UUPS Example
    • Minimal Proxy Example
    • TPP Example
    • 🚧Diamond
      • On Storage
  • Gas Opt
    • Block Limit
    • gasLimit & min cost
    • Solidity Optimiser
    • Memory v calldata
    • Memory caching vs direct storage vs pointers
    • < vs <=
    • reverting early
    • X && Y, ||
    • constant and immutable
    • caching sload into mload
    • Syntactic Sugar
    • using unchecked w/o require
    • Compact Strings
    • Calling a view function
    • Custom errors over require
    • usage of this.
      • multiple address(this)
  • ERCs & EIPs
    • ERC-20.sol
      • Core functions
      • transfer()
      • transferFrom()
      • TLDR transfer vs transferFrom
    • Landing
      • ERC721.sol
      • EIP-721
        • LooksRare
        • Page 1
      • ERC-1271
      • EIP-2981
      • ERC-165
      • EIP-1167: Minimal Proxy Contract
    • VRFConsumerBase
    • UniswapV2Library
  • Yield Mentorship 2022
    • Projects
      • #1 Simple Registry
      • #2 Basic Vault
      • #3 ERC20+ETH Wrapper
        • setFailTransferTrue
      • #4 Fractional Wrapper
      • #5 Collateralized Vault
        • Process
        • Vault.sol
        • Testing
        • Chainlink Oracles
        • Pricing + Decimal scaling
        • Refactor for Simplicity
      • #9 Flash Loan Vault
        • Implementing ERC3156
        • Full code for lender
        • Ex-rate calculation
    • State Inheritance Testing
    • Testing w/ Mocks
    • Yield Style Guide
    • Github Actions
    • TransferHelper.sol
    • math logic + internal fn
    • Interfaces: IERC20
  • Foundry
    • Overview
    • Importing Contracts
    • Testing
      • stdError.arithmeticError
      • assume vs bound
      • Traces
      • label & console2
      • std-storage
  • Smart Contract Security
    • Damn Vulnerable Defi
      • 1. Unstoppable
      • 2. Naive receiver
      • 3. Truster
      • 4. Side Entrance
      • 5. The Rewarder
      • 6. Selfie
      • 7. Compromised
      • 8. Puppet
      • 9. Puppet V2
      • 10 - Free Rider
    • Merkle Tree: shortened proof attack
  • Fixed-Point Math
    • AMM Math
  • Solidity Patterns
    • checks-effects-interactions pattern
    • Router // batch
    • claimDelegate: stack unique owners
    • claimDelegate: cache previous user
  • Array: dup/ascending check
  • Deployment
    • Behind the Scenes
    • Interacting with External Contracts
    • Logging, Events, Solidity, Bloom Filter
  • Misc
    • Mnemonic Phrases
    • Bidul Ideas
  • Archive
    • Brownie Framework
      • Brownie basics
        • storing wallets in .env
        • Deployment to ganache
        • Interacting with contract
        • Unit Testing
        • Testnet deployment
        • Interacting w/ deployed contract
        • Brownie console
      • Brownie Advanced
        • Dependencies: import contracts
        • helpful_scripts.py
        • verify and publish
        • Forking and Mocking
        • Mocking
        • Forking
      • Testing
      • Scripts Framework
        • deploy.py
        • get_accounts
        • deploy_mocks()
        • fund_with_<token>()
      • Brownie Networks
    • Brownie Projects
      • SharedWallet
        • Multiple Beneficiaries
        • Common Code Contract
        • Adding Events
        • Renounce Ownership
        • Separate Files
      • Supply Chain
        • ItemManager()
        • Adding Events
        • Adding unique address to each item
      • Lottery
      • Aave - Lending and Borrowing
        • Approve & Deposit
        • Borrow
      • NFT
      • Advanced Collectible
        • adv_deploy() + Testing
        • Create Metadata
        • Setting the TokenURI
    • node npm
    • Ganache
    • Truffle
    • Remix
    • Installing Env
Powered by GitBook
On this page
  • Objective
  • What does this mean?
  • Exchange rate is dynamic
  • Flash Loan flow
  1. Yield Mentorship 2022
  2. Projects

#9 Flash Loan Vault

ERC 3156 & ERC 4626 compliant

PreviousRefactor for SimplicityNextImplementing ERC3156

Last updated 2 years ago

  • Problem Statement:

  • Github:

Objective

Refactor the Fractional Wrapper from assignment #4 into a Proportional Ownership Flash Loan Server, conforming to specifications ERC3156 and ERC4626.

  1. Refactor the Fractional Wrapper into an ERC3156 Flash Loan Server: https://eips.ethereum.org/EIPS/eip-3156

  2. The underlying is the token available for flash lending -> e.g. DAI | wrapper token = yvDAI

  3. Fee is a constant 0.1%

  4. Make the contract a proportional ownership contract

  5. When users deposit underlying, they get a proportion of wrapper tokens, based on the following:

wrapperMinted / wrapperSupply == underlyingDeposited / underlyingInWrapper

What does this mean?

Essentially, the Fractional wrapper operates as per usual; accepting deposits, withdrawals and so forth as specified in ERC4626.

Additionally, it can now offer flashloans, conforming to ERC3156. The flashlending token will be the underlying token that the FractionWrapper operates upon.

For example:

Users can deposit DAI, which is the underlying, for which they will receive yvDAI (wrapped tokens) as per:

wrapperMinted = (underlyingDeposited * wrapperSupply) / underlyingInWrapper

  • Other users can flash borrow DAI that has been deposited, for whatever purpose they have in mind.

  • They will be charged a fee of 0.1% for this service.

  • In this way, the Vault accumulates fees, which can then be partially passed on to depositors as yield, while the rest is retained as revenue.

Exchange rate is dynamic

Initial deployment will be an edge case, as supply of tokens will be 0. So we begin with a peg.

Assume at t=0 (s=0), exchange rate is 1 -> 1 DAI : 1 yvDAI

Deployer deposits DAI in to vault to get the ball rolling, and receives wrapper tokens as per the peg.

Deposit 1000 DAI, receive 1000 yvDAI tokens

After this initial deposit, the exchange rate still holds at the peg.

The peg "moves" or is altered based on the yield generated from flash loans.

Since there is a fee levied for the flash loan service, supply of underlying tokens will increase and this will result in the exchange rate float away from peg.

Flash Loan flow

  1. Borrower contract executes flashBorrow():

    • total repayment amount (fee + amount) is calculated and approved as allowance for lender to claw back via transferFrom()

    • lender.flashloan() is called, initiating the flashloan service on the lender contract.

  2. flashLoan() checks the following:

    • Tokens that was being requested for flash loan are supported & calculates fee to be charged

    • Transfers the loan amount to the receiver (via .transfer)

    • Call back to receiver: calls receiver.onFlashLoan() which does the following:

      • verifying the sender is the correct lender

      • verifying the initiator for the flash loan was actually the receiver contract

      • returns keccak256("ERC3156FlashBorrower.onFlashLoan")

    • Finally, amount+fee is transferred from the receiver to the lender (via .transferFrom)

    • returns true on success.

https://github.com/yieldprotocol/mentorship2022/issues/9
https://github.com/calnix/Flash-Loan-Yield-Bearing-Vault