@pendle/core-v2 0.2.2 → 0.3.0
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/contracts/SuperComposableYield/ISuperComposableYield.sol +1 -5
- package/contracts/SuperComposableYield/implementations/RewardManager.sol +2 -2
- package/contracts/SuperComposableYield/implementations/SCYBase.sol +2 -2
- package/contracts/SuperComposableYield/implementations/SCYBaseWithRewards.sol +4 -7
- package/contracts/core/PendleMarket.sol +24 -22
- package/contracts/core/PendleMarketFactory.sol +7 -6
- package/contracts/core/PendleSCYImpl/PendleBenQiErc20SCY.sol +1 -1
- package/contracts/core/PendleSCYImpl/PendleBtrflySCY.sol +2 -7
- package/contracts/core/PendleSCYImpl/PendleYearnVaultSCY.sol +2 -7
- package/contracts/core/PendleYieldContractFactory.sol +12 -7
- package/contracts/core/PendleYieldToken.sol +93 -55
- package/contracts/core/router/PendleRouterCoreUpg.sol +35 -21
- package/contracts/core/router/PendleRouterProxy.sol +12 -6
- package/contracts/core/router/{PendleRouterStatic.sol → PendleRouterStaticUpg.sol} +43 -18
- package/contracts/core/router/PendleRouterYTUpg.sol +47 -13
- package/contracts/core/router/base/PendleRouterOTBaseUpg.sol +22 -32
- package/contracts/core/router/base/PendleRouterSCYAndForgeBaseUpg.sol +1 -1
- package/contracts/core/router/base/PendleRouterYTBaseUpg.sol +62 -43
- package/contracts/interfaces/IPMarket.sol +4 -2
- package/contracts/interfaces/{IPPermissionsV2.sol → IPPermissionsV2Upg.sol} +1 -1
- package/contracts/interfaces/IPRouterCore.sol +24 -21
- package/contracts/interfaces/IPRouterStatic.sol +10 -1
- package/contracts/interfaces/IPRouterYT.sol +16 -4
- package/contracts/interfaces/IPYieldContractFactory.sol +4 -0
- package/contracts/interfaces/IPYieldToken.sol +2 -4
- package/contracts/libraries/SCYIndex.sol +3 -3
- package/contracts/libraries/math/LogExpMath.sol +1 -90
- package/contracts/libraries/math/MarketApproxLib.sol +336 -94
- package/contracts/libraries/math/MarketMathAux.sol +101 -0
- package/contracts/libraries/math/MarketMathCore.sol +423 -0
- package/contracts/libraries/math/Math.sol +144 -0
- package/contracts/{core/misc → periphery}/PendleJoeSwapHelperUpg.sol +2 -2
- package/contracts/periphery/{PermissionsV2.sol → PermissionsV2Upg.sol} +2 -2
- package/package.json +1 -1
- package/typechain-types/IPMarket.ts +22 -11
- package/typechain-types/IPRouterCore.ts +68 -58
- package/typechain-types/IPRouterStatic.ts +52 -0
- package/typechain-types/IPRouterYT.ts +96 -12
- package/typechain-types/IPYieldContractFactory.ts +32 -0
- package/typechain-types/IPYieldToken.ts +14 -48
- package/typechain-types/IPermissionsV2Upg.ts +87 -0
- package/typechain-types/ISuperComposableYield.ts +3 -11
- package/typechain-types/OwnableUpgradeable.ts +165 -0
- package/typechain-types/PendleAaveV3SCY.ts +3 -11
- package/typechain-types/PendleBenQiErc20SCY.ts +3 -11
- package/typechain-types/PendleBtrflyScy.ts +3 -11
- package/typechain-types/PendleMarket.ts +22 -11
- package/typechain-types/PendleRouterCoreUpg.ts +66 -48
- package/typechain-types/PendleRouterProxy.ts +15 -118
- package/typechain-types/PendleRouterStaticUpg.ts +92 -0
- package/typechain-types/PendleRouterYTUpg.ts +96 -12
- package/typechain-types/PendleYearnVaultScy.ts +3 -11
- package/typechain-types/PendleYieldContractFactory.ts +40 -113
- package/typechain-types/PendleYieldToken.ts +106 -7
- package/typechain-types/PermissionsV2Upg.ts +87 -0
- package/typechain-types/SCYBase.ts +3 -11
- package/typechain-types/SCYBaseWithRewards.ts +3 -11
- package/typechain-types/factories/IPMarket__factory.ts +8 -2
- package/typechain-types/factories/IPRouterCore__factory.ts +38 -23
- package/typechain-types/factories/IPRouterStatic__factory.ts +29 -0
- package/typechain-types/factories/IPRouterYT__factory.ts +65 -6
- package/typechain-types/factories/IPYieldContractFactory__factory.ts +38 -0
- package/typechain-types/factories/IPYieldToken__factory.ts +1 -20
- package/typechain-types/factories/IPermissionsV2Upg__factory.ts +39 -0
- package/typechain-types/factories/ISuperComposableYield__factory.ts +0 -5
- package/typechain-types/factories/OwnableUpgradeable__factory.ts +78 -0
- package/typechain-types/factories/PendleAaveV3SCY__factory.ts +1 -6
- package/typechain-types/factories/PendleBenQiErc20SCY__factory.ts +1 -6
- package/typechain-types/factories/PendleBtrflyScy__factory.ts +1 -6
- package/typechain-types/factories/PendleMarketFactory__factory.ts +1 -1
- package/typechain-types/factories/PendleMarket__factory.ts +9 -3
- package/typechain-types/factories/PendleRouterCoreUpg__factory.ts +26 -11
- package/typechain-types/factories/PendleRouterProxy__factory.ts +14 -67
- package/typechain-types/factories/PendleRouterStaticUpg__factory.ts +63 -17
- package/typechain-types/factories/PendleRouterYTUpg__factory.ts +66 -7
- package/typechain-types/factories/PendleYearnVaultScy__factory.ts +1 -6
- package/typechain-types/factories/PendleYieldContractFactory__factory.ts +39 -54
- package/typechain-types/factories/PendleYieldToken__factory.ts +53 -2
- package/typechain-types/factories/PermissionsV2Upg__factory.ts +39 -0
- package/typechain-types/factories/SCYBaseWithRewards__factory.ts +0 -5
- package/typechain-types/factories/SCYBase__factory.ts +0 -5
- package/typechain-types/hardhat.d.ts +26 -53
- package/typechain-types/index.ts +8 -14
- package/contracts/core/misc/BoringOwnable.sol +0 -62
- package/contracts/core/misc/BoringOwnableUpg.sol +0 -64
- package/contracts/libraries/math/FixedPoint.sol +0 -205
- package/contracts/libraries/math/MarketMathLib.sol +0 -614
|
@@ -1,140 +1,382 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
2
|
pragma solidity 0.8.9;
|
|
3
3
|
|
|
4
|
-
import "./
|
|
5
|
-
import "./
|
|
4
|
+
import "./Math.sol";
|
|
5
|
+
import "./MarketMathCore.sol";
|
|
6
|
+
import "./MarketMathCore.sol";
|
|
7
|
+
|
|
8
|
+
struct ApproxParams {
|
|
9
|
+
uint256 guessMin;
|
|
10
|
+
uint256 guessMax;
|
|
11
|
+
uint256 maxIteration;
|
|
12
|
+
uint256 eps;
|
|
13
|
+
}
|
|
6
14
|
|
|
7
15
|
// solhint-disable reason-string, ordering
|
|
8
16
|
library MarketApproxLib {
|
|
9
|
-
using
|
|
10
|
-
using
|
|
17
|
+
using Math for uint256;
|
|
18
|
+
using Math for int256;
|
|
11
19
|
using LogExpMath for int256;
|
|
12
20
|
using SCYIndexLib for SCYIndex;
|
|
13
|
-
using
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
uint256
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
using MarketMathCore for MarketState;
|
|
22
|
+
|
|
23
|
+
function approxSwapOtForExactScy(
|
|
24
|
+
MarketState memory market,
|
|
25
|
+
SCYIndex index,
|
|
26
|
+
uint256 minScyOut,
|
|
27
|
+
uint256 blockTime,
|
|
28
|
+
ApproxParams memory approx
|
|
29
|
+
)
|
|
30
|
+
internal
|
|
31
|
+
pure
|
|
32
|
+
returns (
|
|
33
|
+
uint256, /*netOtIn*/
|
|
34
|
+
uint256 /*netScyOut*/
|
|
35
|
+
)
|
|
36
|
+
{
|
|
37
|
+
/// ------------------------------------------------------------
|
|
38
|
+
/// CHECKS
|
|
39
|
+
/// ------------------------------------------------------------
|
|
40
|
+
require(minScyOut > 0, "invalid minScyOut");
|
|
41
|
+
require(isValidApproxParams(approx), "invalid approx approx");
|
|
42
|
+
|
|
43
|
+
/// ------------------------------------------------------------
|
|
44
|
+
/// SET UP VAIRBALES
|
|
45
|
+
/// ------------------------------------------------------------
|
|
46
|
+
uint256 minAssetOut = index.scyToAsset(minScyOut);
|
|
47
|
+
uint256 largestGoodSlope;
|
|
48
|
+
bool isSlopeNonNeg;
|
|
49
|
+
|
|
50
|
+
MarketPreCompute memory comp = market.getMarketPreCompute(index, blockTime);
|
|
51
|
+
|
|
52
|
+
if (approx.guessMax == type(uint256).max) {
|
|
53
|
+
approx.guessMax = calcMaxOtIn(market.totalOt, comp.totalAsset);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/// ------------------------------------------------------------
|
|
57
|
+
/// BINARY SEARCH
|
|
58
|
+
/// ------------------------------------------------------------
|
|
59
|
+
|
|
60
|
+
while (approx.maxIteration != 0) {
|
|
61
|
+
unchecked {
|
|
62
|
+
approx.maxIteration--;
|
|
63
|
+
}
|
|
64
|
+
uint256 otInGuess = (approx.guessMin + approx.guessMax) / 2;
|
|
65
|
+
|
|
66
|
+
/// ------------------------------------------------------------
|
|
67
|
+
/// CHECK SLOPE
|
|
68
|
+
/// ------------------------------------------------------------
|
|
69
|
+
(isSlopeNonNeg, largestGoodSlope) = updateSlope(
|
|
70
|
+
market.totalOt,
|
|
71
|
+
otInGuess,
|
|
72
|
+
comp,
|
|
73
|
+
largestGoodSlope
|
|
74
|
+
);
|
|
75
|
+
if (!isSlopeNonNeg) {
|
|
76
|
+
approx.guessMax = otInGuess;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/// ------------------------------------------------------------
|
|
81
|
+
/// CHECK ASSET
|
|
82
|
+
/// ------------------------------------------------------------
|
|
83
|
+
(int256 _assetToAccount, ) = market.calcTrade(comp, otInGuess.neg());
|
|
84
|
+
uint256 netAssetOut = _assetToAccount.Uint();
|
|
85
|
+
|
|
86
|
+
if (netAssetOut >= minAssetOut) {
|
|
87
|
+
approx.guessMax = otInGuess;
|
|
88
|
+
/// ------------------------------------------------------------
|
|
89
|
+
/// CHECK IF ANSWER FOUND
|
|
90
|
+
/// ------------------------------------------------------------
|
|
91
|
+
if (Math.isAGreaterApproxB(netAssetOut, minAssetOut, approx.eps)) {
|
|
92
|
+
return (otInGuess, index.assetToScy(netAssetOut));
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
approx.guessMin = otInGuess + 1;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
revert("approx fail");
|
|
25
99
|
}
|
|
26
100
|
|
|
27
101
|
function approxSwapExactScyForOt(
|
|
28
|
-
|
|
102
|
+
MarketState memory market,
|
|
29
103
|
SCYIndex index,
|
|
30
|
-
uint256
|
|
104
|
+
uint256 maxScyIn,
|
|
31
105
|
uint256 blockTime,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
)
|
|
106
|
+
ApproxParams memory approx
|
|
107
|
+
)
|
|
108
|
+
internal
|
|
109
|
+
pure
|
|
110
|
+
returns (
|
|
111
|
+
uint256, /*netOtOut*/
|
|
112
|
+
uint256 /*netScyIn*/
|
|
113
|
+
)
|
|
114
|
+
{
|
|
115
|
+
/// ------------------------------------------------------------
|
|
116
|
+
/// CHECKS
|
|
117
|
+
/// ------------------------------------------------------------
|
|
118
|
+
require(maxScyIn > 0, "invalid maxScyIn");
|
|
119
|
+
require(isValidApproxParams(approx), "invalid approx approx");
|
|
120
|
+
|
|
121
|
+
/// ------------------------------------------------------------
|
|
122
|
+
/// SET UP VAIRBALES
|
|
123
|
+
/// ------------------------------------------------------------
|
|
124
|
+
uint256 maxAssetIn = index.scyToAsset(maxScyIn);
|
|
125
|
+
|
|
126
|
+
MarketPreCompute memory comp = market.getMarketPreCompute(index, blockTime);
|
|
40
127
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
128
|
+
if (approx.guessMax == type(uint256).max) {
|
|
129
|
+
approx.guessMax = calcMaxOtOut(market.totalOt, comp);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/// ------------------------------------------------------------
|
|
133
|
+
/// BINARY SEARCH
|
|
134
|
+
/// ------------------------------------------------------------
|
|
135
|
+
|
|
136
|
+
while (approx.maxIteration != 0) {
|
|
137
|
+
unchecked {
|
|
138
|
+
approx.maxIteration--;
|
|
139
|
+
}
|
|
140
|
+
uint256 otOutGuess = (approx.guessMin + approx.guessMax + 1) / 2;
|
|
44
141
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
142
|
+
/// ------------------------------------------------------------
|
|
143
|
+
/// CHECK ASSET
|
|
144
|
+
/// ------------------------------------------------------------
|
|
145
|
+
(int256 _assetToAccount, ) = market.calcTrade(comp, otOutGuess.Int());
|
|
146
|
+
uint256 netAssetIn = _assetToAccount.neg().Uint();
|
|
48
147
|
|
|
49
|
-
(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
148
|
+
if (netAssetIn <= maxAssetIn) {
|
|
149
|
+
approx.guessMin = otOutGuess;
|
|
150
|
+
/// ------------------------------------------------------------
|
|
151
|
+
/// CHECK IF ANSWER FOUND
|
|
152
|
+
/// ------------------------------------------------------------
|
|
153
|
+
if (Math.isASmallerApproxB(netAssetIn, maxAssetIn, approx.eps)) {
|
|
154
|
+
return (otOutGuess, index.assetToScy(netAssetIn));
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
approx.guessMax = otOutGuess - 1;
|
|
158
|
+
}
|
|
55
159
|
}
|
|
160
|
+
revert("approx fail");
|
|
161
|
+
}
|
|
56
162
|
|
|
57
|
-
|
|
58
|
-
|
|
163
|
+
struct SlotSwapExactScyForYt {
|
|
164
|
+
uint256 otInGuess;
|
|
165
|
+
int256 _assetToAccount;
|
|
166
|
+
uint256 netAssetOut;
|
|
167
|
+
uint256 amountAssetNeedMore;
|
|
59
168
|
}
|
|
60
169
|
|
|
61
|
-
function
|
|
62
|
-
|
|
170
|
+
function approxSwapExactScyForYt(
|
|
171
|
+
MarketState memory market,
|
|
63
172
|
SCYIndex index,
|
|
64
|
-
uint256
|
|
173
|
+
uint256 maxScyIn,
|
|
65
174
|
uint256 blockTime,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
)
|
|
175
|
+
ApproxParams memory approx
|
|
176
|
+
)
|
|
177
|
+
internal
|
|
178
|
+
pure
|
|
179
|
+
returns (
|
|
180
|
+
uint256, /*netYtOut*/
|
|
181
|
+
uint256 /*netScyIn*/
|
|
182
|
+
)
|
|
183
|
+
{
|
|
184
|
+
/// ------------------------------------------------------------
|
|
185
|
+
/// CHECKS
|
|
186
|
+
/// ------------------------------------------------------------
|
|
187
|
+
require(maxScyIn > 0, "invalid maxScyIn");
|
|
188
|
+
require(isValidApproxParams(approx), "invalid approx approx");
|
|
189
|
+
|
|
190
|
+
/// ------------------------------------------------------------
|
|
191
|
+
/// SET UP VAIRBALES
|
|
192
|
+
/// ------------------------------------------------------------
|
|
193
|
+
uint256 maxAssetIn = index.scyToAsset(maxScyIn);
|
|
194
|
+
uint256 largestGoodSlope;
|
|
195
|
+
bool isSlopeNonNeg;
|
|
196
|
+
|
|
197
|
+
MarketPreCompute memory comp = market.getMarketPreCompute(index, blockTime);
|
|
74
198
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
199
|
+
if (approx.guessMax == type(uint256).max) {
|
|
200
|
+
approx.guessMax = calcMaxOtIn(market.totalOt, comp.totalAsset);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/// ------------------------------------------------------------
|
|
204
|
+
/// BINARY SEARCH
|
|
205
|
+
/// ------------------------------------------------------------
|
|
206
|
+
|
|
207
|
+
while (approx.maxIteration != 0) {
|
|
208
|
+
unchecked {
|
|
209
|
+
approx.maxIteration--;
|
|
210
|
+
}
|
|
78
211
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
212
|
+
SlotSwapExactScyForYt memory slot;
|
|
213
|
+
// ytOutGuess = otInGuess
|
|
214
|
+
slot.otInGuess = (approx.guessMin + approx.guessMax + 1) / 2;
|
|
82
215
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
216
|
+
/// ------------------------------------------------------------
|
|
217
|
+
/// CHECK SLOPE
|
|
218
|
+
/// ------------------------------------------------------------
|
|
219
|
+
(isSlopeNonNeg, largestGoodSlope) = updateSlope(
|
|
220
|
+
market.totalOt,
|
|
221
|
+
slot.otInGuess,
|
|
222
|
+
comp,
|
|
223
|
+
largestGoodSlope
|
|
87
224
|
);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
225
|
+
if (!isSlopeNonNeg) {
|
|
226
|
+
approx.guessMax = slot.otInGuess - 1;
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/// ------------------------------------------------------------
|
|
231
|
+
/// CHECK ASSET
|
|
232
|
+
/// ------------------------------------------------------------
|
|
233
|
+
(slot._assetToAccount, ) = market.calcTrade(comp, slot.otInGuess.neg());
|
|
234
|
+
slot.netAssetOut = slot._assetToAccount.Uint();
|
|
235
|
+
slot.amountAssetNeedMore = slot.otInGuess - slot.netAssetOut;
|
|
236
|
+
|
|
237
|
+
if (slot.amountAssetNeedMore <= maxAssetIn) {
|
|
238
|
+
approx.guessMin = slot.otInGuess;
|
|
239
|
+
/// ------------------------------------------------------------
|
|
240
|
+
/// CHECK IF ANSWER FOUND
|
|
241
|
+
/// ------------------------------------------------------------
|
|
242
|
+
if (Math.isASmallerApproxB(slot.amountAssetNeedMore, maxAssetIn, approx.eps)) {
|
|
243
|
+
return (slot.otInGuess, index.assetToScy(slot.amountAssetNeedMore));
|
|
244
|
+
}
|
|
92
245
|
} else {
|
|
93
|
-
|
|
246
|
+
approx.guessMax = slot.otInGuess - 1;
|
|
94
247
|
}
|
|
95
248
|
}
|
|
96
|
-
|
|
97
|
-
require(isAcceptableAnswerExisted, "guess fail");
|
|
98
|
-
netOtIn = high;
|
|
249
|
+
revert("approx fail");
|
|
99
250
|
}
|
|
100
251
|
|
|
101
|
-
function
|
|
102
|
-
|
|
252
|
+
function approxSwapYtForExactScy(
|
|
253
|
+
MarketState memory market,
|
|
103
254
|
SCYIndex index,
|
|
104
|
-
uint256
|
|
255
|
+
uint256 minScyOut,
|
|
105
256
|
uint256 blockTime,
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
257
|
+
ApproxParams memory approx
|
|
258
|
+
)
|
|
259
|
+
internal
|
|
260
|
+
pure
|
|
261
|
+
returns (
|
|
262
|
+
uint256, /*netYtIn*/
|
|
263
|
+
uint256 /*netScyOut*/
|
|
264
|
+
)
|
|
265
|
+
{
|
|
266
|
+
/// ------------------------------------------------------------
|
|
267
|
+
/// CHECKS
|
|
268
|
+
/// ------------------------------------------------------------
|
|
269
|
+
require(minScyOut > 0, "invalid maxScyIn");
|
|
270
|
+
require(isValidApproxParams(approx), "invalid approx approx");
|
|
271
|
+
|
|
272
|
+
/// ------------------------------------------------------------
|
|
273
|
+
/// SET UP VAIRBALES
|
|
274
|
+
/// ------------------------------------------------------------
|
|
275
|
+
uint256 minAssetOut = index.scyToAsset(minScyOut);
|
|
111
276
|
|
|
112
|
-
|
|
277
|
+
MarketPreCompute memory comp = market.getMarketPreCompute(index, blockTime);
|
|
113
278
|
|
|
114
|
-
|
|
115
|
-
|
|
279
|
+
if (approx.guessMax == type(uint256).max) {
|
|
280
|
+
approx.guessMax = calcMaxOtOut(market.totalOt, comp);
|
|
281
|
+
}
|
|
116
282
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
283
|
+
/// ------------------------------------------------------------
|
|
284
|
+
/// BINARY SEARCH
|
|
285
|
+
/// ------------------------------------------------------------
|
|
120
286
|
|
|
121
|
-
|
|
287
|
+
while (approx.maxIteration != 0) {
|
|
288
|
+
unchecked {
|
|
289
|
+
approx.maxIteration--;
|
|
290
|
+
}
|
|
291
|
+
// ytInGuess = otOutGuess
|
|
292
|
+
uint256 otOutGuess = (approx.guessMin + approx.guessMax) / 2;
|
|
122
293
|
|
|
123
|
-
|
|
294
|
+
/// ------------------------------------------------------------
|
|
295
|
+
/// CHECK ASSET
|
|
296
|
+
/// ------------------------------------------------------------
|
|
297
|
+
(int256 _assetToAccount, ) = market.calcTrade(comp, otOutGuess.Int());
|
|
298
|
+
uint256 netAssetOwed = _assetToAccount.neg().Uint();
|
|
124
299
|
|
|
125
|
-
|
|
300
|
+
// since otOutGuess is between guessMin & guessMax, it's guaranteed that
|
|
301
|
+
// there are enough Yt to pair with otOut
|
|
126
302
|
|
|
127
|
-
|
|
303
|
+
uint256 netAssetOut = otOutGuess - netAssetOwed;
|
|
128
304
|
|
|
129
|
-
|
|
305
|
+
if (netAssetOut >= minAssetOut) {
|
|
306
|
+
approx.guessMax = otOutGuess;
|
|
307
|
+
/// ------------------------------------------------------------
|
|
308
|
+
/// CHECK IF ANSWER FOUND
|
|
309
|
+
/// ------------------------------------------------------------
|
|
310
|
+
if (Math.isAGreaterApproxB(netAssetOut, minAssetOut, approx.eps)) {
|
|
311
|
+
return (otOutGuess, index.assetToScy(netAssetOut));
|
|
312
|
+
}
|
|
313
|
+
} else {
|
|
314
|
+
approx.guessMin = otOutGuess + 1;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
revert("approx fail");
|
|
318
|
+
}
|
|
130
319
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
320
|
+
function updateSlope(
|
|
321
|
+
int256 totalOt,
|
|
322
|
+
uint256 otInGuess,
|
|
323
|
+
MarketPreCompute memory comp,
|
|
324
|
+
uint256 largestGoodSlope
|
|
325
|
+
) internal pure returns (bool isSlopeNonNeg, uint256 newLargestGoodSlop) {
|
|
326
|
+
if (otInGuess <= largestGoodSlope) {
|
|
327
|
+
return (true, largestGoodSlope);
|
|
135
328
|
}
|
|
329
|
+
// it's not guaranteed that the current slop is good
|
|
330
|
+
// we therefore have to recalculate the slope
|
|
331
|
+
int256 slope = slopeFactor(totalOt, otInGuess.neg(), comp);
|
|
332
|
+
if (slope >= 0) return (true, otInGuess);
|
|
333
|
+
else return (false, largestGoodSlope);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// otToMarket < totalAsset && totalOt
|
|
337
|
+
function slopeFactor(
|
|
338
|
+
int256 totalOt,
|
|
339
|
+
int256 otToAccount,
|
|
340
|
+
MarketPreCompute memory comp
|
|
341
|
+
) internal pure returns (int256) {
|
|
342
|
+
int256 otToMarket = -otToAccount;
|
|
343
|
+
int256 diffAssetOtToMarket = comp.totalAsset - otToMarket;
|
|
344
|
+
int256 sumOt = otToMarket + totalOt;
|
|
345
|
+
|
|
346
|
+
require(diffAssetOtToMarket > 0 && sumOt > 0, "invalid otToMarket");
|
|
347
|
+
|
|
348
|
+
int256 part1 = (otToMarket * (totalOt + comp.totalAsset)).divDown(
|
|
349
|
+
sumOt * diffAssetOtToMarket
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
int256 part2 = sumOt.divDown(diffAssetOtToMarket).ln();
|
|
353
|
+
int256 part3 = Math.IONE.divDown(comp.rateScalar);
|
|
354
|
+
|
|
355
|
+
return comp.rateAnchor - (part1 - part2).mulDown(part3);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function calcMaxOtOut(int256 totalOt, MarketPreCompute memory comp)
|
|
359
|
+
internal
|
|
360
|
+
pure
|
|
361
|
+
returns (uint256)
|
|
362
|
+
{
|
|
363
|
+
int256 logitP = (Math.IONE.mulDown(comp.feeRate) - comp.rateAnchor)
|
|
364
|
+
.mulDown(comp.rateScalar)
|
|
365
|
+
.exp();
|
|
366
|
+
int256 proportion = logitP.divDown(logitP + Math.IONE);
|
|
367
|
+
int256 numerator = proportion.mulDown(totalOt + comp.totalAsset);
|
|
368
|
+
int256 maxOtOut = totalOt - numerator;
|
|
369
|
+
// TODO: 999 & 1000 are magic numbers
|
|
370
|
+
return (maxOtOut.Uint() * 999) / 1000;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function calcMaxOtIn(int256 totalOt, int256 totalAsset) internal pure returns (uint256) {
|
|
374
|
+
return Math.min(totalOt, totalAsset).Uint() - 1;
|
|
375
|
+
}
|
|
136
376
|
|
|
137
|
-
|
|
138
|
-
|
|
377
|
+
function isValidApproxParams(ApproxParams memory approx) internal pure returns (bool) {
|
|
378
|
+
return (approx.guessMin <= approx.guessMax &&
|
|
379
|
+
approx.maxIteration <= 256 &&
|
|
380
|
+
approx.eps <= Math.ONE);
|
|
139
381
|
}
|
|
140
382
|
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
pragma solidity 0.8.9;
|
|
3
|
+
|
|
4
|
+
import "./Math.sol";
|
|
5
|
+
import "./LogExpMath.sol";
|
|
6
|
+
import "../SCYIndex.sol";
|
|
7
|
+
import "./MarketMathCore.sol";
|
|
8
|
+
|
|
9
|
+
// solhint-disable ordering
|
|
10
|
+
library MarketMathAux {
|
|
11
|
+
using Math for uint256;
|
|
12
|
+
using Math for int256;
|
|
13
|
+
|
|
14
|
+
function addLiquidity(
|
|
15
|
+
MarketState memory market,
|
|
16
|
+
SCYIndex index,
|
|
17
|
+
uint256 scyDesired,
|
|
18
|
+
uint256 otDesired,
|
|
19
|
+
bool updateState
|
|
20
|
+
)
|
|
21
|
+
internal
|
|
22
|
+
pure
|
|
23
|
+
returns (
|
|
24
|
+
uint256 lpToReserve,
|
|
25
|
+
uint256 lpToAccount,
|
|
26
|
+
uint256 scyUsed,
|
|
27
|
+
uint256 otUsed
|
|
28
|
+
)
|
|
29
|
+
{
|
|
30
|
+
(
|
|
31
|
+
int256 _lpToReserve,
|
|
32
|
+
int256 _lpToAccount,
|
|
33
|
+
int256 _scyUsed,
|
|
34
|
+
int256 _otUsed
|
|
35
|
+
) = MarketMathCore.addLiquidityCore(
|
|
36
|
+
market,
|
|
37
|
+
index,
|
|
38
|
+
scyDesired.Int(),
|
|
39
|
+
otDesired.Int(),
|
|
40
|
+
updateState
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
lpToReserve = _lpToReserve.Uint();
|
|
44
|
+
lpToAccount = _lpToAccount.Uint();
|
|
45
|
+
scyUsed = _scyUsed.Uint();
|
|
46
|
+
otUsed = _otUsed.Uint();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function removeLiquidity(
|
|
50
|
+
MarketState memory market,
|
|
51
|
+
uint256 lpToRemove,
|
|
52
|
+
bool updateState
|
|
53
|
+
) internal pure returns (uint256 scyToAccount, uint256 netOtToAccount) {
|
|
54
|
+
(int256 _scyToAccount, int256 _otToAccount) = MarketMathCore.removeLiquidityCore(
|
|
55
|
+
market,
|
|
56
|
+
lpToRemove.Int(),
|
|
57
|
+
updateState
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
scyToAccount = _scyToAccount.Uint();
|
|
61
|
+
netOtToAccount = _otToAccount.Uint();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function swapExactOtForScy(
|
|
65
|
+
MarketState memory market,
|
|
66
|
+
SCYIndex index,
|
|
67
|
+
uint256 exactOtToMarket,
|
|
68
|
+
uint256 blockTime,
|
|
69
|
+
bool updateState
|
|
70
|
+
) internal pure returns (uint256 netScyToAccount, uint256 netScyToReserve) {
|
|
71
|
+
(int256 _netScyToAccount, int256 _netScyToReserve) = MarketMathCore.executeTradeCore(
|
|
72
|
+
market,
|
|
73
|
+
index,
|
|
74
|
+
exactOtToMarket.neg(),
|
|
75
|
+
blockTime,
|
|
76
|
+
updateState
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
netScyToAccount = _netScyToAccount.Uint();
|
|
80
|
+
netScyToReserve = _netScyToReserve.Uint();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function swapScyForExactOt(
|
|
84
|
+
MarketState memory market,
|
|
85
|
+
SCYIndex index,
|
|
86
|
+
uint256 exactOtToAccount,
|
|
87
|
+
uint256 blockTime,
|
|
88
|
+
bool updateState
|
|
89
|
+
) internal pure returns (uint256 netScyToMarket, uint256 netScyToReserve) {
|
|
90
|
+
(int256 _netScyToAccount, int256 _netScyToReserve) = MarketMathCore.executeTradeCore(
|
|
91
|
+
market,
|
|
92
|
+
index,
|
|
93
|
+
exactOtToAccount.Int(),
|
|
94
|
+
blockTime,
|
|
95
|
+
updateState
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
netScyToMarket = _netScyToAccount.neg().Uint();
|
|
99
|
+
netScyToReserve = _netScyToReserve.Uint();
|
|
100
|
+
}
|
|
101
|
+
}
|