@pendle/core-v2 4.4.6 → 4.5.0-beta-2

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 (126) hide show
  1. package/build/artifacts/contracts/core/StandardizedYield/implementations/PendleERC20WithSupplyCapSY.sol/PendleERC20WithSupplyCapSY.dbg.json +4 -0
  2. package/build/artifacts/contracts/core/StandardizedYield/implementations/PendleERC20WithSupplyCapSY.sol/PendleERC20WithSupplyCapSY.json +1073 -0
  3. package/build/artifacts/contracts/core/StandardizedYield/implementations/Tensorplex/PendleStTAOSY.sol/PendleStTAOSY.dbg.json +1 -1
  4. package/build/artifacts/contracts/core/StandardizedYield/implementations/Tensorplex/PendleStTAOSY.sol/PendleStTAOSY.json +2 -2
  5. package/build/artifacts/contracts/interfaces/IPActionAddRemoveLiqV3.sol/IPActionAddRemoveLiqV3.dbg.json +1 -1
  6. package/build/artifacts/contracts/interfaces/IPActionMiscV3.sol/IPActionMiscV3.dbg.json +1 -1
  7. package/build/artifacts/contracts/interfaces/IPActionStorageStatic.sol/IPActionStorageStatic.dbg.json +1 -1
  8. package/build/artifacts/contracts/interfaces/IPActionStorageV4.sol/IPActionStorageV4.dbg.json +4 -0
  9. package/build/artifacts/contracts/interfaces/IPActionStorageV4.sol/IPActionStorageV4.json +149 -0
  10. package/build/artifacts/contracts/interfaces/IPActionSwapPTV3.sol/IPActionSwapPTV3.dbg.json +1 -1
  11. package/build/artifacts/contracts/interfaces/IPActionSwapYTV3.sol/IPActionSwapYTV3.dbg.json +1 -1
  12. package/build/artifacts/contracts/interfaces/IPAllActionV3.sol/IPAllActionV3.dbg.json +1 -1
  13. package/build/artifacts/contracts/interfaces/IPAllActionV3.sol/IPAllActionV3.json +134 -72
  14. package/build/artifacts/contracts/interfaces/IPMiniDiamond.sol/IPMiniDiamond.dbg.json +1 -1
  15. package/build/artifacts/contracts/interfaces/IPRouterHelper.sol/IPRouterHelper.dbg.json +1 -1
  16. package/build/artifacts/contracts/interfaces/IPRouterStatic.sol/IPRouterStatic.dbg.json +1 -1
  17. package/build/artifacts/contracts/limit/LimitRouterBase.sol/LimitRouterBase.dbg.json +1 -1
  18. package/build/artifacts/contracts/limit/PendleLimitRouter.sol/PendleLimitRouter.dbg.json +1 -1
  19. package/build/artifacts/contracts/limit/PendleLimitRouter.sol/PendleLimitRouter.json +2 -2
  20. package/build/artifacts/contracts/offchain-helpers/PendlePoolDeployHelper.sol/PendlePoolDeployHelper.dbg.json +1 -1
  21. package/build/artifacts/contracts/offchain-helpers/PendlePoolDeployHelper.sol/PendlePoolDeployHelper.json +2 -2
  22. package/build/artifacts/contracts/offchain-helpers/router-static/PendleRouterStatic.sol/PendleRouterStatic.dbg.json +1 -1
  23. package/build/artifacts/contracts/offchain-helpers/router-static/PendleRouterStatic.sol/PendleRouterStatic.json +2 -2
  24. package/build/artifacts/contracts/offchain-helpers/router-static/base/ActionInfoStatic.sol/ActionInfoStatic.dbg.json +1 -1
  25. package/build/artifacts/contracts/offchain-helpers/router-static/base/ActionInfoStatic.sol/ActionInfoStatic.json +2 -2
  26. package/build/artifacts/contracts/offchain-helpers/router-static/base/ActionMarketAuxStatic.sol/ActionMarketAuxStatic.dbg.json +1 -1
  27. package/build/artifacts/contracts/offchain-helpers/router-static/base/ActionMarketAuxStatic.sol/ActionMarketAuxStatic.json +2 -2
  28. package/build/artifacts/contracts/offchain-helpers/router-static/base/ActionMarketCoreStatic.sol/ActionMarketCoreStatic.dbg.json +1 -1
  29. package/build/artifacts/contracts/offchain-helpers/router-static/base/ActionMarketCoreStatic.sol/ActionMarketCoreStatic.json +2 -28
  30. package/build/artifacts/contracts/offchain-helpers/router-static/base/ActionMintRedeemStatic.sol/ActionMintRedeemStatic.dbg.json +1 -1
  31. package/build/artifacts/contracts/offchain-helpers/router-static/base/ActionMintRedeemStatic.sol/ActionMintRedeemStatic.json +2 -2
  32. package/build/artifacts/contracts/offchain-helpers/router-static/base/ActionStorageStatic.sol/ActionStorageStatic.dbg.json +1 -1
  33. package/build/artifacts/contracts/offchain-helpers/router-static/base/ActionStorageStatic.sol/ActionStorageStatic.json +2 -2
  34. package/build/artifacts/contracts/offchain-helpers/router-static/base/ActionVePendleStatic.sol/ActionVePendleStatic.dbg.json +1 -1
  35. package/build/artifacts/contracts/offchain-helpers/router-static/base/ActionVePendleStatic.sol/ActionVePendleStatic.json +2 -2
  36. package/build/artifacts/contracts/offchain-helpers/router-static/base/StorageLayout.sol/StorageLayout.dbg.json +1 -1
  37. package/build/artifacts/contracts/router/ActionAddRemoveLiqV3.sol/ActionAddRemoveLiqV3.dbg.json +1 -1
  38. package/build/artifacts/contracts/router/ActionAddRemoveLiqV3.sol/ActionAddRemoveLiqV3.json +2 -124
  39. package/build/artifacts/contracts/router/ActionCallbackV3.sol/ActionCallbackV3.dbg.json +1 -1
  40. package/build/artifacts/contracts/router/ActionCallbackV3.sol/ActionCallbackV3.json +3 -51
  41. package/build/artifacts/contracts/router/ActionMiscV3.sol/ActionMiscV3.dbg.json +1 -1
  42. package/build/artifacts/contracts/router/ActionMiscV3.sol/ActionMiscV3.json +2 -50
  43. package/build/artifacts/contracts/router/ActionStorageV4.sol/ActionStorageV4.dbg.json +4 -0
  44. package/build/artifacts/contracts/router/ActionStorageV4.sol/ActionStorageV4.json +149 -0
  45. package/build/artifacts/contracts/router/ActionSwapPTV3.sol/ActionSwapPTV3.dbg.json +1 -1
  46. package/build/artifacts/contracts/router/ActionSwapPTV3.sol/ActionSwapPTV3.json +2 -76
  47. package/build/artifacts/contracts/router/ActionSwapYTV3.sol/ActionSwapYTV3.dbg.json +1 -1
  48. package/build/artifacts/contracts/router/ActionSwapYTV3.sol/ActionSwapYTV3.json +2 -92
  49. package/build/artifacts/contracts/router/PendleRouterV4.sol/PendleRouterV4.dbg.json +4 -0
  50. package/build/artifacts/contracts/router/PendleRouterV4.sol/PendleRouterV4.json +35 -0
  51. package/build/artifacts/contracts/router/RouterStorage.sol/RouterStorage.dbg.json +4 -0
  52. package/build/artifacts/contracts/router/RouterStorage.sol/RouterStorage.json +10 -0
  53. package/build/artifacts/contracts/router/base/ActionBase.sol/ActionBase.dbg.json +1 -1
  54. package/build/artifacts/contracts/router/base/MarketApproxLib.sol/MarketApproxPtInLib.dbg.json +1 -1
  55. package/build/artifacts/contracts/router/base/MarketApproxLib.sol/MarketApproxPtInLib.json +2 -2
  56. package/build/artifacts/contracts/router/base/MarketApproxLib.sol/MarketApproxPtOutLib.dbg.json +1 -1
  57. package/build/artifacts/contracts/router/base/MarketApproxLib.sol/MarketApproxPtOutLib.json +2 -2
  58. package/contracts/core/StandardizedYield/implementations/PendleERC20WithSupplyCapSY.sol +55 -0
  59. package/contracts/core/StandardizedYield/implementations/Tensorplex/PendleStTAOSY.sol +1 -1
  60. package/contracts/interfaces/IPActionStorageStatic.sol +1 -0
  61. package/contracts/interfaces/IPActionStorageV4.sol +25 -0
  62. package/contracts/interfaces/IPAllActionV3.sol +2 -2
  63. package/contracts/interfaces/IPMiniDiamond.sol +1 -0
  64. package/contracts/limit/LimitRouterBase.sol +48 -25
  65. package/contracts/router/ActionAddRemoveLiqV3.sol +12 -12
  66. package/contracts/router/ActionCallbackV3.sol +14 -13
  67. package/contracts/router/ActionMiscV3.sol +1 -3
  68. package/contracts/router/ActionStorageV4.sol +64 -0
  69. package/contracts/router/ActionSwapYTV3.sol +3 -3
  70. package/contracts/router/PendleRouterV4.sol +23 -0
  71. package/contracts/router/RouterStorage.sol +19 -0
  72. package/contracts/router/base/ActionBase.sol +5 -7
  73. package/contracts/router/base/MarketApproxLib.sol +18 -16
  74. package/deployments/1-core.json +1 -1
  75. package/deployments/1-markets/ENA-AUG2024.json +13 -0
  76. package/deployments/1-markets/EZETH-DEC2024.json +11 -0
  77. package/deployments/1-markets/SUSDE-JUL2024.json +13 -0
  78. package/deployments/1-markets/WEETH-DEC2024.json +13 -0
  79. package/deployments/10-core.json +1 -1
  80. package/deployments/42161-core.json +1 -1
  81. package/deployments/5000-core.json +1 -1
  82. package/deployments/56-core.json +1 -1
  83. package/deployments/56-markets/EZETH-BSC-SEP2024.json +13 -0
  84. package/package.json +1 -1
  85. package/typechain-types/ActionCallbackV3.ts +5 -5
  86. package/typechain-types/ActionStorageV4.ts +293 -0
  87. package/typechain-types/IPActionStorageV4.ts +293 -0
  88. package/typechain-types/IPAllActionV3.ts +208 -109
  89. package/typechain-types/PendleERC20WithSupplyCapSY.ts +1332 -0
  90. package/typechain-types/PendleRouterV4.ts +57 -0
  91. package/typechain-types/factories/ActionAddRemoveLiqV3__factory.ts +1 -123
  92. package/typechain-types/factories/ActionCallbackV3__factory.ts +2 -50
  93. package/typechain-types/factories/ActionInfoStatic__factory.ts +1 -1
  94. package/typechain-types/factories/ActionMarketAuxStatic__factory.ts +1 -1
  95. package/typechain-types/factories/ActionMarketCoreStatic__factory.ts +1 -27
  96. package/typechain-types/factories/ActionMintRedeemStatic__factory.ts +1 -1
  97. package/typechain-types/factories/ActionMiscV3__factory.ts +1 -49
  98. package/typechain-types/factories/ActionStorageStatic__factory.ts +1 -1
  99. package/typechain-types/factories/ActionStorageV4__factory.ts +202 -0
  100. package/typechain-types/factories/ActionSwapPTV3__factory.ts +1 -75
  101. package/typechain-types/factories/ActionSwapYTV3__factory.ts +1 -91
  102. package/typechain-types/factories/ActionVePendleStatic__factory.ts +1 -1
  103. package/typechain-types/factories/IPActionStorageV4__factory.ts +164 -0
  104. package/typechain-types/factories/IPAllActionV3__factory.ts +134 -72
  105. package/typechain-types/factories/PendleERC20WithSupplyCapSY__factory.ts +1157 -0
  106. package/typechain-types/factories/PendleLimitRouter__factory.ts +1 -1
  107. package/typechain-types/factories/PendlePoolDeployHelper__factory.ts +1 -1
  108. package/typechain-types/factories/PendleRouterStatic__factory.ts +1 -1
  109. package/typechain-types/factories/PendleRouterV4__factory.ts +96 -0
  110. package/typechain-types/factories/PendleStTAOSY__factory.ts +1 -1
  111. package/typechain-types/hardhat.d.ts +31 -58
  112. package/typechain-types/index.ts +8 -14
  113. package/build/artifacts/contracts/interfaces/IDiamondCut.sol/IDiamondCut.dbg.json +0 -4
  114. package/build/artifacts/contracts/interfaces/IDiamondCut.sol/IDiamondCut.json +0 -93
  115. package/build/artifacts/contracts/interfaces/IDiamondLoupe.sol/IDiamondLoupe.dbg.json +0 -4
  116. package/build/artifacts/contracts/interfaces/IDiamondLoupe.sol/IDiamondLoupe.json +0 -87
  117. package/build/artifacts/contracts/router/PendleRouterHelper.sol/PendleRouterHelper.dbg.json +0 -4
  118. package/build/artifacts/contracts/router/PendleRouterHelper.sol/PendleRouterHelper.json +0 -1002
  119. package/build/artifacts/contracts/router/PendleRouterHelper.sol/RouterV2InterfaceForRouterHelper.dbg.json +0 -4
  120. package/build/artifacts/contracts/router/PendleRouterHelper.sol/RouterV2InterfaceForRouterHelper.json +0 -466
  121. package/build/artifacts/contracts/router/PendleRouterV3.sol/PendleRouterV3.dbg.json +0 -4
  122. package/build/artifacts/contracts/router/PendleRouterV3.sol/PendleRouterV3.json +0 -179
  123. package/contracts/interfaces/IDiamondCut.sol +0 -32
  124. package/contracts/interfaces/IDiamondLoupe.sol +0 -38
  125. package/contracts/router/PendleRouterHelper.sol +0 -305
  126. package/contracts/router/PendleRouterV3.sol +0 -235
