ctfnote
  • /home/ret2basic.eth
  • Game Hacking
    • โœ…C++
    • Ghidra
    • Cheat Engine
    • Proxy
    • DLL injection
    • Keygen
    • Aimbot
  • Web3 Security Research
    • ๐Ÿ‘‘Web3 Security Research Trivia
    • โœ…Solidity
      • โœ…Mastering Ethereum
      • โœ…Storage
      • โœ…Memory
      • โœ…Calldata
      • โœ…ABI
    • โœ…Foundry
      • โœ…Introduction
      • โœ…How to Write Basic Tests
      • โœ…Set Soliditiy Compiler Version
      • โœ…Remappings
      • โœ…Auto Format Code
      • โœ…Console Log
      • โœ…Authentication
      • โœ…Error
      • โœ…Event
      • โœ…Time
      • โœ…Send ETH
      • โœ…Signature
      • โœ…Fork
      • โœ…Mint 1 Million DAI on Mainnet Fork
      • โœ…FFI
      • โœ…Fuzz
      • โœ…Invariant Testing - Part 1
      • Invariant Testing - Part 2
      • Invariant Testing - Part 3
      • Differential Test
    • โœ…Secureum
      • โœ…Epoch 0
        • โœ…Slot 1: Ethereum 101
          • โœ…Notes
          • โœ…Ethereum Whitepaper
          • โœ…Extra Study: What happens when you send 1 DAI
          • โœ…Quiz
        • โœ…Slot 2: Solidity 101
          • โœ…Notes
          • โœ…OpenZeppelin ERC20
          • โœ…OpenZeppelin ERC721
          • โœ…OpenZeppelin Ownable
          • โœ…OpenZeppelin Pausable
          • โœ…OpenZeppelin ReentrancyGuard
          • โœ…Quiz
        • โœ…Slot 3: Solidity 201
          • โœ…Notes
          • โœ…OpenZeppelin SafeERC20
          • โœ…OpenZeppelin ERC-777
          • โœ…OpenZeppelin ERC-1155
          • โœ…OpenZeppelin ERC-3156
          • โœ…OpenZeppelin - Proxy Upgrade Pattern
          • โœ…Quiz
        • โœ…Slot 4: Pitfalls and Best Practices 101
          • โœ…Notes
          • โœ…Intro to Security First Development
          • โœ…Quiz
        • โœ…Slot 5: Pitfalls and Best Practices 201
          • โœ…Notes
          • So you want to use a price oracle
          • The Dangers of Surprising Code
          • โœ…Quiz
        • โœ…Slot 6: Auditing Techniques & Tools 101
          • โœ…Notes
          • โœ…Quiz
        • โœ…Slot 7: Audit Findings 101
          • Notes
          • โœ…Fei Protocol - ConsenSys
          • โœ…Uniswap V3 - Trail of Bits
          • โœ…Chainlink - Sigma Prime
          • โœ…Opyn Gamma - OpenZeppelin
          • โœ…Quiz
        • โœ…Slot 8: Audit Findings 201
          • Notes
          • 1inch Liquidity - Consensus
          • Original Dollar - Trail of Bits
          • Synthetix EtherCollateral - Sigma Prime
          • Holdefi - OpenZeppelin
          • Quiz
      • โœ…Epoch โˆž
        • โœ…RACE #4 - ERC20 Implementation
        • โœ…RACE #5 - ERC1155 Implementation
        • โœ…RACE #6 - ERC721 Application
        • โœ…RACE #7 - Bored Ape
        • โœ…RACE #8 - ERC721 Roles
        • โœ…RACE #9 - Proxy
        • โœ…RACE #10 - Test Cases
        • โœ…RACE #11 - Staking
        • โœ…RACE #12 - ERC20 Permit
        • โœ…RACE #13 - ERC20 with Callback
        • โœ…RACE #14 - Lending
        • โœ…RACE #15 - DEX
        • โœ…RACE #16 - Flash Loan
        • โœ…RACE #17
    • DeFi
      • Glossary
        • TWAP vs. VWAP
        • Tranches
      • DeFi MOOC
        • Lecture 2: Introduction to Blockchain Technologies
        • Lecture 5: DEX
        • Lecture 6: Decentralized Lending
        • Lecture 10: Privacy on the Blockchain
        • Lecture 12: Practical Smart Contract Security
        • Lecture 13: DeFi Security
      • Uniswap V2
      • Compound V3
        • โœ…Whitepaper
        • โœ…Interacting with Compound
          • โœ…Supply and Redeem
          • โœ…Borrow and Repay
          • โœ…Liquidation
          • โœ…Long and Short
        • โœ…Interest Model
        • CToken
      • Aave
      • Chainlink
        • โœ…Getting Started
        • โœ…Data Feeds
        • โœ…VRF
      • Optimism
        • Bedrock
      • LayerZero
      • Opensea
        • Seaport
    • EVM
      • โœ…Andreas Antonopoulos - The Ethereum Virtual Machine
      • โœ…Program The Blockchain - Smart Contract Storage
      • โœ…EVM Codes - EVM Playground for Opcodes
      • โœ…Fvictorio - EVM Puzzles
      • โœ…Daltyboy11 - More EVM Puzzles
      • โœ…EVM Through Huff
      • Noxx - EVM Deep Dives
      • โœ…Jordan McKinney - EVM Explained
      • Openzepplin - Deconstructing a Solidity Contract
      • Jeancvllr - EVM Assembly
      • Peter Robinson - Solidity to Bytecode, Memory & Storage
      • Marek Kirejczyk - Ethereum Under The Hood
      • โœ…Official Solidity Docs
      • Dissecting EVM using go-ethereum Eth client implementation - deliriusz.eth
    • Vulnerabilities
      • Rounding Issues
        • Kyberswap
      • Bridges
      • Governance / Voting Escrows
      • Bizzare Bug Classes
        • TIME - ERC2771Context + Multicall calldata manipulation
    • Fancy Topics
      • Vulnerabilities SoK
        • โœ…Demystifying Exploitable Bugs in Smart Contracts
        • Blockchain Hacking Techniques 2022 Top 10 - Todo
      • yAcademy
        • Proxies
          • yAcademy - Proxy Basics
          • yAcademy - Proxies Deep Dive
          • yAcademy - Security Guide to Proxy Vulns
        • defi-fork-bugs
      • Spearbit
        • โœ…Community Workshop: Riley Holterhus
        • Economic Security with fmrmf
        • Numerical Analysis for DeFi Audits: A TWAMM Case Study by Kurt Barry
  • Red Teaming
    • โœ…Enumeration
      • Service Enumeration
        • SMTP (Port 25)
        • Samba (Port 139, 445)
        • SNMP (Port 161,162,10161,10162)
        • rsync (Port 873)
        • NFS (Port 2049)
        • Apache JServ Protocol (Port 8081)
        • NetBIOS
      • Nmap
      • Gobuster / Feroxbuster / FUFF / Wfuzz
      • Drupal
    • โœ…Exploitation
      • Public Exploits
      • PHP Webshells
      • Reverse Shell
      • TTY
      • File Transfer
      • Metasploit
      • Password Spray
    • โœ…Buffer Overflow
      • Step 0: Spiking (Optional)
      • Step 1: Fuzzing
      • Step 2: Finding the Offset
      • Step 3: Overwriting the EIP
      • Step 4: Finding Bad Characters
      • Step 5: Finding the Right Module
      • Step 6: Generating Shellcode and Gaining Root
    • โœ…Privilege Escalation
      • Linux Privilege Escalation
        • Linux Permissions
        • Manual Enumeration
        • Automated Tools
        • Kernel Exploits
        • Passwords and File Permissions
        • SSH Keys
        • Sudo
        • SUID
        • Capabilities
        • Cron Jobs
        • NFS Root Squashing
        • Docker
        • GNU C Library
        • Exim
        • Linux Privilege Escalation Course Capstone
      • Windows Privilege Escalation
        • Manual Enumeration
        • Automated Tools
        • Kernel Exploits
        • Passwords and Port Forwarding
        • WSL
        • Token Impersonation and Potato Attacks
        • Meterpreter getsystem
        • Runas
        • UAC Bypass
        • Registry
        • Executable Files
        • Startup Applications
        • DLL Hijacking
        • Service Permissions (Paths)
        • CVE-2019-1388
        • HiveNightmare
        • Bypass Space Filter
    • โœ…Post Exploitation
      • Linux Post Exploitation
        • Add a User
        • SSH Key
      • Windows Post Exploitation
        • windows-resources
        • Add a User
        • RDP
    • โœ…Pivoting
      • Windows: Chisel
      • Linux: sshuttle
    • Active Directory (AD)
      • Initial Compromise
        • HTA Phishing
        • VBA Macro Phishing
        • LLMNR Poisoning
        • SMB Relay
        • GPP / cPassword
      • Domain Enumeration
        • Manual Enumeration
        • PowerView
        • BloodHound
      • Lateral Movement
        • PsExec
        • WMI
        • Runas
        • Pass the Hash
        • Overpass the Hash
        • Pass the Ticket
      • Kerberos
        • Kerberoast
        • AS-REP Roast
      • MS SQL Server
    • Command & Control (C2)
      • Cobalt Strike
        • Bypassing Defences
          • Artifact Kit
          • Resource Kit
          • AMSI Bypass
          • PowerPick
        • Extending Cobalt Strike
          • Elevate Kit
          • Malleable C2 Profile
      • Metasploit
        • Payloads
        • Post Exploitation
        • Automation
      • C2 Development
    • Malware Development
      • "Hot Dropper"
      • PE Format
        • Overview
      • Process Injection
      • Reflective DLL
      • x86 <=> x64
      • Hooking
      • VeraCry
      • Offensive C#
      • AV Evasion
        • AV Evasion with C# and PowerShell
        • AMSI Bypass
  • Cryptography
    • Hash Functions
    • MAC
    • AES
      • Byte at a Time
      • CBC CCA
      • CBC Bit Flipping
      • CBC Padding Oracle
    • Diffie-Hellman
    • RSA
      • Prime Factors
      • Multiple Ciphertexts
      • Low Public Exponent
      • Low Private Exponent
    • ECC
    • Digital Signature
    • JWT
    • PRNG
    • SSL/TLS
    • Research
      • โœ…Lattice-based Cryptography (Lattice)
      • Elliptic Curve Cryptography (ECC)
      • Oblivious Transfer (OT)
      • Secure Multi-party Computation (MPC)
      • Learning with Error (LWE)
      • Fully Homomorphic Encryption (FHE)
      • Zero Knowledge Proof (ZKP)
      • Oblivious RAM (ORAM)
  • Computer Science
    • Linux
      • Setup
      • curl
      • Hard Link vs. Symlink
      • Man Page
      • /dev/null
    • Python
      • New Features
      • Operators, Expressions, and Data Manipulation
      • Program Structure and Control Flow
      • Objects, Types, and Protocols
      • Functions 101
      • Generators
      • Classes and Object-Oriented Programming
      • Memory Management
      • Concurrency and Parallelism
        • Multithreading and Thread Safety
        • Asynchronization
        • Multiprocessing
        • Global Interpreter Lock (GIL)
      • Built-in Functions and Standard Library
        • import collections
        • import itertools
        • import sys
        • import re
        • import pickle
        • import json
      • Third-party Library
        • from pwn import *
        • import requests
        • from bs4 import BeautifulSoup
        • from scapy.all import *
        • py2exe
    • HTML, CSS, JavaScript, and React
      • HTML
      • CSS
      • JavaScript
        • var vs. let
        • Objects
        • Arrays
        • Functions
        • Modules
        • Asynchronous JavaScript
      • React
    • Data Structures and Algorithms
      • Binary Search
    • The Linux Programming Interface
      • Processes
        • Memory Allocation
        • The Process API
        • Process Creation
        • Process Termination
        • Monitoring Child Processes
        • Program Execution
      • Signals
      • Threads
        • Thread Synchronization
        • Thread Safety and Pre-Thread Storage
      • IPC
        • Pipes and FIFOs
        • Memory Mappings
        • Virtual Memory Operations
      • Sockets
    • Computer Systems
      • Hexadecimal
      • Signedness
      • Registers
      • Instructions
      • Syscall
      • Process Memory
      • Stack Frame
      • Preemptive Multitasking
      • IPC
      • Threads
    • Databases
      • MySQL
        • Basic Syntax
        • Data Types
        • Modifying Tables
        • Duplicating and Deleting
        • SELECT
        • Transaction
      • GraphQL
    • Distributed Systems
      • Introduction
        • What is a Distributed System?
        • Design Goals
        • Scaling Techniques
        • Types of Distributed Systems
      • Architecture
        • System Architectures
        • Example Architectures
      • Communication
        • Foundations
        • Remote Procedure Call
        • Message-oriented Communication
      • Coordination
        • Clock Synchronization
        • Logical Clock
      • Consistency and Replication
        • Introduction
        • Data-centric Consistency
        • Client-centric Consistency
    • Static Analysis
      • Intermediate Representation
      • Data Flow Analysis
      • Interprocedural Analysis
      • Pointer Analysis
      • Static Analysis for Security
      • Datalog-Based Program Analysis
      • Soundness and Soundiness
      • CFL-Reachability and IFDS
  • Web
    • โœ…Prerequisites
      • OWASP Top 10
        • 1. Broken Access Control
        • 2. Cryptographic Failures
        • 3. Injection
        • 4. Insecure Design
        • 5. Security Misconfiguration
        • 6. Vulnerable and Outdated Components
        • 7. Identification and Authentication Failures
        • 8. Software and Data Integrity Failures
        • 9. Security Logging and Monitoring Failures
        • 10. SSRF
      • HTTP
        • HTTP Status Codes
        • HTTP Headers
      • Burp Suite
        • Burp Intruder
        • Burp Extender
        • Burp Collaborator
      • Information Gathering
        • DNS
        • Git
        • Editor
        • Server
      • Bug Bounty Report Writing
    • File Upload
      • Webshell
      • IIS, Nginx, and Apache Vulnerabilities
      • .htaccess (Apache) / web.config (IIS)
      • Alternate Data Stream
      • Code Review: bWAPP Unrestricted File Upload
    • SQL Injection (SQLi)
      • Cheat Sheet
      • UNION Attacks
      • Examining the Database
      • Blind SQL Injection
      • WAF Bypass
      • Out-Of-Band (OOB)
      • Webshell and UDF
      • sqlmap
        • Code Review: Initialization
        • Code Review: tamper
    • Cross-Site Scripting (XSS)
      • Cheat Sheet
      • Reflected XSS
      • Stored XSS
      • DOM-Based XSS
      • XSS Contexts
      • CSP
    • CSRF and SSRF
      • Client-Side Request Forgery (CSRF)
        • XSS vs. CSRF
        • CSRF Tokens and SameSite Cookies
      • Server-Side Request Forgery (SSRF)
        • Attacks
        • Bypassing Restrictions
        • SSRF + Redis
    • XML External Entities (XXE)
    • Insecure Deserialization
      • Python Deserialization
      • PHP Deserialization
      • Java Deserialization
        • Shiro
        • FastJSON
        • WebLogic
    • HTTP Request Smuggling
    • OS Command Injection
      • Whitespace Bypass
      • Blacklist Bypass
      • Blind OS Command Injection
      • Lab 1: HITCON 2015 BabyFirst
      • Lab 2: HITCON 2017 BabyFirst Revenge
      • Lab 3: HITCON 2017 BabyFirst Revenge v2
    • โœ…Directory Traversal
    • HTTP Parameter Pollution
    • Server-Side Template Injection (SSTI)
    • LDAP Injection
    • Redis
      • Authentication
      • RCE
      • Mitigations
  • Pwn
    • Linux Exploitation
      • Protections
      • Shellcoding
        • Calling Convention
        • Null-free
        • Reverse Shell
        • ORW
      • ROP
        • Stack Alignment
        • ret2text
        • ret2syscall
        • ret2libc
        • ret2csu
        • BROP
        • SROP
        • Stack Pivot
      • ptmalloc
        • chunks
        • malloc() and free()
        • bins
        • tcache
      • UAF
      • Race Conditions
        • TOCTTOU
        • Dirty Cow
        • Meltdown
        • Spectre
      • Kernel
      • Appendix: Tools
        • socat
        • LibcSearcher-ng
        • OneGadget
    • Windows Exploitation
      • Classic
      • SEH
      • Egghunting
      • Unicode
      • Shellcoding
      • ROP
      • Appendix: Tools
        • ImmunityDbg
        • Mona.py
    • Fuzzing
      • AFL++
        • Quickstart
        • Instrumentation
        • ASAN
        • Code Coverage
        • Dictionary
        • Parallelization
        • Partial Instrumentation
        • QEMU Mode
        • afl-libprotobuf-mutator
      • WinAFL
      • Fuzzilli
  • Reverse
    • Bytecode
      • Python Bytecode
    • ๐Ÿ‘‘Z3 solver
    • angr
      • angr Template
