Puzzle #3
LatentRisk
Author
0xb49bf876be26435b6fae1ef42c3c82c5867fa149
chainlight.io
SoliditySolidity's logo.Puzzle
Curtacallsverify()
1
pragma solidity ^0.8.20;
2
3
import "./Comptroller.sol";
4
import "./JumpRateModel.sol";
5
import "./CErc20Immutable.sol";
6
import "./CurtaToken.sol";
7
import "./CurtaOracle.sol";
8
9
contract 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
25
contract 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
First Blood
beepidibop.eth
23:09:10
10
Time Left

Solve locally (WIP)

  1. Clone GitHub repo + install deps
git clone https://github.com/waterfall-mkt/curta-puzzles.git && cd curta-puzzles && forge install
  1. Set RPC_URL_MAINNET in .env
.env
RPC_URL_MAINNET=""
  1. Write solution + run script
forge script <PATH_TO_PUZZLE> -f mainnet -vvv
This is still WIP.
Waterfall