@pendle/core-v2 0.11.1-testnet → 0.11.2-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 (30) hide show
  1. package/contracts/core/LiquidityMining/GaugeController/PendleGaugeControllerBaseUpg.sol +1 -1
  2. package/contracts/core/LiquidityMining/PendleGauge.sol +1 -1
  3. package/contracts/core/LiquidityMining/VotingController/PendleVotingControllerUpg.sol +2 -1
  4. package/contracts/core/LiquidityMining/VotingEscrow/VotingEscrowTokenBase.sol +2 -2
  5. package/contracts/core/Market/PendleMarketFactory.sol +16 -11
  6. package/contracts/core/PendleRouter.sol +3 -1
  7. package/contracts/core/YieldContracts/PendlePrincipalToken.sol +1 -1
  8. package/contracts/core/YieldContracts/PendleYieldContractFactory.sol +5 -5
  9. package/contracts/core/actions/base/ActionBaseMintRedeem.sol +1 -0
  10. package/contracts/interfaces/IPGaugeController.sol +1 -1
  11. package/contracts/interfaces/IPMarketFactory.sol +1 -1
  12. package/contracts/interfaces/ISJoe.sol +6 -3
  13. package/contracts/libraries/kyberswap/KyberSwapHelper.sol +1 -7
  14. package/contracts/libraries/math/WeekMath.sol +1 -1
  15. package/contracts/offchain-helpers/RouterStatic.sol +5 -5
  16. package/contracts/periphery/BoringOwnableUpgradeable.sol +2 -2
  17. package/contracts/periphery/PendleGovernanceManager.sol +38 -0
  18. package/contracts/periphery/PermissionsV2Upg.sol +29 -0
  19. package/deployments/43113-core.json +7 -8
  20. package/deployments/43113-markets/benqi-market-10D931.json +8 -0
  21. package/deployments/43113-markets/benqi-market-9fbD64.json +8 -0
  22. package/deployments/43113-markets/benqi-market-A12361.json +8 -0
  23. package/deployments/43113-testenv.json +1 -1
  24. package/package.json +5 -4
  25. package/contracts/libraries/kyberswap/AggregationRouterHelper.sol +0 -308
  26. package/contracts/libraries/kyberswap/IMultihopRouter.sol +0 -139
  27. package/contracts/offchain-helpers/SSTORE2DeployerContract.sol +0 -21
  28. package/deployments/43113-markets/benqi-market-QI-USDC-FEB-2ND.json +0 -8
  29. package/deployments/43113-markets/benqi-market-QI-USDC-SEP-22TH.json +0 -8
  30. package/deployments/43113-markets/benqi-market-QI-WETH-DEC-1ST.json +0 -8
@@ -62,7 +62,7 @@ abstract contract PendleGaugeControllerBaseUpg is IPGaugeController, BoringOwnab
62
62
  - rewardData[market] is updated with the data up to now
63
63
  - all accumulatedPendle is transferred out & the accumulatedPendle is set to 0
64
64
  */