Powered by GitBook
On this page
  • Intro
  • Setup
  • Collateral
  • Account Liquidity
  • Price Feed
  • borrow() - borrower enters market and borrows loan
  • repay() - borrower repays loan
  • Test

Was this helpful?

  1. Web3 Security Research
  2. DeFi
  3. Compound V3
  4. Interacting with Compound

Borrow and Repay

PreviousSupply and RedeemNextLiquidation

Last updated 2 years ago

Was this helpful?

Intro

In this section we are going to implement the borrower's functions borrow and repay. The following concepts will be covered:

  • collateral

  • account liquidity: calculate how much can I borrow?

  • open price feed: USD price of token to borrow

  • enter market and borrow

  • borrowed balance (includes interest)

  • borrow rate

  • repay borrow

Code:

Setup

Initialize Compound controller and price feed:

// borrow and repay //
Comptroller public comptroller = Comptroller(0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B);
PriceFeed public priceFeed = PriceFeed(0x922018674c12a7F0D394ebEEf9B58F186CdE13c1);

Collateral

Query collateral factor via comptroller.markets():

// collateral
function getCollateralFactor() external view returns (uint) {
    (bool isListed, uint colFactor, bool isComped) = comptroller.markets(
        address(cToken)
    );
    return colFactor; // divide by 1e18 to get in %
}

