@pendle/core-v2 0.11.8-testnet → 0.11.10-testnet
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/SuperComposableYield/SCY-implementations/AaveV3/PendleAaveV3SCY.sol/PendleAaveV3SCY.dbg.json +1 -1
- package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/AaveV3/WadRayMath.sol/WadRayMath.dbg.json +1 -1
- package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/BenQi/PendleQiSAvaxSCY.sol/PendleQiSAvaxSCY.dbg.json +1 -1
- package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/BenQi/PendleQiTokenSCY.sol/PendleQiTokenSCY.dbg.json +1 -1
- package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/BenQi/PendleSAvaxSCY.sol/PendleSAvaxSCY.dbg.json +1 -1
- package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/Euler/PendleEulerSCY.sol/PendleEulerSCY.dbg.json +1 -1
- package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/PendleERC4626SCY.sol/PendleERC4626SCY.dbg.json +1 -1
- package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/PendleStargateSCY.sol/PendleStargateSCY.dbg.json +1 -1
- package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/PendleWstEthSCY.sol/PendleWstEthSCY.dbg.json +1 -1
- package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/PendleYearnVaultSCY.sol/PendleYearnVaultSCY.dbg.json +1 -1
- package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/TraderJoe/PendleSJoeSCY.sol/PendleSJoeSCY.dbg.json +1 -1
- package/build/artifacts/contracts/SuperComposableYield/base-implementations/SCYBase.sol/SCYBase.dbg.json +1 -1
- package/build/artifacts/contracts/SuperComposableYield/base-implementations/SCYBaseWithRewards.sol/SCYBaseWithRewards.dbg.json +1 -1
- package/build/artifacts/contracts/core/LiquidityMining/CelerAbstracts/CelerReceiverUpg.sol/CelerReceiverUpg.dbg.json +1 -1
- package/build/artifacts/contracts/core/LiquidityMining/CelerAbstracts/CelerSenderUpg.sol/CelerSenderUpg.dbg.json +1 -1
- package/build/artifacts/contracts/core/LiquidityMining/GaugeController/PendleGaugeControllerBaseUpg.sol/PendleGaugeControllerBaseUpg.dbg.json +1 -1
- package/build/artifacts/contracts/core/LiquidityMining/GaugeController/PendleGaugeControllerMainchainUpg.sol/PendleGaugeControllerMainchainUpg.dbg.json +1 -1
- package/build/artifacts/contracts/core/LiquidityMining/GaugeController/PendleGaugeControllerSidechainUpg.sol/PendleGaugeControllerSidechainUpg.dbg.json +1 -1
- package/build/artifacts/contracts/core/LiquidityMining/PendleGauge.sol/PendleGauge.dbg.json +1 -1
- package/build/artifacts/contracts/core/LiquidityMining/VotingController/PendleVotingControllerUpg.sol/PendleVotingControllerUpg.dbg.json +1 -1
- package/build/artifacts/contracts/core/LiquidityMining/VotingController/VotingControllerStorageUpg.sol/VotingControllerStorageUpg.dbg.json +1 -1
- package/build/artifacts/contracts/core/LiquidityMining/VotingEscrow/VotingEscrowPendleMainchain.sol/VotingEscrowPendleMainchain.dbg.json +1 -1
- package/build/artifacts/contracts/core/LiquidityMining/VotingEscrow/VotingEscrowPendleMainchain.sol/VotingEscrowPendleMainchain.json +2 -2
- package/build/artifacts/contracts/core/LiquidityMining/VotingEscrow/VotingEscrowPendleSidechain.sol/VotingEscrowPendleSidechain.dbg.json +1 -1
- package/build/artifacts/contracts/core/LiquidityMining/VotingEscrow/VotingEscrowTokenBase.sol/VotingEscrowTokenBase.dbg.json +1 -1
- package/build/artifacts/contracts/core/Market/PendleMarket.sol/PendleMarket.dbg.json +1 -1
- package/build/artifacts/contracts/core/Market/PendleMarketFactory.sol/PendleMarketFactory.dbg.json +1 -1
- package/build/artifacts/contracts/core/PendleRouter.sol/PendleRouter.dbg.json +1 -1
- package/build/artifacts/contracts/core/PendleRouter.sol/PendleRouter.json +20 -2
- package/build/artifacts/contracts/core/YieldContracts/InterestManagerYT.sol/InterestManagerYT.dbg.json +1 -1
- package/build/artifacts/contracts/core/YieldContracts/PendlePrincipalToken.sol/PendlePrincipalToken.dbg.json +1 -1
- package/build/artifacts/contracts/core/YieldContracts/PendleYieldContractFactory.sol/PendleYieldContractFactory.dbg.json +1 -1
- package/build/artifacts/contracts/core/YieldContracts/PendleYieldToken.sol/PendleYieldToken.dbg.json +1 -1
- package/build/artifacts/contracts/core/actions/ActionAddRemoveLiq.sol/ActionAddRemoveLiq.dbg.json +1 -1
- package/build/artifacts/contracts/core/actions/ActionAddRemoveLiq.sol/ActionAddRemoveLiq.json +4 -4
- package/build/artifacts/contracts/core/actions/ActionCallback.sol/ActionCallback.dbg.json +1 -1
- package/build/artifacts/contracts/core/actions/ActionCallback.sol/ActionCallback.json +2 -2
- package/build/artifacts/contracts/core/actions/ActionMintRedeem.sol/ActionMintRedeem.dbg.json +1 -1
- package/build/artifacts/contracts/core/actions/ActionMintRedeem.sol/ActionMintRedeem.json +2 -2
- package/build/artifacts/contracts/core/actions/ActionMisc.sol/ActionMisc.dbg.json +1 -1
- package/build/artifacts/contracts/core/actions/ActionSwapPT.sol/ActionSwapPT.dbg.json +1 -1
- package/build/artifacts/contracts/core/actions/ActionSwapPT.sol/ActionSwapPT.json +2 -2
- package/build/artifacts/contracts/core/actions/ActionSwapPTYT.sol/ActionSwapPTYT.dbg.json +4 -0
- package/build/artifacts/contracts/core/actions/ActionSwapPTYT.sol/ActionSwapPTYT.json +185 -0
- package/build/artifacts/contracts/core/actions/ActionSwapYT.sol/ActionSwapYT.dbg.json +1 -1
- package/build/artifacts/contracts/core/actions/ActionSwapYT.sol/ActionSwapYT.json +2 -2
- package/build/artifacts/contracts/core/actions/base/ActionBaseMintRedeem.sol/ActionBaseMintRedeem.dbg.json +1 -1
- package/build/artifacts/contracts/core/actions/base/CallbackHelper.sol/CallbackHelper.dbg.json +1 -1
- package/build/artifacts/contracts/interfaces/IPActionAddRemoveLiq.sol/IPActionAddRemoveLiq.dbg.json +1 -1
- package/build/artifacts/contracts/interfaces/IPActionMintRedeem.sol/IPActionMintRedeem.dbg.json +1 -1
- package/build/artifacts/contracts/interfaces/IPActionSwapPT.sol/IPActionSwapPT.dbg.json +1 -1
- package/build/artifacts/contracts/interfaces/IPActionSwapPTYT.sol/IPActionSwapPTYT.dbg.json +4 -0
- package/build/artifacts/contracts/interfaces/IPActionSwapPTYT.sol/IPActionSwapPTYT.json +180 -0
- package/build/artifacts/contracts/interfaces/IPActionSwapYT.sol/IPActionSwapYT.dbg.json +1 -1
- package/build/artifacts/contracts/interfaces/IPAllAction.sol/IPAllAction.dbg.json +1 -1
- package/build/artifacts/contracts/interfaces/IPAllAction.sol/IPAllAction.json +169 -0
- package/build/artifacts/contracts/interfaces/IPMarket.sol/IPMarket.dbg.json +1 -1
- package/build/artifacts/contracts/interfaces/IPVotingController.sol/IPVotingController.dbg.json +1 -1
- package/build/artifacts/contracts/interfaces/IPVotingEscrow.sol/IPVotingEscrow.dbg.json +1 -1
- package/build/artifacts/contracts/interfaces/IPVotingEscrow.sol/IPVotingEscrow.json +93 -0
- package/build/artifacts/contracts/interfaces/ISuperComposableYield.sol/ISuperComposableYield.dbg.json +1 -1
- package/build/artifacts/contracts/libraries/RewardManager.sol/RewardManager.dbg.json +1 -1
- package/build/artifacts/contracts/libraries/RewardManagerAbstract.sol/RewardManagerAbstract.dbg.json +1 -1
- package/build/artifacts/contracts/libraries/VeBalanceLib.sol/VeBalanceLib.dbg.json +1 -1
- package/build/artifacts/contracts/libraries/VeHistoryLib.sol/Checkpoints.dbg.json +1 -1
- package/build/artifacts/contracts/libraries/helpers/PYIndex.sol/PYIndexLib.dbg.json +1 -1
- package/build/artifacts/contracts/libraries/helpers/SSTORE2Deployer.sol/SSTORE2Deployer.dbg.json +1 -1
- package/build/artifacts/contracts/libraries/kyberswap/AggregationRouterHelper.sol/AggregationRouterHelper.dbg.json +1 -1
- package/build/artifacts/contracts/libraries/kyberswap/KyberSwapHelper.sol/KyberSwapHelper.dbg.json +1 -1
- package/build/artifacts/contracts/libraries/math/MarketApproxLib.sol/MarketApproxPtInLib.dbg.json +1 -1
- package/build/artifacts/contracts/libraries/math/MarketApproxLib.sol/MarketApproxPtInLib.json +2 -2
- package/build/artifacts/contracts/libraries/math/MarketApproxLib.sol/MarketApproxPtOutLib.dbg.json +1 -1
- package/build/artifacts/contracts/libraries/math/MarketApproxLib.sol/MarketApproxPtOutLib.json +2 -2
- package/build/artifacts/contracts/libraries/math/MarketMathCore.sol/MarketMathCore.dbg.json +1 -1
- package/build/artifacts/contracts/libraries/math/Math.sol/Math.dbg.json +1 -1
- package/build/artifacts/contracts/libraries/math/WeekMath.sol/WeekMath.dbg.json +1 -1
- package/build/artifacts/contracts/libraries/solmate/SSTORE2.sol/SSTORE2.dbg.json +1 -1
- package/build/artifacts/contracts/offchain-helpers/MarketMathStatic.sol/MarketMathStatic.dbg.json +1 -1
- package/build/artifacts/contracts/offchain-helpers/MarketMathStatic.sol/MarketMathStatic.json +2 -2
- package/build/artifacts/contracts/offchain-helpers/RouterStatic.sol/RouterStatic.dbg.json +1 -1
- package/build/artifacts/contracts/offchain-helpers/RouterStatic.sol/RouterStatic.json +210 -56
- package/build/artifacts/contracts/offchain-helpers/SSTORE2DeployerContract.sol/SSTORE2DeployerContract.dbg.json +1 -1
- package/contracts/core/LiquidityMining/VotingEscrow/VotingEscrowPendleMainchain.sol +6 -1
- package/contracts/core/PendleRouter.sol +10 -1
- package/contracts/core/actions/ActionAddRemoveLiq.sol +23 -2
- package/contracts/core/actions/ActionCallback.sol +39 -0
- package/contracts/core/actions/ActionSwapPTYT.sol +86 -0
- package/contracts/core/actions/base/CallbackHelper.sol +49 -1
- package/contracts/interfaces/IPActionSwapPTYT.sol +31 -0
- package/contracts/interfaces/IPAllAction.sol +2 -0
- package/contracts/interfaces/IPVotingEscrow.sol +1 -1
- package/contracts/libraries/math/MarketApproxLib.sol +117 -0
- package/contracts/offchain-helpers/MarketMathStatic.sol +69 -8
- package/contracts/offchain-helpers/RouterStatic.sol +76 -3
- package/deployments/43113-core.json +1 -1
- package/package.json +1 -3
- package/typechain-types/ActionSwapPTYT.ts +233 -0
- package/typechain-types/IPActionSwapPTYT.ts +233 -0
- package/typechain-types/IPAllAction.ts +138 -0
- package/typechain-types/IPVotingEscrow.ts +131 -0
- package/typechain-types/PendleFeeDistributorFactory.ts +97 -8
- package/typechain-types/PendleRouter.ts +19 -0
- package/typechain-types/RouterStatic.ts +174 -0
- package/typechain-types/factories/ActionAddRemoveLiq__factory.ts +1 -1
- package/typechain-types/factories/ActionCallback__factory.ts +1 -1
- package/typechain-types/factories/ActionMintRedeem__factory.ts +1 -1
- package/typechain-types/factories/ActionSwapPTYT__factory.ts +238 -0
- package/typechain-types/factories/ActionSwapPT__factory.ts +1 -1
- package/typechain-types/factories/ActionSwapYT__factory.ts +1 -1
- package/typechain-types/factories/IPActionSwapPTYT__factory.ts +195 -0
- package/typechain-types/factories/IPAllAction__factory.ts +169 -0
- package/typechain-types/factories/IPVotingEscrow__factory.ts +93 -0
- package/typechain-types/factories/MarketMathStatic__factory.ts +1 -1
- package/typechain-types/factories/PendleFeeDistributorFactory__factory.ts +81 -8
- package/typechain-types/factories/PendleFeeDistributor__factory.ts +1 -1
- package/typechain-types/factories/PendleMsgSendEndpointUpg__factory.ts +1 -1
- package/typechain-types/factories/PendleRouter__factory.ts +23 -1
- package/typechain-types/factories/RouterStatic__factory.ts +143 -1
- package/typechain-types/factories/VotingEscrowPendleMainchain__factory.ts +1 -1
- package/typechain-types/hardhat.d.ts +72 -117
- package/typechain-types/index.ts +16 -26
|
@@ -119,7 +119,12 @@ contract VotingEscrowPendleMainchain is IPVotingEscrow, VotingEscrowTokenBase, C
|
|
|
119
119
|
* @dev state changes expected:
|
|
120
120
|
- _totalSupply & lastSlopeChangeAppliedAt is updated
|
|
121
121
|
*/
|
|
122
|
-
function totalSupplyCurrent()
|
|
122
|
+
function totalSupplyCurrent()
|
|
123
|
+
public
|
|
124
|
+
virtual
|
|
125
|
+
override(IPVeToken, VotingEscrowTokenBase)
|
|
126
|
+
returns (uint128)
|
|
127
|
+
{
|
|
123
128
|
(VeBalance memory supply, ) = _applySlopeChange();
|
|
124
129
|
return supply.getCurrentValue();
|
|
125
130
|
}
|
|
@@ -17,6 +17,7 @@ contract PendleRouter is Proxy, Initializable, UUPSUpgradeable, BoringOwnableUpg
|
|
|
17
17
|
address public immutable ACTION_ADD_REMOVE_LIQ;
|
|
18
18
|
address public immutable ACTION_SWAP_PT;
|
|
19
19
|
address public immutable ACTION_SWAP_YT;
|
|
20
|
+
address public immutable ACTION_SWAP_PTYT;
|
|
20
21
|
address public immutable ACTION_CALLBACK;
|
|
21
22
|
address public immutable ACTION_MISC;
|
|
22
23
|
|
|
@@ -25,6 +26,7 @@ contract PendleRouter is Proxy, Initializable, UUPSUpgradeable, BoringOwnableUpg
|
|
|
25
26
|
address _ACTION_ADD_REMOVE_LIQ,
|
|
26
27
|
address _ACTION_SWAP_PT,
|
|
27
28
|
address _ACTION_SWAP_YT,
|
|
29
|
+
address _ACTION_SWAP_PTYT,
|
|
28
30
|
address _ACTION_CALLBACK,
|
|
29
31
|
address _ACTION_MISC
|
|
30
32
|
) initializer {
|
|
@@ -32,6 +34,7 @@ contract PendleRouter is Proxy, Initializable, UUPSUpgradeable, BoringOwnableUpg
|
|
|
32
34
|
ACTION_ADD_REMOVE_LIQ = _ACTION_ADD_REMOVE_LIQ;
|
|
33
35
|
ACTION_SWAP_PT = _ACTION_SWAP_PT;
|
|
34
36
|
ACTION_SWAP_YT = _ACTION_SWAP_YT;
|
|
37
|
+
ACTION_SWAP_PTYT = _ACTION_SWAP_PTYT;
|
|
35
38
|
ACTION_CALLBACK = _ACTION_CALLBACK;
|
|
36
39
|
ACTION_MISC = _ACTION_MISC;
|
|
37
40
|
}
|
|
@@ -48,7 +51,8 @@ contract PendleRouter is Proxy, Initializable, UUPSUpgradeable, BoringOwnableUpg
|
|
|
48
51
|
sig == IPActionMintRedeem.redeemPyToToken.selector ||
|
|
49
52
|
sig == IPActionMintRedeem.mintPyFromScy.selector ||
|
|
50
53
|
sig == IPActionMintRedeem.redeemPyToScy.selector ||
|
|
51
|
-
sig == IPActionMintRedeem.redeemDueInterestAndRewards.selector
|
|
54
|
+
sig == IPActionMintRedeem.redeemDueInterestAndRewards.selector ||
|
|
55
|
+
sig == IPActionMintRedeem.redeemDueInterestAndRewardsThenSwapAll.selector
|
|
52
56
|
) {
|
|
53
57
|
return ACTION_MINT_REDEEM;
|
|
54
58
|
} else if (
|
|
@@ -82,6 +86,11 @@ contract PendleRouter is Proxy, Initializable, UUPSUpgradeable, BoringOwnableUpg
|
|
|
82
86
|
sig == IPActionSwapYT.swapYtForExactScy.selector
|
|
83
87
|
) {
|
|
84
88
|
return ACTION_SWAP_YT;
|
|
89
|
+
} else if (
|
|
90
|
+
sig == IPActionSwapPTYT.swapExactPtForYt.selector ||
|
|
91
|
+
sig == IPActionSwapPTYT.swapExactYtForPt.selector
|
|
92
|
+
) {
|
|
93
|
+
return ACTION_SWAP_PTYT;
|
|
85
94
|
} else if (sig == IPMarketSwapCallback.swapCallback.selector) {
|
|
86
95
|
return ACTION_CALLBACK;
|
|
87
96
|
} else if (sig == IPActionMisc.consult.selector) {
|
|
@@ -369,6 +369,29 @@ contract ActionAddRemoveLiq is IPActionAddRemoveLiq, ActionBaseMintRedeem {
|
|
|
369
369
|
address market,
|
|
370
370
|
uint256 netLpToRemove,
|
|
371
371
|
uint256 minScyOut
|
|
372
|
+
) internal returns (uint256 netScyOut) {
|
|
373
|
+
if (IPMarket(market).isExpired()) {
|
|
374
|
+
netScyOut = __removeLpToScyAfterExpiry(receiver, market, netLpToRemove);
|
|
375
|
+
} else {
|
|
376
|
+
netScyOut = __removeLpToScyBeforeExpiry(receiver, market, netLpToRemove);
|
|
377
|
+
}
|
|
378
|
+
require(netScyOut >= minScyOut, "insufficient lp out");
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
function __removeLpToScyAfterExpiry(
|
|
382
|
+
address receiver,
|
|
383
|
+
address market,
|
|
384
|
+
uint256 netLpToRemove
|
|
385
|
+
) internal returns (uint256 netScyOut) {
|
|
386
|
+
(, , IPYieldToken YT) = IPMarket(market).readTokens();
|
|
387
|
+
(uint256 scyFromBurn, ) = IPMarket(market).burn(receiver, address(YT), netLpToRemove);
|
|
388
|
+
netScyOut = scyFromBurn + IPYieldToken(YT).redeemPY(receiver);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
function __removeLpToScyBeforeExpiry(
|
|
392
|
+
address receiver,
|
|
393
|
+
address market,
|
|
394
|
+
uint256 netLpToRemove
|
|
372
395
|
) internal returns (uint256 netScyOut) {
|
|
373
396
|
(uint256 scyFromBurn, uint256 ptFromBurn) = IPMarket(market).burn(
|
|
374
397
|
receiver,
|
|
@@ -380,8 +403,6 @@ contract ActionAddRemoveLiq is IPActionAddRemoveLiq, ActionBaseMintRedeem {
|
|
|
380
403
|
ptFromBurn,
|
|
381
404
|
EMPTY_BYTES
|
|
382
405
|
);
|
|
383
|
-
|
|
384
|
-
require(scyFromBurn + scyFromSwap >= minScyOut, "insufficient lp out");
|
|
385
406
|
netScyOut = scyFromBurn + scyFromSwap;
|
|
386
407
|
}
|
|
387
408
|
}
|
|
@@ -15,6 +15,7 @@ contract ActionCallback is IPMarketSwapCallback, CallbackHelper {
|
|
|
15
15
|
using Math for uint256;
|
|
16
16
|
using SafeERC20 for ISuperComposableYield;
|
|
17
17
|
using SafeERC20 for IPYieldToken;
|
|
18
|
+
using SafeERC20 for IPPrincipalToken;
|
|
18
19
|
using SafeERC20 for IERC20;
|
|
19
20
|
using PYIndexLib for PYIndex;
|
|
20
21
|
using PYIndexLib for IPYieldToken;
|
|
@@ -48,6 +49,10 @@ contract ActionCallback is IPMarketSwapCallback, CallbackHelper {
|
|
|
48
49
|
_callbackSwapScyForExactYt(market, ptToAccount, scyToAccount, data);
|
|
49
50
|
} else if (swapType == ActionType.SwapYtForScy) {
|
|
50
51
|
_callbackSwapYtForScy(market, ptToAccount, scyToAccount, data);
|
|
52
|
+
} else if (swapType == ActionType.SwapExactYtForPt) {
|
|
53
|
+
_callbackSwapExactYtForPt(market, ptToAccount, scyToAccount, data);
|
|
54
|
+
} else if (swapType == ActionType.SwapExactPtForYt) {
|
|
55
|
+
_callbackSwapExactPtForYt(market, ptToAccount, scyToAccount, data);
|
|
51
56
|
} else {
|
|
52
57
|
require(false, "unknown swapType");
|
|
53
58
|
}
|
|
@@ -137,4 +142,38 @@ contract ActionCallback is IPMarketSwapCallback, CallbackHelper {
|
|
|
137
142
|
uint256[] memory amountScyOuts = YT.redeemPYMulti(receivers, amountPYToRedeems);
|
|
138
143
|
require(amountScyOuts[1] >= minScyOut, "insufficient SCY out");
|
|
139
144
|
}
|
|
145
|
+
|
|
146
|
+
function _callbackSwapExactPtForYt(
|
|
147
|
+
address market,
|
|
148
|
+
int256 ptToAccount,
|
|
149
|
+
int256, /*scyToAccount*/
|
|
150
|
+
bytes calldata data
|
|
151
|
+
) internal {
|
|
152
|
+
(address receiver, uint256 exactPtIn, uint256 minYtOut) = _decodeSwapExactPtForYt(data);
|
|
153
|
+
uint256 netPtOwed = ptToAccount.abs();
|
|
154
|
+
(, , IPYieldToken YT) = IPMarket(market).readTokens();
|
|
155
|
+
|
|
156
|
+
uint256 netPyOut = YT.mintPY(market, receiver);
|
|
157
|
+
require(netPyOut >= minYtOut, "insufficient YT out");
|
|
158
|
+
require(exactPtIn + netPyOut >= netPtOwed, "insufficient PT to pay");
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function _callbackSwapExactYtForPt(
|
|
162
|
+
address market,
|
|
163
|
+
int256 ptToAccount,
|
|
164
|
+
int256 scyToAccount,
|
|
165
|
+
bytes calldata data
|
|
166
|
+
) internal {
|
|
167
|
+
(address receiver, uint256 exactYtIn, uint256 minPtOut) = _decodeSwapExactYtForPt(data);
|
|
168
|
+
(, IPPrincipalToken PT, IPYieldToken YT) = IPMarket(market).readTokens();
|
|
169
|
+
|
|
170
|
+
uint256 netScyOwed = scyToAccount.abs();
|
|
171
|
+
|
|
172
|
+
PT.safeTransfer(address(YT), exactYtIn);
|
|
173
|
+
uint256 netScyToMarket = YT.redeemPY(market);
|
|
174
|
+
|
|
175
|
+
require(netScyToMarket >= netScyOwed, "insufficient SCY to pay");
|
|
176
|
+
require(ptToAccount.Uint() - exactYtIn >= minPtOut, "insufficient PT out");
|
|
177
|
+
PT.safeTransfer(receiver, ptToAccount.Uint() - exactYtIn);
|
|
178
|
+
}
|
|
140
179
|
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
pragma solidity 0.8.15;
|
|
3
|
+
|
|
4
|
+
import "../../interfaces/IPActionSwapPTYT.sol";
|
|
5
|
+
import "../../interfaces/IPMarket.sol";
|
|
6
|
+
import "./base/CallbackHelper.sol";
|
|
7
|
+
|
|
8
|
+
contract ActionSwapPTYT is IPActionSwapPTYT, CallbackHelper {
|
|
9
|
+
using MarketMathCore for MarketState;
|
|
10
|
+
using MarketApproxPtInLib for MarketState;
|
|
11
|
+
using MarketApproxPtOutLib for MarketState;
|
|
12
|
+
using Math for uint256;
|
|
13
|
+
using Math for int256;
|
|
14
|
+
using SafeERC20 for IERC20;
|
|
15
|
+
using PYIndexLib for IPYieldToken;
|
|
16
|
+
using SafeERC20 for ISuperComposableYield;
|
|
17
|
+
using SafeERC20 for IPYieldToken;
|
|
18
|
+
using SafeERC20 for IPPrincipalToken;
|
|
19
|
+
|
|
20
|
+
/// @dev since this contract will be proxied, it must not contains non-immutable variables
|
|
21
|
+
constructor() //solhint-disable-next-line no-empty-blocks
|
|
22
|
+
{
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function swapExactPtForYt(
|
|
27
|
+
address receiver,
|
|
28
|
+
address market,
|
|
29
|
+
uint256 exactPtIn,
|
|
30
|
+
uint256 minYtOut,
|
|
31
|
+
ApproxParams calldata guessTotalPtToSwap
|
|
32
|
+
) external returns (uint256 netYtOut) {
|
|
33
|
+
(, IPPrincipalToken PT, IPYieldToken YT) = IPMarket(market).readTokens();
|
|
34
|
+
MarketState memory state = IPMarket(market).readState();
|
|
35
|
+
|
|
36
|
+
PT.safeTransferFrom(msg.sender, market, exactPtIn);
|
|
37
|
+
|
|
38
|
+
uint256 totalPtToSwap;
|
|
39
|
+
(netYtOut, , totalPtToSwap, ) = state.approxSwapExactPtForYt(
|
|
40
|
+
YT.newIndex(),
|
|
41
|
+
exactPtIn,
|
|
42
|
+
block.timestamp,
|
|
43
|
+
guessTotalPtToSwap
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
require(netYtOut >= minYtOut, "insufficient YT out");
|
|
47
|
+
IPMarket(market).swapExactPtForScy(
|
|
48
|
+
address(YT),
|
|
49
|
+
totalPtToSwap,
|
|
50
|
+
_encodeSwapExactPtForYt(receiver, exactPtIn, minYtOut)
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
emit SwapPtAndYt(msg.sender, market, receiver, exactPtIn.neg(), netYtOut.Int());
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function swapExactYtForPt(
|
|
57
|
+
address receiver,
|
|
58
|
+
address market,
|
|
59
|
+
uint256 exactYtIn,
|
|
60
|
+
uint256 minPtOut,
|
|
61
|
+
ApproxParams calldata guessTotalPtSwapped
|
|
62
|
+
) external returns (uint256 netPtOut) {
|
|
63
|
+
(, , IPYieldToken YT) = IPMarket(market).readTokens();
|
|
64
|
+
MarketState memory state = IPMarket(market).readState();
|
|
65
|
+
|
|
66
|
+
YT.safeTransferFrom(msg.sender, address(YT), exactYtIn);
|
|
67
|
+
|
|
68
|
+
uint256 totalPtSwapped;
|
|
69
|
+
(netPtOut, , totalPtSwapped, ) = state.approxSwapExactYtForPt(
|
|
70
|
+
YT.newIndex(),
|
|
71
|
+
exactYtIn,
|
|
72
|
+
block.timestamp,
|
|
73
|
+
guessTotalPtSwapped
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
require(netPtOut >= minPtOut, "insufficient PT out");
|
|
77
|
+
|
|
78
|
+
IPMarket(market).swapScyForExactPt(
|
|
79
|
+
address(this),
|
|
80
|
+
totalPtSwapped,
|
|
81
|
+
_encodeSwapExactYtForPt(receiver, exactYtIn, minPtOut)
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
emit SwapPtAndYt(msg.sender, market, receiver, netPtOut.Int(), exactYtIn.neg());
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -5,7 +5,9 @@ abstract contract CallbackHelper {
|
|
|
5
5
|
enum ActionType {
|
|
6
6
|
SwapScyForExactYt,
|
|
7
7
|
SwapExactScyForYt,
|
|
8
|
-
SwapYtForScy
|
|
8
|
+
SwapYtForScy,
|
|
9
|
+
SwapExactYtForPt,
|
|
10
|
+
SwapExactPtForYt
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
/// ------------------------------------------------------------
|
|
@@ -72,6 +74,52 @@ abstract contract CallbackHelper {
|
|
|
72
74
|
(, receiver, minScyOut) = abi.decode(data, (ActionType, address, uint256));
|
|
73
75
|
}
|
|
74
76
|
|
|
77
|
+
function _encodeSwapExactYtForPt(
|
|
78
|
+
address receiver,
|
|
79
|
+
uint256 exactYtIn,
|
|
80
|
+
uint256 minPtOut
|
|
81
|
+
) internal pure returns (bytes memory) {
|
|
82
|
+
return abi.encode(ActionType.SwapExactYtForPt, receiver, exactYtIn, minPtOut);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function _decodeSwapExactYtForPt(bytes memory data)
|
|
86
|
+
internal
|
|
87
|
+
pure
|
|
88
|
+
returns (
|
|
89
|
+
address receiver,
|
|
90
|
+
uint256 exactYtIn,
|
|
91
|
+
uint256 minPtOut
|
|
92
|
+
)
|
|
93
|
+
{
|
|
94
|
+
(, receiver, exactYtIn, minPtOut) = abi.decode(
|
|
95
|
+
data,
|
|
96
|
+
(ActionType, address, uint256, uint256)
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function _encodeSwapExactPtForYt(
|
|
101
|
+
address receiver,
|
|
102
|
+
uint256 exactPtIn,
|
|
103
|
+
uint256 minYtOut
|
|
104
|
+
) internal pure returns (bytes memory) {
|
|
105
|
+
return abi.encode(ActionType.SwapExactPtForYt, receiver, exactPtIn, minYtOut);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function _decodeSwapExactPtForYt(bytes memory data)
|
|
109
|
+
internal
|
|
110
|
+
pure
|
|
111
|
+
returns (
|
|
112
|
+
address receiver,
|
|
113
|
+
uint256 exactPtIn,
|
|
114
|
+
uint256 minYtOut
|
|
115
|
+
)
|
|
116
|
+
{
|
|
117
|
+
(, receiver, exactPtIn, minYtOut) = abi.decode(
|
|
118
|
+
data,
|
|
119
|
+
(ActionType, address, uint256, uint256)
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
75
123
|
/// ------------------------------------------------------------
|
|
76
124
|
/// Misc functions
|
|
77
125
|
/// ------------------------------------------------------------
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
pragma solidity 0.8.15;
|
|
3
|
+
|
|
4
|
+
import "../libraries/math/MarketApproxLib.sol";
|
|
5
|
+
import "../libraries/kyberswap/KyberSwapHelper.sol";
|
|
6
|
+
|
|
7
|
+
interface IPActionSwapPTYT {
|
|
8
|
+
event SwapPtAndYt(
|
|
9
|
+
address indexed caller,
|
|
10
|
+
address indexed market,
|
|
11
|
+
address indexed receiver,
|
|
12
|
+
int256 netPtToAccount,
|
|
13
|
+
int256 netYtToAccount
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
function swapExactPtForYt(
|
|
17
|
+
address receiver,
|
|
18
|
+
address market,
|
|
19
|
+
uint256 exactPtIn,
|
|
20
|
+
uint256 minYtOut,
|
|
21
|
+
ApproxParams calldata guessTotalPtToSwap
|
|
22
|
+
) external returns (uint256 netYtOut);
|
|
23
|
+
|
|
24
|
+
function swapExactYtForPt(
|
|
25
|
+
address receiver,
|
|
26
|
+
address market,
|
|
27
|
+
uint256 exactYtIn,
|
|
28
|
+
uint256 minPtOut,
|
|
29
|
+
ApproxParams calldata guessTotalPtSwapped
|
|
30
|
+
) external returns (uint256 netPtOut);
|
|
31
|
+
}
|
|
@@ -5,6 +5,7 @@ pragma solidity 0.8.15;
|
|
|
5
5
|
import "./IPActionAddRemoveLiq.sol";
|
|
6
6
|
import "./IPActionSwapPT.sol";
|
|
7
7
|
import "./IPActionSwapYT.sol";
|
|
8
|
+
import "./IPActionSwapPTYT.sol";
|
|
8
9
|
import "./IPActionMintRedeem.sol";
|
|
9
10
|
import "./IPActionMisc.sol";
|
|
10
11
|
|
|
@@ -12,6 +13,7 @@ interface IPAllAction is
|
|
|
12
13
|
IPActionAddRemoveLiq,
|
|
13
14
|
IPActionSwapPT,
|
|
14
15
|
IPActionSwapYT,
|
|
16
|
+
IPActionSwapPTYT,
|
|
15
17
|
IPActionMintRedeem,
|
|
16
18
|
IPActionMisc
|
|
17
19
|
{}
|
|
@@ -5,7 +5,7 @@ pragma solidity 0.8.15;
|
|
|
5
5
|
import "./IPVeToken.sol";
|
|
6
6
|
import "../libraries/VeBalanceLib.sol";
|
|
7
7
|
|
|
8
|
-
interface IPVotingEscrow {
|
|
8
|
+
interface IPVotingEscrow is IPVeToken {
|
|
9
9
|
event NewLockPosition(address indexed user, uint128 amount, uint128 expiry);
|
|
10
10
|
|
|
11
11
|
event Withdraw(address indexed user, uint128 amount);
|
|
@@ -272,6 +272,64 @@ library MarketApproxPtInLib {
|
|
|
272
272
|
revert("approx fail");
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
+
struct Args7 {
|
|
276
|
+
MarketState market;
|
|
277
|
+
PYIndex index;
|
|
278
|
+
uint256 maxPtIn;
|
|
279
|
+
uint256 blockTime;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function approxSwapExactPtForYt(
|
|
283
|
+
MarketState memory _market,
|
|
284
|
+
PYIndex _index,
|
|
285
|
+
uint256 _maxPtIn,
|
|
286
|
+
uint256 _blockTime,
|
|
287
|
+
ApproxParams memory _approx // approx for totalPtToSwap
|
|
288
|
+
)
|
|
289
|
+
internal
|
|
290
|
+
pure
|
|
291
|
+
returns (
|
|
292
|
+
uint256, /*netYtOut*/
|
|
293
|
+
uint256, /*netPtIn*/
|
|
294
|
+
uint256, /*totalPtToSwap*/
|
|
295
|
+
uint256 /*netScyToReserve*/
|
|
296
|
+
)
|
|
297
|
+
{
|
|
298
|
+
Args7 memory arg = Args7(_market, _index, _maxPtIn, _blockTime);
|
|
299
|
+
|
|
300
|
+
MarketPreCompute memory comp = arg.market.getMarketPreCompute(arg.index, arg.blockTime);
|
|
301
|
+
ApproxParamsPtIn memory p = newApproxParamsPtIn(_approx, comp.totalAsset);
|
|
302
|
+
|
|
303
|
+
p.guessMin = Math.max(p.guessMin, arg.maxPtIn);
|
|
304
|
+
|
|
305
|
+
for (uint256 iter = 0; iter < p.maxIteration; ++iter) {
|
|
306
|
+
(bool isGoodSlope, uint256 guess) = nextGuess(p, comp, arg.market.totalPt, iter);
|
|
307
|
+
|
|
308
|
+
if (!isGoodSlope) {
|
|
309
|
+
p.guessMax = guess;
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
(uint256 netAssetOut, uint256 netAssetToReserve) = calcAssetOut(
|
|
314
|
+
arg.market,
|
|
315
|
+
comp,
|
|
316
|
+
guess
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
uint256 netPtPayable = netAssetOut + arg.maxPtIn;
|
|
320
|
+
if (guess <= netPtPayable) {
|
|
321
|
+
p.guessMin = guess;
|
|
322
|
+
uint256 netPtIn = guess - netAssetOut; // guess >= netAssetOut (market invariant)
|
|
323
|
+
if (Math.isASmallerApproxB(netPtIn, arg.maxPtIn, p.eps)) {
|
|
324
|
+
return (netAssetOut, netPtIn, guess, arg.index.assetToScy(netAssetToReserve));
|
|
325
|
+
}
|
|
326
|
+
} else {
|
|
327
|
+
p.guessMax = guess - 1;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
revert("approx fail");
|
|
331
|
+
}
|
|
332
|
+
|
|
275
333
|
////////////////////////////////////////////////////////////////////////////////
|
|
276
334
|
|
|
277
335
|
function calcAssetOut(
|
|
@@ -569,6 +627,65 @@ library MarketApproxPtOutLib {
|
|
|
569
627
|
revert("approx fail");
|
|
570
628
|
}
|
|
571
629
|
|
|
630
|
+
struct Args8 {
|
|
631
|
+
MarketState market;
|
|
632
|
+
PYIndex index;
|
|
633
|
+
uint256 maxYtIn;
|
|
634
|
+
uint256 blockTime;
|
|
635
|
+
uint256 maxScyRedeemableFromPY;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
function approxSwapExactYtForPt(
|
|
639
|
+
MarketState memory _market,
|
|
640
|
+
PYIndex _index,
|
|
641
|
+
uint256 _maxYtIn,
|
|
642
|
+
uint256 _blockTime,
|
|
643
|
+
ApproxParams memory _approx
|
|
644
|
+
)
|
|
645
|
+
internal
|
|
646
|
+
pure
|
|
647
|
+
returns (
|
|
648
|
+
uint256, /*netPtOut*/
|
|
649
|
+
uint256, /*netYtIn*/
|
|
650
|
+
uint256, /*totalPtSwapped*/
|
|
651
|
+
uint256 /*netScyToReserve*/
|
|
652
|
+
)
|
|
653
|
+
{
|
|
654
|
+
Args8 memory arg = Args8(
|
|
655
|
+
_market,
|
|
656
|
+
_index,
|
|
657
|
+
_maxYtIn,
|
|
658
|
+
_blockTime,
|
|
659
|
+
_index.assetToScy(_maxYtIn)
|
|
660
|
+
);
|
|
661
|
+
MarketPreCompute memory comp = arg.market.getMarketPreCompute(arg.index, arg.blockTime);
|
|
662
|
+
ApproxParamsPtOut memory p = newApproxParamsPtOut(_approx, comp, arg.market.totalPt);
|
|
663
|
+
|
|
664
|
+
p.guessMin = Math.max(p.guessMin, arg.maxYtIn);
|
|
665
|
+
|
|
666
|
+
for (uint256 iter = 0; iter < p.maxIteration; ++iter) {
|
|
667
|
+
uint256 guess = nextGuess(p, iter);
|
|
668
|
+
|
|
669
|
+
(uint256 netAssetIn, uint256 netAssetToReserve) = calcAssetIn(arg.market, comp, guess);
|
|
670
|
+
uint256 netScyIn = arg.index.assetToScyUp(netAssetIn);
|
|
671
|
+
|
|
672
|
+
if (netScyIn <= arg.maxScyRedeemableFromPY) {
|
|
673
|
+
p.guessMin = guess;
|
|
674
|
+
if (Math.isASmallerApproxB(netAssetIn, arg.maxYtIn, p.eps)) {
|
|
675
|
+
return (
|
|
676
|
+
guess - arg.maxYtIn,
|
|
677
|
+
arg.maxYtIn,
|
|
678
|
+
guess,
|
|
679
|
+
arg.index.assetToScy(netAssetToReserve)
|
|
680
|
+
);
|
|
681
|
+
}
|
|
682
|
+
} else {
|
|
683
|
+
p.guessMax = guess - 1;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
revert("approx fail");
|
|
687
|
+
}
|
|
688
|
+
|
|
572
689
|
////////////////////////////////////////////////////////////////////////////////
|
|
573
690
|
|
|
574
691
|
function calcAssetIn(
|
|
@@ -233,15 +233,22 @@ library MarketMathStatic {
|
|
|
233
233
|
MarketState memory state = IPMarket(market).readState();
|
|
234
234
|
|
|
235
235
|
(uint256 scyFromBurn, uint256 ptFromBurn) = state.removeLiquidity(lpToRemove);
|
|
236
|
-
uint256 scyFromSwap;
|
|
237
|
-
(scyFromSwap, netScyFee) = state.swapExactPtForScy(
|
|
238
|
-
pyIndex(market),
|
|
239
|
-
ptFromBurn,
|
|
240
|
-
block.timestamp
|
|
241
|
-
);
|
|
242
236
|
|
|
243
|
-
|
|
244
|
-
|
|
237
|
+
if (IPMarket(market).isExpired()) {
|
|
238
|
+
(,, IPYieldToken YT) = IPMarket(market).readTokens();
|
|
239
|
+
PYIndex index = PYIndex.wrap(YT.pyIndexCurrent());
|
|
240
|
+
netScyOut = scyFromBurn + index.assetToScy(ptFromBurn);
|
|
241
|
+
} else {
|
|
242
|
+
uint256 scyFromSwap;
|
|
243
|
+
(scyFromSwap, netScyFee) = state.swapExactPtForScy(
|
|
244
|
+
pyIndex(market),
|
|
245
|
+
ptFromBurn,
|
|
246
|
+
block.timestamp
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
netScyOut = scyFromBurn + scyFromSwap;
|
|
250
|
+
priceImpact = calcPriceImpact(market, ptFromBurn.neg());
|
|
251
|
+
}
|
|
245
252
|
}
|
|
246
253
|
|
|
247
254
|
function removeLiquiditySingleBaseTokenStatic(
|
|
@@ -529,6 +536,59 @@ library MarketMathStatic {
|
|
|
529
536
|
);
|
|
530
537
|
}
|
|
531
538
|
|
|
539
|
+
// totalPtToSwap is the param to approx
|
|
540
|
+
function swapExactPtForYt(
|
|
541
|
+
address market,
|
|
542
|
+
uint256 exactPtIn,
|
|
543
|
+
ApproxParams memory approxParams
|
|
544
|
+
)
|
|
545
|
+
external
|
|
546
|
+
returns (
|
|
547
|
+
uint256 netYtOut,
|
|
548
|
+
uint256 totalPtToSwap,
|
|
549
|
+
uint256 netScyFee,
|
|
550
|
+
uint256 priceImpact
|
|
551
|
+
)
|
|
552
|
+
{
|
|
553
|
+
MarketState memory state = IPMarket(market).readState();
|
|
554
|
+
PYIndex index = pyIndex(market);
|
|
555
|
+
|
|
556
|
+
(netYtOut, , totalPtToSwap, netScyFee) = state.approxSwapExactPtForYt(
|
|
557
|
+
index,
|
|
558
|
+
exactPtIn,
|
|
559
|
+
block.timestamp,
|
|
560
|
+
approxParams
|
|
561
|
+
);
|
|
562
|
+
priceImpact = calcPriceImpact(market, totalPtToSwap.neg());
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// totalPtSwapped is the param to approx
|
|
566
|
+
function swapExactYtForPt(
|
|
567
|
+
address market,
|
|
568
|
+
uint256 exactYtIn,
|
|
569
|
+
ApproxParams memory approxParams
|
|
570
|
+
)
|
|
571
|
+
external
|
|
572
|
+
returns (
|
|
573
|
+
uint256 netPtOut,
|
|
574
|
+
uint256 totalPtSwapped,
|
|
575
|
+
uint256 netScyFee,
|
|
576
|
+
uint256 priceImpact
|
|
577
|
+
)
|
|
578
|
+
{
|
|
579
|
+
MarketState memory state = IPMarket(market).readState();
|
|
580
|
+
PYIndex index = pyIndex(market);
|
|
581
|
+
|
|
582
|
+
(netPtOut, , totalPtSwapped, netScyFee) = state.approxSwapExactYtForPt(
|
|
583
|
+
index,
|
|
584
|
+
exactYtIn,
|
|
585
|
+
block.timestamp,
|
|
586
|
+
approxParams
|
|
587
|
+
);
|
|
588
|
+
|
|
589
|
+
priceImpact = calcPriceImpact(market, totalPtSwapped.Int());
|
|
590
|
+
}
|
|
591
|
+
|
|
532
592
|
function pyIndex(address market) public returns (PYIndex index) {
|
|
533
593
|
(, , IPYieldToken YT) = IPMarket(market).readTokens();
|
|
534
594
|
|
|
@@ -543,6 +603,7 @@ library MarketMathStatic {
|
|
|
543
603
|
public
|
|
544
604
|
returns (uint256)
|
|
545
605
|
{
|
|
606
|
+
if (IPMarket(market).isExpired()) return Math.ONE;
|
|
546
607
|
int256 netPtToAccount = netPtOut;
|
|
547
608
|
MarketState memory state = IPMarket(market).readState();
|
|
548
609
|
MarketPreCompute memory comp = state.getMarketPreCompute(pyIndex(market), block.timestamp);
|