GithubHelp home page GithubHelp logo

fraxlend-audit's Introduction

Scope TLDR

  • Fraxlend Repository: https://github.com/FraxFinance/fraxlend
  • 7 Non-library contracts in the scope
  • 1384 Total sLoC in scope.
  • 2 library dependencies
  • 4 structs, 1 external interface
  • Contracts use inheritance
  • 1 external function with external call to UniV2 router, 6 external functions with ERC-20 transfers, 1 external function with call to Chainlink oracle (No other oracles)
  • No other external context/code base required
  • FraxlendPair.sol conforms to ERC-4626 and ERC-20 standards
  • No novel or unique curve logic or mathematical models
  • No timelock function
  • Not an NFT
  • Not an AMM
  • Not a fork of a popular project
  • Does not use rollups
  • Single-chain only


Introduction to Fraxlend

  • The Fraxlend platform allows for the deployment of Fraxlend Pairs, each pair represents an isolated lending market.
  • Each pair is configured with one asset and one collateral token, Asset Tokens are borrowed by depositing Collateral Tokens. Asset Tokens are lent in exchange for fTokens. fTokens are redeemed for Asset Tokens plus accrued interest.
  • Each pair is configured to use one or two Chainlink oracle contracts to provide an exchange rate between the two assets.
  • Each pair is configured to use one Rate Calculator contract to determine interest rates.

Pair Interaction Overview

https://github.com/FraxFinance/fraxlend/raw/main/documentation/_images/PairOverview.png



Deployment & Environment Setup

  • Fraxlend Pairs are intended to be deployed from the Fraxlend Pair Deployer
  • There are two ways to deploy a Fraxlend Pair:
    • Public Deploy - available to anyone but with limited configuration
    • Custom Deploy - available to whitelisted deployers
  • Custom Deployment is only available to addresses whitelisted for deployment

Intended Deployment Setup

  • Fraxlend is intended to be used with whitelisted Chainlink crypto oracles only
  • Fraxlend is intended to be used with whitelisted rate contracts LinearInterestRate.sol and VariableInterestRate.sol
  • Fraxlend does not support rebasing tokens
  • Fraxlend does not support fee-on-transfer tokens
  • COMPTROLLER_ADDRESS is a 4/7 gnosis-safe
  • CIRCUIT_BREAKER_ADDRESS is a 1/5 gnosis-safe
  • TIME_LOCK_ADDRESS is a time-delay address

Deployment steps

  1. Deploy rate contracts, LinearInterestRate.sol and VariableInterestRate.sol
  2. Deploy Fraxlend Whitelist and set owner to COMPTROLLER_ADDRESS
  3. Whitelist intended oracles (chainlink crypto only, no FRAX oracles)
    1. Use $USD value for $FRAX, no $FRAX price oracles whitelisted.
  4. Whitelist intended rateContracts from step 1
  5. Whitelist intended custom deployment addresses
  6. Deploy Fraxlend Deployer with proper constructor arguments and set owner to COMPTROLLER_ADDRESS

Oracle Configuration

  • Each Fraxlend Pair takes in two oracle addresses and a normalization parameter. The normalization parameter helps account for oracle precision and for different decimal values between asset and collateral.
  • exchangeRate is a uint224 value and represents the amount of collateral needed to exchange for 1e18 asset (collateral/asset)
  • _oracleMultiply - is the chainlink oracle which forms the numerator of the exchange rate
  • _oracleDivide - is the chainlink oracle address which forms the denominator of the exchange rate
  • _oracleNormalization - is a value which accounts for differences in precision across both oracles and the asset and denominator
    • It is calculated as: 1^(18 + precision of numerator oracle - precision of denominator oracle + precision of asset token - precision of collateral token)

Example Deployment Configuration

The deploy() function takes a single abi encoded bytes array as an argument:

// Frax asset (1e18 precision), WETH collateral (1e18 precision)
bytes memory _configData = abi.encode(
	FRAX_ERC20_ADDRESS, // asset
	WETH_ERC20_ADDRESS, // collateral
	address(0), // numerator oracle
	CHAINLINK_USD_ETH_ADDRESS, // denominator oracle
	1e10, // oracle normalization (18 + 0 - 8 + 18 - 18)
	VARIABLE_RATE_CONTRACT_ADDRESS,
	abi.encode() // No init for variable rate contract
);

// MKR asset (1e18 precision), WBTC collateral (1e8 precision)
bytes memory _configData = abi.encode(
	MKR_ERC20_ADDRESS, // asset
	WBTC_ERC20_ADDRESS, // collateral
	CHAINLINK_USD_WBTC, // numerator oracle (1e8 precision)
	CHAINLINK_USD_ETH_ADDRESS, // denominator oracle (1e8) precision
	1e28, // oracle normalization (18 + 18 - 8 + 8 - 8)
	VARIABLE_RATE_CONTRACT_ADDRESS,
	abi.encode() // No init for variable rate contract
);

fraxlendPairDeployer.deploy(_configData);


Building and Testing

  • First copy .env.example to .env and fill in archival node URLs as well as a mnemonic (hardhat only)
  • To download needed modules run npm install
  • This repository contains scripts to compile and test using both Hardhat and Foundry
  • To run foundry tests you will need to make sure foundry is installed