Account Liquidity

How much can I borrow? We can query the maximal amount we can borrow via comptroller.getAccountLiquidity():

// account liquidity - calculate how much can I borrow?
// sum of (supplied balance of market entered * col factor) - borrowed
function getAccountLiquidity()
    external
    view
    returns (uint liquidity, uint shortfall)
{
    // liquidity and shortfall in USD scaled up by 1e18
    (uint error, uint _liquidity, uint _shortfall) = comptroller.getAccountLiquidity(
        address(this)
    );
    // error == 0 means no error
    require(error == 0, "error");
    // normal circumstance - liquidity > 0 and shortfall == 0
    // liquidity > 0 means account can borrow up to `liquidity`
    // shortfall > 0 is subject to liquidation, you borrowed over limit
    return (_liquidity, _shortfall);
}

shortfall > 0 means borrowing amount exceeds limit and the collateral is facing liquidation. Under normal circumstances we want liquidity > 0 and shortfall == 0.

_liquidity is in USD.

Price Feed

USD price for borrowing token can be queried via priceFeed.getUnderlyingPrice():

// open price feed - USD price of token to borrow
function getPriceFeed(address _cToken) external view returns (uint) {
    // scaled up by 1e18
    return priceFeed.getUnderlyingPrice(_cToken);
}