65
- function redeemMarketReward() external onlyPendleMarket {
65
+ function claimMarketReward() external onlyPendleMarket {
66
66
  address market = msg.sender;
67
67
  rewardData[market] = _getUpdatedMarketReward(market);
68
68
 
@@ -97,7 +97,7 @@ abstract contract PendleGauge is RewardManager, IPGauge {
97
97
 
98
98
  function _redeemExternalReward() internal virtual override {
99
99
  ISuperComposableYield(SCY).claimRewards(address(this));
100
- IPGaugeController(gaugeController).redeemMarketReward();
100
+ IPGaugeController(gaugeController).claimMarketReward();
101
101
  }
102
102
 
103
103
  function _stakedBalance(address user) internal view virtual returns (uint256);
@@ -7,7 +7,8 @@ import "../../../libraries/VeBalanceLib.sol";
7
7
  import "../../../libraries/math/Math.sol";
8
8
  import "../../../interfaces/IPGaugeControllerMainchain.sol";
9
9
  import "../../../interfaces/IPVotingController.sol";
10
- import "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
10
+ import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
11
+ import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
11
12
 
12
13
  /*
13
14
  Voting accounting:
@@ -23,9 +23,9 @@ abstract contract VotingEscrowTokenBase is IPVeToken {
23
23
  using VeBalanceLib for VeBalance;
24
24
  using VeBalanceLib for LockedPosition;
25
25
 
26
- uint128 public constant WEEK = 2 hours;
26
+ uint128 public constant WEEK = 1 weeks;
27
27
  uint128 public constant MAX_LOCK_TIME = 104 weeks;
28
- uint128 public constant MIN_LOCK_TIME = 1 hours;
28
+ uint128 public constant MIN_LOCK_TIME = 1 weeks;
29
29
 
30
30
  VeBalance internal _totalSupply;
31
31
  uint128 public lastSlopeChangeAppliedAt;
@@ -17,47 +17,52 @@ contract PendleMarketFactory is BoringOwnableUpgradeable, IPMarketFactory {
17
17
 
18
18
  struct MarketConfig {
19
19
  address treasury;
20
- uint88 lnFeeRateRoot;
21
- uint8 reserveFeePercent;
20
+ uint96 lnFeeRateRoot;
22
21
  // 1 SLOT = 256 bits
22
+ uint8 reserveFeePercent;
23
+ // 1 SLOT = 8 bits
23
24
  }
24
25
 
26
+ uint256 private constant MIN_RATE_ORACLE_TIME_WINDOW = 300 seconds;
27
+
25
28
  address public immutable yieldContractFactory;
26
- address public immutable marketCreationCodePointer;
29
+ address public marketCreationCodePointer;
27
30
  uint256 public immutable maxLnFeeRateRoot;
28
31
 
29
32
  // PT -> scalarRoot -> initialAnchor
30
33
  mapping(address => mapping(int256 => mapping(int256 => address))) internal markets;
31
34
  EnumerableSet.AddressSet internal allMarkets;
35
+
32
36
  address public vePendle;
33
37
  address public gaugeController;
34
38
 
35
39
  MarketConfig public marketConfig;
36
40
 
37
- constructor(address _yieldContractFactory, address _marketCreationCodePointer) {
41
+ constructor(
42
+ address _yieldContractFactory
43
+ ) {
38
44
  require(_yieldContractFactory != address(0), "zero address");
39
45
  yieldContractFactory = _yieldContractFactory;
40
46
  maxLnFeeRateRoot = uint256(LogExpMath.ln(int256((105 * Math.IONE) / 100))); // ln(1.05)
41
-
42
- marketCreationCodePointer = _marketCreationCodePointer;
43
47
  }
44
48
 
45
49
  function initialize(
46
50
  address _treasury,
47
- uint88 _lnFeeRateRoot,
51
+ uint96 _lnFeeRateRoot,
48
52
  uint8 _reserveFeePercent,
49
53
  address newVePendle,
50
- address newGaugeController
54
+ address newGaugeController,
55
+ bytes memory _marketCreationCode
51
56
  ) external initializer {
52
- require(newVePendle != address(0) && newGaugeController != address(0), "zero address");
53
-
54
57
  __BoringOwnable_init();
55
58
  setTreasury(_treasury);
56
59
  setlnFeeRateRoot(_lnFeeRateRoot);
57
60
  setReserveFeePercent(_reserveFeePercent);
58
61
 
62
+ require(newVePendle != address(0) && newGaugeController != address(0), "zero address");
59
63
  vePendle = newVePendle;
60
64
  gaugeController = newGaugeController;
65
+ marketCreationCodePointer = SSTORE2Deployer.setCreationCode(_marketCreationCode);
61
66
  }
62
67
 
63
68
  /**
@@ -101,7 +106,7 @@ contract PendleMarketFactory is BoringOwnableUpgradeable, IPMarketFactory {
101
106
  _emitNewMarketConfigEvent();
102
107
  }
103
108
 
104
- function setlnFeeRateRoot(uint88 newlnFeeRateRoot) public onlyOwner {
109
+ function setlnFeeRateRoot(uint96 newlnFeeRateRoot) public onlyOwner {
105
110
  require(newlnFeeRateRoot <= maxLnFeeRateRoot, "invalid fee rate root");
106
111
  marketConfig.lnFeeRateRoot = newlnFeeRateRoot;
107
112
  _emitNewMarketConfigEvent();
@@ -1,7 +1,8 @@
1
1
  // SPDX-License-Identifier: GPL-3.0-or-later
2
2
  pragma solidity 0.8.15;
3
3
 
4
- import "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
4
+ import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
5
+ import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
5
6
  import "@openzeppelin/contracts/proxy/Proxy.sol";
6
7
  import "../interfaces/IPAllAction.sol";
7
8
  import "../interfaces/IPMarketSwapCallback.sol";
@@ -37,6 +38,7 @@ contract PendleRouter is Proxy, Initializable, UUPSUpgradeable, BoringOwnableUpg
37
38
  }
38
39
 
39
40
  function initialize() external initializer {
41
+ __UUPSUpgradeable_init();
40
42
  __BoringOwnable_init();
41
43
  }
42
44
 
@@ -6,7 +6,7 @@ import "../../interfaces/IPYieldToken.sol";
6
6
 
7
7
  import "../PendleERC20.sol";
8
8
  import "../../libraries/helpers/MiniHelpers.sol";
9
- import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
9
+ import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
10
10
 
11
11
  contract PendlePrincipalToken is PendleERC20, Initializable, IPPrincipalToken {
12
12
  address public immutable SCY;
@@ -44,7 +44,7 @@ contract PendleYieldContractFactory is BoringOwnableUpgradeable, IPYieldContract
44
44
  string private constant PT_PREFIX = "PT";
45
45
  string private constant YT_PREFIX = "YT";
46
46
 
47
- address public immutable pendleYtCreationCodePointer;
47
+ address public pendleYtCreationCodePointer;
48
48
 
49
49
  // 1 SLOT
50
50
  uint128 public interestFeeRate; // a fixed point number
@@ -60,21 +60,21 @@ contract PendleYieldContractFactory is BoringOwnableUpgradeable, IPYieldContract
60
60
  mapping(address => bool) public isPT;
61
61
  mapping(address => bool) public isYT;
62
62
 
63
- constructor(address _pendleYtCreationCodePointer) {
64
- pendleYtCreationCodePointer = _pendleYtCreationCodePointer;
65
- }
63
+ constructor() {}
66
64
 
67
65
  function initialize(
68
66
  uint96 _expiryDivisor,
69
67
  uint128 _interestFeeRate,
70
68
  uint128 _rewardFeeRate,
71
- address _treasury
69
+ address _treasury,
70
+ bytes memory _pendleYtCreationCode
72
71
  ) external initializer {
73
72
  __BoringOwnable_init();
74
73
  setExpiryDivisor(_expiryDivisor);
75
74
  setInterestFeeRate(_interestFeeRate);
76
75
  setRewardFeeRate(_rewardFeeRate);
77
76
  setTreasury(_treasury);
77
+ pendleYtCreationCodePointer = SSTORE2Deployer.setCreationCode(_pendleYtCreationCode);
78
78
  }
79
79
 
80
80
  /**
@@ -68,6 +68,7 @@ abstract contract ActionBaseMintRedeem is TokenHelper, KyberSwapHelper {
68
68
  output.tokenRedeemScy,
69
69
  1
70
70
  );
71
+ _safeApproveInf(output.tokenRedeemScy, SCY);
71
72
  _kyberswap(output.tokenRedeemScy, netTokenRedeemed, output.kybercall);
72
73
 
73
74
  netTokenOut = _selfBalance(output.tokenOut);
@@ -12,7 +12,7 @@ interface IPGaugeController {
12
12
 
13
13
  function pendle() external returns (address);
14
14
 
15
- function redeemMarketReward() external;
15
+ function claimMarketReward() external;
16
16
 
17
17
  function rewardData(address pool)
18
18
  external
@@ -21,7 +21,7 @@ interface IPMarketFactory {
21
21
  view
22
22
  returns (
23
23
  address treasury,
24
- uint88 lnFeeRateRoot,
24
+ uint96 lnFeeRateRoot,
25
25
  uint8 reserveFeePercent
26
26
  );
27
27
  }
@@ -1,7 +1,7 @@
1
1
  // SPDX-License-Identifier: GPL-3.0-or-later
2
2
  pragma solidity 0.8.15;
3
3
 
4
- import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
4
+ import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
5
5
 
6
6
  interface ISJoe {
7
7
  function joe() external view returns (address);
@@ -23,7 +23,7 @@ interface ISJoe {
23
23
  * @return The amount of JOE user has deposited
24
24
  * @return The reward debt for the chosen token
25
25
  */
26
- function getUserInfo(address _user, IERC20 _rewardToken)
26
+ function getUserInfo(address _user, IERC20Upgradeable _rewardToken)
27
27
  external
28
28
  view
29
29
  returns (uint256, uint256);
@@ -42,7 +42,10 @@ interface ISJoe {
42
42
  * @param _token The address of the token
43
43
  * @return `_user`'s pending reward token
44
44
  */
45
- function pendingReward(address _user, IERC20 _token) external view returns (uint256);
45
+ function pendingReward(address _user, IERC20Upgradeable _token)
46
+ external
47
+ view
48
+ returns (uint256);
46
49
 
47
50
  /**
48
51
  * @notice Withdraw JOE and harvest the rewards
@@ -26,7 +26,6 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
26
26
  import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
27
27
  import "@openzeppelin/contracts/utils/Address.sol";
28
28
  import "../helpers/TokenHelper.sol";
29
- import "./AggregationRouterHelper.sol";
30
29
 
31
30
  struct TokenInput {
32
31
  address tokenIn;
@@ -54,14 +53,9 @@ abstract contract KyberSwapHelper is TokenHelper {
54
53
  function _kyberswap(
55
54
  address tokenIn,
56
55
  uint256 amountIn,
57
- bytes calldata rawKybercall
56
+ bytes calldata kybercall
58
57
  ) internal {
59
58
  _safeApproveInf(tokenIn, kyberSwapRouter);
60
-
61
- bytes memory kybercall = AggregationRouterHelper.getScaledInputData(
62
- rawKybercall,
63
- amountIn
64
- );
65
59
  kyberSwapRouter.functionCallWithValue(kybercall, tokenIn == NATIVE ? amountIn : 0);
66
60
  }
67
61
  }
@@ -3,7 +3,7 @@
3
3
  pragma solidity 0.8.15;
4
4
 
5
5
  library WeekMath {
6
- uint128 internal constant WEEK = 2 hours;
6
+ uint128 internal constant WEEK = 7 days;
7
7
 
8
8
  function getWeekStartTimestamp(uint128 timestamp) internal pure returns (uint128) {
9
9
  return (timestamp / WEEK) * WEEK;
@@ -4,12 +4,12 @@ pragma solidity 0.8.15;
4
4
  import "../interfaces/IPYieldContractFactory.sol";
5
5
  import "../interfaces/IPMarketFactory.sol";
6
6
  import "./MarketMathStatic.sol";
7
- import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
8
- import "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
9
- import "../periphery/BoringOwnableUpgradeable.sol";
7
+ import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
8
+ import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
9
+ import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
10
10
 
11
11
  /// EXCLUDED FROM ALL AUDITS, TO BE CALLED ONLY BY PENDLE's SDK
12
- contract RouterStatic is Initializable, BoringOwnableUpgradeable, UUPSUpgradeable {
12
+ contract RouterStatic is OwnableUpgradeable, UUPSUpgradeable {
13
13
  using Math for uint256;
14
14
 
15
15
  struct TokenAmount {
@@ -56,7 +56,7 @@ contract RouterStatic is Initializable, BoringOwnableUpgradeable, UUPSUpgradeabl
56
56
  }
57
57
 
58
58
  function initialize() external initializer {
59
- __BoringOwnable_init();
59
+ __Ownable_init();
60
60
  }
61
61
 
62
62
  function getDefaultApproxParams() public pure returns (ApproxParams memory) {
@@ -1,14 +1,14 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity 0.8.15;
3
3
 
4
- import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
4
+ import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
5
5
 
6
6
  contract BoringOwnableUpgradeableData {
7
7
  address public owner;
8
8
  address public pendingOwner;
9
9
  }
10
10
 
11
- abstract contract BoringOwnableUpgradeable is BoringOwnableUpgradeableData, Initializable {
11
+ contract BoringOwnableUpgradeable is BoringOwnableUpgradeableData, Initializable {
12
12
  event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
13
13
 
14
14
  function __BoringOwnable_init() internal onlyInitializing {
@@ -0,0 +1,38 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity 0.8.15;
3
+
4
+ contract PendleGovernanceManager {
5
+ address public governance;
6
+ address public pendingGovernance;
7
+
8
+ event GovernanceTransferred(address newGovernance, address previousGovernance);
9
+
10
+ modifier onlyGovernance() {
11
+ require(msg.sender == governance, "ONLY_GOVERNANCE");
12
+ _;
13
+ }
14
+
15
+ constructor(address _governance) {
16
+ require(_governance != address(0), "zero address");
17
+ governance = _governance;
18
+ }
19
+
20
+ /**
21
+ * @dev Allows the pendingGovernance address to finalize the change governance process.
22
+ */
23
+ function claimGovernance() external {
24
+ require(pendingGovernance == msg.sender, "FORBIDDEN");
25
+ emit GovernanceTransferred(pendingGovernance, governance);
26
+ governance = pendingGovernance;
27
+ pendingGovernance = address(0);
28
+ }
29
+
30
+ /**
31
+ * @dev Allows the current governance to set the pendingGovernance address.
32
+ * @param newGovernance The address to transfer ownership to.
33
+ */
34
+ function transferGovernance(address newGovernance) external onlyGovernance {
35
+ require(newGovernance != address(0), "zero address");
36
+ pendingGovernance = newGovernance;
37
+ }
38
+ }
@@ -0,0 +1,29 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity 0.8.15;
3
+
4
+ import "../interfaces/IPGovernanceManager.sol";
5
+ import "../interfaces/IPPermissionsV2Upg.sol";
6
+
7
+ /// This contract is upgradable because
8
+ /// - its constructor only sets immutable variables
9
+ /// - it has storage gaps for safe addition of future variables
10
+ /// - it inherits only upgradable contract
11
+ abstract contract PermissionsV2Upg is IPermissionsV2Upg {
12
+ address public immutable governanceManager;
13
+
14
+ uint256[100] private __gap;
15
+
16
+ modifier onlyGovernance() {
17
+ require(msg.sender == _governance(), "ONLY_GOVERNANCE");
18
+ _;
19
+ }
20
+
21
+ constructor(address _governanceManager) {
22
+ require(_governanceManager != address(0), "ZERO_ADDRESS");
23
+ governanceManager = _governanceManager;
24
+ }
25
+
26
+ function _governance() internal view returns (address) {
27
+ return IPGovernanceManager(governanceManager).governance();
28
+ }
29
+ }
@@ -1,16 +1,15 @@
1
1
  {
2
2
  "deployer": "0x1FcCC097db89A86Bfc474A1028F93958295b1Fb7",
3
- "sstore2": "0x00E8aAE633b426cb67614f432B4604C6fA2BF101",
4
3
  "network": 43113,
5
4
  "celerBus": "0xE9533976C590200E32d95C53f06AE12d292cFc47",
6
5
  "treasury": "0xB4E292AD98Ba0D5531Ca573757f7b7d6c0C205d8",
7
6
  "PENDLE": "0x83B694f9Ef84D22BECe87257f0cd4513737A505e",
8
- "yieldContractFactory": "0x2e5DF6e3DA5Ae730aC357Ca1b6a823A9B0EAFaC0",
9
- "marketFactory": "0x3Ba006773B0cfd7f3549B2D4259524FCb3dCC8E2",
10
- "router": "0x17C433893321F4457066045E1356e8E8B0C5F596",
11
- "routerStatic": "0x8CC254DcaE3d01c4Aff79A396d94623E4D9dD2b1",
7
+ "yieldContractFactory": "0x38E5A1D591553b5FF18b151B587745a4A9B206d2",
8
+ "marketFactory": "0xE646E5425fD448b2f9dDF6de12383CcF5275143B",
9
+ "router": "0xa4C21f51DE870a283f362A7331f0C4f8288c3e41",
10
+ "routerStatic": "0xc875e3b8aED24cc54C4750D790036D631F6cacbD",
12
11
  "startTime": 1657756800,
13
- "vePendle": "0xdc6aFe3Aae143f73Abc84766E9c99f18fF3c5aAe",
14
- "votingController": "0x7d9Bd862090337D572c50068b40E39F76b8dFE03",
15
- "gaugeController": "0xcE19aEaBE9229F8070ADe311A2d3aAf4f6864B26"
12
+ "vePendle": "0x3AE0fee115057cCF8A0B5255751027C26D83B912",
13
+ "votingController": "0x76815E13679C7F18a406f5BA94E352E656BeE378",
14
+ "gaugeController": "0xD9F5f311dA64645D4b38D055e1726D8B217272e7"
16
15
  }
@@ -0,0 +1,8 @@
1
+ {
2
+ "symbol": "SCY-qiUSDC",
3
+ "SCY": "0x0930810274379bDE70534068F37562eA660de10e",
4
+ "expiry": 1675382400,
5
+ "PT": "0x30773E8c6243AD6D31B1664335d851a845fD4246",
6
+ "YT": "0x1cF1e47c4AFE6e0099fB51345B89408B26eAD9a7",
7
+ "market": "0xF0f539F6Ff098403c3034A57657dAd9b3510D931"
8
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "symbol": "SCY-qiUSDC",
3
+ "SCY": "0x0930810274379bDE70534068F37562eA660de10e",
4
+ "expiry": 1663804800,
5
+ "PT": "0xff445E1FA4f8B5b6Ca237b21e83063eF1C3f2D53",
6
+ "YT": "0x0cD7b5ec16366B40bF0B95EBdD157361B4263296",
7
+ "market": "0x9F9C7750edABDa9a822E7ca9141511c35B9fbD64"
8
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "symbol": "SCY-qiWETH",
3
+ "SCY": "0x5e243CC04e9B122B7dFA828f5f46681E4bF1Af55",
4
+ "expiry": 1669852800,
5
+ "PT": "0x393Dc55047838E3e123edecd0AC1125ACdbDC9Bd",
6
+ "YT": "0xCaB06ad3df61691e7B506C7F5B965510494D9CfB",
7
+ "market": "0x55481608A45ED862f0eC2996283ddF6967A12361"
8
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "tokens": {
3
3
  "fundKeeper": "0x45e03eB183962884d50eC0Af39B03970333426cb",
4
- "faucet": "0x6C881F2b27aB065c6b6fbDf1407f2895104D5856",
4
+ "faucet": "0x1A2775c9bEe6e798De971c369849CF9130D3e25a",
5
5
  "WAVAX": "0xe43a7aD7C09d8fAE3ADe7361f0b847b23adD5094",
6
6
  "DAI": "0xCd3748CE3Bf75A01D99Bf301668E0748558a592C",
7
7
  "USDC": "0xc2A6b8d7d0FAB3749A6Bda84cEdb58D2d58f045e",
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@pendle/core-v2",
3
3
  "description": "Core smart contracts of Pendle Protocol.",
4
4
  "license": "BUSL-1.1",
5
- "version": "0.11.1-testnet",
5
+ "version": "0.11.2-testnet",
6
6
  "homepage": "https://pendle.finance",
7
7
  "keywords": [
8
8
  "pendle",
@@ -25,7 +25,7 @@
25
25
  "devDependencies": {
26
26
  "@typechain/ethers-v5": "^9.0.0",
27
27
  "@typechain/hardhat": "^4.0.0",
28
- "hardhat": "^2.11.0",
28
+ "hardhat": "^2.10.2",
29
29
  "hardhat-contract-sizer": "^2.6.1",
30
30
  "hardhat-storage-layout-diff": "^0.0.4",
31
31
  "prettier": "^2.7.1",
@@ -34,7 +34,7 @@
34
34
  "solhint": "^3.3.7",
35
35
  "ts-node": "^10.9.1",
36
36
  "typechain": "^8.1.0",
37
- "typescript": "^4.8.2"
37
+ "typescript": "^4.7.4"
38
38
  },
39
39
  "scripts": {
40
40
  "compile": "yarn hardhat compile",
@@ -44,6 +44,7 @@
44
44
  },
45
45
  "packageManager": "yarn@3.2.2",
46
46
  "dependencies": {
47
- "@openzeppelin/contracts": "^4.5.0"
47
+ "@openzeppelin/contracts": "^4.5.0",
48
+ "@openzeppelin/contracts-upgradeable": "^4.5.2"
48
49
  }
49
50
  }
@@ -1,308 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
-
3
- pragma solidity 0.8.15;
4
- import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
5
- import "./IMultihopRouter.sol";
6
-
7
- library AggregationRouterHelper {
8
- uint256 private constant _PARTIAL_FILL = 0x01;
9
- uint256 private constant _REQUIRES_EXTRA_ETH = 0x02;
10
- uint256 private constant _SHOULD_CLAIM = 0x04;
11
- uint256 private constant _BURN_FROM_MSG_SENDER = 0x08;
12
- uint256 private constant _BURN_FROM_TX_ORIGIN = 0x10;
13
- uint256 private constant _SIMPLE_SWAP = 0x20;
14
-
15
- uint256 private constant SLIPPAGE_RANGE = 10; // over 100
16
-
17
- enum DexType {
18
- UNI,
19
- STABLESWAP,
20
- CURVE,
21
- KYBERDMM,
22
- SADDLE,
23
- UNIV3PROMM,
24
- BALANCERV2,
25
- KYBERRFQ,
26
- DODO,
27
- VELODROME,
28
- PLATYPUS
29
- }
30
-
31
- struct SwapDescription {
32
- IERC20 srcToken;
33
- IERC20 dstToken;
34
- address[] srcReceivers;
35
- uint256[] srcAmounts;
36
- address dstReceiver;
37
- uint256 amount;
38
- uint256 minReturnAmount;
39
- uint256 flags;
40
- bytes permit;
41
- }
42
-
43
- struct SimpleSwapData {
44
- address[] firstPools;
45
- uint256[] firstSwapAmounts;
46
- bytes[] swapDatas;
47
- uint256 deadline;
48
- bytes destTokenFeeData;
49
- }
50
-
51
- struct SwapExecutorDescription {
52
- IMultihopRouter.Swap[][] swapSequences;
53
- address tokenIn;
54
- address tokenOut;
55
- uint256 minTotalAmountOut;
56
- address to;
57
- uint256 deadline;
58
- bytes destTokenFeeData;
59
- }
60
-
61
- function getScaledInputData(bytes calldata kybercall, uint256 newAmount)
62
- external
63
- pure
64
- returns (bytes memory)
65
- {
66
- bytes4 selector = bytes4(kybercall[:4]);
67
- (
68
- address caller,
69
- SwapDescription memory desc,
70
- bytes memory executorData,
71
- bytes memory clientData
72
- ) = abi.decode(kybercall[4:], (address, SwapDescription, bytes, bytes));
73
-
74
- (desc, executorData) = _getScaledInputData(desc, executorData, newAmount);
75
- return abi.encodeWithSelector(selector, caller, desc, executorData, clientData);
76
- }
77
-
78
- function _getScaledInputData(
79
- SwapDescription memory desc,
80
- bytes memory executorData,
81
- uint256 newAmount
82
- ) internal pure returns (SwapDescription memory, bytes memory) {
83
- uint256 flags = desc.flags;
84
- uint256 oldAmount = desc.amount;
85
- if (oldAmount == newAmount) {
86
- return (desc, executorData);
87
- }
88
-
89
- //if the difference of newAmount and oldAmount > 5%, revert
90
- require(
91
- (oldAmount * (100 - SLIPPAGE_RANGE)) / 100 <= newAmount &&
92
- newAmount <= (oldAmount * (100 + SLIPPAGE_RANGE)) / 100,
93
- "kyber: difference too large"
94
- );
95
-
96
- // simple mode swap
97
- if (flags & _SIMPLE_SWAP != 0) {
98
- require(desc.srcReceivers.length == 0, "kyber: can't scale if take fee");
99
- return (
100
- _getNewDescription(desc, oldAmount, newAmount),
101
- _getNewSimpleSwapData(executorData, oldAmount, newAmount)
102
- );
103
- }
104
-
105
- //normal mode swap
106
- bytes memory newExecutorData = _getNewExecutorData(executorData, oldAmount, newAmount);
107
- return (_getNewDescription(desc, oldAmount, newAmount), newExecutorData);
108
- }
109
-
110
- function _getNewDescription(
111
- SwapDescription memory desc,
112
- uint256 oldAmount,
113
- uint256 newAmount
114
- ) internal pure returns (SwapDescription memory) {
115
- uint256 oldMinReturnAmount = desc.minReturnAmount;
116
- desc.minReturnAmount = (desc.minReturnAmount * newAmount) / oldAmount;
117
- //newMinReturnAmount should no be 0 if oldMinReturnAmount > 0
118
- if (oldMinReturnAmount > 0 && desc.minReturnAmount == 0) desc.minReturnAmount = 1;
119
- desc.amount = newAmount;
120
- if (desc.srcReceivers.length == 0) {
121
- return desc;
122
- }
123
-
124
- uint256 newTotal;
125
- for (uint256 i = 0; i < desc.srcReceivers.length; i++) {
126
- if (i == desc.srcReceivers.length - 1) {
127
- desc.srcAmounts[i] = newAmount - newTotal;
128
- } else {
129
- desc.srcAmounts[i] = (desc.srcAmounts[i] * newAmount) / oldAmount;
130
- }
131
- newTotal += desc.srcAmounts[i];
132
- }
133
- return desc;
134
- }
135
-
136
- function _getNewSimpleSwapData(
137
- bytes memory data,
138
- uint256 oldAmount,
139
- uint256 newAmount
140
- ) internal pure returns (bytes memory) {
141
- SimpleSwapData memory swapData = abi.decode(data, (SimpleSwapData));
142
- uint256 numberSeq = swapData.firstPools.length;
143
- uint256 newTotalSwapAmount;
144
- for (uint256 i = 0; i < numberSeq; i++) {
145
- if (i == numberSeq - 1) {
146
- swapData.firstSwapAmounts[i] = newAmount - newTotalSwapAmount;
147
- } else {
148
- swapData.firstSwapAmounts[i] =
149
- (swapData.firstSwapAmounts[i] * newAmount) /
150
- oldAmount;
151
- }
152
- newTotalSwapAmount += swapData.firstSwapAmounts[i];
153
- }
154
- return abi.encode(swapData);
155
- }
156
-
157
- function _getNewExecutorData(
158
- bytes memory data,
159
- uint256 oldAmount,
160
- uint256 newAmount
161
- ) internal pure returns (bytes memory) {
162
- SwapExecutorDescription memory swapExecutorDescription = abi.decode(
163
- data,
164
- (SwapExecutorDescription)
165
- );
166
- swapExecutorDescription.minTotalAmountOut =
167
- (swapExecutorDescription.minTotalAmountOut * newAmount) /
168
- oldAmount;
169
-
170
- uint256 newTotalSwapAmount;
171
- for (uint256 i = 0; i < swapExecutorDescription.swapSequences.length; i++) {
172
- IMultihopRouter.Swap memory swap = swapExecutorDescription.swapSequences[i][0];
173
- uint8 dexType = uint8(swap.dexOption >> 8);
174
- uint256 value;
175
- if (i == swapExecutorDescription.swapSequences.length - 1)
176
- value = newAmount - newTotalSwapAmount;
177
-
178
- if (dexType == uint8(DexType.UNI)) {
179
- (swap.data, value) = _newUniSwap(swap.data, value, oldAmount, newAmount);
180
- } else if (dexType == uint8(DexType.STABLESWAP) || dexType == uint8(DexType.SADDLE)) {
181
- (swap.data, value) = _newStableSwap(swap.data, value, oldAmount, newAmount);
182
- } else if (dexType == uint8(DexType.CURVE)) {
183
- (swap.data, value) = _newCurveSwap(swap.data, value, oldAmount, newAmount);
184
- } else if (dexType == uint8(DexType.KYBERDMM)) {
185
- (swap.data, value) = _newKyberDMMSwap(swap.data, value, oldAmount, newAmount);
186
- } else if (dexType == uint8(DexType.UNIV3PROMM)) {
187
- (swap.data, value) = _newUniV3ProMMSwap(swap.data, value, oldAmount, newAmount);
188
- } else if (dexType == uint8(DexType.BALANCERV2)) {
189
- (swap.data, value) = _newBalancerV2Swap(swap.data, value, oldAmount, newAmount);
190
- } else if (dexType == uint8(DexType.KYBERRFQ)) {
191
- revert("kyber: can't scale kyberrfq");
192
- } else if (dexType == uint8(DexType.DODO)) {
193
- (swap.data, value) = _newDODOSwap(swap.data, value, oldAmount, newAmount);
194
- } else if (dexType == uint8(DexType.VELODROME)) {
195
- (swap.data, value) = _newVelodromeSwap(swap.data, value, oldAmount, newAmount);
196
- } else {
197
- revert("AggregationExecutor: Dex type not supported");
198
- }
199
- newTotalSwapAmount += value;
200
- }
201
- return abi.encode(swapExecutorDescription);
202
- }
203
-
204
- function _newUniSwap(
205
- bytes memory data,
206
- uint256 value,
207
- uint256 oldAmount,
208
- uint256 newAmount
209
- ) internal pure returns (bytes memory, uint256) {
210
- IMultihopRouter.UniSwap memory uniSwap = abi.decode(data, (IMultihopRouter.UniSwap));
211
- if (value > 0) uniSwap.collectAmount = value;
212
- else uniSwap.collectAmount = (uniSwap.collectAmount * newAmount) / oldAmount;
213
- return (abi.encode(uniSwap), uniSwap.collectAmount);
214
- }
215
-
216
- function _newStableSwap(
217
- bytes memory data,
218
- uint256 value,
219
- uint256 oldAmount,
220
- uint256 newAmount
221
- ) internal pure returns (bytes memory, uint256) {
222
- IMultihopRouter.StableSwap memory stableSwap = abi.decode(
223
- data,
224
- (IMultihopRouter.StableSwap)
225
- );
226
- if (value > 0) stableSwap.dx = value;
227
- else stableSwap.dx = (stableSwap.dx * newAmount) / oldAmount;
228
- return (abi.encode(stableSwap), stableSwap.dx);
229
- }
230
-
231
- function _newCurveSwap(
232
- bytes memory data,
233
- uint256 value,
234
- uint256 oldAmount,
235
- uint256 newAmount
236
- ) internal pure returns (bytes memory, uint256) {
237
- IMultihopRouter.CurveSwap memory curveSwap = abi.decode(data, (IMultihopRouter.CurveSwap));
238
- if (value > 0) curveSwap.dx = value;
239
- else curveSwap.dx = (curveSwap.dx * newAmount) / oldAmount;
240
- return (abi.encode(curveSwap), curveSwap.dx);
241
- }
242
-
243
- function _newKyberDMMSwap(
244
- bytes memory data,
245
- uint256 value,
246
- uint256 oldAmount,
247
- uint256 newAmount
248
- ) internal pure returns (bytes memory, uint256) {
249
- IMultihopRouter.UniSwap memory kyberDMMSwap = abi.decode(data, (IMultihopRouter.UniSwap));
250
- if (value > 0) kyberDMMSwap.collectAmount = value;
251
- else kyberDMMSwap.collectAmount = (kyberDMMSwap.collectAmount * newAmount) / oldAmount;
252
- return (abi.encode(kyberDMMSwap), kyberDMMSwap.collectAmount);
253
- }
254
-
255
- function _newUniV3ProMMSwap(
256
- bytes memory data,
257
- uint256 value,
258
- uint256 oldAmount,
259
- uint256 newAmount
260
- ) internal pure returns (bytes memory, uint256) {
261
- IMultihopRouter.UniSwapV3ProMM memory uniSwapV3ProMM = abi.decode(
262
- data,
263
- (IMultihopRouter.UniSwapV3ProMM)
264
- );
265
- if (value > 0) uniSwapV3ProMM.swapAmount = value;
266
- else uniSwapV3ProMM.swapAmount = (uniSwapV3ProMM.swapAmount * newAmount) / oldAmount;
267
- return (abi.encode(uniSwapV3ProMM), uniSwapV3ProMM.swapAmount);
268
- }
269
-
270
- function _newBalancerV2Swap(
271
- bytes memory data,
272
- uint256 value,
273
- uint256 oldAmount,
274
- uint256 newAmount
275
- ) internal pure returns (bytes memory, uint256) {
276
- IMultihopRouter.BalancerV2 memory balancerV2 = abi.decode(
277
- data,
278
- (IMultihopRouter.BalancerV2)
279
- );
280
- if (value > 0) balancerV2.amount = value;
281
- else balancerV2.amount = (balancerV2.amount * newAmount) / oldAmount;
282
- return (abi.encode(balancerV2, balancerV2.amount), balancerV2.amount);
283
- }
284
-
285
- function _newDODOSwap(
286
- bytes memory data,
287
- uint256 value,
288
- uint256 oldAmount,
289
- uint256 newAmount
290
- ) internal pure returns (bytes memory, uint256) {
291
- IMultihopRouter.DODO memory dodo = abi.decode(data, (IMultihopRouter.DODO));
292
- if (value > 0) dodo.amount = value;
293
- else dodo.amount = (dodo.amount * newAmount) / oldAmount;
294
- return (abi.encode(dodo), dodo.amount);
295
- }
296
-
297
- function _newVelodromeSwap(
298
- bytes memory data,
299
- uint256 value,
300
- uint256 oldAmount,
301
- uint256 newAmount
302
- ) internal pure returns (bytes memory, uint256) {
303
- IMultihopRouter.UniSwap memory velodrome = abi.decode(data, (IMultihopRouter.UniSwap));
304
- if (value > 0) velodrome.collectAmount = value;
305
- else velodrome.collectAmount = (velodrome.collectAmount * newAmount) / oldAmount;
306
- return (abi.encode(velodrome), velodrome.collectAmount);
307
- }
308
- }
@@ -1,139 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
-
3
- pragma solidity >=0.7.6;
4
-
5
- pragma abicoder v2;
6
-
7
- interface IMultihopRouter {
8
- enum DexType {
9
- UNI,
10
- STABLESWAP,
11
- CURVE,
12
- KYBERDMM,
13
- SADDLE,
14
- UNIV3PROMM,
15
- BALANCERV2,
16
- KYBERRFQ,
17
- DODO,
18
- VELODROME,
19
- PLATYPUS
20
- }
21
-
22
- event Exchange(address pair, uint256 amountOut, address output);
23
- struct Swap {
24
- bytes data;
25
- //dexType:
26
- // 0: uni
27
- // 1: stable swap
28
- // 2: curve
29
- // 3: kyber dmm
30
- // 4: saddle
31
- // 5: univ3 or kyber ProMM
32
- // 6: balancerv2
33
- // 7: kyber RFQ
34
- // 8: dodo
35
- // 9: velodrome
36
- // 10: platypus
37
- //dexId:
38
- // 0: firebird
39
- uint16 dexOption; //dexType(8bit) + dexId(8bit)
40
- }
41
-
42
- struct UniSwap {
43
- address pool;
44
- address tokenIn;
45
- address tokenOut;
46
- address recipient;
47
- uint256 collectAmount; // amount that should be transferred to the pool
48
- uint256 limitReturnAmount;
49
- }
50
-
51
- struct StableSwap {
52
- address pool;
53
- address tokenFrom;
54
- address tokenTo;
55
- uint8 tokenIndexFrom;
56
- uint8 tokenIndexTo;
57
- uint256 dx;
58
- uint256 minDy;
59
- uint256 poolLength;
60
- address poolLp;
61
- }
62
-
63
- struct CurveSwap {
64
- address pool;
65
- address tokenFrom;
66
- address tokenTo;
67
- int128 tokenIndexFrom;
68
- int128 tokenIndexTo;
69
- uint256 dx;
70
- uint256 minDy;
71
- bool usePoolUnderlying;
72
- bool useTriCrypto;
73
- }
74
-
75
- struct UniSwapV3ProMM {
76
- address recipient;
77
- address pool;
78
- address tokenIn;
79
- address tokenOut;
80
- uint256 swapAmount;
81
- uint256 limitReturnAmount;
82
- uint160 sqrtPriceLimitX96;
83
- bool isUniV3; // true = UniV3, false = ProMM
84
- }
85
- struct SwapCallbackData {
86
- bytes path;
87
- address payer;
88
- }
89
- struct SwapCallbackDataPath {
90
- address pool;
91
- address tokenIn;
92
- address tokenOut;
93
- }
94
-
95
- struct BalancerV2 {
96
- address vault;
97
- bytes32 poolId;
98
- address assetIn;
99
- address assetOut;
100
- uint256 amount;
101
- uint256 limit;
102
- }
103
-
104
- struct KyberRFQ {
105
- address rfq;
106
- bytes order;
107
- bytes signature;
108
- uint256 amount;
109
- address payable target;
110
- }
111
-
112
- struct DODO {
113
- address recipient;
114
- address pool;
115
- address tokenFrom;
116
- address tokenTo;
117
- uint256 amount;
118
- uint256 minReceiveQuote;
119
- address sellHelper;
120
- bool isSellBase;
121
- bool isVersion2;
122
- }
123
-
124
- function factory() external view returns (address);
125
-
126
- function formula() external view returns (address);
127
-
128
- function WETH() external view returns (address);
129
-
130
- function multihopBatchSwapExactIn(
131
- Swap[][] memory swapSequences,
132
- address tokenIn,
133
- address tokenOut,
134
- uint256 minTotalAmountOut,
135
- address to,
136
- uint256 deadline,
137
- bytes memory destTokenFeeData
138
- ) external payable returns (uint256 totalAmountOut);
139
- }
@@ -1,21 +0,0 @@
1
- // SPDX-License-Identifier: GPL-3.0-or-later
2
- pragma solidity 0.8.15;
3
- import "../libraries/helpers/SSTORE2Deployer.sol";
4
- import "../periphery/BoringOwnableUpgradeable.sol";
5
-
6
- contract SSTORE2DeployerContract is BoringOwnableUpgradeable {
7
- event Deployed(string name, address addr);
8
-
9
- constructor() {
10
- __BoringOwnable_init();
11
- }
12
-
13
- function deploy(string memory name, bytes calldata creationCode)
14
- external
15
- onlyOwner
16
- returns (address res)
17
- {
18
- res = SSTORE2Deployer.setCreationCode(creationCode);
19
- emit Deployed(name, res);
20
- }
21
- }
@@ -1,8 +0,0 @@
1
- {
2
- "symbol": "SCY-qiUSDC",
3
- "SCY": "0xe41eebdC5124693cD9C18162D375590273a911Ed",
4
- "expiry": 1675382400,
5
- "PT": "0xF8F6ca86D40A8a9FFc0aC2D9F96a1A439b5535A8",
6
- "YT": "0x924b41c12FE9b9DAA311E0e0B050C16538c70283",
7
- "market": "0x485991210C8ec45644588EC1f4957d3d0aA0cE39"
8
- }
@@ -1,8 +0,0 @@
1
- {
2
- "symbol": "SCY-qiUSDC",
3
- "SCY": "0xe41eebdC5124693cD9C18162D375590273a911Ed",
4
- "expiry": 1663804800,
5
- "PT": "0x549b110782B89bd40018c12BC1770Cc55e6a2267",
6
- "YT": "0x80F8302a86775A810c2233e3AbE62990f7cc1051",
7
- "market": "0x6b2CC53E2c08b9054D00a4a84bf22462a18A249f"
8
- }
@@ -1,8 +0,0 @@
1
- {
2
- "symbol": "SCY-qiWETH",
3
- "SCY": "0x92A502318c1d77f3b2eFCb1BD8ee625Ad206A8d5",
4
- "expiry": 1669852800,
5
- "PT": "0x59E95f6f2191bc7dB730a3125cB76c3a4A35a835",
6
- "YT": "0xf400888C27f134E8cd6313E33d10d2526dec8697",
7
- "market": "0xbF23860F807Dbc7678Cf53be78D06A14A5c36D16"
8
- }