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
  • getUserAccountData()
  • Into main()
  • DAI
  • Price of DAI/ETH
  • Into main()
  • Lending_pool.borrow
  1. Archive
  2. Brownie Projects
  3. Aave - Lending and Borrowing

Borrow

PreviousApprove & DepositNextNFT

Last updated 3 years ago

We need to find out how much we can borrow against our deposits/collateral.

getUserAccountData()

  • function getUserAccountData(address user)

  • values are returned in WEI, we will convert to ETH

def get_borrowable_data(lending_pool,account):
    (totalCollateralETH, totalDebtETH, availableBorrowsETH, currentLiquidationThreshold, ltv, healthFactor) = lending_pool.getUserAccountData(account)
    
    # all ETH values are denominated in WEI - convert to ETH
    total_collateral_eth = Web3.fromWei(totalCollateralETH, "ether")
    total_debt_eth = Web3.fromWei(totalDebtETH, "ether")
    available_borrow_ETH = Web3.fromWei(availableBorrowsETH, "ether")

    print(f"...You have {total_collateral_eth} worth of ETH deposited...")
    print(f"...You have {total_debt_eth} worth of ETH borrowed...")
    print(f"...You can borrow {available_borrow_ETH} worth of ETH...")
    return (float(available_borrow_ETH), float(total_debt_eth))
  • return multiple variables using tuple syntax.

  • float allows for decimal places.

Into main()

add the following code

# Borrow DAI
## how much can we borrow - pull account stats - getUserAccountData(address user)
(borrowable_eth, total_debt_eth) = get_borrowable_data(lending_pool,account)

DAI

We now know much we can borrow in terms of ETH, {available_borrow_ETH}, from above.

How much is that in terms of DAI?

We will need to get DAI/ETH price and convert -> via chainlink pricefeed contract

Price of DAI/ETH

Chainlink has a standard interface contract AggregatorV3Interface which works with all of its different price feed contracts.

With this interface, we simply need to pass the corresponding price feed address into it, to create the contract object in brownie.

def get_token_price(token_price_feed_address):
    # use chainlink pricefeed
    token_eth_price_feed = interface.AggregatorV3Interface(token_price_feed_address)
    price = token_eth_price_feed.latestRoundData()[1]   #price is index 1 
    norm_price = Web3.fromWei(price, "ether")
    print(f"...DAI/ETH price is {norm_price}")
    return float(price)
  • create price feed contract object

  • calls latestRoundData from price feed contract, slicing out price variable from return tuple

  • convert price from Wei to Ether (decimal place modification)

Into main()

# Borrow DAI
## how much can we borrow - pull account stats - getUserAccountData(address user)
(borrowable_eth, total_debt_eth) = get_borrowable_data(lending_pool,account)

# DAI in terms of ETH
dai_eth_price = get_token_price(config["networks"][network.show_active()]["dai_eth_price_feed"])

Lending_pool.borrow

call borrow() from lendingPool contract

## function borrow(address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf)
# interestRateMode: 1 - stable | 2 - variable
tx2 = lending_pool.borrow(config["networks"][network.show_active()]["dai_token_address"], dai_to_borrow, 1, 0, account.address, {"from": account})

We will need to add the DAI token address into brownie-config.yaml

  • mainnet-fork: get DAI address off etherscan

  • Kovan/Rinkeby: refer to Aave documentation to get their testnet version of DAI

For assets on testnets, we use different versions of the token (e.g. testnet Dai). This is to ensure enough liquidity for our reserves and to easily mint more tokens when needed.

Testnet assets addresses are different depending on stable vs variable rate of borrowing

If you are developing on a testnet and require tokens, go to making sure that your wallet is set to the relevant testnet.

getUserAccountData
https://testnet.aave.com/faucet,
https://docs.aave.com/developers/deployed-contracts/v3-testnet-addresses
https://docs.aave.com/developers/v/2.0/deployed-contracts/deployed-contracts