We need this function to compute how many cTokens we can borrow, since _liquidity divided by price gives us the amount of cTokens we can borrow.

borrow() - borrower enters market and borrows loan

We are going to build the borrow() function on top of the helper functions we just wrote. Here is the plan:

  • Step 1: enter market

  • Step 2: check account liquidity (how much we can borrow in USD)

  • Step 3: calculate max amount of cTokens that we can borrow

  • Step 4: borrow 50% of max borrow

Step 1: enter market

// enter market
// enter the supply market so you can borrow another type of asset
address[] memory cTokens = new address[](1);
cTokens[0] = address(cToken);
uint[] memory errors = comptroller.enterMarkets(cTokens);
require(errors[0] == 0, "Comptroller.enterMarkets failed.");

Step 2: check account liquidity (how much we can borrow in USD)

// check liquidity
(uint error, uint liquidity, uint shortfall) = comptroller.getAccountLiquidity(
    address(this)
);
require(error == 0, "error");
require(shortfall == 0, "shortfall > 0");
require(liquidity > 0, "liquidity = 0");

Step 3: calculate max amount of cTokens that we can borrow

// calculate max borrow
uint price = priceFeed.getUnderlyingPrice(_cTokenToBorrow);
    
// liquidity - USD scaled up by 1e18
// price - USD scaled up by 1e18
// decimals - decimals of token to borrow
uint maxBorrow = (liquidity * (10**_decimals)) / price;
require(maxBorrow > 0, "max borrow = 0");

