-
Notifications
You must be signed in to change notification settings - Fork 2
/
Test3rdPartyProtocol.sol
166 lines (143 loc) · 5.47 KB
/
Test3rdPartyProtocol.sol
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../utilities/RubiconRouter.sol";
import "../utilities/FeeWrapper.sol";
contract Test3rdPartyProtocol {
address public feeWrapper;
uint256 feeType = 10_000; // BPS
uint256 fee = 10; // 10/10_000
address feeTo;
address rubiRouter;
constructor(address _feeWrapper, address _feeTo, address _rubiRouter) {
feeWrapper = _feeWrapper;
feeTo = _feeTo;
rubiRouter = _rubiRouter;
}
function executeSwap(
uint256 pay_amt,
uint256 buy_amt_min,
address[] calldata route
) external {
// transfer full amount
IERC20(route[0]).transferFrom(msg.sender, address(this), pay_amt);
// for RubiconRouter both `pay_amt` and `buy_amt_min` should be updated
uint256[] memory tokenAmounts = new uint256[](2);
tokenAmounts[0] = pay_amt;
tokenAmounts[1] = buy_amt_min;
// calculate fee to pay using FeeWrapper
(uint256[] memory new_amounts, uint256[] memory fees_) = FeeWrapper(
feeWrapper
).calculateFee(tokenAmounts, feeType, fee);
// construct fee params
FeeWrapper.FeeParams memory feeParams = FeeWrapper.FeeParams(
route[0],
pay_amt,
fees_[0], // use only the first fee for router
feeTo
);
// approve total amount to the FeeWrapper
IERC20(route[0]).approve(feeWrapper, pay_amt);
// update both pay_amt and buy_amt_min with fee deducted
pay_amt = new_amounts[0];
buy_amt_min = new_amounts[1];
FeeWrapper.CallParams memory params = FeeWrapper.CallParams(
RubiconRouter.swap.selector,
abi.encode(pay_amt, buy_amt_min, route, msg.sender),
rubiRouter,
feeParams
);
FeeWrapper(feeWrapper).rubicall(params);
}
function executeSwapWithETH(
uint256 pay_amt,
uint256 buy_amt_min,
address[] calldata route
) external payable {
require(msg.value == pay_amt, "nah bro");
// for RubiconRouter both `pay_amt` and `buy_amt_min` should be updated
uint256[] memory tokenAmounts = new uint256[](2);
tokenAmounts[0] = pay_amt;
tokenAmounts[1] = buy_amt_min;
// calculate fee to pay using FeeWrapper
(uint256[] memory new_amounts, uint256[] memory fees_) = FeeWrapper(
feeWrapper
).calculateFee(tokenAmounts, feeType, fee);
// construct fee params
FeeWrapper.FeeParams memory feeParams = FeeWrapper.FeeParams(
route[0], // MUS be WETH
pay_amt,
fees_[0], // use only the first fee for router
feeTo
);
// approve total amount to the FeeWrapper
IERC20(route[0]).approve(feeWrapper, pay_amt);
// update both pay_amt and buy_amt_min with fee deducted
pay_amt = new_amounts[0];
buy_amt_min = new_amounts[1];
FeeWrapper.CallParams memory params = FeeWrapper.CallParams(
RubiconRouter.swapWithETH.selector,
abi.encode(pay_amt, buy_amt_min, route, msg.sender),
rubiRouter,
feeParams
);
FeeWrapper(feeWrapper).rubicall{value: msg.value}(params);
}
function executeOfferWithETH(
uint256 pay_amt,
uint256 buy_amt,
address buy_gem,
uint256 pos
) external payable {
require(pay_amt == msg.value, "no no no");
uint256[] memory tokenAmounts = new uint256[](2);
tokenAmounts[0] = pay_amt;
tokenAmounts[1] = buy_amt;
// calculate fee to pay using FeeWrapper
(uint256[] memory new_amounts, uint256[] memory fees_) = FeeWrapper(
feeWrapper
).calculateFee(tokenAmounts, feeType, fee);
FeeWrapper.FeeParams memory feeParams = FeeWrapper.FeeParams(
address(0), // don't care since the func is payable
pay_amt,
fees_[0],
feeTo
);
// update both pay_amt and buy_amt_min with fee deducted
pay_amt = new_amounts[0];
FeeWrapper.CallParams memory params = FeeWrapper.CallParams(
RubiconRouter.offerWithETH.selector,
abi.encode(pay_amt, buy_amt, buy_gem, pos, msg.sender),
rubiRouter,
feeParams
);
FeeWrapper(feeWrapper).rubicall{value: msg.value}(params);
}
function executeDepositWithETH(
uint256 amount,
address bathToken
) external payable {
require(amount == msg.value, "no no no");
uint256[] memory tokenAmounts = new uint256[](1);
tokenAmounts[0] = amount;
// calculate fee to pay using FeeWrapper
(uint256[] memory new_amounts, uint256[] memory fees_) = FeeWrapper(
feeWrapper
).calculateFee(tokenAmounts, feeType, fee);
FeeWrapper.FeeParams memory feeParams = FeeWrapper.FeeParams(
address(0), // don't care since the func is payable
amount,
fees_[0],
feeTo
);
// update both pay_amt and buy_amt_min with fee deducted
amount = new_amounts[0];
FeeWrapper.CallParams memory params = FeeWrapper.CallParams(
RubiconRouter.depositWithETH.selector,
abi.encode(amount, bathToken, msg.sender),
rubiRouter,
feeParams
);
FeeWrapper(feeWrapper).rubicall{value: msg.value}(params);
}
}