@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.
Files changed (121) hide show
  1. package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/AaveV3/PendleAaveV3SCY.sol/PendleAaveV3SCY.dbg.json +1 -1
  2. package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/AaveV3/WadRayMath.sol/WadRayMath.dbg.json +1 -1
  3. package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/BenQi/PendleQiSAvaxSCY.sol/PendleQiSAvaxSCY.dbg.json +1 -1
  4. package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/BenQi/PendleQiTokenSCY.sol/PendleQiTokenSCY.dbg.json +1 -1
  5. package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/BenQi/PendleSAvaxSCY.sol/PendleSAvaxSCY.dbg.json +1 -1
  6. package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/Euler/PendleEulerSCY.sol/PendleEulerSCY.dbg.json +1 -1
  7. package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/PendleERC4626SCY.sol/PendleERC4626SCY.dbg.json +1 -1
  8. package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/PendleStargateSCY.sol/PendleStargateSCY.dbg.json +1 -1
  9. package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/PendleWstEthSCY.sol/PendleWstEthSCY.dbg.json +1 -1
  10. package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/PendleYearnVaultSCY.sol/PendleYearnVaultSCY.dbg.json +1 -1
  11. package/build/artifacts/contracts/SuperComposableYield/SCY-implementations/TraderJoe/PendleSJoeSCY.sol/PendleSJoeSCY.dbg.json +1 -1
  12. package/build/artifacts/contracts/SuperComposableYield/base-implementations/SCYBase.sol/SCYBase.dbg.json +1 -1
  13. package/build/artifacts/contracts/SuperComposableYield/base-implementations/SCYBaseWithRewards.sol/SCYBaseWithRewards.dbg.json +1 -1
  14. package/build/artifacts/contracts/core/LiquidityMining/CelerAbstracts/CelerReceiverUpg.sol/CelerReceiverUpg.dbg.json +1 -1
  15. package/build/artifacts/contracts/core/LiquidityMining/CelerAbstracts/CelerSenderUpg.sol/CelerSenderUpg.dbg.json +1 -1
  16. package/build/artifacts/contracts/core/LiquidityMining/GaugeController/PendleGaugeControllerBaseUpg.sol/PendleGaugeControllerBaseUpg.dbg.json +1 -1
  17. package/build/artifacts/contracts/core/LiquidityMining/GaugeController/PendleGaugeControllerMainchainUpg.sol/PendleGaugeControllerMainchainUpg.dbg.json +1 -1
  18. package/build/artifacts/contracts/core/LiquidityMining/GaugeController/PendleGaugeControllerSidechainUpg.sol/PendleGaugeControllerSidechainUpg.dbg.json +1 -1
  19. package/build/artifacts/contracts/core/LiquidityMining/PendleGauge.sol/PendleGauge.dbg.json +1 -1
  20. package/build/artifacts/contracts/core/LiquidityMining/VotingController/PendleVotingControllerUpg.sol/PendleVotingControllerUpg.dbg.json +1 -1
  21. package/build/artifacts/contracts/core/LiquidityMining/VotingController/VotingControllerStorageUpg.sol/VotingControllerStorageUpg.dbg.json +1 -1
  22. package/build/artifacts/contracts/core/LiquidityMining/VotingEscrow/VotingEscrowPendleMainchain.sol/VotingEscrowPendleMainchain.dbg.json +1 -1
  23. package/build/artifacts/contracts/core/LiquidityMining/VotingEscrow/VotingEscrowPendleMainchain.sol/VotingEscrowPendleMainchain.json +2 -2
  24. package/build/artifacts/contracts/core/LiquidityMining/VotingEscrow/VotingEscrowPendleSidechain.sol/VotingEscrowPendleSidechain.dbg.json +1 -1
  25. package/build/artifacts/contracts/core/LiquidityMining/VotingEscrow/VotingEscrowTokenBase.sol/VotingEscrowTokenBase.dbg.json +1 -1
  26. package/build/artifacts/contracts/core/Market/PendleMarket.sol/PendleMarket.dbg.json +1 -1
  27. package/build/artifacts/contracts/core/Market/PendleMarketFactory.sol/PendleMarketFactory.dbg.json +1 -1
  28. package/build/artifacts/contracts/core/PendleRouter.sol/PendleRouter.dbg.json +1 -1
  29. package/build/artifacts/contracts/core/PendleRouter.sol/PendleRouter.json +20 -2
  30. package/build/artifacts/contracts/core/YieldContracts/InterestManagerYT.sol/InterestManagerYT.dbg.json +1 -1
  31. package/build/artifacts/contracts/core/YieldContracts/PendlePrincipalToken.sol/PendlePrincipalToken.dbg.json +1 -1
  32. package/build/artifacts/contracts/core/YieldContracts/PendleYieldContractFactory.sol/PendleYieldContractFactory.dbg.json +1 -1
  33. package/build/artifacts/contracts/core/YieldContracts/PendleYieldToken.sol/PendleYieldToken.dbg.json +1 -1
  34. package/build/artifacts/contracts/core/actions/ActionAddRemoveLiq.sol/ActionAddRemoveLiq.dbg.json +1 -1
  35. package/build/artifacts/contracts/core/actions/ActionAddRemoveLiq.sol/ActionAddRemoveLiq.json +4 -4
  36. package/build/artifacts/contracts/core/actions/ActionCallback.sol/ActionCallback.dbg.json +1 -1
  37. package/build/artifacts/contracts/core/actions/ActionCallback.sol/ActionCallback.json +2 -2
  38. package/build/artifacts/contracts/core/actions/ActionMintRedeem.sol/ActionMintRedeem.dbg.json +1 -1
  39. package/build/artifacts/contracts/core/actions/ActionMintRedeem.sol/ActionMintRedeem.json +2 -2
  40. package/build/artifacts/contracts/core/actions/ActionMisc.sol/ActionMisc.dbg.json +1 -1
  41. package/build/artifacts/contracts/core/actions/ActionSwapPT.sol/ActionSwapPT.dbg.json +1 -1
  42. package/build/artifacts/contracts/core/actions/ActionSwapPT.sol/ActionSwapPT.json +2 -2
  43. package/build/artifacts/contracts/core/actions/ActionSwapPTYT.sol/ActionSwapPTYT.dbg.json +4 -0
  44. package/build/artifacts/contracts/core/actions/ActionSwapPTYT.sol/ActionSwapPTYT.json +185 -0
  45. package/build/artifacts/contracts/core/actions/ActionSwapYT.sol/ActionSwapYT.dbg.json +1 -1
  46. package/build/artifacts/contracts/core/actions/ActionSwapYT.sol/ActionSwapYT.json +2 -2
  47. package/build/artifacts/contracts/core/actions/base/ActionBaseMintRedeem.sol/ActionBaseMintRedeem.dbg.json +1 -1
  48. package/build/artifacts/contracts/core/actions/base/CallbackHelper.sol/CallbackHelper.dbg.json +1 -1
  49. package/build/artifacts/contracts/interfaces/IPActionAddRemoveLiq.sol/IPActionAddRemoveLiq.dbg.json +1 -1
  50. package/build/artifacts/contracts/interfaces/IPActionMintRedeem.sol/IPActionMintRedeem.dbg.json +1 -1
  51. package/build/artifacts/contracts/interfaces/IPActionSwapPT.sol/IPActionSwapPT.dbg.json +1 -1
  52. package/build/artifacts/contracts/interfaces/IPActionSwapPTYT.sol/IPActionSwapPTYT.dbg.json +4 -0
  53. package/build/artifacts/contracts/interfaces/IPActionSwapPTYT.sol/IPActionSwapPTYT.json +180 -0
  54. package/build/artifacts/contracts/interfaces/IPActionSwapYT.sol/IPActionSwapYT.dbg.json +1 -1
  55. package/build/artifacts/contracts/interfaces/IPAllAction.sol/IPAllAction.dbg.json +1 -1
  56. package/build/artifacts/contracts/interfaces/IPAllAction.sol/IPAllAction.json +169 -0
  57. package/build/artifacts/contracts/interfaces/IPMarket.sol/IPMarket.dbg.json +1 -1
  58. package/build/artifacts/contracts/interfaces/IPVotingController.sol/IPVotingController.dbg.json +1 -1
  59. package/build/artifacts/contracts/interfaces/IPVotingEscrow.sol/IPVotingEscrow.dbg.json +1 -1
  60. package/build/artifacts/contracts/interfaces/IPVotingEscrow.sol/IPVotingEscrow.json +93 -0
  61. package/build/artifacts/contracts/interfaces/ISuperComposableYield.sol/ISuperComposableYield.dbg.json +1 -1
  62. package/build/artifacts/contracts/libraries/RewardManager.sol/RewardManager.dbg.json +1 -1
  63. package/build/artifacts/contracts/libraries/RewardManagerAbstract.sol/RewardManagerAbstract.dbg.json +1 -1
  64. package/build/artifacts/contracts/libraries/VeBalanceLib.sol/VeBalanceLib.dbg.json +1 -1
  65. package/build/artifacts/contracts/libraries/VeHistoryLib.sol/Checkpoints.dbg.json +1 -1
  66. package/build/artifacts/contracts/libraries/helpers/PYIndex.sol/PYIndexLib.dbg.json +1 -1
  67. package/build/artifacts/contracts/libraries/helpers/SSTORE2Deployer.sol/SSTORE2Deployer.dbg.json +1 -1
  68. package/build/artifacts/contracts/libraries/kyberswap/AggregationRouterHelper.sol/AggregationRouterHelper.dbg.json +1 -1
  69. package/build/artifacts/contracts/libraries/kyberswap/KyberSwapHelper.sol/KyberSwapHelper.dbg.json +1 -1
  70. package/build/artifacts/contracts/libraries/math/MarketApproxLib.sol/MarketApproxPtInLib.dbg.json +1 -1
  71. package/build/artifacts/contracts/libraries/math/MarketApproxLib.sol/MarketApproxPtInLib.json +2 -2
  72. package/build/artifacts/contracts/libraries/math/MarketApproxLib.sol/MarketApproxPtOutLib.dbg.json +1 -1
  73. package/build/artifacts/contracts/libraries/math/MarketApproxLib.sol/MarketApproxPtOutLib.json +2 -2
  74. package/build/artifacts/contracts/libraries/math/MarketMathCore.sol/MarketMathCore.dbg.json +1 -1
  75. package/build/artifacts/contracts/libraries/math/Math.sol/Math.dbg.json +1 -1
  76. package/build/artifacts/contracts/libraries/math/WeekMath.sol/WeekMath.dbg.json +1 -1
  77. package/build/artifacts/contracts/libraries/solmate/SSTORE2.sol/SSTORE2.dbg.json +1 -1
  78. package/build/artifacts/contracts/offchain-helpers/MarketMathStatic.sol/MarketMathStatic.dbg.json +1 -1
  79. package/build/artifacts/contracts/offchain-helpers/MarketMathStatic.sol/MarketMathStatic.json +2 -2
  80. package/build/artifacts/contracts/offchain-helpers/RouterStatic.sol/RouterStatic.dbg.json +1 -1
  81. package/build/artifacts/contracts/offchain-helpers/RouterStatic.sol/RouterStatic.json +210 -56
  82. package/build/artifacts/contracts/offchain-helpers/SSTORE2DeployerContract.sol/SSTORE2DeployerContract.dbg.json +1 -1
  83. package/contracts/core/LiquidityMining/VotingEscrow/VotingEscrowPendleMainchain.sol +6 -1
  84. package/contracts/core/PendleRouter.sol +10 -1
  85. package/contracts/core/actions/ActionAddRemoveLiq.sol +23 -2
  86. package/contracts/core/actions/ActionCallback.sol +39 -0
  87. package/contracts/core/actions/ActionSwapPTYT.sol +86 -0
  88. package/contracts/core/actions/base/CallbackHelper.sol +49 -1
  89. package/contracts/interfaces/IPActionSwapPTYT.sol +31 -0
  90. package/contracts/interfaces/IPAllAction.sol +2 -0
  91. package/contracts/interfaces/IPVotingEscrow.sol +1 -1
  92. package/contracts/libraries/math/MarketApproxLib.sol +117 -0
  93. package/contracts/offchain-helpers/MarketMathStatic.sol +69 -8
  94. package/contracts/offchain-helpers/RouterStatic.sol +76 -3
  95. package/deployments/43113-core.json +1 -1
  96. package/package.json +1 -3
  97. package/typechain-types/ActionSwapPTYT.ts +233 -0
  98. package/typechain-types/IPActionSwapPTYT.ts +233 -0
  99. package/typechain-types/IPAllAction.ts +138 -0
  100. package/typechain-types/IPVotingEscrow.ts +131 -0
  101. package/typechain-types/PendleFeeDistributorFactory.ts +97 -8
  102. package/typechain-types/PendleRouter.ts +19 -0
  103. package/typechain-types/RouterStatic.ts +174 -0
  104. package/typechain-types/factories/ActionAddRemoveLiq__factory.ts +1 -1
  105. package/typechain-types/factories/ActionCallback__factory.ts +1 -1
  106. package/typechain-types/factories/ActionMintRedeem__factory.ts +1 -1
  107. package/typechain-types/factories/ActionSwapPTYT__factory.ts +238 -0
  108. package/typechain-types/factories/ActionSwapPT__factory.ts +1 -1
  109. package/typechain-types/factories/ActionSwapYT__factory.ts +1 -1
  110. package/typechain-types/factories/IPActionSwapPTYT__factory.ts +195 -0
  111. package/typechain-types/factories/IPAllAction__factory.ts +169 -0
  112. package/typechain-types/factories/IPVotingEscrow__factory.ts +93 -0
  113. package/typechain-types/factories/MarketMathStatic__factory.ts +1 -1
  114. package/typechain-types/factories/PendleFeeDistributorFactory__factory.ts +81 -8
  115. package/typechain-types/factories/PendleFeeDistributor__factory.ts +1 -1
  116. package/typechain-types/factories/PendleMsgSendEndpointUpg__factory.ts +1 -1
  117. package/typechain-types/factories/PendleRouter__factory.ts +23 -1
  118. package/typechain-types/factories/RouterStatic__factory.ts +143 -1
  119. package/typechain-types/factories/VotingEscrowPendleMainchain__factory.ts +1 -1
  120. package/typechain-types/hardhat.d.ts +72 -117
  121. package/typechain-types/index.ts +16 -26
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "_format": "hh-sol-dbg-1",
3
- "buildInfo": "../../../build-info/20ebeca750412294184becd43b05ac5c.json"
3
+ "buildInfo": "../../../build-info/d246d0fd3945c2c082231b431b6c99e6.json"
4
4
  }
@@ -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() public virtual override returns (uint128) {
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
- netScyOut = scyFromBurn + scyFromSwap;
244
- priceImpact = calcPriceImpact(market, ptFromBurn.neg());
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);