Step 4: borrow 50% of max borrow

// borrow 50% of max borrow
uint amount = (maxBorrow * 50) / 100;
require(CErc20(_cTokenToBorrow).borrow(amount) == 0, "borrow failed");

Here is the complete implementation of borrow():

// enter market and borrow
function borrow(address _cTokenToBorrow, uint _decimals) external {
    // enter market
    // enter the supply market so you can borrow another type of asset
    address[] memory cTokens = new address[](1);
    cTokens[0] = address(cToken);
    uint[] memory errors = comptroller.enterMarkets(cTokens);
    require(errors[0] == 0, "Comptroller.enterMarkets failed.");

    // check liquidity
    (uint error, uint liquidity, uint shortfall) = comptroller.getAccountLiquidity(
        address(this)
    );
    require(error == 0, "error");
    require(shortfall == 0, "shortfall > 0");
    require(liquidity > 0, "liquidity = 0");

    // calculate max borrow
    uint price = priceFeed.getUnderlyingPrice(_cTokenToBorrow);

    // liquidity - USD scaled up by 1e18
    // price - USD scaled up by 1e18
    // decimals - decimals of token to borrow
    uint maxBorrow = (liquidity * (10**_decimals)) / price;
    require(maxBorrow > 0, "max borrow = 0");

    // borrow 50% of max borrow
    uint amount = (maxBorrow * 50) / 100;
    require(CErc20(_cTokenToBorrow).borrow(amount) == 0, "borrow failed");
}

