-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathRocketArb.huff
89 lines (83 loc) · 3.9 KB
/
RocketArb.huff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#define constant rETH = 0xae78736Cd615f374D3085123A210448E74Fc6393
#define constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
#define constant rock = 0x1d8f8f00cfa6758d7bE78336684788Fb0ee0Fa46
#define constant dkey = 0x65dd923ddfc8d8ae6088f80077201d2403cbd565f0ba25e09841e2799ec90bb2 // keccak256('contract.addressrocketDepositPool')
#define constant lady = FREE_STORAGE_POINTER()
#define constant swap = FREE_STORAGE_POINTER()
#define macro CONSTRUCTOR() = {
0xB0De8cB8Dcc8c5382c4b7F3E978b491140B2bC55 [lady] sstore
0x1111111254EEB25477B68fb85Ed929f73A960582 [swap] sstore
}
#define macro DIE(x) = { <x> push0 mstore8 0x1 push0 revert }
// error code: 0x0 (unauthorised)
#define macro SET(name) = {
caller [lady] sload eq auth jumpi 0x1 push0 revert auth:
0x4 calldataload <name> sstore stop }
// drain to the lady
// error codes: 0x1 (balanceOf), 0x2 (rETH transfer), 0x3 (WETH withdraw), 0x4 (send)
#define macro OUT() = {
__FUNC_SIG("balanceOf(address)") push0 mstore address 0x20 mstore
0x20 0x40 0x24 0x1c [rETH] gas staticcall
0x20 0x60 0x24 0x1c [WETH] gas staticcall
and drain jumpi DIE(0x1) drain:
[lady] sload 0x20 mstore
0x40 mload iszero skiprETH jumpi
__FUNC_SIG("transfer(address,uint256)") push0 mstore
0x20 push0 0x44 0x1c push0 [rETH] gas call
push0 mload and skiprETH jumpi DIE(0x2) skiprETH:
0x60 mload iszero skipWETH jumpi
__FUNC_SIG("withdraw(uint256)") 0x40 mstore
push0 push0 0x24 0x5c push0 [WETH] gas call
skipWETH jumpi DIE(0x3) skipWETH:
push0 push0 push0 push0 selfbalance 0x20 mload gas call
end jumpi DIE(0x4) end: stop }
// actually do an arb(rETH_amount, ETH_amount, min_profit, data)
// error codes: 0x5 (approve), 0x6 (swap), 0x7 (check swap), 0x8 (check+withdraw WETH),
// 0x9 (deposit/mint), 0xa (not enough rETH minted), 0xb (not enough profit), 0xc (send)
#define macro ARB() = {
__FUNC_SIG("balanceOf(address)") push0 mstore address 0x20 mstore
0x20 0x40 0x24 0x1c [rETH] gas staticcall
approve jumpi DIE(0x1) approve: 0x40 mload
// approve the current swap router to spend the rETH amount argument of rETH
__FUNC_SIG("approve(address,uint256)") 0x40 mstore [swap] sload 0x60 mstore
0x4 calldataload 0x80 mstore
0x20 0x40 0x44 0x5c push0 [rETH] gas call
0x40 mload and sell jumpi DIE(0x5) sell:
// call the current swap router with the data argument
// sig reth eth minp head len data
// 0x0 0x04 0x24 0x44 0x64 0x84 0xa4
push0 push0 0x84 calldataload dup1 // data.length data.length 0 0 rETH.balance
0xa4 0x80 calldatacopy 0x80 // 0x80 data.length 0 0 rETH.balance
push0 0x60 mload gas call
mint jumpi DIE(0x6) mint:
// withdraw any WETH balance
0x20 0x60 0x24 0x1c [WETH] gas staticcall
withdraw jumpi DIE(0x1) withdraw:
0x60 mload iszero skipWithdraw jumpi
__FUNC_SIG("withdraw(uint256)") 0x40 mstore
push0 push0 0x24 0x5c push0 [WETH] gas call
skipWithdraw jumpi DIE(0x3) skipWithdraw:
// deposit the ETH amount argument of ETH to mint rETH
__FUNC_SIG("getAddress(bytes32)") 0x40 mstore [dkey] 0x60 mstore
0x20 0x40 0x24 0x5c [rock] gas staticcall
deposit jumpi DIE(0x9) deposit:
__FUNC_SIG("deposit()") 0x60 mstore
push0 push0 0x4 0x7c 0x24 calldataload 0x40 mload gas call
check jumpi DIE(0x9) check:
// check that the amount of rETH is now at least the original amount
0x20 0x40 0x24 0x1c [rETH] gas staticcall
amount jumpi DIE(0x1) amount: 0x40 mload // newBalance oldBalance
lt iszero // oldBalance ≤ newBalance
profit jumpi DIE(0xa) profit:
// check that the ETH contract balance is at least the min profit argument
push0 push0 push0 push0 selfbalance
0x44 calldataload dup2 lt fail jumpi
// send the ETH balance to the caller
caller gas call fin jumpi DIE(0xc) fin: stop fail: DIE(0xb) }
#define macro MAIN() = {
push0 calldataload 0xe0 shr
dup1 __FUNC_SIG("arb(uint256,uint256,uint256,bytes)") eq arb jumpi
dup1 __FUNC_SIG("out()") eq out jumpi
dup1 __FUNC_SIG("set(address)") eq set jumpi
__FUNC_SIG("own(address)") eq own jumpi
stop out: OUT() arb: ARB() own: SET(lady) set: SET(swap) }