@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,121 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0
|
|
2
|
+
|
|
3
|
+
pragma solidity 0.8.9;
|
|
4
|
+
|
|
5
|
+
import "../interfaces/IJoePair.sol";
|
|
6
|
+
|
|
7
|
+
library JoeLibrary {
|
|
8
|
+
// returns sorted token addresses, used to handle return values from pairs sorted in this order
|
|
9
|
+
function sortTokens(address tokenA, address tokenB)
|
|
10
|
+
internal
|
|
11
|
+
pure
|
|
12
|
+
returns (address token0, address token1)
|
|
13
|
+
{
|
|
14
|
+
require(tokenA != tokenB, "JoeLibrary: IDENTICAL_ADDRESSES");
|
|
15
|
+
(token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
|
|
16
|
+
require(token0 != address(0), "JoeLibrary: ZERO_ADDRESS");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// calculates the CREATE2 address for a pair without making any external calls
|
|
20
|
+
function pairFor(
|
|
21
|
+
address factory,
|
|
22
|
+
address tokenA,
|
|
23
|
+
address tokenB
|
|
24
|
+
) internal pure returns (address pair) {
|
|
25
|
+
(address token0, address token1) = sortTokens(tokenA, tokenB);
|
|
26
|
+
pair = address(
|
|
27
|
+
uint160(
|
|
28
|
+
uint256(
|
|
29
|
+
keccak256(
|
|
30
|
+
abi.encodePacked(
|
|
31
|
+
hex"ff",
|
|
32
|
+
factory,
|
|
33
|
+
keccak256(abi.encodePacked(token0, token1)),
|
|
34
|
+
hex"0bbca9af0511ad1a1da383135cf3a8d2ac620e549ef9f6ae3a4c33c2fed0af91" // init code fuji
|
|
35
|
+
)
|
|
36
|
+
)
|
|
37
|
+
)
|
|
38
|
+
)
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// fetches and sorts the reserves for a pair
|
|
43
|
+
function getReserves(
|
|
44
|
+
address factory,
|
|
45
|
+
address tokenA,
|
|
46
|
+
address tokenB
|
|
47
|
+
) internal view returns (uint256 reserveA, uint256 reserveB) {
|
|
48
|
+
(address token0, ) = sortTokens(tokenA, tokenB);
|
|
49
|
+
(uint256 reserve0, uint256 reserve1, ) = IJoePair(pairFor(factory, tokenA, tokenB))
|
|
50
|
+
.getReserves();
|
|
51
|
+
(reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// given some amount of an asset and pair reserves, returns an equivalent amount of the other asset
|
|
55
|
+
function quote(
|
|
56
|
+
uint256 amountA,
|
|
57
|
+
uint256 reserveA,
|
|
58
|
+
uint256 reserveB
|
|
59
|
+
) internal pure returns (uint256 amountB) {
|
|
60
|
+
require(amountA > 0, "JoeLibrary: INSUFFICIENT_AMOUNT");
|
|
61
|
+
require(reserveA > 0 && reserveB > 0, "JoeLibrary: INSUFFICIENT_LIQUIDITY");
|
|
62
|
+
amountB = (amountA * reserveB) / reserveA;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset
|
|
66
|
+
function getAmountOut(
|
|
67
|
+
uint256 amountIn,
|
|
68
|
+
uint256 reserveIn,
|
|
69
|
+
uint256 reserveOut
|
|
70
|
+
) internal pure returns (uint256 amountOut) {
|
|
71
|
+
require(amountIn > 0, "JoeLibrary: INSUFFICIENT_INPUT_AMOUNT");
|
|
72
|
+
require(reserveIn > 0 && reserveOut > 0, "JoeLibrary: INSUFFICIENT_LIQUIDITY");
|
|
73
|
+
uint256 amountInWithFee = amountIn * 997;
|
|
74
|
+
uint256 numerator = amountInWithFee * reserveOut;
|
|
75
|
+
uint256 denominator = reserveIn * 1000 + amountInWithFee;
|
|
76
|
+
amountOut = numerator / denominator;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// given an output amount of an asset and pair reserves, returns a required input amount of the other asset
|
|
80
|
+
function getAmountIn(
|
|
81
|
+
uint256 amountOut,
|
|
82
|
+
uint256 reserveIn,
|
|
83
|
+
uint256 reserveOut
|
|
84
|
+
) internal pure returns (uint256 amountIn) {
|
|
85
|
+
require(amountOut > 0, "JoeLibrary: INSUFFICIENT_OUTPUT_AMOUNT");
|
|
86
|
+
require(reserveIn > 0 && reserveOut > 0, "JoeLibrary: INSUFFICIENT_LIQUIDITY");
|
|
87
|
+
uint256 numerator = reserveIn * amountOut * 1000;
|
|
88
|
+
uint256 denominator = (reserveOut - amountOut) * 997;
|
|
89
|
+
amountIn = (numerator / denominator) + 1;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// performs chained getAmountOut calculations on any number of pairs
|
|
93
|
+
function getAmountsOut(
|
|
94
|
+
address factory,
|
|
95
|
+
uint256 amountIn,
|
|
96
|
+
address[] memory path
|
|
97
|
+
) internal view returns (uint256[] memory amounts) {
|
|
98
|
+
require(path.length >= 2, "JoeLibrary: INVALID_PATH");
|
|
99
|
+
amounts = new uint256[](path.length);
|
|
100
|
+
amounts[0] = amountIn;
|
|
101
|
+
for (uint256 i; i < path.length - 1; i++) {
|
|
102
|
+
(uint256 reserveIn, uint256 reserveOut) = getReserves(factory, path[i], path[i + 1]);
|
|
103
|
+
amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// performs chained getAmountIn calculations on any number of pairs
|
|
108
|
+
function getAmountsIn(
|
|
109
|
+
address factory,
|
|
110
|
+
uint256 amountOut,
|
|
111
|
+
address[] memory path
|
|
112
|
+
) internal view returns (uint256[] memory amounts) {
|
|
113
|
+
require(path.length >= 2, "JoeLibrary: INVALID_PATH");
|
|
114
|
+
amounts = new uint256[](path.length);
|
|
115
|
+
amounts[amounts.length - 1] = amountOut;
|
|
116
|
+
for (uint256 i = path.length - 1; i > 0; i--) {
|
|
117
|
+
(uint256 reserveIn, uint256 reserveOut) = getReserves(factory, path[i - 1], path[i]);
|
|
118
|
+
amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
pragma solidity 0.8.9;
|
|
3
|
+
import "../SuperComposableYield/ISuperComposableYield.sol";
|
|
4
|
+
import "../SuperComposableYield/SCYUtils.sol";
|
|
5
|
+
import "./math/FixedPoint.sol";
|
|
6
|
+
|
|
7
|
+
type SCYIndex is uint256;
|
|
8
|
+
|
|
9
|
+
library SCYIndexLib {
|
|
10
|
+
using FixedPoint for uint256;
|
|
11
|
+
using FixedPoint for int256;
|
|
12
|
+
|
|
13
|
+
function newIndex(ISuperComposableYield SCY) internal returns (SCYIndex) {
|
|
14
|
+
return SCYIndex.wrap(SCY.scyIndexCurrent());
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function newIndex(address SCY) internal returns (SCYIndex) {
|
|
18
|
+
return SCYIndex.wrap(ISuperComposableYield(SCY).scyIndexCurrent());
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function scyToAsset(SCYIndex index, uint256 scyAmount)
|
|
22
|
+
internal
|
|
23
|
+
pure
|
|
24
|
+
returns (uint256)
|
|
25
|
+
{
|
|
26
|
+
return SCYUtils.scyToAsset(SCYIndex.unwrap(index), scyAmount);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function assetToScy(SCYIndex index, uint256 assetAmount)
|
|
30
|
+
internal
|
|
31
|
+
pure
|
|
32
|
+
returns (uint256)
|
|
33
|
+
{
|
|
34
|
+
return SCYUtils.assetToScy(SCYIndex.unwrap(index), assetAmount);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function scyToAsset(SCYIndex index, int256 scyAmount)
|
|
38
|
+
internal
|
|
39
|
+
pure
|
|
40
|
+
returns (int256)
|
|
41
|
+
{
|
|
42
|
+
int256 sign = scyAmount < 0 ? int256(-1) : int256(1);
|
|
43
|
+
return sign * (SCYUtils.scyToAsset(SCYIndex.unwrap(index), scyAmount.abs())).Int();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function assetToScy(SCYIndex index, int256 assetAmount)
|
|
47
|
+
internal
|
|
48
|
+
pure
|
|
49
|
+
returns (int256)
|
|
50
|
+
{
|
|
51
|
+
int256 sign = assetAmount < 0 ? int256(-1) : int256(1);
|
|
52
|
+
return sign * (SCYUtils.assetToScy(SCYIndex.unwrap(index), assetAmount.abs())).Int();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
pragma solidity 0.8.9;
|
|
3
|
+
|
|
4
|
+
library ExpiryUtils {
|
|
5
|
+
struct Date {
|
|
6
|
+
uint16 year;
|
|
7
|
+
uint8 month;
|
|
8
|
+
uint8 day;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
uint256 private constant DAY_IN_SECONDS = 86400;
|
|
12
|
+
uint256 private constant YEAR_IN_SECONDS = 31536000;
|
|
13
|
+
uint256 private constant LEAP_YEAR_IN_SECONDS = 31622400;
|
|
14
|
+
uint16 private constant ORIGIN_YEAR = 1970;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @notice Concatenates a Pendle token name/symbol, a yield token name/symbol,
|
|
18
|
+
* and an expiry, using a delimiter (usually "-" or " ").
|
|
19
|
+
* @param _bt The Pendle token name/symbol.
|
|
20
|
+
* @param _yt The yield token name/symbol.
|
|
21
|
+
* @param _expiry The expiry in epoch time.
|
|
22
|
+
* @param _delimiter Can be any delimiter, but usually "-" or " ".
|
|
23
|
+
* @return result Returns the concatenated string.
|
|
24
|
+
**/
|
|
25
|
+
function concat(
|
|
26
|
+
string memory _bt,
|
|
27
|
+
string memory _yt,
|
|
28
|
+
uint256 _expiry,
|
|
29
|
+
string memory _delimiter
|
|
30
|
+
) internal pure returns (string memory result) {
|
|
31
|
+
result = string(
|
|
32
|
+
abi.encodePacked(_bt, _delimiter, _yt, _delimiter, toRFC2822String(_expiry))
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function toRFC2822String(uint256 _timestamp) internal pure returns (string memory s) {
|
|
37
|
+
Date memory d = parseTimestamp(_timestamp);
|
|
38
|
+
string memory day = uintToString(d.day);
|
|
39
|
+
string memory month = monthName(d);
|
|
40
|
+
string memory year = uintToString(d.year);
|
|
41
|
+
s = string(abi.encodePacked(day, month, year));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function getDaysInMonth(uint8 _month, uint16 _year) private pure returns (uint8) {
|
|
45
|
+
if (
|
|
46
|
+
_month == 1 ||
|
|
47
|
+
_month == 3 ||
|
|
48
|
+
_month == 5 ||
|
|
49
|
+
_month == 7 ||
|
|
50
|
+
_month == 8 ||
|
|
51
|
+
_month == 10 ||
|
|
52
|
+
_month == 12
|
|
53
|
+
) {
|
|
54
|
+
return 31;
|
|
55
|
+
} else if (_month == 4 || _month == 6 || _month == 9 || _month == 11) {
|
|
56
|
+
return 30;
|
|
57
|
+
} else if (isLeapYear(_year)) {
|
|
58
|
+
return 29;
|
|
59
|
+
} else {
|
|
60
|
+
return 28;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function getYear(uint256 _timestamp) private pure returns (uint16) {
|
|
65
|
+
uint256 secondsAccountedFor = 0;
|
|
66
|
+
uint16 year;
|
|
67
|
+
uint256 numLeapYears;
|
|
68
|
+
|
|
69
|
+
// Year
|
|
70
|
+
year = uint16(ORIGIN_YEAR + _timestamp / YEAR_IN_SECONDS);
|
|
71
|
+
numLeapYears = leapYearsBefore(year) - leapYearsBefore(ORIGIN_YEAR);
|
|
72
|
+
|
|
73
|
+
secondsAccountedFor += LEAP_YEAR_IN_SECONDS * numLeapYears;
|
|
74
|
+
secondsAccountedFor += YEAR_IN_SECONDS * (year - ORIGIN_YEAR - numLeapYears);
|
|
75
|
+
|
|
76
|
+
while (secondsAccountedFor > _timestamp) {
|
|
77
|
+
if (isLeapYear(uint16(year - 1))) {
|
|
78
|
+
secondsAccountedFor -= LEAP_YEAR_IN_SECONDS;
|
|
79
|
+
} else {
|
|
80
|
+
secondsAccountedFor -= YEAR_IN_SECONDS;
|
|
81
|
+
}
|
|
82
|
+
year -= 1;
|
|
83
|
+
}
|
|
84
|
+
return year;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function isLeapYear(uint16 _year) private pure returns (bool) {
|
|
88
|
+
return ((_year % 4 == 0) && (_year % 100 != 0)) || (_year % 400 == 0);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function leapYearsBefore(uint256 _year) private pure returns (uint256) {
|
|
92
|
+
_year -= 1;
|
|
93
|
+
return _year / 4 - _year / 100 + _year / 400;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function monthName(Date memory d) private pure returns (string memory) {
|
|
97
|
+
string[12] memory months = [
|
|
98
|
+
"JAN",
|
|
99
|
+
"FEB",
|
|
100
|
+
"MAR",
|
|
101
|
+
"APR",
|
|
102
|
+
"MAY",
|
|
103
|
+
"JUN",
|
|
104
|
+
"JUL",
|
|
105
|
+
"AUG",
|
|
106
|
+
"SEP",
|
|
107
|
+
"OCT",
|
|
108
|
+
"NOV",
|
|
109
|
+
"DEC"
|
|
110
|
+
];
|
|
111
|
+
return months[d.month - 1];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function parseTimestamp(uint256 _timestamp) private pure returns (Date memory d) {
|
|
115
|
+
uint256 secondsAccountedFor = 0;
|
|
116
|
+
uint256 buf;
|
|
117
|
+
uint8 i;
|
|
118
|
+
|
|
119
|
+
// Year
|
|
120
|
+
d.year = getYear(_timestamp);
|
|
121
|
+
buf = leapYearsBefore(d.year) - leapYearsBefore(ORIGIN_YEAR);
|
|
122
|
+
|
|
123
|
+
secondsAccountedFor += LEAP_YEAR_IN_SECONDS * buf;
|
|
124
|
+
secondsAccountedFor += YEAR_IN_SECONDS * (d.year - ORIGIN_YEAR - buf);
|
|
125
|
+
|
|
126
|
+
// Month
|
|
127
|
+
uint256 secondsInMonth;
|
|
128
|
+
for (i = 1; i <= 12; i++) {
|
|
129
|
+
secondsInMonth = DAY_IN_SECONDS * getDaysInMonth(i, d.year);
|
|
130
|
+
if (secondsInMonth + secondsAccountedFor > _timestamp) {
|
|
131
|
+
d.month = i;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
secondsAccountedFor += secondsInMonth;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Day
|
|
138
|
+
for (i = 1; i <= getDaysInMonth(d.month, d.year); i++) {
|
|
139
|
+
if (DAY_IN_SECONDS + secondsAccountedFor > _timestamp) {
|
|
140
|
+
d.day = i;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
secondsAccountedFor += DAY_IN_SECONDS;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function uintToString(uint256 _i) private pure returns (string memory) {
|
|
148
|
+
if (_i == 0) {
|
|
149
|
+
return "0";
|
|
150
|
+
}
|
|
151
|
+
uint256 j = _i;
|
|
152
|
+
uint256 len;
|
|
153
|
+
while (j != 0) {
|
|
154
|
+
len++;
|
|
155
|
+
j /= 10;
|
|
156
|
+
}
|
|
157
|
+
bytes memory bstr = new bytes(len);
|
|
158
|
+
uint256 k = len - 1;
|
|
159
|
+
while (_i != 0) {
|
|
160
|
+
bstr[k] = bytes1(uint8(48 + (_i % 10)));
|
|
161
|
+
if (k != 0) k--;
|
|
162
|
+
_i /= 10;
|
|
163
|
+
}
|
|
164
|
+
return string(bstr);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
// This program is free software: you can redistribute it and/or modify
|
|
3
|
+
// it under the terms of the GNU General Public License as published by
|
|
4
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
5
|
+
// (at your option) any later version.
|
|
6
|
+
|
|
7
|
+
// This program is distributed in the hope that it will be useful,
|
|
8
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10
|
+
// GNU General Public License for more details.
|
|
11
|
+
|
|
12
|
+
// You should have received a copy of the GNU General Public License
|
|
13
|
+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
14
|
+
|
|
15
|
+
pragma solidity 0.8.9;
|
|
16
|
+
|
|
17
|
+
import "./LogExpMath.sol";
|
|
18
|
+
|
|
19
|
+
/* solhint-disable private-vars-leading-underscore, reason-string */
|
|
20
|
+
|
|
21
|
+
library FixedPoint {
|
|
22
|
+
uint256 internal constant ONE = 1e18; // 18 decimal places
|
|
23
|
+
int256 internal constant ONE_INT = 1e18; // 18 decimal places
|
|
24
|
+
|
|
25
|
+
uint256 internal constant MAX_POW_RELATIVE_ERROR = 10000; // 10^(-14)
|
|
26
|
+
|
|
27
|
+
// Minimum base for the power function when the exponent is 'free' (larger than ONE).
|
|
28
|
+
uint256 internal constant MIN_POW_BASE_FREE_EXPONENT = 0.7e18;
|
|
29
|
+
|
|
30
|
+
function subMax0(uint256 a, uint256 b) internal pure returns (uint256) {
|
|
31
|
+
return (a >= b ? a - b : 0);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function subNoNeg(int256 a, int256 b) internal pure returns (int256) {
|
|
35
|
+
require(a >= b, "NEGATIVE");
|
|
36
|
+
return a - b;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function subNoNeg(int256 a, uint256 b) internal pure returns (int256) {
|
|
40
|
+
int256 _b = Int(b);
|
|
41
|
+
require(a >= _b, "NEGATIVE");
|
|
42
|
+
return a - _b;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function mulDown(uint256 a, uint256 b) internal pure returns (uint256) {
|
|
46
|
+
uint256 product = a * b;
|
|
47
|
+
return product / ONE;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function mulDown(int256 a, int256 b) internal pure returns (int256) {
|
|
51
|
+
int256 product = a * b;
|
|
52
|
+
return product / Int(ONE);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function mulDown(int256 a, uint256 b) internal pure returns (int256) {
|
|
56
|
+
return mulDown(a, Int(b));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function mulDown(uint256 a, int256 b) internal pure returns (int256) {
|
|
60
|
+
return mulDown(Int(a), b);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function mulUp(uint256 a, uint256 b) internal pure returns (uint256) {
|
|
64
|
+
uint256 product = a * b;
|
|
65
|
+
|
|
66
|
+
if (product == 0) {
|
|
67
|
+
return 0;
|
|
68
|
+
} else {
|
|
69
|
+
// The traditional divUp formula is:
|
|
70
|
+
// divUp(x, y) := (x + y - 1) / y
|
|
71
|
+
// To avoid intermediate overflow in the addition, we distribute the division and get:
|
|
72
|
+
// divUp(x, y) := (x - 1) / y + 1
|
|
73
|
+
// Note that this requires x != 0, which we already tested for.
|
|
74
|
+
|
|
75
|
+
return ((product - 1) / ONE) + 1;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function divDown(uint256 a, uint256 b) internal pure returns (uint256) {
|
|
80
|
+
if (a == 0) {
|
|
81
|
+
return 0;
|
|
82
|
+
} else {
|
|
83
|
+
uint256 aInflated = a * ONE;
|
|
84
|
+
return aInflated / b;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function divDown(int256 a, int256 b) internal pure returns (int256) {
|
|
89
|
+
if (a == 0) {
|
|
90
|
+
return 0;
|
|
91
|
+
} else {
|
|
92
|
+
int256 aInflated = a * Int(ONE);
|
|
93
|
+
return aInflated / b;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function divDown(uint256 a, int256 b) internal pure returns (int256) {
|
|
98
|
+
return divDown(Int(a), b);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function divDown(int256 a, uint256 b) internal pure returns (int256) {
|
|
102
|
+
return divDown(a, Int(b));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function divUp(uint256 a, uint256 b) internal pure returns (uint256) {
|
|
106
|
+
if (a == 0) {
|
|
107
|
+
return 0;
|
|
108
|
+
} else {
|
|
109
|
+
uint256 aInflated = a * ONE;
|
|
110
|
+
// The traditional divUp formula is:
|
|
111
|
+
// divUp(x, y) := (x + y - 1) / y
|
|
112
|
+
// To avoid intermediate overflow in the addition, we distribute the division and get:
|
|
113
|
+
// divUp(x, y) := (x - 1) / y + 1
|
|
114
|
+
// Note that this requires x != 0, which we already tested for.
|
|
115
|
+
|
|
116
|
+
return ((aInflated - 1) / b) + 1;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @dev Returns x^y, assuming both are fixed point numbers, rounding down. The result is guaranteed to not be above
|
|
122
|
+
* the true value (that is, the error function expected - actual is always positive).
|
|
123
|
+
*/
|
|
124
|
+
function powDown(uint256 x, uint256 y) internal pure returns (uint256) {
|
|
125
|
+
uint256 raw = LogExpMath.pow(x, y);
|
|
126
|
+
uint256 maxError = mulUp(raw, MAX_POW_RELATIVE_ERROR) + 1;
|
|
127
|
+
|
|
128
|
+
if (raw < maxError) {
|
|
129
|
+
return 0;
|
|
130
|
+
} else {
|
|
131
|
+
return raw - maxError;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* @dev Returns x^y, assuming both are fixed point numbers, rounding up. The result is guaranteed to not be below
|
|
137
|
+
* the true value (that is, the error function expected - actual is always negative).
|
|
138
|
+
*/
|
|
139
|
+
function powUp(uint256 x, uint256 y) internal pure returns (uint256) {
|
|
140
|
+
uint256 raw = LogExpMath.pow(x, y);
|
|
141
|
+
uint256 maxError = mulUp(raw, MAX_POW_RELATIVE_ERROR) + 1;
|
|
142
|
+
|
|
143
|
+
return raw + maxError;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* @dev Returns the complement of a value (1 - x), capped to 0 if x is larger than 1.
|
|
148
|
+
*
|
|
149
|
+
* Useful when computing the complement for values with some level of relative error, as it strips this error and
|
|
150
|
+
* prevents intermediate negative values.
|
|
151
|
+
*/
|
|
152
|
+
function complement(uint256 x) internal pure returns (uint256) {
|
|
153
|
+
return (x < ONE) ? (ONE - x) : 0;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function abs(int256 x) internal pure returns (uint256) {
|
|
157
|
+
return uint256(x > 0 ? x : -x);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function neg(int256 x) internal pure returns (int256) {
|
|
161
|
+
return -x;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function neg(uint256 x) internal pure returns (int256) {
|
|
165
|
+
return -Int(x);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function max(uint256 x, uint256 y) internal pure returns (uint256) {
|
|
169
|
+
return (x > y ? x : y);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function max(int256 x, int256 y) internal pure returns (int256) {
|
|
173
|
+
return (x > y ? x : y);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function min(uint256 x, uint256 y) internal pure returns (uint256) {
|
|
177
|
+
return (x < y ? x : y);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function min(int256 x, int256 y) internal pure returns (int256) {
|
|
181
|
+
return (x < y ? x : y);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function Uint(int256 x) internal pure returns (uint256) {
|
|
185
|
+
require(x >= 0);
|
|
186
|
+
return uint256(x);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function Int(uint256 x) internal pure returns (int256) {
|
|
190
|
+
require(x <= uint256(type(int256).max));
|
|
191
|
+
return int256(x);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function Int128(int256 x) internal pure returns (int128) {
|
|
195
|
+
require(0 <= x && x <= type(int128).max);
|
|
196
|
+
return int128(x);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function Uint32(uint256 x) internal pure returns (uint32) {
|
|
200
|
+
require(0 <= x && x <= type(uint32).max);
|
|
201
|
+
return uint32(x);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function Uint112(uint256 x) internal pure returns (uint112) {
|
|
205
|
+
require(0 <= x && x <= type(uint112).max);
|
|
206
|
+
return uint112(x);
|
|
207
|
+
}
|
|
208
|
+
}
|