@pendle/core-v2 4.5.0 → 4.5.1-beta-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/artifacts/contracts/core/StandardizedYield/implementations/PendleERC20WithSupplyCapSY.sol/PendleERC20WithSupplyCapSY.dbg.json +1 -1
- package/build/artifacts/contracts/interfaces/IPActionMiscV3.sol/IPActionMiscV3.dbg.json +1 -1
- package/build/artifacts/contracts/interfaces/IPActionMiscV3.sol/IPActionMiscV3.json +431 -0
- package/build/artifacts/contracts/interfaces/IPAllActionV3.sol/IPAllActionV3.dbg.json +1 -1
- package/build/artifacts/contracts/interfaces/IPAllActionV3.sol/IPAllActionV3.json +431 -0
- package/build/artifacts/contracts/offchain-helpers/PendlePoolDeployHelper.sol/PendlePoolDeployHelper.dbg.json +1 -1
- package/build/artifacts/contracts/offchain-helpers/PendlePoolDeployHelper.sol/PendlePoolDeployHelper.json +2 -2
- package/build/artifacts/contracts/offchain-helpers/router-static/base/ActionMarketAuxStatic.sol/ActionMarketAuxStatic.dbg.json +1 -1
- package/build/artifacts/contracts/router/ActionAddRemoveLiqV3.sol/ActionAddRemoveLiqV3.dbg.json +1 -1
- package/build/artifacts/contracts/router/ActionAddRemoveLiqV3.sol/ActionAddRemoveLiqV3.json +2 -2
- package/build/artifacts/contracts/router/ActionMiscV3.sol/ActionMiscV3.dbg.json +1 -1
- package/build/artifacts/contracts/router/ActionMiscV3.sol/ActionMiscV3.json +591 -2
- package/build/artifacts/contracts/router/ActionSwapPTV3.sol/ActionSwapPTV3.dbg.json +1 -1
- package/build/artifacts/contracts/router/ActionSwapPTV3.sol/ActionSwapPTV3.json +2 -2
- package/build/artifacts/contracts/router/ActionSwapYTV3.sol/ActionSwapYTV3.dbg.json +1 -1
- package/build/artifacts/contracts/router/ActionSwapYTV3.sol/ActionSwapYTV3.json +2 -2
- package/build/artifacts/contracts/router/base/ActionBase.sol/ActionBase.dbg.json +1 -1
- package/contracts/interfaces/IPActionMiscV3.sol +38 -0
- package/contracts/router/ActionMiscV3.sol +216 -36
- package/contracts/router/ActionSwapYTV3.sol +0 -85
- package/contracts/router/base/ActionBase.sol +106 -1
- package/deployments/merkle-distribution/2024-04-25.json +14930 -0
- package/package.json +1 -1
- package/typechain-types/ActionMiscV3.ts +379 -16
- package/typechain-types/IPActionMiscV3.ts +249 -16
- package/typechain-types/IPAllActionV3.ts +156 -0
- package/typechain-types/ISwellSimpleStakingERC20.ts +289 -0
- package/typechain-types/PendleSwellRswETHStakingSY.ts +1325 -0
- package/typechain-types/PendleSwellStakingERC20SY.ts +1299 -0
- package/typechain-types/factories/ActionAddRemoveLiqV3__factory.ts +1 -1
- package/typechain-types/factories/ActionMiscV3__factory.ts +590 -1
- package/typechain-types/factories/ActionSwapPTV3__factory.ts +1 -1
- package/typechain-types/factories/ActionSwapYTV3__factory.ts +1 -1
- package/typechain-types/factories/IPActionMiscV3__factory.ts +431 -0
- package/typechain-types/factories/IPAllActionV3__factory.ts +431 -0
- package/typechain-types/factories/ISwellSimpleStakingERC20__factory.ts +226 -0
- package/typechain-types/factories/PendlePoolDeployHelper__factory.ts +1 -1
- package/typechain-types/factories/PendleSwellRswETHStakingSY__factory.ts +1106 -0
- package/typechain-types/factories/PendleSwellStakingERC20SY__factory.ts +1112 -0
- package/typechain-types/hardhat.d.ts +27 -0
- package/typechain-types/index.ts +6 -0
|
@@ -79,18 +79,16 @@ contract ActionMiscV3 is IPActionMiscV3, ActionBase {
|
|
|
79
79
|
address[] calldata yts,
|
|
80
80
|
address[] calldata markets
|
|
81
81
|
) external {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
IPMarket(markets[i]).redeemRewards(user);
|
|
93
|
-
}
|
|
82
|
+
for (uint256 i = 0; i < sys.length; ++i) {
|
|
83
|
+
IStandardizedYield(sys[i]).claimRewards(user);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
for (uint256 i = 0; i < yts.length; ++i) {
|
|
87
|
+
IPYieldToken(yts[i]).redeemDueInterestAndRewards(user, true, true);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
for (uint256 i = 0; i < markets.length; ++i) {
|
|
91
|
+
IPMarket(markets[i]).redeemRewards(user);
|
|
94
92
|
}
|
|
95
93
|
}
|
|
96
94
|
|
|
@@ -118,40 +116,222 @@ contract ActionMiscV3 is IPActionMiscV3, ActionBase {
|
|
|
118
116
|
netTokenOut = IStandardizedYield(SY).redeem(receiver, netSyInterm, tokenRedeemSy, minTokenOut, true);
|
|
119
117
|
}
|
|
120
118
|
|
|
119
|
+
event ExitMultiplePreExpiry(
|
|
120
|
+
address indexed caller,
|
|
121
|
+
address indexed market,
|
|
122
|
+
address indexed token,
|
|
123
|
+
address receiver,
|
|
124
|
+
uint256 netLpToRemove,
|
|
125
|
+
uint256 netPtFromRemove,
|
|
126
|
+
uint256 netSyFromRemove,
|
|
127
|
+
uint256 netPyRedeem,
|
|
128
|
+
uint256 netSyFromRedeem,
|
|
129
|
+
uint256 netPtSwap,
|
|
130
|
+
uint256 netYtSwap,
|
|
131
|
+
uint256 netSyFromSwap,
|
|
132
|
+
uint256 netSyFee,
|
|
133
|
+
uint256 netTokenOut
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
event ExitMultiplePostExpiry(
|
|
137
|
+
address indexed caller,
|
|
138
|
+
address indexed market,
|
|
139
|
+
address indexed token,
|
|
140
|
+
address receiver,
|
|
141
|
+
uint256 netLpToRemove,
|
|
142
|
+
uint256 netPtFromRemove, //
|
|
143
|
+
uint256 netSyFromRemove, //
|
|
144
|
+
uint256 netPtRedeem,
|
|
145
|
+
uint256 netSyFromRedeem, //
|
|
146
|
+
uint256 netTokenOut //
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
// TODO: need to allow exit to SY as well
|
|
150
|
+
|
|
151
|
+
struct ExitMultipleParams {
|
|
152
|
+
address receiver;
|
|
153
|
+
address market;
|
|
154
|
+
uint256 netPtIn;
|
|
155
|
+
uint256 netYtIn;
|
|
156
|
+
uint256 netLpIn;
|
|
157
|
+
TokenOutput output;
|
|
158
|
+
LimitOrderData limit;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function exitMultiplePreExpiry(
|
|
162
|
+
address receiver,
|
|
163
|
+
address market,
|
|
164
|
+
uint256 netPtIn,
|
|
165
|
+
uint256 netYtIn,
|
|
166
|
+
uint256 netLpIn,
|
|
167
|
+
TokenOutput calldata output,
|
|
168
|
+
LimitOrderData calldata limit
|
|
169
|
+
)
|
|
170
|
+
external
|
|
171
|
+
returns (
|
|
172
|
+
uint256 netTokenOut,
|
|
173
|
+
uint256 netPtFromRemove,
|
|
174
|
+
uint256 netSyFromRemove,
|
|
175
|
+
uint256 netPyRedeem,
|
|
176
|
+
uint256 netSyFromRedeem,
|
|
177
|
+
uint256 netPtSwap,
|
|
178
|
+
uint256 netYtSwap,
|
|
179
|
+
uint256 netSyFromSwap,
|
|
180
|
+
uint256 netSyFee
|
|
181
|
+
)
|
|
182
|
+
{
|
|
183
|
+
(
|
|
184
|
+
netTokenOut,
|
|
185
|
+
netPtFromRemove,
|
|
186
|
+
netSyFromRemove,
|
|
187
|
+
netPyRedeem,
|
|
188
|
+
netSyFromRedeem,
|
|
189
|
+
netPtSwap,
|
|
190
|
+
netYtSwap,
|
|
191
|
+
netSyFromSwap,
|
|
192
|
+
netSyFee
|
|
193
|
+
) = exitMultiplePreExpiryInner(receiver, market, netPtIn, netYtIn, netLpIn, output, limit);
|
|
194
|
+
|
|
195
|
+
emit ExitMultiplePreExpiry(
|
|
196
|
+
msg.sender,
|
|
197
|
+
market,
|
|
198
|
+
output.tokenOut,
|
|
199
|
+
receiver,
|
|
200
|
+
netLpIn,
|
|
201
|
+
netPtFromRemove,
|
|
202
|
+
netSyFromRemove,
|
|
203
|
+
netPyRedeem,
|
|
204
|
+
netSyFromRedeem,
|
|
205
|
+
netPtSwap,
|
|
206
|
+
netYtSwap,
|
|
207
|
+
netSyFromSwap,
|
|
208
|
+
netSyFee,
|
|
209
|
+
netTokenOut
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function exitMultiplePreExpiryInner(
|
|
214
|
+
address receiver,
|
|
215
|
+
address market,
|
|
216
|
+
uint256 netPtIn,
|
|
217
|
+
uint256 netYtIn,
|
|
218
|
+
uint256 netLpIn,
|
|
219
|
+
TokenOutput calldata output,
|
|
220
|
+
LimitOrderData calldata limit
|
|
221
|
+
)
|
|
222
|
+
internal
|
|
223
|
+
returns (
|
|
224
|
+
uint256 netTokenOut,
|
|
225
|
+
uint256 netPtFromRemove,
|
|
226
|
+
uint256 netSyFromRemove,
|
|
227
|
+
uint256 netPyRedeem,
|
|
228
|
+
uint256 netSyFromRedeem,
|
|
229
|
+
uint256 netPtSwap,
|
|
230
|
+
uint256 netYtSwap,
|
|
231
|
+
uint256 netSyFromSwap,
|
|
232
|
+
uint256 netSyFee
|
|
233
|
+
)
|
|
234
|
+
{
|
|
235
|
+
// (IStandardizedYield SY, IPPrincipalToken PT, IPYieldToken YT) = IPMarket(market).readTokens();
|
|
236
|
+
// if (netLpIn > 0) {
|
|
237
|
+
// _transferFrom(IERC20(market), msg.sender, market, netLpIn);
|
|
238
|
+
// (netSyFromRemove, netPtFromRemove) = IPMarket(market).burn(address(SY), address(this), netLpIn);
|
|
239
|
+
// }
|
|
240
|
+
// if (netPtIn > 0) {
|
|
241
|
+
// _transferIn(address(PT), address(this), netPtIn);
|
|
242
|
+
// }
|
|
243
|
+
// netPyRedeem = PMath.min(netPtFromRemove + netPtIn, netYtIn);
|
|
244
|
+
// if (netPyRedeem > 0) {
|
|
245
|
+
// _transferOut(address(PT), address(YT), netPyRedeem);
|
|
246
|
+
// _transferFrom(YT, msg.sender, address(YT), netPyRedeem);
|
|
247
|
+
// netSyFromRedeem = IPYieldToken(YT).redeemPY(address(SY));
|
|
248
|
+
// }
|
|
249
|
+
// netPtSwap = netPtFromRemove + netPtIn - netPyRedeem;
|
|
250
|
+
// netYtSwap = netYtIn - netPyRedeem;
|
|
251
|
+
// if (netPtSwap > 0) {
|
|
252
|
+
// address ptEntry = _entry_swapExactPtForSy(market, limit);
|
|
253
|
+
// if (ptEntry != address(this)) _transferOut(address(PT), ptEntry, netPtSwap);
|
|
254
|
+
// (netSyFromSwap, netSyFee) = _swapExactPtForSy(address(SY), market, netPtSwap, 0, limit);
|
|
255
|
+
// } else if (netYtSwap > 0) {
|
|
256
|
+
// _transferFrom(YT, msg.sender, _entry_swapExactYtForSy(YT, limit), netYtSwap);
|
|
257
|
+
// (netSyFromSwap, netSyFee) = _swapExactYtForSy(address(SY), market, SY, YT, netYtSwap, 0, limit);
|
|
258
|
+
// }
|
|
259
|
+
// uint256 netSyRedeem = netSyFromRemove + netSyFromRedeem + netSyFromSwap;
|
|
260
|
+
// netTokenOut = _redeemSyToToken(receiver, address(SY), netSyRedeem, output, false);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// TODO: is netSyInterm necessary? can we return more?
|
|
264
|
+
// TODO: compare interface against existing functions, to see if it makes sense
|
|
265
|
+
function exitMultiplePostExpiry(
|
|
266
|
+
address receiver,
|
|
267
|
+
address market,
|
|
268
|
+
uint256 netPtIn,
|
|
269
|
+
uint256 netLpIn,
|
|
270
|
+
TokenOutput calldata output
|
|
271
|
+
)
|
|
272
|
+
external
|
|
273
|
+
returns (
|
|
274
|
+
uint256 netTokenOut,
|
|
275
|
+
uint256 netPtFromRemove,
|
|
276
|
+
uint256 netSyFromRemove,
|
|
277
|
+
uint256 netPtRedeem,
|
|
278
|
+
uint256 netSyFromRedeem
|
|
279
|
+
)
|
|
280
|
+
{
|
|
281
|
+
// * (done) maybe shouldn't reuse functions because of conflicting events
|
|
282
|
+
// * (KIV) expose all inner workings variables
|
|
283
|
+
// also: should match events with existing events
|
|
284
|
+
// events, no matter what is emitted, can be parsed dynamically on BE. Say if only PT is exited, it can be parsed
|
|
285
|
+
// as swapExact
|
|
286
|
+
|
|
287
|
+
(IStandardizedYield SY, IPPrincipalToken PT, IPYieldToken YT) = IPMarket(market).readTokens();
|
|
288
|
+
|
|
289
|
+
// uint256 netPtFromRemove;
|
|
290
|
+
// uint256 netSyFromRemove;
|
|
291
|
+
|
|
292
|
+
if (netLpIn > 0) {
|
|
293
|
+
_transferFrom(IERC20(market), msg.sender, market, netLpIn);
|
|
294
|
+
(netSyFromRemove, netPtFromRemove) = IPMarket(market).burn(address(SY), address(YT), netLpIn);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (netPtIn > 0) {
|
|
298
|
+
_transferFrom(PT, msg.sender, address(YT), netPtIn);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
netPtRedeem = netPtFromRemove + netPtIn;
|
|
302
|
+
netSyFromRedeem = IPYieldToken(YT).redeemPY(address(SY));
|
|
303
|
+
|
|
304
|
+
uint256 netSyRedeem = netSyFromRemove + netSyFromRedeem;
|
|
305
|
+
netTokenOut = _redeemSyToToken(receiver, address(SY), netSyRedeem, output, false);
|
|
306
|
+
|
|
307
|
+
emit ExitMultiplePostExpiry(
|
|
308
|
+
msg.sender,
|
|
309
|
+
market,
|
|
310
|
+
output.tokenOut,
|
|
311
|
+
receiver,
|
|
312
|
+
netLpIn,
|
|
313
|
+
netPtFromRemove,
|
|
314
|
+
netSyFromRemove,
|
|
315
|
+
netPtRedeem,
|
|
316
|
+
netSyFromRedeem,
|
|
317
|
+
netTokenOut
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
|
|
121
321
|
// ----------------- MISC FUNCTIONS -----------------
|
|
122
322
|
|
|
123
323
|
function boostMarkets(address[] memory markets) external {
|
|
124
|
-
for (uint256 i = 0; i < markets.length; ) {
|
|
324
|
+
for (uint256 i = 0; i < markets.length; i++) {
|
|
125
325
|
IPMarket(markets[i]).transferFrom(msg.sender, markets[i], 0);
|
|
126
|
-
unchecked {
|
|
127
|
-
i++;
|
|
128
|
-
}
|
|
129
326
|
}
|
|
130
327
|
}
|
|
131
328
|
|
|
132
329
|
function multicall(Call3[] calldata calls) external payable returns (Result[] memory res) {
|
|
133
330
|
uint256 length = calls.length;
|
|
134
331
|
res = new Result[](length);
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
// delegatecall to itself, it turns allowing invoking functions from other actions
|
|
140
|
-
(bool success, bytes memory result) = address(this).delegatecall(call.callData);
|
|
141
|
-
|
|
142
|
-
if (!success && !call.allowFailure) {
|
|
143
|
-
assembly {
|
|
144
|
-
// We use Yul's revert() to bubble up errors from the target contract.
|
|
145
|
-
revert(add(32, result), mload(result))
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
res[i].success = success;
|
|
150
|
-
res[i].returnData = result;
|
|
151
|
-
|
|
152
|
-
unchecked {
|
|
153
|
-
++i;
|
|
154
|
-
}
|
|
332
|
+
for (uint256 i = 0; i < length; i++) {
|
|
333
|
+
(bool success, bytes memory result) = _delegateToSelf(calls[i].callData, calls[i].allowFailure);
|
|
334
|
+
res[i] = Result(success, result);
|
|
155
335
|
}
|
|
156
336
|
}
|
|
157
337
|
|
|
@@ -52,51 +52,6 @@ contract ActionSwapYTV3 is CallbackHelper, IPActionSwapYTV3, ActionBase {
|
|
|
52
52
|
emit SwapYtAndSy(msg.sender, market, receiver, netYtOut.Int(), exactSyIn.neg());
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
function _entry_swapExactSyForYt(IPYieldToken YT, LimitOrderData calldata limit) internal view returns (address) {
|
|
56
|
-
return !_isEmptyLimit(limit) ? address(this) : address(YT);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function _swapExactSyForYt(
|
|
60
|
-
address receiver,
|
|
61
|
-
address market,
|
|
62
|
-
IStandardizedYield SY,
|
|
63
|
-
IPYieldToken YT,
|
|
64
|
-
uint256 exactSyIn,
|
|
65
|
-
uint256 minYtOut,
|
|
66
|
-
ApproxParams calldata guessYtOut,
|
|
67
|
-
LimitOrderData calldata limit
|
|
68
|
-
) internal returns (uint256 netYtOut, uint256 netSyFee) {
|
|
69
|
-
uint256 netSyLeft = exactSyIn;
|
|
70
|
-
bool doMarketOrder = true;
|
|
71
|
-
|
|
72
|
-
if (!_isEmptyLimit(limit)) {
|
|
73
|
-
(netSyLeft, netYtOut, netSyFee, doMarketOrder) = _fillLimit(receiver, SY, netSyLeft, limit);
|
|
74
|
-
if (doMarketOrder) {
|
|
75
|
-
_transferOut(address(SY), address(YT), netSyLeft);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (doMarketOrder) {
|
|
80
|
-
(uint256 netYtOutMarket, ) = _readMarket(market).approxSwapExactSyForYt(
|
|
81
|
-
YT.newIndex(),
|
|
82
|
-
netSyLeft,
|
|
83
|
-
block.timestamp,
|
|
84
|
-
guessYtOut
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
(, uint256 netSyFeeMarket) = IPMarket(market).swapExactPtForSy(
|
|
88
|
-
address(YT),
|
|
89
|
-
netYtOutMarket, // exactPtIn = netYtOut
|
|
90
|
-
_encodeSwapExactSyForYt(receiver, YT)
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
netYtOut += netYtOutMarket;
|
|
94
|
-
netSyFee += netSyFeeMarket;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (netYtOut < minYtOut) revert("Slippage: INSUFFICIENT_YT_OUT");
|
|
98
|
-
}
|
|
99
|
-
|
|
100
55
|
// ------------------ SWAP TOKEN FOR TOKEN ------------------
|
|
101
56
|
|
|
102
57
|
function swapExactYtForToken(
|
|
@@ -138,46 +93,6 @@ contract ActionSwapYTV3 is CallbackHelper, IPActionSwapYTV3, ActionBase {
|
|
|
138
93
|
emit SwapYtAndSy(msg.sender, market, receiver, exactYtIn.neg(), netSyOut.Int());
|
|
139
94
|
}
|
|
140
95
|
|
|
141
|
-
function _entry_swapExactYtForSy(IPYieldToken YT, LimitOrderData calldata limit) internal view returns (address) {
|
|
142
|
-
return !_isEmptyLimit(limit) ? address(this) : address(YT);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function _swapExactYtForSy(
|
|
146
|
-
address receiver,
|
|
147
|
-
address market,
|
|
148
|
-
IStandardizedYield SY,
|
|
149
|
-
IPYieldToken YT,
|
|
150
|
-
uint256 exactYtIn,
|
|
151
|
-
uint256 minSyOut,
|
|
152
|
-
LimitOrderData calldata limit
|
|
153
|
-
) internal returns (uint256 netSyOut, uint256 netSyFee) {
|
|
154
|
-
uint256 netYtLeft = exactYtIn;
|
|
155
|
-
bool doMarketOrder = true;
|
|
156
|
-
|
|
157
|
-
if (!_isEmptyLimit(limit)) {
|
|
158
|
-
(netYtLeft, netSyOut, netSyFee, doMarketOrder) = _fillLimit(receiver, YT, netYtLeft, limit);
|
|
159
|
-
if (doMarketOrder) {
|
|
160
|
-
_transferOut(address(YT), address(YT), netYtLeft);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
if (doMarketOrder) {
|
|
165
|
-
uint256 preSyBalance = SY.balanceOf(receiver);
|
|
166
|
-
|
|
167
|
-
(, uint256 netSyFeeMarket) = IPMarket(market).swapSyForExactPt(
|
|
168
|
-
address(YT),
|
|
169
|
-
netYtLeft, // exactPtOut = netYtLeft
|
|
170
|
-
_encodeSwapYtForSy(receiver, YT)
|
|
171
|
-
);
|
|
172
|
-
|
|
173
|
-
// avoid stack issue
|
|
174
|
-
netSyFee += netSyFeeMarket;
|
|
175
|
-
netSyOut += SY.balanceOf(receiver) - preSyBalance;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
if (netSyOut < minSyOut) revert("Slippage: INSUFFICIENT_SY_OUT");
|
|
179
|
-
}
|
|
180
|
-
|
|
181
96
|
// ------------------ SWAP PT FOR YT ------------------
|
|
182
97
|
|
|
183
98
|
function swapExactPtForYt(
|
|
@@ -10,8 +10,10 @@ import "../../router/base/MarketApproxLib.sol";
|
|
|
10
10
|
|
|
11
11
|
import "../../core/libraries/Errors.sol";
|
|
12
12
|
import "../swap-aggregator/IPSwapAggregator.sol";
|
|
13
|
+
import "./CallbackHelper.sol";
|
|
13
14
|
|
|
14
|
-
abstract contract ActionBase is TokenHelper, IPLimitOrderType {
|
|
15
|
+
abstract contract ActionBase is TokenHelper, CallbackHelper, IPLimitOrderType {
|
|
16
|
+
using MarketApproxPtInLib for MarketState;
|
|
15
17
|
using MarketApproxPtOutLib for MarketState;
|
|
16
18
|
using PMath for uint256;
|
|
17
19
|
using PYIndexLib for IPYieldToken;
|
|
@@ -236,6 +238,93 @@ abstract contract ActionBase is TokenHelper, IPLimitOrderType {
|
|
|
236
238
|
if (netPtOut < minPtOut) revert("Slippage: INSUFFICIENT_PT_OUT");
|
|
237
239
|
}
|
|
238
240
|
|
|
241
|
+
// ----------------- YT SWAP -----------------
|
|
242
|
+
|
|
243
|
+
function _entry_swapExactYtForSy(IPYieldToken YT, LimitOrderData calldata limit) internal view returns (address) {
|
|
244
|
+
return !_isEmptyLimit(limit) ? address(this) : address(YT);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function _swapExactYtForSy(
|
|
248
|
+
address receiver,
|
|
249
|
+
address market,
|
|
250
|
+
IStandardizedYield SY,
|
|
251
|
+
IPYieldToken YT,
|
|
252
|
+
uint256 exactYtIn,
|
|
253
|
+
uint256 minSyOut,
|
|
254
|
+
LimitOrderData calldata limit
|
|
255
|
+
) internal returns (uint256 netSyOut, uint256 netSyFee) {
|
|
256
|
+
uint256 netYtLeft = exactYtIn;
|
|
257
|
+
bool doMarketOrder = true;
|
|
258
|
+
|
|
259
|
+
if (!_isEmptyLimit(limit)) {
|
|
260
|
+
(netYtLeft, netSyOut, netSyFee, doMarketOrder) = _fillLimit(receiver, YT, netYtLeft, limit);
|
|
261
|
+
if (doMarketOrder) {
|
|
262
|
+
_transferOut(address(YT), address(YT), netYtLeft);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (doMarketOrder) {
|
|
267
|
+
uint256 preSyBalance = SY.balanceOf(receiver);
|
|
268
|
+
|
|
269
|
+
(, uint256 netSyFeeMarket) = IPMarket(market).swapSyForExactPt(
|
|
270
|
+
address(YT),
|
|
271
|
+
netYtLeft, // exactPtOut = netYtLeft
|
|
272
|
+
_encodeSwapYtForSy(receiver, YT)
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
// avoid stack issue
|
|
276
|
+
netSyFee += netSyFeeMarket;
|
|
277
|
+
netSyOut += SY.balanceOf(receiver) - preSyBalance;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (netSyOut < minSyOut) revert("Slippage: INSUFFICIENT_SY_OUT");
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function _entry_swapExactSyForYt(IPYieldToken YT, LimitOrderData calldata limit) internal view returns (address) {
|
|
284
|
+
return !_isEmptyLimit(limit) ? address(this) : address(YT);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function _swapExactSyForYt(
|
|
288
|
+
address receiver,
|
|
289
|
+
address market,
|
|
290
|
+
IStandardizedYield SY,
|
|
291
|
+
IPYieldToken YT,
|
|
292
|
+
uint256 exactSyIn,
|
|
293
|
+
uint256 minYtOut,
|
|
294
|
+
ApproxParams calldata guessYtOut,
|
|
295
|
+
LimitOrderData calldata limit
|
|
296
|
+
) internal returns (uint256 netYtOut, uint256 netSyFee) {
|
|
297
|
+
uint256 netSyLeft = exactSyIn;
|
|
298
|
+
bool doMarketOrder = true;
|
|
299
|
+
|
|
300
|
+
if (!_isEmptyLimit(limit)) {
|
|
301
|
+
(netSyLeft, netYtOut, netSyFee, doMarketOrder) = _fillLimit(receiver, SY, netSyLeft, limit);
|
|
302
|
+
if (doMarketOrder) {
|
|
303
|
+
_transferOut(address(SY), address(YT), netSyLeft);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if (doMarketOrder) {
|
|
308
|
+
(uint256 netYtOutMarket, ) = _readMarket(market).approxSwapExactSyForYt(
|
|
309
|
+
YT.newIndex(),
|
|
310
|
+
netSyLeft,
|
|
311
|
+
block.timestamp,
|
|
312
|
+
guessYtOut
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
(, uint256 netSyFeeMarket) = IPMarket(market).swapExactPtForSy(
|
|
316
|
+
address(YT),
|
|
317
|
+
netYtOutMarket, // exactPtIn = netYtOut
|
|
318
|
+
_encodeSwapExactSyForYt(receiver, YT)
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
netYtOut += netYtOutMarket;
|
|
322
|
+
netSyFee += netSyFeeMarket;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (netYtOut < minYtOut) revert("Slippage: INSUFFICIENT_YT_OUT");
|
|
326
|
+
}
|
|
327
|
+
|
|
239
328
|
// ----------------- LIMIT ORDERS -----------------
|
|
240
329
|
function _fillLimit(
|
|
241
330
|
address receiver,
|
|
@@ -284,4 +373,20 @@ abstract contract ActionBase is TokenHelper, IPLimitOrderType {
|
|
|
284
373
|
function _isEmptyLimit(LimitOrderData calldata a) internal pure returns (bool) {
|
|
285
374
|
return a.normalFills.length == 0 && a.flashFills.length == 0;
|
|
286
375
|
}
|
|
376
|
+
|
|
377
|
+
// ----------------- DELEGATE CALL -----------------
|
|
378
|
+
|
|
379
|
+
function _delegateToSelf(
|
|
380
|
+
bytes memory data,
|
|
381
|
+
bool allowFailure
|
|
382
|
+
) internal returns (bool success, bytes memory result) {
|
|
383
|
+
(success, result) = address(this).delegatecall(data);
|
|
384
|
+
|
|
385
|
+
if (!success && !allowFailure) {
|
|
386
|
+
assembly {
|
|
387
|
+
// We use Yul's revert() to bubble up errors from the target contract.
|
|
388
|
+
revert(add(32, result), mload(result))
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
287
392
|
}
|