Compilation

  • forge build
  • npx hardhat compile

Testing with Fuzz Testing (can take a while)

  • source .env && forge test --fork-url $MAINNET_URL --fork-block-number $DEFAULT_FORK_BLOCK

Testing without Fuzz Testing

  • source .env && forge test --fork-url $MAINNET_URL --fork-block-number $DEFAULT_FORK_BLOCK --no-match-test=".*Fuzz.*"

Slither Static Analyzer

  • If you would like to run slither, move the src/contracts directory to the root directory by running mv src/contracts contracts
  • Then update key config.paths.sources in hardhat.config.ts (line 70) to be:
    • sources: "./contracts"
  • Then run slither .


Known Issues

Misconfigured Oracles

  • It is possible to misconfigure pairs and choose oracles and oracle normalization that do not match the assets or that cause prices to be invalid
  • Assume that oracles and normalization are properly configured

Low borrow balance combined with low interest rates

  • When there is an exceptionally low borrow balance and a low interest rate, interest does not accrue due to rounding

Custom Deployment Misconfiguration

  • The custom deployment gives significantly more control to deployers, assume that deployer makes reasonable configuration choices on liquidationFee, maxLTV, penaltyRate etc.
  • When making under-collateralized loans, lenders know and trust the counter-party

Chainlink Oracle

  • Chainlink oracles can provide outdated answers
  • Very large chainlink oracle prices can cause overflow when calculating and when casting to uint224

Frax Price Volatility

  • Because $FRAX is treated as having a price of $1, $FRAX price volatility could cause bad debt or unnecessary liquidations


Contracts Under Review

  • Contains helper functions to wrap the symbol(), name(), and decimal() functions found in ERC20 Metadata calls
  • Contains Open-Zeppelins SafeTransfer() and SafeTransferFrom() implementations
  • LOC: 52
  • Defines the VaultAccount struct, an instance of the struct is used to keep track of the accounting for borrows and for asset lending (see Fraxlend - Advanced Concepts - Vault Account)
  • Provides helper functions for converting between shares and amounts
  • LOC: 35
  • Adheres to the IRateCalculator.sol interface
  • Provides logic for calculating the new interest rate as a function of utilization %
  • Holds no state
  • See: Fraxlend - Advanced Concepts - Linear Rate for an explanation of the math
  • LOC: 49
  • Provides 3 whitelists:
    • RateCalculatorWhitelist - controls which calculators can be used for rate calculations
    • OracleWhitelist - controls which oracle contracts can be used for exchange rates
    • DeployerWhitelist - controls which addresses can deploy custom Fraxlend Pair instances
  • LOC: 29
  • Defines constants and errors only
  • Inherited by tests and FraxlendPairCore
  • LOC: 32
  • Contains all external state-modifying functions without access modifiers (i.e callable by anyone)
  • Contains core logic for the pair
  • Contains all state for the pair
  • Inherited by FraxlendPair
  • Libraries:
    • VaultAccount (libraries/VaultAccount.sol)
    • SafeERC20 (libraries/SafeERC20.sol)
  • External Contract Interactions:
    • During deployment the constructor Interacts with the FraxlendWhitelist to ensure the configured oracles and rate contracts have been whitelisted
    • During Deposit, Withdraw, Mint, Redeem, Borrow, Repay, Liquidate, RepayAssetWithCollateral, LeveragedPosition interacts with the configured asset contract
    • During Borrow, AddCollateral, RemoveCollateral, Liquidate, RepayAssetWithCollateral, LeveragedPosition interacts with the configured collateral contract
    • Leverage and RepayAssetWithCollateral interact with a whitelisted swapper contract which adheres to the Uniswap V2 Router interface
    • _updateExchangeRate interacts with the two chainlink oracles
    • _addInterest interacts with the configured Rate Calculator contract (adheres to IRateCalculator.sol interface)
  • LOC: 693
  • Contains all view functions necessary to adhere to ERC-4626
  • Contains access controlled configuration functions including
    • SetSwapper,
    • ChangeFee
    • WithdrawFees
    • Pause/Unpause
    • SetApprovedBorrower/Lender
  • LOC: 197
  • Contains logic to deploy two pair types: Custom and Public
    • Public pairs are permissionlessly deployed
    • Custom pairs have access to an extra set of configuration items not allowed to pairs deployed via the public function and are only deployable by whitelisted addresses
  • Stores information about pairs deployed like name, address, and whether they are custom pairs
  • Contains the globalPause function which bulk pauses deployed fraxlend pairs
  • Libraries:
    • solidity-bytes-utils: Used to concatenate creation code during deployment
    • Strings library from Open Zeppelin
    • SafeERC20 (libraries/SafeERC20.sol)
  • External Contract Interactions:
    • During customDeployment, calls FraxlendWhitelist to make sure deployer is on whitelist
    • After initial deployment calls initialize() and transferOwnership() on the deployed FraxlendPair instance
  • LOC: 257

Total LOC: 1,384



Contracts Included but not under review

  • This contract contains view functions for previewing interest accrued and updating exchange rate
  • Can be helpful for predicting the effects of your transaction prior to execution

interfaces/*

  • Interfaces provided for reference but are not included in audit

fraxlend-audit's People

Contributors

kartoonjoy avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.