@@ -0,0 +1,55 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity ^0.8.17;
3
+
4
+ import "./PendleERC20SY.sol";
5
+
6
+ contract PendleERC20WithSupplyCapSY is PendleERC20SY {
7
+ uint256 public supplyCap;
8
+
9
+ event SupplyCapUpdated(uint256 newSupplyCap);
10
+
11
+ error SupplyCapExceeded(uint256 totalSupply, uint256 supplyCap);
12
+
13
+ constructor(string memory _name, string memory _symbol, address _erc20, uint256 _initialSupplyCap) PendleERC20SY(_name, _symbol, _erc20) {
14
+ _updateSupplyCap(_initialSupplyCap);
15
+ }
16
+
17
+ function _previewDeposit(
18
+ address /*tokenIn*/,
19
+ uint256 amountTokenToDeposit
20
+ ) internal view override returns (uint256 /*amountSharesOut*/) {
21
+ uint256 _newSupply = totalSupply() + amountTokenToDeposit;
22
+ uint256 _supplyCap = supplyCap;
23
+
24
+ if (_newSupply > _supplyCap) {
25
+ revert SupplyCapExceeded(_newSupply, _supplyCap);
26
+ }
27
+
28
+ return amountTokenToDeposit;
29
+ }
30
+
31
+ function updateSupplyCap(uint256 newSupplyCap) external onlyOwner {
32
+ _updateSupplyCap(newSupplyCap);
33
+ }
34
+
35
+ function _updateSupplyCap(uint256 newSupplyCap) internal {
36
+ supplyCap = newSupplyCap;
37
+ emit SupplyCapUpdated(newSupplyCap);
38
+ }
39
+
40
+ // @dev: whenNotPaused not needed as it has already been added to beforeTransfer
41
+ function _afterTokenTransfer(address from, address, uint256) internal virtual override {
42
+ // only check for minting case
43
+ // saving gas on user->user transfers
44
+ // skip supply cap checking on burn to allow lowering supply cap
45
+ if (from != address(0)) {
46
+ return;
47
+ }
48
+
49
+ uint256 _supply = totalSupply();
50
+ uint256 _supplyCap = supplyCap;
51
+ if (_supply > _supplyCap) {
52
+ revert SupplyCapExceeded(_supply, _supplyCap);
53
+ }
54
+ }
55
+ }
@@ -25,7 +25,7 @@ contract PendleStTAOSY is SYBaseUpg {
25
25
  wTAO = ITensorplexStTAO(stTAO).wrappedToken();
26
26
  }
