@pendle/core-v2 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +100 -0
- package/contracts/SuperComposableYield/ISuperComposableYield.sol +68 -0
- package/contracts/SuperComposableYield/SCYUtils.sol +14 -0
- package/contracts/SuperComposableYield/implementations/RewardManager.sol +117 -0
- package/contracts/SuperComposableYield/implementations/SCYBase.sol +126 -0
- package/contracts/SuperComposableYield/implementations/SCYBaseWithRewards.sol +79 -0
- package/contracts/core/PendleBaseToken.sol +39 -0
- package/contracts/core/PendleMarket.sol +248 -0
- package/contracts/core/PendleMarketFactory.sol +60 -0
- package/contracts/core/PendleOwnershipToken.sol +44 -0
- package/contracts/core/PendleSCYImpl/AaveV3/PendleAaveV3SCY.sol +139 -0
- package/contracts/core/PendleSCYImpl/AaveV3/WadRayMath.sol +126 -0
- package/contracts/core/PendleSCYImpl/PendleBenQiErc20SCY.sol +127 -0
- package/contracts/core/PendleSCYImpl/PendleBtrflySCY.sol +125 -0
- package/contracts/core/PendleSCYImpl/PendleYearnVaultSCY.sol +115 -0
- package/contracts/core/PendleYieldContractFactory.sol +109 -0
- package/contracts/core/PendleYieldToken.sol +240 -0
- package/contracts/core/misc/BoringOwnable.sol +62 -0
- package/contracts/core/misc/BoringOwnableUpg.sol +64 -0
- package/contracts/core/misc/PendleJoeSwapHelperUpg.sol +82 -0
- package/contracts/core/router/PendleRouterCoreUpg.sol +219 -0
- package/contracts/core/router/PendleRouterProxy.sol +64 -0
- package/contracts/core/router/PendleRouterYTUpg.sol +134 -0
- package/contracts/core/router/base/PendleRouterOTBaseUpg.sol +218 -0
- package/contracts/core/router/base/PendleRouterSCYAndForgeBaseUpg.sol +141 -0
- package/contracts/core/router/base/PendleRouterYTBaseUpg.sol +212 -0
- package/contracts/interfaces/IAToken.sol +34 -0
- package/contracts/interfaces/IAavePool.sol +41 -0
- package/contracts/interfaces/IAaveRewardsController.sol +32 -0
- package/contracts/interfaces/IBenQiComptroller.sol +33 -0
- package/contracts/interfaces/IJoePair.sol +98 -0
- package/contracts/interfaces/IJoeRouter01.sol +162 -0
- package/contracts/interfaces/IPBaseToken.sol +9 -0
- package/contracts/interfaces/IPFlashCallBack.sol +10 -0
- package/contracts/interfaces/IPGovernanceManager.sol +28 -0
- package/contracts/interfaces/IPMarket.sol +57 -0
- package/contracts/interfaces/IPMarketAddRemoveCallback.sol +18 -0
- package/contracts/interfaces/IPMarketFactory.sol +8 -0
- package/contracts/interfaces/IPMarketSwapCallback.sol +10 -0
- package/contracts/interfaces/IPOwnershipToken.sol +15 -0
- package/contracts/interfaces/IPPermissionsV2.sol +28 -0
- package/contracts/interfaces/IPRouterCore.sol +108 -0
- package/contracts/interfaces/IPRouterYT.sol +47 -0
- package/contracts/interfaces/IPYieldContractFactory.sol +36 -0
- package/contracts/interfaces/IPYieldToken.sol +19 -0
- package/contracts/interfaces/IQiErc20.sol +35 -0
- package/contracts/interfaces/IQiToken.sol +29 -0
- package/contracts/interfaces/IREDACTEDStaking.sol +35 -0
- package/contracts/interfaces/IWETH.sol +34 -0
- package/contracts/interfaces/IWXBTRFLY.sol +37 -0
- package/contracts/interfaces/IYearnVault.sol +32 -0
- package/contracts/libraries/JoeLibrary.sol +121 -0
- package/contracts/libraries/SCYIndex.sol +55 -0
- package/contracts/libraries/helpers/ExpiryUtilsLib.sol +166 -0
- package/contracts/libraries/math/FixedPoint.sol +208 -0
- package/contracts/libraries/math/LogExpMath.sol +515 -0
- package/contracts/libraries/math/MarketApproxLib.sol +140 -0
- package/contracts/libraries/math/MarketMathLib.sol +606 -0
- package/contracts/periphery/PendleGovernanceManager.sol +36 -0
- package/contracts/periphery/PermissionsV2.sol +23 -0
- package/package.json +76 -0
- package/typechain-types/BoringOwnable.ts +194 -0
- package/typechain-types/BoringOwnableData.ts +100 -0
- package/typechain-types/BoringOwnableUpg.ts +194 -0
- package/typechain-types/BoringOwnableUpgData.ts +100 -0
- package/typechain-types/ERC1967UpgradeUpgradeable.ts +97 -0
- package/typechain-types/ERC20.ts +417 -0
- package/typechain-types/IAToken.ts +331 -0
- package/typechain-types/IAavePool.ts +192 -0
- package/typechain-types/IAaveRewardsController.ts +148 -0
- package/typechain-types/IBeaconUpgradeable.ts +87 -0
- package/typechain-types/IBenQiComptroller.ts +125 -0
- package/typechain-types/IERC1822ProxiableUpgradeable.ts +87 -0
- package/typechain-types/IERC20.ts +300 -0
- package/typechain-types/IERC20Metadata.ts +339 -0
- package/typechain-types/IJoePair.ts +888 -0
- package/typechain-types/IJoeRouter01.ts +1107 -0
- package/typechain-types/IPBaseToken.ts +365 -0
- package/typechain-types/IPFlashCallback.ts +115 -0
- package/typechain-types/IPGovernanceManager.ts +84 -0
- package/typechain-types/IPMarket.ts +701 -0
- package/typechain-types/IPMarketAddRemoveCallback.ts +169 -0
- package/typechain-types/IPMarketFactory.ts +109 -0
- package/typechain-types/IPMarketSwapCallback.ts +115 -0
- package/typechain-types/IPOwnershipToken.ts +488 -0
- package/typechain-types/IPRouterCore.ts +759 -0
- package/typechain-types/IPRouterYT.ts +405 -0
- package/typechain-types/IPYieldContractFactory.ts +192 -0
- package/typechain-types/IPYieldToken.ts +525 -0
- package/typechain-types/IPermissionsV2.ts +87 -0
- package/typechain-types/IQiErc20.ts +402 -0
- package/typechain-types/IQiToken.ts +327 -0
- package/typechain-types/IREDACTEDStaking.ts +216 -0
- package/typechain-types/ISuperComposableYield.ts +652 -0
- package/typechain-types/IWETH.ts +380 -0
- package/typechain-types/IWXBTRFLY.ts +254 -0
- package/typechain-types/IYearnVault.ts +152 -0
- package/typechain-types/PendleAaveV3SCY.ts +901 -0
- package/typechain-types/PendleBaseToken.ts +505 -0
- package/typechain-types/PendleBenQiErc20SCY.ts +914 -0
- package/typechain-types/PendleBtrflyScy.ts +794 -0
- package/typechain-types/PendleGovernanceManager.ts +187 -0
- package/typechain-types/PendleJoeSwapHelperUpg.ts +97 -0
- package/typechain-types/PendleMarket.ts +1008 -0
- package/typechain-types/PendleMarketFactory.ts +246 -0
- package/typechain-types/PendleOwnershipToken.ts +628 -0
- package/typechain-types/PendleRouterCoreUpg.ts +780 -0
- package/typechain-types/PendleRouterProxy.ts +417 -0
- package/typechain-types/PendleRouterSCYAndForgeBaseUpg.ts +98 -0
- package/typechain-types/PendleRouterYTBaseUpg.ts +134 -0
- package/typechain-types/PendleRouterYTUpg.ts +453 -0
- package/typechain-types/PendleYearnVaultScy.ts +784 -0
- package/typechain-types/PendleYieldContractFactory.ts +479 -0
- package/typechain-types/PendleYieldToken.ts +1030 -0
- package/typechain-types/PermissionsV2.ts +87 -0
- package/typechain-types/Proxy.ts +57 -0
- package/typechain-types/RewardManager.ts +172 -0
- package/typechain-types/SCYBase.ts +734 -0
- package/typechain-types/SCYBaseWithRewards.ts +819 -0
- package/typechain-types/UUPSUpgradeable.ts +197 -0
- package/typechain-types/common.ts +44 -0
- package/typechain-types/factories/BoringOwnableData__factory.ts +90 -0
- package/typechain-types/factories/BoringOwnableUpgData__factory.ts +94 -0
- package/typechain-types/factories/BoringOwnableUpg__factory.ts +139 -0
- package/typechain-types/factories/BoringOwnable__factory.ts +149 -0
- package/typechain-types/factories/ERC1967UpgradeUpgradeable__factory.ts +75 -0
- package/typechain-types/factories/ERC20__factory.ts +348 -0
- package/typechain-types/factories/IAToken__factory.ts +225 -0
- package/typechain-types/factories/IAavePool__factory.ts +99 -0
- package/typechain-types/factories/IAaveRewardsController__factory.ts +78 -0
- package/typechain-types/factories/IBeaconUpgradeable__factory.ts +39 -0
- package/typechain-types/factories/IBenQiComptroller__factory.ts +59 -0
- package/typechain-types/factories/IERC1822ProxiableUpgradeable__factory.ts +43 -0
- package/typechain-types/factories/IERC20Metadata__factory.ts +248 -0
- package/typechain-types/factories/IERC20__factory.ts +203 -0
- package/typechain-types/factories/IJoePair__factory.ts +674 -0
- package/typechain-types/factories/IJoeRouter01__factory.ts +772 -0
- package/typechain-types/factories/IPBaseToken__factory.ts +271 -0
- package/typechain-types/factories/IPFlashCallback__factory.ts +49 -0
- package/typechain-types/factories/IPGovernanceManager__factory.ts +39 -0
- package/typechain-types/factories/IPMarketAddRemoveCallback__factory.ts +86 -0
- package/typechain-types/factories/IPMarketFactory__factory.ts +58 -0
- package/typechain-types/factories/IPMarketSwapCallback__factory.ts +53 -0
- package/typechain-types/factories/IPMarket__factory.ts +559 -0
- package/typechain-types/factories/IPOwnershipToken__factory.ts +349 -0
- package/typechain-types/factories/IPRouterCore__factory.ts +516 -0
- package/typechain-types/factories/IPRouterYT__factory.ts +246 -0
- package/typechain-types/factories/IPYieldContractFactory__factory.ts +117 -0
- package/typechain-types/factories/IPYieldToken__factory.ts +383 -0
- package/typechain-types/factories/IPermissionsV2__factory.ts +39 -0
- package/typechain-types/factories/IQiErc20__factory.ts +270 -0
- package/typechain-types/factories/IQiToken__factory.ts +219 -0
- package/typechain-types/factories/IREDACTEDStaking__factory.ts +107 -0
- package/typechain-types/factories/ISuperComposableYield__factory.ts +438 -0
- package/typechain-types/factories/IWETH__factory.ts +261 -0
- package/typechain-types/factories/IWXBTRFLY__factory.ts +131 -0
- package/typechain-types/factories/IYearnVault__factory.ts +74 -0
- package/typechain-types/factories/PendleAaveV3SCY__factory.ts +727 -0
- package/typechain-types/factories/PendleBaseToken__factory.ts +386 -0
- package/typechain-types/factories/PendleBenQiErc20SCY__factory.ts +753 -0
- package/typechain-types/factories/PendleBtrflyScy__factory.ts +652 -0
- package/typechain-types/factories/PendleGovernanceManager__factory.ts +149 -0
- package/typechain-types/factories/PendleJoeSwapHelperUpg__factory.ts +56 -0
- package/typechain-types/factories/PendleMarketFactory__factory.ts +207 -0
- package/typechain-types/factories/PendleMarket__factory.ts +891 -0
- package/typechain-types/factories/PendleOwnershipToken__factory.ts +565 -0
- package/typechain-types/factories/PendleRouterCoreUpg__factory.ts +620 -0
- package/typechain-types/factories/PendleRouterProxy__factory.ts +316 -0
- package/typechain-types/factories/PendleRouterSCYAndForgeBaseUpg__factory.ts +56 -0
- package/typechain-types/factories/PendleRouterYTBaseUpg__factory.ts +66 -0
- package/typechain-types/factories/PendleRouterYTUpg__factory.ts +363 -0
- package/typechain-types/factories/PendleYearnVaultScy__factory.ts +630 -0
- package/typechain-types/factories/PendleYieldContractFactory__factory.ts +368 -0
- package/typechain-types/factories/PendleYieldToken__factory.ts +814 -0
- package/typechain-types/factories/PermissionsV2__factory.ts +36 -0
- package/typechain-types/factories/Proxy__factory.ts +28 -0
- package/typechain-types/factories/RewardManager__factory.ts +89 -0
- package/typechain-types/factories/SCYBaseWithRewards__factory.ts +535 -0
- package/typechain-types/factories/SCYBase__factory.ts +479 -0
- package/typechain-types/factories/UUPSUpgradeable__factory.ts +115 -0
- package/typechain-types/hardhat.d.ts +564 -0
- package/typechain-types/index.ts +122 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
pragma solidity 0.8.9;
|
|
3
|
+
|
|
4
|
+
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
|
5
|
+
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
|
6
|
+
import "../misc/BoringOwnableUpg.sol";
|
|
7
|
+
import "@openzeppelin/contracts/proxy/Proxy.sol";
|
|
8
|
+
import "../../interfaces/IPRouterCore.sol";
|
|
9
|
+
import "../../interfaces/IPRouterYT.sol";
|
|
10
|
+
|
|
11
|
+
/// @dev this contract will be deployed behind an ERC1967 proxy
|
|
12
|
+
/// calls to the ERC1967 proxy will be resolved at this contract, and proxied again to the
|
|
13
|
+
/// corresponding implementation contracts
|
|
14
|
+
contract PendleRouterProxy is Proxy, Initializable, UUPSUpgradeable, BoringOwnableUpg {
|
|
15
|
+
address public immutable PENDLE_ROUTER_CORE;
|
|
16
|
+
address public immutable PENDLE_ROUTER_YT;
|
|
17
|
+
|
|
18
|
+
constructor(address _PENDLE_ROUTER_CORE, address _PENDLE_ROUTER_YT) {
|
|
19
|
+
PENDLE_ROUTER_CORE = _PENDLE_ROUTER_CORE;
|
|
20
|
+
PENDLE_ROUTER_YT = _PENDLE_ROUTER_YT;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function initialize() external initializer {
|
|
24
|
+
__UUPSUpgradeable_init();
|
|
25
|
+
__BoringOwnable_init();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function getRouterImplementation(bytes4 sig) public view returns (address) {
|
|
29
|
+
if (
|
|
30
|
+
sig == IPRouterCore.mintScyFromRawToken.selector ||
|
|
31
|
+
sig == IPRouterCore.redeemScyToRawToken.selector ||
|
|
32
|
+
sig == IPRouterCore.mintYoFromRawToken.selector ||
|
|
33
|
+
sig == IPRouterCore.redeemYoToRawToken.selector ||
|
|
34
|
+
sig == IPRouterCore.addLiquidity.selector ||
|
|
35
|
+
sig == IPRouterCore.removeLiquidity.selector ||
|
|
36
|
+
sig == IPRouterCore.swapExactOtForScy.selector ||
|
|
37
|
+
sig == IPRouterCore.swapOtForExactScy.selector ||
|
|
38
|
+
sig == IPRouterCore.swapScyForExactOt.selector ||
|
|
39
|
+
sig == IPRouterCore.swapExactScyForOt.selector ||
|
|
40
|
+
sig == IPRouterCore.swapExactRawTokenForOt.selector ||
|
|
41
|
+
sig == IPRouterCore.swapExactOtForRawToken.selector
|
|
42
|
+
) {
|
|
43
|
+
return PENDLE_ROUTER_CORE;
|
|
44
|
+
} else if (
|
|
45
|
+
sig == IPRouterYT.swapExactYtForScy.selector ||
|
|
46
|
+
sig == IPRouterYT.swapScyForExactYt.selector ||
|
|
47
|
+
sig == IPRouterYT.swapExactScyForYt.selector ||
|
|
48
|
+
sig == IPRouterYT.swapExactRawTokenForYt.selector ||
|
|
49
|
+
sig == IPRouterYT.swapExactYtForRawToken.selector
|
|
50
|
+
) {
|
|
51
|
+
return PENDLE_ROUTER_YT;
|
|
52
|
+
} else if (sig == IPMarketSwapCallback.swapCallback.selector) {
|
|
53
|
+
// only ROUTER_YT is doing callback
|
|
54
|
+
return PENDLE_ROUTER_YT;
|
|
55
|
+
}
|
|
56
|
+
require(false, "invalid market sig");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function _implementation() internal view override returns (address) {
|
|
60
|
+
return getRouterImplementation(msg.sig);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
|
|
64
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
pragma solidity 0.8.9;
|
|
3
|
+
|
|
4
|
+
import "./base/PendleRouterSCYAndForgeBaseUpg.sol";
|
|
5
|
+
import "./base/PendleRouterYTBaseUpg.sol";
|
|
6
|
+
import "../../interfaces/IPOwnershipToken.sol";
|
|
7
|
+
import "../../interfaces/IPYieldToken.sol";
|
|
8
|
+
|
|
9
|
+
contract PendleRouterYTUpg is PendleRouterSCYAndForgeBaseUpg, PendleRouterYTBaseUpg {
|
|
10
|
+
using MarketMathLib for MarketParameters;
|
|
11
|
+
using FixedPoint for uint256;
|
|
12
|
+
using FixedPoint for int256;
|
|
13
|
+
|
|
14
|
+
/// @dev since this contract will be proxied, it must not contains non-immutable variables
|
|
15
|
+
constructor(
|
|
16
|
+
address _joeRouter,
|
|
17
|
+
address _joeFactory,
|
|
18
|
+
address _marketFactory
|
|
19
|
+
)
|
|
20
|
+
PendleRouterSCYAndForgeBaseUpg(_joeRouter, _joeFactory)
|
|
21
|
+
PendleRouterYTBaseUpg(_marketFactory)
|
|
22
|
+
//solhint-disable-next-line no-empty-blocks
|
|
23
|
+
{
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function swapExactYtForScy(
|
|
28
|
+
address receiver,
|
|
29
|
+
address market,
|
|
30
|
+
uint256 exactYtIn,
|
|
31
|
+
uint256 minScyOut
|
|
32
|
+
) external returns (uint256) {
|
|
33
|
+
return _swapExactYtForScy(receiver, market, exactYtIn, minScyOut, true);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function swapScyForExactYt(
|
|
37
|
+
address receiver,
|
|
38
|
+
address market,
|
|
39
|
+
uint256 exactYtOut,
|
|
40
|
+
uint256 maxScyIn
|
|
41
|
+
) external returns (uint256) {
|
|
42
|
+
return _swapScyForExactYt(receiver, market, exactYtOut, maxScyIn);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function swapExactScyForYt(
|
|
46
|
+
address receiver,
|
|
47
|
+
address market,
|
|
48
|
+
uint256 exactScyIn,
|
|
49
|
+
uint256 minYtOut,
|
|
50
|
+
uint256 netYtOutGuessMin,
|
|
51
|
+
uint256 netYtOutGuessMax
|
|
52
|
+
) external returns (uint256) {
|
|
53
|
+
return
|
|
54
|
+
_swapExactScyForYt(
|
|
55
|
+
receiver,
|
|
56
|
+
market,
|
|
57
|
+
exactScyIn,
|
|
58
|
+
minYtOut,
|
|
59
|
+
netYtOutGuessMin,
|
|
60
|
+
netYtOutGuessMax,
|
|
61
|
+
true
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @dev netYtOutGuessMin & Max can be used in the same way as RawTokenOT
|
|
67
|
+
* @param path the path to swap from rawToken to baseToken. path = [baseToken] if no swap is needed
|
|
68
|
+
* @dev inner working of this function:
|
|
69
|
+
- mintScyFromRawToken is invoked, except the YT contract will receive all the outcome SCY
|
|
70
|
+
- market.swap is called, which will transfer SCY to the YT contract, and callback is invoked
|
|
71
|
+
- callback will do call YT's mintYO, which will mint OT to the market & YT to the receiver
|
|
72
|
+
*/
|
|
73
|
+
function swapExactRawTokenForYt(
|
|
74
|
+
uint256 exactRawTokenIn,
|
|
75
|
+
address receiver,
|
|
76
|
+
address[] calldata path,
|
|
77
|
+
address market,
|
|
78
|
+
uint256 minYtOut,
|
|
79
|
+
uint256 netYtOutGuessMin,
|
|
80
|
+
uint256 netYtOutGuessMax
|
|
81
|
+
) external returns (uint256 netYtOut) {
|
|
82
|
+
(ISuperComposableYield SCY, , IPYieldToken YT) = IPMarket(market).readTokens();
|
|
83
|
+
|
|
84
|
+
uint256 netScyUsedToBuyYT = _mintScyFromRawToken(
|
|
85
|
+
exactRawTokenIn,
|
|
86
|
+
address(SCY),
|
|
87
|
+
1,
|
|
88
|
+
address(YT),
|
|
89
|
+
path,
|
|
90
|
+
true
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
netYtOut = _swapExactScyForYt(
|
|
94
|
+
receiver,
|
|
95
|
+
market,
|
|
96
|
+
netScyUsedToBuyYT,
|
|
97
|
+
minYtOut,
|
|
98
|
+
netYtOutGuessMin,
|
|
99
|
+
netYtOutGuessMax,
|
|
100
|
+
false
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @notice swap YT -> SCY -> baseToken -> rawToken
|
|
106
|
+
* @notice the algorithm to swap will guarantee to swap all the YT available
|
|
107
|
+
* @param path the path to swap from rawToken to baseToken. path = [baseToken] if no swap is needed
|
|
108
|
+
* @dev inner working of this function:
|
|
109
|
+
- YT is transferred to the YT contract
|
|
110
|
+
- market.swap is called, which will transfer OT directly to the YT contract, and callback is invoked
|
|
111
|
+
- callback will do call YT's redeemYO, which will redeem the outcome SCY to this router, then
|
|
112
|
+
all SCY owed to the market will be paid, the rest is used to feed redeemScyToRawToken
|
|
113
|
+
*/
|
|
114
|
+
function swapExactYtForRawToken(
|
|
115
|
+
uint256 exactYtIn,
|
|
116
|
+
address receiver,
|
|
117
|
+
address[] calldata path,
|
|
118
|
+
address market,
|
|
119
|
+
uint256 minRawTokenOut
|
|
120
|
+
) external returns (uint256 netRawTokenOut) {
|
|
121
|
+
(ISuperComposableYield SCY, , ) = IPMarket(market).readTokens();
|
|
122
|
+
|
|
123
|
+
uint256 netScyOut = _swapExactYtForScy(address(SCY), market, exactYtIn, 1, true);
|
|
124
|
+
|
|
125
|
+
netRawTokenOut = _redeemScyToRawToken(
|
|
126
|
+
address(SCY),
|
|
127
|
+
netScyOut,
|
|
128
|
+
minRawTokenOut,
|
|
129
|
+
receiver,
|
|
130
|
+
path,
|
|
131
|
+
false
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
pragma solidity 0.8.9;
|
|
3
|
+
|
|
4
|
+
import "../../../interfaces/IPMarketFactory.sol";
|
|
5
|
+
import "../../../interfaces/IPMarket.sol";
|
|
6
|
+
import "../../../interfaces/IPMarketAddRemoveCallback.sol";
|
|
7
|
+
import "../../../interfaces/IPMarketSwapCallback.sol";
|
|
8
|
+
import "../../../libraries/math/MarketApproxLib.sol";
|
|
9
|
+
import "openzeppelin-solidity/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
10
|
+
|
|
11
|
+
abstract contract PendleRouterOTBaseUpg {
|
|
12
|
+
using FixedPoint for uint256;
|
|
13
|
+
using FixedPoint for int256;
|
|
14
|
+
using MarketMathLib for MarketParameters;
|
|
15
|
+
using MarketApproxLib for MarketParameters;
|
|
16
|
+
using SafeERC20 for IERC20;
|
|
17
|
+
|
|
18
|
+
/// @dev since this contract will be proxied, it must not contains non-immutable variables
|
|
19
|
+
constructor() //solhint-disable-next-line no-empty-blocks
|
|
20
|
+
{
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @notice addLiquidity to the market, using both SCY & OT, the receiver will receive LP before
|
|
26
|
+
msg.sender is required to pay SCY & OT
|
|
27
|
+
* @dev inner working of this function:
|
|
28
|
+
- market.addLiquidity is called
|
|
29
|
+
- LP is minted to the receiver, and this router's addLiquidityCallback is invoked
|
|
30
|
+
- the router will transfer the necessary scy & ot from msg.sender to the market, and finish the callback
|
|
31
|
+
*/
|
|
32
|
+
function _addLiquidity(
|
|
33
|
+
address receiver,
|
|
34
|
+
address market,
|
|
35
|
+
uint256 scyDesired,
|
|
36
|
+
uint256 otDesired,
|
|
37
|
+
uint256 minLpOut,
|
|
38
|
+
bool doPull
|
|
39
|
+
)
|
|
40
|
+
internal
|
|
41
|
+
returns (
|
|
42
|
+
uint256 netLpOut,
|
|
43
|
+
uint256 scyUsed,
|
|
44
|
+
uint256 otUsed
|
|
45
|
+
)
|
|
46
|
+
{
|
|
47
|
+
(ISuperComposableYield SCY, IPOwnershipToken OT, ) = IPMarket(market).readTokens();
|
|
48
|
+
|
|
49
|
+
MarketParameters memory state = IPMarket(market).readState();
|
|
50
|
+
(, netLpOut, scyUsed, otUsed) = state.addLiquidity(
|
|
51
|
+
SCYIndexLib.newIndex(SCY),
|
|
52
|
+
scyDesired,
|
|
53
|
+
otDesired
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
require(netLpOut >= minLpOut, "insufficient lp out");
|
|
57
|
+
|
|
58
|
+
if (doPull) {
|
|
59
|
+
IERC20(SCY).safeTransferFrom(msg.sender, market, scyUsed);
|
|
60
|
+
IERC20(OT).safeTransferFrom(msg.sender, market, otUsed);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
IPMarket(market).addLiquidity(receiver, otDesired, scyDesired, abi.encode());
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @notice removeLiquidity from the market to receive both SCY & OT. The receiver will receive
|
|
68
|
+
SCY & OT before msg.sender is required to transfer in the necessary LP
|
|
69
|
+
* @dev inner working of this function:
|
|
70
|
+
- market.removeLiquidity is called
|
|
71
|
+
- SCY & OT is transferred to the receiver, and the router's callback is invoked
|
|
72
|
+
- the router will transfer the necessary LP from msg.sender to the market, and finish the callback
|
|
73
|
+
*/
|
|
74
|
+
function _removeLiquidity(
|
|
75
|
+
address receiver,
|
|
76
|
+
address market,
|
|
77
|
+
uint256 lpToRemove,
|
|
78
|
+
uint256 scyOutMin,
|
|
79
|
+
uint256 otOutMin,
|
|
80
|
+
bool doPull
|
|
81
|
+
) internal returns (uint256 netScyOut, uint256 netOtOut) {
|
|
82
|
+
MarketParameters memory state = IPMarket(market).readState();
|
|
83
|
+
|
|
84
|
+
(netScyOut, netOtOut) = state.removeLiquidity(lpToRemove);
|
|
85
|
+
require(netScyOut >= scyOutMin, "insufficient scy out");
|
|
86
|
+
require(netOtOut >= otOutMin, "insufficient ot out");
|
|
87
|
+
|
|
88
|
+
if (doPull) {
|
|
89
|
+
IERC20(market).safeTransferFrom(msg.sender, market, lpToRemove);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
IPMarket(market).removeLiquidity(receiver, lpToRemove, abi.encode());
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @notice swap exact OT for SCY, with receiver receiving SCY before msg.sender is required to
|
|
97
|
+
transfer the owed OT
|
|
98
|
+
* @dev inner working of this function:
|
|
99
|
+
- market.swap is called
|
|
100
|
+
- SCY is transferred to the receiver, and the router's callback is invoked
|
|
101
|
+
- the router will transfer the necessary OT from msg.sender to the market, and finish the callback
|
|
102
|
+
*/
|
|
103
|
+
function _swapExactOtForScy(
|
|
104
|
+
address receiver,
|
|
105
|
+
address market,
|
|
106
|
+
uint256 exactOtIn,
|
|
107
|
+
uint256 minScyOut,
|
|
108
|
+
bool doPull
|
|
109
|
+
) internal returns (uint256 netScyOut) {
|
|
110
|
+
if (doPull) {
|
|
111
|
+
address OT = IPMarket(market).OT();
|
|
112
|
+
IERC20(OT).safeTransferFrom(msg.sender, market, exactOtIn);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
(netScyOut, ) = IPMarket(market).swapExactOtForScy(
|
|
116
|
+
receiver,
|
|
117
|
+
exactOtIn,
|
|
118
|
+
minScyOut,
|
|
119
|
+
abi.encode()
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
require(netScyOut >= minScyOut, "insufficient scy out");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function _swapOtForExactScy(
|
|
126
|
+
address receiver,
|
|
127
|
+
address market,
|
|
128
|
+
uint256 maxOtIn,
|
|
129
|
+
uint256 exactScyOut,
|
|
130
|
+
uint256 netOtInGuessMin,
|
|
131
|
+
uint256 netOtInGuessMax,
|
|
132
|
+
bool doPull
|
|
133
|
+
) internal returns (uint256 netOtIn) {
|
|
134
|
+
MarketParameters memory state = IPMarket(market).readState();
|
|
135
|
+
(ISuperComposableYield SCY, IPOwnershipToken OT, ) = IPMarket(market).readTokens();
|
|
136
|
+
|
|
137
|
+
netOtIn = state.approxSwapOtForExactScy(
|
|
138
|
+
SCYIndexLib.newIndex(SCY),
|
|
139
|
+
exactScyOut,
|
|
140
|
+
block.timestamp,
|
|
141
|
+
netOtInGuessMin,
|
|
142
|
+
netOtInGuessMax
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
require(netOtIn <= maxOtIn, "ot in exceed limit");
|
|
146
|
+
|
|
147
|
+
if (doPull) {
|
|
148
|
+
IERC20(OT).safeTransferFrom(msg.sender, market, netOtIn);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
IPMarket(market).swapExactOtForScy(receiver, netOtIn, exactScyOut, abi.encode());
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @notice swap SCY for exact OT, with receiver receiving OT before msg.sender is required to
|
|
156
|
+
transfer the owed SCY
|
|
157
|
+
* @dev inner working of this function:
|
|
158
|
+
- market.swap is called
|
|
159
|
+
- OT is transferred to the receiver, and the router's callback is invoked
|
|
160
|
+
- the router will transfer the necessary SCY from msg.sender to the market, and finish the callback
|
|
161
|
+
*/
|
|
162
|
+
function _swapScyForExactOt(
|
|
163
|
+
address receiver,
|
|
164
|
+
address market,
|
|
165
|
+
uint256 exactOtOut,
|
|
166
|
+
uint256 maxScyIn,
|
|
167
|
+
bool doPull
|
|
168
|
+
) internal returns (uint256 netScyIn) {
|
|
169
|
+
MarketParameters memory state = IPMarket(market).readState();
|
|
170
|
+
address SCY = IPMarket(market).SCY();
|
|
171
|
+
|
|
172
|
+
(netScyIn, ) = state.swapScyForExactOt(
|
|
173
|
+
SCYIndexLib.newIndex(SCY),
|
|
174
|
+
exactOtOut,
|
|
175
|
+
block.timestamp
|
|
176
|
+
);
|
|
177
|
+
require(netScyIn <= maxScyIn, "exceed limit scy in");
|
|
178
|
+
|
|
179
|
+
if (doPull) {
|
|
180
|
+
IERC20(SCY).safeTransferFrom(msg.sender, market, netScyIn);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
IPMarket(market).swapScyForExactOt(receiver, exactOtOut, maxScyIn, abi.encode());
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function _swapExactScyForOt(
|
|
187
|
+
address receiver,
|
|
188
|
+
address market,
|
|
189
|
+
uint256 exactScyIn,
|
|
190
|
+
uint256 minOtOut,
|
|
191
|
+
uint256 netOtOutGuessMin,
|
|
192
|
+
uint256 netOtOutGuessMax,
|
|
193
|
+
bool doPull
|
|
194
|
+
) internal returns (uint256 netOtOut) {
|
|
195
|
+
MarketParameters memory state = IPMarket(market).readState();
|
|
196
|
+
address SCY = IPMarket(market).SCY();
|
|
197
|
+
|
|
198
|
+
if (netOtOutGuessMax == type(uint256).max) {
|
|
199
|
+
netOtOutGuessMax = state.totalOt.Uint();
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
netOtOut = state.approxSwapExactScyForOt(
|
|
203
|
+
SCYIndexLib.newIndex(SCY),
|
|
204
|
+
exactScyIn,
|
|
205
|
+
block.timestamp,
|
|
206
|
+
netOtOutGuessMin,
|
|
207
|
+
netOtOutGuessMax
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
require(netOtOut >= minOtOut, "insufficient out");
|
|
211
|
+
|
|
212
|
+
if (doPull) {
|
|
213
|
+
IERC20(SCY).safeTransferFrom(msg.sender, market, exactScyIn);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
IPMarket(market).swapScyForExactOt(receiver, netOtOut, exactScyIn, abi.encode());
|
|
217
|
+
}
|
|
218
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
pragma solidity 0.8.9;
|
|
3
|
+
|
|
4
|
+
import "openzeppelin-solidity/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
5
|
+
import "../../misc/PendleJoeSwapHelperUpg.sol";
|
|
6
|
+
import "../../../SuperComposableYield/ISuperComposableYield.sol";
|
|
7
|
+
import "../../../interfaces/IPYieldToken.sol";
|
|
8
|
+
|
|
9
|
+
abstract contract PendleRouterSCYAndForgeBaseUpg is PendleJoeSwapHelperUpg {
|
|
10
|
+
using SafeERC20 for IERC20;
|
|
11
|
+
|
|
12
|
+
/// @dev since this contract will be proxied, it must not contains non-immutable variables
|
|
13
|
+
constructor(address _joeRouter, address _joeFactory)
|
|
14
|
+
PendleJoeSwapHelperUpg(_joeRouter, _joeFactory)
|
|
15
|
+
// solhint-disable-next-line no-empty-blocks
|
|
16
|
+
{
|
|
17
|
+
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @notice swap rawToken to baseToken -> baseToken to mint SCY
|
|
22
|
+
* @param path the path to swap from rawToken to baseToken. path = [baseToken] if no swap is needed
|
|
23
|
+
* @dev inner working of this function:
|
|
24
|
+
- if [rawToken == baseToken], rawToken is transferred to SCY contract
|
|
25
|
+
else, it is transferred to the first pair of path, swap is called, and the output token is transferred
|
|
26
|
+
to SCY contract
|
|
27
|
+
- SCY.mint is called, minting SCY directly to receiver
|
|
28
|
+
*/
|
|
29
|
+
function _mintScyFromRawToken(
|
|
30
|
+
uint256 netRawTokenIn,
|
|
31
|
+
address SCY,
|
|
32
|
+
uint256 minScyOut,
|
|
33
|
+
address receiver,
|
|
34
|
+
address[] calldata path,
|
|
35
|
+
bool doPull
|
|
36
|
+
) internal returns (uint256 netScyOut) {
|
|
37
|
+
if (doPull) {
|
|
38
|
+
if (path.length == 1) {
|
|
39
|
+
IERC20(path[0]).safeTransferFrom(msg.sender, SCY, netRawTokenIn);
|
|
40
|
+
} else {
|
|
41
|
+
IERC20(path[0]).safeTransferFrom(msg.sender, _getFirstPair(path), netRawTokenIn);
|
|
42
|
+
_swapExactIn(path, netRawTokenIn, SCY);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
address baseToken = path[path.length - 1];
|
|
47
|
+
netScyOut = ISuperComposableYield(SCY).mint(receiver, baseToken, minScyOut);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @notice redeem SCY to baseToken -> swap baseToken to rawToken
|
|
52
|
+
* @dev path[0] will be the baseToken that SCY is redeemed to, and path[path.length-1] is the
|
|
53
|
+
final rawToken output
|
|
54
|
+
* @param path the path to swap from rawToken to baseToken. path = [baseToken] if no swap is needed
|
|
55
|
+
* @dev inner working of this function:
|
|
56
|
+
- SCY is transferred to SCY contract
|
|
57
|
+
- if [rawToken == baseToken], SCY.redeem is called & directly redeem tokens to the receiver
|
|
58
|
+
else, SCY.redeem is called with receiver = first pair in the path,
|
|
59
|
+
and swap is called, and the output token is transferred to receiver
|
|
60
|
+
*/
|
|
61
|
+
function _redeemScyToRawToken(
|
|
62
|
+
address SCY,
|
|
63
|
+
uint256 netScyIn,
|
|
64
|
+
uint256 minRawTokenOut,
|
|
65
|
+
address receiver,
|
|
66
|
+
address[] memory path,
|
|
67
|
+
bool doPull
|
|
68
|
+
) internal returns (uint256 netRawTokenOut) {
|
|
69
|
+
if (doPull) {
|
|
70
|
+
IERC20(SCY).safeTransferFrom(msg.sender, SCY, netScyIn);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
address baseToken = path[0];
|
|
74
|
+
if (path.length == 1) {
|
|
75
|
+
netRawTokenOut = ISuperComposableYield(SCY).redeem(
|
|
76
|
+
receiver,
|
|
77
|
+
baseToken,
|
|
78
|
+
minRawTokenOut
|
|
79
|
+
);
|
|
80
|
+
} else {
|
|
81
|
+
uint256 netBaseTokenOut = ISuperComposableYield(SCY).redeem(
|
|
82
|
+
_getFirstPair(path),
|
|
83
|
+
baseToken,
|
|
84
|
+
1
|
|
85
|
+
);
|
|
86
|
+
netRawTokenOut = _swapExactIn(path, netBaseTokenOut, receiver);
|
|
87
|
+
require(netRawTokenOut >= minRawTokenOut, "insufficient out");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @notice swap rawToken to baseToken -> convert to SCY -> convert to OT + YT
|
|
93
|
+
* @param path the path to swap from rawToken to baseToken. path = [baseToken] if no swap is needed
|
|
94
|
+
* @dev inner working of this function:
|
|
95
|
+
- same as mintScyFromRawToken, except the receiver of SCY will be the YT contract, then mintYO
|
|
96
|
+
will be called, minting OT + YT directly to receiver
|
|
97
|
+
*/
|
|
98
|
+
function _mintYoFromRawToken(
|
|
99
|
+
uint256 netRawTokenIn,
|
|
100
|
+
address YT,
|
|
101
|
+
uint256 minYoOut,
|
|
102
|
+
address receiver,
|
|
103
|
+
address[] calldata path,
|
|
104
|
+
bool doPull
|
|
105
|
+
) internal returns (uint256 netYoOut) {
|
|
106
|
+
address SCY = IPYieldToken(YT).SCY();
|
|
107
|
+
_mintScyFromRawToken(netRawTokenIn, SCY, 1, YT, path, doPull);
|
|
108
|
+
netYoOut = IPYieldToken(YT).mintYO(receiver, receiver);
|
|
109
|
+
require(netYoOut >= minYoOut, "insufficient YO out");
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* @notice redeem OT + YT to SCY -> redeem SCY to baseToken -> swap baseToken to rawToken
|
|
114
|
+
* @param path the path to swap from rawToken to baseToken. path = [baseToken] if no swap is needed
|
|
115
|
+
* @dev inner working of this function:
|
|
116
|
+
- OT (+ YT if not expired) is transferred to the YT contract
|
|
117
|
+
- redeemYO is called, redeem all outcome SCY to the SCY contract
|
|
118
|
+
- The rest is the same as redeemScyToRawToken (except the first SCY transfer is skipped)
|
|
119
|
+
*/
|
|
120
|
+
function _redeemYoToRawToken(
|
|
121
|
+
address YT,
|
|
122
|
+
uint256 netYoIn,
|
|
123
|
+
uint256 minRawTokenOut,
|
|
124
|
+
address receiver,
|
|
125
|
+
address[] memory path,
|
|
126
|
+
bool doPull
|
|
127
|
+
) internal returns (uint256 netRawTokenOut) {
|
|
128
|
+
address OT = IPYieldToken(YT).OT();
|
|
129
|
+
address SCY = IPYieldToken(YT).SCY();
|
|
130
|
+
|
|
131
|
+
if (doPull) {
|
|
132
|
+
bool isNeedToBurnYt = (IPBaseToken(YT).isExpired() == false);
|
|
133
|
+
IERC20(OT).safeTransferFrom(msg.sender, YT, netYoIn);
|
|
134
|
+
if (isNeedToBurnYt) IERC20(YT).safeTransferFrom(msg.sender, YT, netYoIn);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
IPYieldToken(YT).redeemYO(SCY);
|
|
138
|
+
|
|
139
|
+
netRawTokenOut = _redeemScyToRawToken(SCY, 0, minRawTokenOut, receiver, path, false);
|
|
140
|
+
}
|
|
141
|
+
}
|