1pragma solidity ^0.8.20;2
3import "./Comptroller.sol";4import "./JumpRateModel.sol";5import "./CErc20Immutable.sol";6import "./CurtaToken.sol";7import "./CurtaOracle.sol";8
9contract Deployer {10 function create(address underlying_,11 ComptrollerInterface comptroller_,12 InterestRateModel interestRateModel_,13 uint256 initialExchangeRateMantissa_,14 string memory name_,15 string memory symbol_) external returns (CErc20Immutable) {16 return new CErc20Immutable(underlying_, comptroller_, interestRateModel_, initialExchangeRateMantissa_, name_, symbol_, uint8(18), payable(msg.sender));17 }18
19 function create2(string memory a, string memory b) external returns (CurtaToken) {20 return new CurtaToken(a, b, msg.sender);21 }22}23
24
25contract Challenge {26 uint256 public seed;27
28 Comptroller public comptroller;29 JumpRateModel public rateModel;30
31 CurtaToken public CUSD;32 CurtaToken public CStUSD;33 CurtaToken public CETH;34 CurtaToken public CWETH;35
36 CErc20Immutable public CCUSD;37 CErc20Immutable public CCStUSD;38 CErc20Immutable public CCETH;39 CErc20Immutable public CCWETH;40
41 CurtaOracle public oracle;42
43 bool public initialized;44
45 function init(uint256 _seed, address _caller) external {46 require(!initialized);47 initialized = true;48 Deployer dd = Deployer(address(0x8555a99DC962D3711101896a3f432d65E8Fbb60f));49
50 seed = _seed;51 CUSD = dd.create2("CUSD", "cUSD");52 CStUSD = dd.create2("CStUSD", "cStUSD");53 CETH = dd.create2("CETH", "cETH");54 CWETH = dd.create2("CWETH", "cWETH");55
56 CUSD.mint(address(this), 10000 ether);57 CStUSD.mint(address(this), 10000 ether);58 CETH.mint(address(this), 10000 ether);59 CWETH.mint(address(this), 10000 ether);60
61 rateModel = new JumpRateModel(2102400, 2102400, 2102400, type(uint256).max);62 comptroller = new Comptroller();63 oracle = new CurtaOracle();64 65 CCUSD =66 dd.create(address(CUSD), ComptrollerInterface(address(comptroller)), InterestRateModel(address(rateModel)), 1e18, "CCUSD", "cCUSD");67 CCStUSD =68 dd.create(address(CStUSD), ComptrollerInterface(address(comptroller)), InterestRateModel(address(rateModel)), 1e18, "CCStUSD", "cCStUSD");69 CCETH =70 dd.create(address(CETH), ComptrollerInterface(address(comptroller)), InterestRateModel(address(rateModel)), 1e18, "CCETH", "cCETH");71 CCWETH =72 dd.create(address(CWETH), ComptrollerInterface(address(comptroller)), InterestRateModel(address(rateModel)), 1e18, "CCWETH", "cCWETH");73
74 CUSD.approve(address(CCUSD), type(uint256).max);75 CStUSD.approve(address(CCStUSD), type(uint256).max);76 CETH.approve(address(CCETH), type(uint256).max);77 CWETH.approve(address(CCWETH), type(uint256).max);78
79 comptroller._supportMarket(CToken(CCUSD));80 comptroller._supportMarket(CToken(CCStUSD));81 comptroller._supportMarket(CToken(CCETH));82 comptroller._supportMarket(CToken(CCWETH));83
84 oracle.setPrice(address(CCUSD), 1e18);85 oracle.setPrice(address(CCStUSD), 1e18);86 oracle.setPrice(address(CCETH), 200e18);87 oracle.setPrice(address(CCWETH), 200e18);88
89 comptroller._setPriceOracle(PriceOracle(address(oracle)));90
91 comptroller._setCollateralFactor(CToken(CCUSD), 0.9 ether);92 comptroller._setCollateralFactor(CToken(CCStUSD), 0.9 ether);93 comptroller._setCollateralFactor(CToken(CCETH), 0.7 ether);94 comptroller._setCollateralFactor(CToken(CCWETH), 0.7 ether);95
96 comptroller._setCloseFactor(0.5 ether);97 comptroller._setLiquidationIncentive(1 ether);98
99 CCUSD.mint(10000 ether);100 CCStUSD.mint(10000 ether);101 CCETH.mint(10000 ether);102 // CWETH.mint(10000 ether);103
104 CWETH.mint(_caller, 10000 ether);105 }106
107 function isSolved() external view returns (bool) {108 address target = address(uint160(seed));109
110 uint256 initUSD = 10000 ether * oracle.getUnderlyingPrice(CToken(CCWETH)) / 1e18;111
112 uint256 profitUSD = (113 CUSD.balanceOf(target) * oracle.getUnderlyingPrice(CToken(CCUSD))114 + CStUSD.balanceOf(target) * oracle.getUnderlyingPrice(CToken(CCStUSD))115 + CETH.balanceOf(target) * oracle.getUnderlyingPrice(CToken(CCETH))116 + CWETH.balanceOf(target) * oracle.getUnderlyingPrice(CToken(CCWETH))117 ) / 1e18 - initUSD;118
119 require(profitUSD > 10000 ether * 200);120
121 return true;122 }123}124
Time Left
Solve locally (WIP)
- Clone GitHub repo + install deps
git clone https://github.com/waterfall-mkt/curta-puzzles.git && cd curta-puzzles && forge install
- Set
RPC_URL_MAINNET
in.env
.env
RPC_URL_MAINNET=""
- Write solution + run script
forge script <PATH_TO_PUZZLE> -f mainnet -vvv
This is still WIP.