Two utility functions related to borrow:

// borrowed balance (includes interest)
// not view function
function getBorrowedBalance(address _cTokenBorrowed) public returns (uint) {
    return CErc20(_cTokenBorrowed).borrowBalanceCurrent(address(this));
}

// borrow rate
function getBorrowRatePerBlock(address _cTokenBorrowed) external view returns (uint) {
    // scaled up by 1e18
    return CErc20(_cTokenBorrowed).borrowRatePerBlock();
 }

repay() - borrower repays loan

Repay the borrowed cTokens via CErc20.repayBorrow():

// repay borrow
function repay(
    address _tokenBorrowed,
    address _cTokenBorrowed,
    uint _amount
) external {
    IERC20(_tokenBorrowed).approve(_cTokenBorrowed, _amount);
    // _amount = 2 ** 256 - 1 means repay all
    require(CErc20(_cTokenBorrowed).repayBorrow(_amount) == 0, "repay failed");
}

Test

Test case:

it("should supply, borrow and repay", async () => {
    // used for debugging
    let tx
    let snap

    // supply
    await token.approve(testCompound.address, SUPPLY_AMOUNT, {
        from: WHALE
    })
    tx = await testCompound.supply(SUPPLY_AMOUNT, {
        from: WHALE,
    })

    // borrow
    snap = await snapshot(testCompound, tokenToBorrow)
    console.log(`--- borrow (before) ---`)
    console.log(`col factor: ${snap.colFactor} %`)
    console.log(`supplied: ${snap.supplied}`)
    console.log(`liquidity: $ ${snap.liquidity}`)
    console.log(`price: $ ${snap.price}`)
    console.log(`max borrow: ${snap.maxBorrow}`)
    console.log(`borrowed balance (compound): ${snap.borrowedBalance}`)
    console.log(`borrowed balance (erc20): ${snap.tokenToBorrowBal}`)
    console.log(`borrow rate: ${snap.borrowRate}`)

    tx = await testCompound.borrow(C_TOKEN_TO_BORROW, BORROW_DECIMALS, {
        from: WHALE
    })
    // for (const log of tx.logs) {
    //   console.log(log.event, log.args.message, log.args.val.toString())
    // }

    snap = await snapshot(testCompound, tokenToBorrow)
    console.log(`--- borrow (after) ---`)
    console.log(`liquidity: $ ${snap.liquidity}`)
    console.log(`max borrow: ${snap.maxBorrow}`)
    console.log(`borrowed balance (compound): ${snap.borrowedBalance}`)
    console.log(`borrowed balance (erc20): ${snap.tokenToBorrowBal}`)

    // accrue interest on borrow
    const block = await web3.eth.getBlockNumber()
    await time.advanceBlockTo(block + 100)

    snap = await snapshot(testCompound, tokenToBorrow)
    console.log(`--- after some blocks... ---`)
    console.log(`liquidity: $ ${snap.liquidity}`)
    console.log(`max borrow: ${snap.maxBorrow}`)
    console.log(`borrowed balance (compound): ${snap.borrowedBalance}`)
    console.log(`borrowed balance (erc20): ${snap.tokenToBorrowBal}`)

    // repay
    await tokenToBorrow.transfer(testCompound.address, BORROW_INTEREST, {
        from: REPAY_WHALE
    })
    const MAX_UINT = pow(2, 256).sub(new BN(1))
    tx = await testCompound.repay(TOKEN_TO_BORROW, C_TOKEN_TO_BORROW, MAX_UINT, {
        from: REPAY_WHALE,
    })

    snap = await snapshot(testCompound, tokenToBorrow)
    console.log(`--- repay ---`)
    console.log(`liquidity: $ ${snap.liquidity}`)
    console.log(`max borrow: ${snap.maxBorrow}`)
    console.log(`borrowed balance (compound): ${snap.borrowedBalance}`)
    console.log(`borrowed balance (erc20): ${snap.tokenToBorrowBal}`)
})
โœ…
โœ…
Borrow and Repay
defi-by-example/test-compound-erc20-borrow.js at main ยท stakewithus/defi-by-exampleGitHub
test-compound-erc20-borrow.js
defi-by-example/TestCompoundErc20.sol at main ยท stakewithus/defi-by-exampleGitHub
TestCompoundErc20.sol
Logo
Logo