27
27
 
28
- function initialize() initializer external {
28
+ function initialize() external initializer {
29
29
  __SYBaseUpg_init("SY Tensorplex Staked TAO", "SY-stTAO");
30
30
  _safeApproveInf(wTAO, stTAO);
31
31
  }
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
1
2
  pragma solidity ^0.8.0;
2
3
 
3
4
  import "../router/base/MarketApproxLib.sol";
@@ -0,0 +1,25 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity ^0.8.0;
3
+
4
+ interface IPActionStorageV4 {
5
+ struct SelectorsToFacet {
6
+ address facet;
7
+ bytes4[] selectors;
8
+ }
9
+
10
+ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
11
+
12
+ event SelectorToFacetSet(bytes4 indexed selector, address indexed facet);
13
+
14
+ function owner() external view returns (address);
15
+
16
+ function pendingOwner() external view returns (address);
17
+
18
+ function transferOwnership(address newOwner, bool direct, bool renounce) external;
19
+
20
+ function claimOwnership() external;
21
+
22
+ function setSelectorToFacets(SelectorsToFacet[] calldata arr) external;
23
+
24
+ function selectorToFacet(bytes4 selector) external view returns (address);
25
+ }
@@ -7,7 +7,7 @@ import "./IPActionSwapPTV3.sol";
7
7
  import "./IPActionSwapYTV3.sol";
8
8
  import "./IPActionMiscV3.sol";
9
9
  import "./IPActionCallbackV3.sol";
10
- import "./IDiamondLoupe.sol";
10
+ import "./IPActionStorageV4.sol";
11
11
 
12
12
  interface IPAllActionV3 is
13
13
  IPActionAddRemoveLiqV3,
@@ -15,5 +15,5 @@ interface IPAllActionV3 is
15
15
  IPActionSwapYTV3,
16
16
  IPActionMiscV3,
17
17
  IPActionCallbackV3,
18
- IDiamondLoupe
18
+ IPActionStorageV4
19
19
  {}
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
1
2
  pragma solidity ^0.8.0;
2
3
 
3
4
  interface IPMiniDiamond {
@@ -30,6 +30,7 @@ abstract contract LimitRouterBase is
30
30
  uint128 internal constant _ORDER_DOES_NOT_EXIST = 0;
31
31
  uint128 internal constant _ORDER_FILLED = 1;
32
32
  uint256 internal constant NEW_PRIME = 12421;
33
+ bytes private constant EMPTY_BYTES = abi.encode();
33
34
 
34
35
  address public feeRecipient;
35
36
 
@@ -62,7 +63,9 @@ abstract contract LimitRouterBase is
62
63
  bytes calldata /*optData*/,
63
64
  bytes memory callback
64
65
  ) external returns (uint256 actualMaking, uint256 actualTaking, uint256 totalFee, bytes memory callbackReturn) {
65
- _validateOrdersSkipSig(params);
66
+ params = _validateSkipSigAndFilterOrders(params);
67
+ if (params.length == 0) return fillNoOrders(callback);
68
+
66
69
  OrderType orderType = params[0].order.orderType;
67
70
  if (orderType == OrderType.SY_FOR_PT || orderType == OrderType.SY_FOR_YT) {
68
71
  return fillTokenForPY(Args(orderType, params, receiver, maxTaking, callback));
@@ -81,6 +84,13 @@ abstract contract LimitRouterBase is
81
84
  bytes callback;
82
85
  }
83
86
 
87
+ function fillNoOrders(
88
+ bytes memory callback
89
+ ) internal returns (uint256 actualMaking, uint256 actualTaking, uint256 totalFee, bytes memory callbackReturn) {
90
+ callbackReturn = callbackIfNeeded(0, 0, 0, callback);
91
+ return (0, 0, 0, callbackReturn);
92
+ }
93
+
84
94
  function fillTokenForPY(
85
95
  Args memory a
86
96
  ) internal returns (uint256 actualMaking, uint256 actualTaking, uint256 totalFee, bytes memory callbackReturn) {
@@ -98,14 +108,7 @@ abstract contract LimitRouterBase is
98
108
  _transferOut(SY, a.receiver, actualMaking);
99
109
 
100
110
  // callback to Taker
101
- if (a.callback.length > 0) {
102
- callbackReturn = IPLimitRouterCallback(msg.sender).limitRouterCallback(
103
- actualMaking,
104
- actualTaking,
105
- totalFee,
106
- a.callback
107
- );
108
- }
111
+ callbackReturn = callbackIfNeeded(actualMaking, actualTaking, totalFee, a.callback);
109
112
 
110
113
  // Taker => Makers
111
114
  address pyToMaker = (a.orderType == OrderType.SY_FOR_PT) ? PT : YT;
@@ -133,14 +136,7 @@ abstract contract LimitRouterBase is
133
136
  _transferFromMakers(IERC20(pyFromMaker), a.params, a.receiver, out.netMakings);
134
137
 
135
138
  // callback to Taker
136
- if (a.callback.length > 0) {
137
- callbackReturn = IPLimitRouterCallback(msg.sender).limitRouterCallback(
138
- actualMaking,
139
- actualTaking,
140
- totalFee,
141
- a.callback
142
- );
143
- }
139
+ callbackReturn = callbackIfNeeded(actualMaking, actualTaking, totalFee, a.callback);
144
140
 
145
141
  // Taker => This
146
142
  _transferFrom(IERC20(SY), msg.sender, address(this), actualTaking);
@@ -156,22 +152,33 @@ abstract contract LimitRouterBase is
156
152
  }
157
153
 
158
154
  // ----------------- verify & convert functions -----------------
159
- function _validateOrdersSkipSig(FillOrderParams[] memory params) internal view {
155
+ function _validateSkipSigAndFilterOrders(
156
+ FillOrderParams[] memory params
157
+ ) internal view returns (FillOrderParams[] memory res) {
160
158
  uint256 len = params.length;
161
159
  require(len != 0, "LOP: empty batch");
162
160
 
163
161
  (address YT, OrderType orderType) = (params[0].order.YT, params[0].order.orderType);
162
+ require(block.timestamp < IPYieldToken(YT).expiry(), "LOP: PY expired");
164
163
 
165
- uint256 expiry = IPYieldToken(YT).expiry();
166
- require(block.timestamp < expiry, "LOP: PY expired");
167
-
164
+ uint256 skipped = 0;
168
165
  for (uint256 i = 0; i < len; i++) {
169
166
  Order memory order = params[i].order;
167
+ require(order.orderType == orderType && order.YT == YT, "LOP: mismatch types");
168
+
169
+ if (!(block.timestamp < order.expiry && order.nonce >= nonce[order.maker])) {
170
+ skipped++;
171
+ params[i].signature = EMPTY_BYTES;
172
+ }
173
+ }
170
174
 
171
- require(order.orderType == orderType, "LOP: not same orderType");
172
- require(order.YT == YT, "LOP: not same YT");
173
- require(block.timestamp < order.expiry, "LOP: order expired");
174
- require(order.nonce >= nonce[order.maker], "LOP: order invalidated");
175
+ res = new FillOrderParams[](len - skipped);
176
+ uint256 iter = 0;
177
+ for (uint256 i = 0; i < len; i++) {
178
+ if (params[i].signature.length != 0) {
179
+ res[iter] = params[i];
180
+ iter++;
181
+ }
175
182
  }
176
183
  }
177
184
 
@@ -235,6 +242,22 @@ abstract contract LimitRouterBase is
235
242
  }
236
243
  }
237
244
 
245
+ function callbackIfNeeded(
246
+ uint256 actualMaking,
247
+ uint256 actualTaking,
248
+ uint256 totalFee,
249
+ bytes memory callback
250
+ ) internal returns (bytes memory callbackReturn) {
251
+ if (callback.length > 0) {
252
+ callbackReturn = IPLimitRouterCallback(msg.sender).limitRouterCallback(
253
+ actualMaking,
254
+ actualTaking,
255
+ totalFee,
256
+ callback
257
+ );
258
+ }
259
+ }
260
+
238
261
  function _checkSig(
239
262
  Order memory order,
240
263
  bytes memory signature
@@ -29,14 +29,14 @@ contract ActionAddRemoveLiqV3 is IPActionAddRemoveLiqV3, ActionBase {
29
29
  (, , netSyUsed, netPtUsed) = _readMarket(market).addLiquidity(netSyInterm, netPtDesired, block.timestamp);
30
30
 
31
31
  if (netSyInterm != netSyUsed) {
32
- revert Errors.RouterNotAllSyUsed(netSyInterm, netSyUsed);
32
+ revert("Slippage: NOT_ALL_SY_USED");
33
33
  }
34
34
 
35
35
  // SY has been minted and transferred to the market
36
36
  _transferFrom(PT, msg.sender, market, netPtUsed);
37
37
  (netLpOut, , ) = IPMarket(market).mint(receiver, netSyUsed, netPtUsed);
38
38
 
39
- if (netLpOut < minLpOut) revert Errors.RouterInsufficientLpOut(netLpOut, minLpOut);
39
+ if (netLpOut < minLpOut) revert("Slippage: INSUFFICIENT_LP_OUT");
40
40
 
41
41
  emit AddLiquidityDualTokenAndPt(
42
42
  msg.sender,
@@ -70,7 +70,7 @@ contract ActionAddRemoveLiqV3 is IPActionAddRemoveLiqV3, ActionBase {
70
70
  _transferFrom(PT, msg.sender, market, netPtUsed);
71
71
  (netLpOut, , ) = IPMarket(market).mint(receiver, netSyUsed, netPtUsed);
72
72
 
73
- if (netLpOut < minLpOut) revert Errors.RouterInsufficientLpOut(netLpOut, minLpOut);
73
+ if (netLpOut < minLpOut) revert("Slippage: INSUFFICIENT_LP_OUT");
74
74
 
75
75
  emit AddLiquidityDualSyAndPt(msg.sender, market, receiver, netSyUsed, netPtUsed, netLpOut);
76
76
  }
@@ -118,7 +118,7 @@ contract ActionAddRemoveLiqV3 is IPActionAddRemoveLiqV3, ActionBase {
118
118
  // execute the addLiquidity
119
119
  (netLpOut, , ) = IPMarket(market).mint(receiver, netSyReceived, netPtLeft);
120
120
 
121
- if (netLpOut < minLpOut) revert Errors.RouterInsufficientLpOut(netLpOut, minLpOut);
121
+ if (netLpOut < minLpOut) revert("Slippage: INSUFFICIENT_LP_OUT");
122
122
 
123
123
  emit AddLiquiditySinglePt(msg.sender, market, receiver, netPtIn, netLpOut);
124
124
  }
@@ -231,7 +231,7 @@ contract ActionAddRemoveLiqV3 is IPActionAddRemoveLiqV3, ActionBase {
231
231
 
232
232
  (netLpOut, , ) = IPMarket(market).mint(receiver, netSyLeft, netPtReceived);
233
233
 
234
- if (netLpOut < minLpOut) revert Errors.RouterInsufficientLpOut(netLpOut, minLpOut);
234
+ if (netLpOut < minLpOut) revert("Slippage: INSUFFICIENT_LP_OUT");
235
235
  }
236
236
 
237
237
  // ------------------ ADD LIQUIDITY SINGLE TOKEN KEEP YT ------------------
@@ -324,8 +324,8 @@ contract ActionAddRemoveLiqV3 is IPActionAddRemoveLiqV3, ActionBase {
324
324
 
325
325
  (netLpOut, , ) = IPMarket(market).mint(receiver, netSyAddLiquidity, netYtOut);
326
326
 
327
- if (netLpOut < minLpOut) revert Errors.RouterInsufficientLpOut(netLpOut, minLpOut);
328
- if (netYtOut < minYtOut) revert Errors.RouterInsufficientYtOut(netYtOut, minYtOut);
327
+ if (netLpOut < minLpOut) revert("Slippage: INSUFFICIENT_LP_OUT");
328
+ if (netYtOut < minYtOut) revert("Slippage: INSUFFICIENT_YT_OUT");
329
329
  }
330
330
 
331
331
  // ------------------ REMOVE LIQUIDITY DUAL ------------------
@@ -343,7 +343,7 @@ contract ActionAddRemoveLiqV3 is IPActionAddRemoveLiqV3, ActionBase {
343
343
  _transferFrom(IERC20(market), msg.sender, market, netLpToRemove);
344
344
 
345
345
  (netSyInterm, netPtOut) = IPMarket(market).burn(address(SY), receiver, netLpToRemove);
346
- if (netPtOut < minPtOut) revert Errors.RouterInsufficientPtOut(netPtOut, minPtOut);
346
+ if (netPtOut < minPtOut) revert("Slippage: INSUFFICIENT_PT_OUT");
347
347
 
348
348
  // redeem SY to token
349
349
  netTokenOut = _redeemSyToToken(receiver, address(SY), netSyInterm, output, false);
@@ -370,8 +370,8 @@ contract ActionAddRemoveLiqV3 is IPActionAddRemoveLiqV3, ActionBase {
370
370
 
371
371
  (netSyOut, netPtOut) = IPMarket(market).burn(receiver, receiver, netLpToRemove);
372
372
 
373
- if (netSyOut < minSyOut) revert Errors.RouterInsufficientSyOut(netSyOut, minSyOut);
374
- if (netPtOut < minPtOut) revert Errors.RouterInsufficientPtOut(netPtOut, minPtOut);
373
+ if (netSyOut < minSyOut) revert("Slippage: INSUFFICIENT_SY_OUT");
374
+ if (netPtOut < minPtOut) revert("Slippage: INSUFFICIENT_PT_OUT");
375
375
 
376
376
  emit RemoveLiquidityDualSyAndPt(msg.sender, market, receiver, netLpToRemove, netPtOut, netSyOut);
377
377
  }
@@ -408,7 +408,7 @@ contract ActionAddRemoveLiqV3 is IPActionAddRemoveLiqV3, ActionBase {
408
408
  netPtOut += netPtOutSwap;
409
409
  netSyFee += netSyFeeSwap;
410
410
 
411
- if (netPtOut < minPtOut) revert Errors.RouterInsufficientPtOut(netPtOut, minPtOut);
411
+ if (netPtOut < minPtOut) revert("Slippage: INSUFFICIENT_PT_OUT");
412
412
 
413
413
  emit RemoveLiquiditySinglePt(msg.sender, market, receiver, netLpToRemove, netPtOut);
414
414
  }
@@ -468,7 +468,7 @@ contract ActionAddRemoveLiqV3 is IPActionAddRemoveLiqV3, ActionBase {
468
468
  } else {
469
469
  (netSyOut, netSyFee) = __removeLpToSyBeforeExpiry(receiver, market, netLpToRemove, limit);
470
470
  }
471
- if (netSyOut < minSyOut) revert Errors.RouterInsufficientSyOut(netSyOut, minSyOut);
471
+ if (netSyOut < minSyOut) revert("Slippage: INSUFFICIENT_SY_OUT");
472
472
  }
473
473
 
474
474
  function __removeLpToSyAfterExpiry(
@@ -31,14 +31,19 @@ contract ActionCallbackV3 is IPLimitOrderType, IPActionCallbackV3, CallbackHelpe
31
31
  function limitRouterCallback(
32
32
  uint256 actualMaking,
33
33
  uint256 actualTaking,
34
- uint256,
35
- /*totalFee*/ bytes memory data
34
+ uint256 totalFee,
35
+ bytes memory data
36
36
  )
37
37
  external
38
38
  returns (
39
39
  bytes memory // encode as netTransferToLimit, netOutputFromLimit
40
40
  )
41
41
  {
42
+ bool isEmptyFill = (actualMaking == 0 && actualTaking == 0 && totalFee == 0);
43
+ if (isEmptyFill) {
44
+ return abi.encode(0, 0);
45
+ }
46
+
42
47
  (OrderType orderType, IPYieldToken YT, uint256 netRemaining, address receiver) = abi.decode(
43
48
  data,
44
49
  (OrderType, IPYieldToken, uint256, address)
@@ -49,7 +54,7 @@ contract ActionCallbackV3 is IPLimitOrderType, IPActionCallbackV3, CallbackHelpe
49
54
  uint256 totalSyToMintPy = index.assetToSyUp(actualTaking);
50
55
  uint256 additionalSyToMint = totalSyToMintPy - actualMaking;
51
56
 
52
- require(additionalSyToMint <= netRemaining, "Router: Max SY to pull exceeded");
57
+ require(additionalSyToMint <= netRemaining, "Slippage: INSUFFICIENT_SY_LIMIT");
53
58
 
54
59
  _transferOut(YT.SY(), address(YT), additionalSyToMint);
55
60
 
@@ -64,7 +69,7 @@ contract ActionCallbackV3 is IPLimitOrderType, IPActionCallbackV3, CallbackHelpe
64
69
 
65
70
  return abi.encode(additionalSyToMint, netPyToReceiver);
66
71
  } else {
67
- require(actualMaking <= netRemaining, "Router: Max PY to pull exceeded");
72
+ require(actualMaking <= netRemaining, "Slippage: INSUFFICIENT_PY_LIMIT");
68
73
 
69
74
  if (orderType == OrderType.PT_FOR_SY) {
70
75
  _transferOut(address(YT), address(YT), actualMaking);
@@ -74,7 +79,7 @@ contract ActionCallbackV3 is IPLimitOrderType, IPActionCallbackV3, CallbackHelpe
74
79
 
75
80
  uint256 netSyRedeemed = IPYieldToken(YT).redeemPY(address(this));
76
81
 
77
- require(actualTaking <= netSyRedeemed, "Router: Insufficient SY redeemed");
82
+ require(actualTaking <= netSyRedeemed, "Slippage: INSUFFICIENT_PY_REDEEM");
78
83
 
79
84
  uint256 netSyToReceiver = netSyRedeemed - actualTaking;
80
85
 
@@ -93,7 +98,7 @@ contract ActionCallbackV3 is IPLimitOrderType, IPActionCallbackV3, CallbackHelpe
93
98
  uint256 ptOwed = ptToAccount.abs();
94
99
  uint256 netPyOut = YT.mintPY(msg.sender, receiver);
95
100
 
96
- if (netPyOut < ptOwed) revert Errors.RouterInsufficientPtRepay(netPyOut, ptOwed);
101
+ if (netPyOut < ptOwed) revert("Slippage: INSUFFICIENT_PT_REPAY");
97
102
  }
98
103
 
99
104
  function _callbackSwapYtForSy(int256 ptToAccount, int256 syToAccount, bytes calldata data) internal {
@@ -116,10 +121,8 @@ contract ActionCallbackV3 is IPLimitOrderType, IPActionCallbackV3, CallbackHelpe
116
121
  uint256 netPtOwed = ptToAccount.abs();
117
122
 
118
123
  uint256 netPyOut = YT.mintPY(msg.sender, receiver);
119
- if (netPyOut < minYtOut) revert Errors.RouterInsufficientYtOut(netPyOut, minYtOut);
120
- if (exactPtIn + netPyOut < netPtOwed) {
121
- revert Errors.RouterInsufficientPtRepay(exactPtIn + netPyOut, netPtOwed);
122
- }
124
+ if (netPyOut < minYtOut) revert("Slippage: INSUFFICIENT_YT_OUT");
125
+ if (exactPtIn + netPyOut < netPtOwed) revert("Slippage: INSUFFICIENT_PT_REPAY");
123
126
  }
124
127
 
125
128
  function _callbackSwapExactYtForPt(int256 ptToAccount, int256 syToAccount, bytes calldata data) internal {
@@ -132,9 +135,7 @@ contract ActionCallbackV3 is IPLimitOrderType, IPActionCallbackV3, CallbackHelpe
132
135
 
133
136
  uint256 netSyToMarket = YT.redeemPY(msg.sender);
134
137
 
135
- if (netSyToMarket < netSyOwed) {
136
- revert Errors.RouterInsufficientSyRepay(netSyToMarket, netSyOwed);
137
- }
138
+ if (netSyToMarket < netSyOwed) revert("Slippage: INSUFFICIENT_SY_REPAY");
138
139
 
139
140
  _transferOut(address(PT), receiver, netPtOut);
140
141
  }
@@ -102,9 +102,7 @@ contract ActionMiscV3 is IPActionMiscV3, ActionBase {
102
102
  _swapTokenInput(inp);
103
103
 
104
104
  netTokenOut = _selfBalance(inp.tokenMintSy);
105
- if (netTokenOut < minTokenOut) {
106
- revert Errors.RouterInsufficientTokenOut(netTokenOut, minTokenOut);
107
- }
105
+ if (netTokenOut < minTokenOut) revert("Slippage: INSUFFICIENT_TOKEN_OUT");
108
106
 
109
107
  _transferOut(inp.tokenMintSy, receiver, netTokenOut);
110
108
  }
@@ -0,0 +1,64 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity ^0.8.17;
3
+
4
+ import "../interfaces/IPActionStorageV4.sol";
5
+ import "./RouterStorage.sol";
6
+
7
+ contract ActionStorageV4 is RouterStorage, IPActionStorageV4 {
8
+ modifier onlyOwner() {
9
+ require(msg.sender == owner(), "Ownable: caller is not the owner");
10
+ _;
11
+ }
12
+
13
+ function owner() public view returns (address) {
14
+ return _getCoreStorage().owner;
15
+ }
16
+
17
+ function pendingOwner() public view returns (address) {
18
+ return _getCoreStorage().pendingOwner;
19
+ }
20
+
21
+ function setSelectorToFacets(SelectorsToFacet[] calldata arr) external onlyOwner {
22
+ CoreStorage storage $ = _getCoreStorage();
23
+
24
+ for (uint256 i = 0; i < arr.length; i++) {
25
+ SelectorsToFacet memory s = arr[i];
26
+ for (uint256 j = 0; j < s.selectors.length; j++) {
27
+ $.selectorToFacet[s.selectors[j]] = s.facet;
28
+ emit SelectorToFacetSet(s.selectors[j], s.facet);
29
+ }
30
+ }
31
+ }
32
+
33
+ function selectorToFacet(bytes4 selector) external view returns (address) {
34
+ CoreStorage storage $ = _getCoreStorage();
35
+ return $.selectorToFacet[selector];
36
+ }
37
+
38
+ // Ownable
39
+ function transferOwnership(address newOwner, bool direct, bool renounce) external onlyOwner {
40
+ CoreStorage storage $ = _getCoreStorage();
41
+
42
+ if (direct) {
43
+ require(newOwner != address(0) || renounce, "Ownable: zero address");
44
+
45
+ emit OwnershipTransferred($.owner, newOwner);
46
+ $.owner = newOwner;
47
+ $.pendingOwner = address(0);
48
+ } else {
49
+ $.pendingOwner = newOwner;
50
+ }
51
+ }
52
+
53
+ function claimOwnership() external {
54
+ CoreStorage storage $ = _getCoreStorage();
55
+
56
+ address _pendingOwner = $.pendingOwner;
57
+
58
+ require(msg.sender == _pendingOwner, "Ownable: caller != pending owner");
59
+
60
+ emit OwnershipTransferred($.owner, _pendingOwner);
61
+ $.owner = _pendingOwner;
62
+ $.pendingOwner = address(0);
63
+ }
64
+ }
@@ -94,7 +94,7 @@ contract ActionSwapYTV3 is CallbackHelper, IPActionSwapYTV3, ActionBase {
94
94
  netSyFee += netSyFeeMarket;
95
95
  }
96
96
 
97
- if (netYtOut < minYtOut) revert Errors.RouterInsufficientYtOut(netYtOut, minYtOut);
97
+ if (netYtOut < minYtOut) revert("Slippage: INSUFFICIENT_YT_OUT");
98
98
  }
99
99
 
100
100
  // ------------------ SWAP TOKEN FOR TOKEN ------------------
@@ -175,7 +175,7 @@ contract ActionSwapYTV3 is CallbackHelper, IPActionSwapYTV3, ActionBase {
175
175
  netSyOut += SY.balanceOf(receiver) - preSyBalance;
176
176
  }
177
177
 
178
- if (netSyOut < minSyOut) revert Errors.RouterInsufficientSyOut(netSyOut, minSyOut);
178
+ if (netSyOut < minSyOut) revert("Slippage: INSUFFICIENT_SY_OUT");
179
179
  }
180
180
 
181
181
  // ------------------ SWAP PT FOR YT ------------------
@@ -226,7 +226,7 @@ contract ActionSwapYTV3 is CallbackHelper, IPActionSwapYTV3, ActionBase {
226
226
  guessTotalPtFromSwap
227
227
  );
228
228
 
229
- if (netPtOut < minPtOut) revert Errors.RouterInsufficientPtOut(netPtOut, minPtOut);
229
+ if (netPtOut < minPtOut) revert("Slippage: INSUFFICIENT_PT_OUT");
230
230
 
231
231
  _transferFrom(IERC20(YT), msg.sender, address(YT), exactYtIn);
232
232
  IPMarket(market).swapSyForExactPt(
@@ -0,0 +1,23 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity ^0.8.17;
3
+
4
+ import "@openzeppelin/contracts/proxy/Proxy.sol";
5
+ import "../interfaces/IPActionStorageV4.sol";
6
+ import "./RouterStorage.sol";
7
+
8
+ contract PendleRouterV4 is Proxy, RouterStorage {
9
+ constructor(address _owner, address actionStorage) {
10
+ RouterStorage.CoreStorage storage $ = _getCoreStorage();
11
+ $.owner = _owner;
12
+ $.selectorToFacet[IPActionStorageV4.setSelectorToFacets.selector] = actionStorage;
13
+ }
14
+
15
+ function _implementation() internal view override returns (address) {
16
+ RouterStorage.CoreStorage storage $ = _getCoreStorage();
17
+ address facet = $.selectorToFacet[msg.sig];
18
+ require(facet != address(0), "INVALID_SELECTOR");
19
+ return facet;
20
+ }
21
+
22
+ receive() external payable override {}
23
+ }
@@ -0,0 +1,19 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity ^0.8.17;
3
+
4
+ abstract contract RouterStorage {
5
+ struct CoreStorage {
6
+ address owner;
7
+ address pendingOwner;
8
+ mapping(bytes4 => address) selectorToFacet;
9
+ }
10
+
11
+ // keccak256(abi.encode(uint256(keccak256("pendle.routerv4.Core")) - 1)) & ~bytes32(uint256(0xff))
12
+ bytes32 private constant CORE_STORAGE_LOCATION = 0xf168c5b0cb4aca9a68f931815c18a144c61ad01d6dd7ca15bd6741672a0ab800;
13
+
14
+ function _getCoreStorage() internal pure returns (CoreStorage storage $) {
15
+ assembly {
16
+ $.slot := CORE_STORAGE_LOCATION
17
+ }
18
+ }
19
+ }
@@ -101,9 +101,7 @@ abstract contract ActionBase is TokenHelper, IPLimitOrderType {
101
101
  _transferOut(out.tokenOut, receiver, netTokenOut);
102
102
  }
103
103
 
104
- if (netTokenOut < out.minTokenOut) {
105
- revert Errors.RouterInsufficientTokenOut(netTokenOut, out.minTokenOut);
106
- }
104
+ if (netTokenOut < out.minTokenOut) revert("Slippage: INSUFFICIENT_TOKEN_OUT");
107
105
  }
108
106
 
109
107
  function __redeemSy(
@@ -133,7 +131,7 @@ abstract contract ActionBase is TokenHelper, IPLimitOrderType {
133
131
  }
134
132
 
135
133
  netPyOut = IPYieldToken(YT).mintPY(receiver, receiver);
136
- if (netPyOut < minPyOut) revert Errors.RouterInsufficientPYOut(netPyOut, minPyOut);
134
+ if (netPyOut < minPyOut) revert("Slippage: INSUFFICIENT_PT_YT_OUT");
137
135
  }
138
136
 
139
137
  function _redeemPyToSy(
@@ -150,7 +148,7 @@ abstract contract ActionBase is TokenHelper, IPLimitOrderType {
150
148
  if (needToBurnYt) _transferFrom(IERC20(YT), msg.sender, YT, netPyIn);
151
149
 
152
150
  netSyOut = IPYieldToken(YT).redeemPY(receiver);
153
- if (netSyOut < minSyOut) revert Errors.RouterInsufficientSyOut(netSyOut, minSyOut);
151
+ if (netSyOut < minSyOut) revert("Slippage: INSUFFICIENT_SY_OUT");
154
152
  }
155
153
 
156
154
  // ----------------- HELPER -----------------
@@ -195,7 +193,7 @@ abstract contract ActionBase is TokenHelper, IPLimitOrderType {
195
193
  netSyFee += netSyFeeMarket;
196
194
  }
197
195
 
198
- if (netSyOut < minSyOut) revert Errors.RouterInsufficientSyOut(netSyOut, minSyOut);
196
+ if (netSyOut < minSyOut) revert("Slippage: INSUFFICIENT_SY_OUT");
199
197
  }
200
198
 
201
199
  function _entry_swapExactSyForPt(address market, LimitOrderData calldata limit) internal view returns (address) {
@@ -235,7 +233,7 @@ abstract contract ActionBase is TokenHelper, IPLimitOrderType {
235
233
  netSyFee += netSyFeeMarket;
236
234
  }
237
235
 
238
- if (netPtOut < minPtOut) revert Errors.RouterInsufficientPtOut(netPtOut, minPtOut);
236
+ if (netPtOut < minPtOut) revert("Slippage: INSUFFICIENT_PT_OUT");
239
237
  }
240
238
 
241
239
  // ----------------- LIMIT ORDERS -----------------