-
-
Save zobront/44a1909a8451d7649443d0e2717a96ab to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.0; | |
import { Test, console2 } from "forge-std/Test.sol"; | |
import { Comptroller } from "../contracts/Comptroller.sol"; | |
import { InterestRateModel } from "../contracts/InterestRateModel.sol"; | |
import { CToken } from "../contracts/CToken.sol"; | |
import { CErc20 } from "../contracts/CErc20.sol"; | |
import { CErc721 } from "../contracts/CErc721.sol"; | |
import { PriceOracle } from "../contracts/PriceOracle.sol"; | |
import { JumpRateModelV2 } from "../contracts/JumpRateModelV2.sol"; | |
import { CErc721InterestRateModel } from "../contracts/CErc721InterestRateModel.sol"; | |
import "../contracts/CTokenInterfaces.sol"; | |
import { AggregatorV3Interface } from "@chainlink/interfaces/AggregatorV3Interface.sol"; | |
import { ChainlinkPriceOracle } from "../contracts/ChainlinkPriceOracle.sol"; | |
import { FloorPriceFeedAdapter } from "../contracts/FloorPriceFeedAdapter.sol"; | |
import { CEther, IWeth } from "../contracts/CEther.sol"; | |
import { CEtherDelegator } from "../contracts/CEtherDelegator.sol"; | |
import { CEtherDelegate } from "../contracts/CEtherDelegate.sol"; | |
import { CErc721Delegate } from "../contracts/CERC721Delegate.sol"; | |
import { CErc721Delegator } from "../contracts/CERC721Delegator.sol"; | |
import { CErc721NoProxy } from "../contracts/CERC721NoProxy.sol"; | |
import { CErc20InterestMarket } from "../contracts/CErc20InterestMarket.sol"; | |
import { CErc20InterestMarketDelegator } from "../contracts/CErc20InterestMarketDelegator.sol"; | |
import { CErc20InterestMarketDelegate } from "../contracts/CErc20InterestMarketDelegate.sol"; | |
import { CErc20InterestMarketNoProxy } from "../contracts/CErc20InterestMarketNoProxy.sol"; | |
import { CErc20Immutable } from "../contracts/CErc20Immutable.sol"; | |
interface IERC721 { | |
function transferFrom(address from, address to, uint256 tokenId) external; | |
function balanceOf(address owner) external view returns (uint256 balance); | |
function approve(address to, uint256 tokenId) external; | |
function ownerOf(uint256 tokenId) external view returns (address owner); | |
} | |
interface IERC20 { | |
function transfer(address recipient, uint256 amount) external returns (bool); | |
function balanceOf(address owner) external view returns (uint256 balance); | |
function approve(address spender, uint256 amount) external returns (bool); | |
} | |
contract MockOracle { | |
uint price; | |
constructor(uint _price) { | |
price = _price; | |
} | |
function setPrice(uint _price) public { | |
price = _price; | |
} | |
function latestRoundData() external view returns (uint80, int256, uint256, uint256, uint80) { | |
return (0, int(price), 0, block.timestamp, 0); | |
} | |
} | |
contract BaseTest is Test { | |
Comptroller comptroller; | |
JumpRateModelV2 jumpRateModel; | |
CErc721InterestRateModel cErc721InterestRateModel; | |
address lender = makeAddr("lender"); | |
address borrower = makeAddr("borrower"); | |
address liquidator = makeAddr("liquidator"); | |
address attacker = makeAddr("attacker"); | |
address constant BAYC = 0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D; | |
address constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; | |
IWeth constant WETH = IWeth(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); | |
AggregatorV3Interface constant ETHUSD = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419); | |
address constant USDUSDC = 0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6; | |
address constant BAYCETH = 0x352f2Bc3039429fC2fe62004a1575aE74001CfcE; | |
uint constant blocksPerYear = 2628000; | |
ChainlinkPriceOracle oracle; | |
CErc721 baycCERC721; | |
CErc20 erc20Market; | |
CErc20InterestMarket imMarket; | |
CEther cether; | |
function setUp() virtual public { | |
vm.createSelectFork("https://mainnet.infura.io/v3/fb419f740b7e401bad5bec77d0d285a5", 18764789); // ~1pm monday | |
////////////////////////////////// | |
////////// COMPTROLLER /////////// | |
////////////////////////////////// | |
comptroller = new Comptroller(); | |
comptroller.initialize(); | |
////////////////////////////////// | |
////// INTEREST RATE MODELS ////// | |
////////////////////////////////// | |
jumpRateModel = new JumpRateModelV2(0, 0.04e18, 1.09e18, 0.8e18, address(this)); | |
cErc721InterestRateModel = new CErc721InterestRateModel(2628000, 0.02e18, 0.1e18); | |
////////////////////////////////// | |
//////////// MARKETS ///////////// | |
////////////////////////////////// | |
address baycCERC721Impl = address(new CErc721Delegate()); | |
baycCERC721 = CErc721(address(new CErc721Delegator( | |
BAYC, | |
ComptrollerInterface(address(comptroller)), | |
InterestRateModel(address(cErc721InterestRateModel)), | |
2e26, | |
"BAYC Market", | |
"cBAYC", | |
8, | |
payable(address(this)), | |
baycCERC721Impl, | |
"" | |
))); | |
baycCERC721._setReserveFactor(7.5e16); | |
imMarket = CErc20InterestMarket(address(new CErc20InterestMarketNoProxy( | |
USDC, | |
ComptrollerInterface(address(comptroller)), | |
InterestRateModel(address(jumpRateModel)), | |
2e14, | |
"cUSDC Interest Market", | |
"imcUSDC", | |
8, | |
payable(address(this)) | |
))); | |
imMarket._setReserveFactor(7.5e16); | |
imMarket._setProtocolSeizeShare(2.8e16); | |
erc20Market = CErc20(address(new CErc20Immutable( | |
USDC, | |
ComptrollerInterface(address(comptroller)), | |
InterestRateModel(address(jumpRateModel)), | |
2e14, | |
"Fungify cUSDC", | |
"fcUSDC", | |
8, | |
payable(address(this)) | |
))); | |
erc20Market._setReserveFactor(7.5e16); | |
erc20Market._setProtocolSeizeShare(2.8e16); | |
cether = CEther(payable(address(new CEtherDelegator( | |
ComptrollerInterface(address(comptroller)), | |
InterestRateModel(address(jumpRateModel)), | |
2e14, | |
"Fungify cETH", | |
"fcETH", | |
8, | |
payable(address(this)), | |
address(new CEtherDelegate(WETH)), | |
"" | |
)))); | |
cether._setReserveFactor(7.5e16); | |
cether._setProtocolSeizeShare(2.8e16); | |
////////////////////////////////// | |
//////////// ORACLES ///////////// | |
////////////////////////////////// | |
oracle = new ChainlinkPriceOracle(); | |
address baycAdapter = address(new FloorPriceFeedAdapter( | |
AggregatorV3Interface(BAYCETH), | |
ETHUSD | |
)); | |
oracle.setAssetPriceFeed(CToken(address(baycCERC721)), baycAdapter); | |
oracle.setAssetPriceFeed(CToken(address(imMarket)), USDUSDC); | |
oracle.setAssetPriceFeed(CToken(address(erc20Market)), USDUSDC); | |
oracle.setAssetPriceFeed(CToken(address(cether)), address(ETHUSD)); | |
////////////////////////////////// | |
////// COMPTROLLER SETTINGS ////// | |
////////////////////////////////// | |
comptroller._setPriceOracle(PriceOracle(address(oracle))); | |
comptroller._setLiquidationIncentive(1.08e18); | |
comptroller._supportMarket(CToken(address(baycCERC721))); | |
comptroller._setCollateralFactor(CToken(address(baycCERC721)), 0.85e18); | |
comptroller._supportMarket(CToken(address(erc20Market))); | |
comptroller._setCollateralFactor(CToken(address(erc20Market)), 0.85e18); | |
comptroller._supportMarket(CToken(address(cether))); | |
comptroller._setCollateralFactor(CToken(address(cether)), 0.85e18); | |
comptroller._supportMarket(CToken(address(imMarket))); | |
comptroller._setCollateralFactor(CToken(address(imMarket)), 0.85e18); | |
comptroller._updateInterestMarket(address(imMarket)); | |
comptroller._setAdminWhitelist(liquidator, true); | |
comptroller._setAdminWhitelist(attacker, true); | |
////////////////////////////////// | |
////////// TOKEN SETUP /////////// | |
////////////////////////////////// | |
address USDC_WHALE = 0x28C6c06298d514Db089934071355E5743bf21d60; | |
vm.prank(USDC_WHALE); | |
IERC20(USDC).transfer(address(this), 100_000_000e6); | |
} | |
function _distributeERC20(address token, address to, uint amount, address marketToApprove) internal { | |
IERC20(token).transfer(to, amount); | |
vm.prank(to); | |
IERC20(token).approve(marketToApprove, amount); | |
} | |
function _distributeERC721(address token, address to, uint tokenId, address marketToApprove) internal { | |
address from = IERC721(token).ownerOf(tokenId); | |
vm.prank(from); | |
IERC721(token).transferFrom(from, to, tokenId); | |
vm.prank(to); | |
IERC721(token).approve(marketToApprove, tokenId); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment