-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
453222d
commit ceefdea
Showing
7 changed files
with
334 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity 0.8.24; | ||
|
||
import '@pendle/contracts/oracles/PendlePYLpOracle.sol'; | ||
import '@pendle/contracts/interfaces/IPAllActionV3.sol'; | ||
import '@pendle/contracts/interfaces/IPMarket.sol'; | ||
import '@interfaces/oracles/IBaseOracle.sol'; | ||
|
||
/** | ||
* @title PendleRelayer | ||
* @notice This contracts transforms a Pendle TWAP price feed into a standard IBaseOracle feed | ||
* | ||
*/ | ||
contract PendleRelayer is IBaseOracle { | ||
using PendlePYOracleLib for IPMarket; | ||
using PendleLpOracleLib for IPMarket; | ||
|
||
IStandardizedYield public SY; | ||
IPPrincipalToken public PT; | ||
IPYieldToken public YT; | ||
|
||
IPMarket public market; | ||
PendlePYLpOracle public oracle; | ||
|
||
uint32 public twapDuration; | ||
|
||
constructor(address _market, address _oracle, uint32 _twapDuration) { | ||
require(_market != address(0) && _oracle != address(0), 'Invalid address'); | ||
require(twapDuration != 0, 'Invalid TWAP duration'); | ||
|
||
market = IPMarket(_market); | ||
oracle = PendlePYLpOracle(_oracle); | ||
twapDuration = _twapDuration; | ||
|
||
(SY, PT, YT) = market.readTokens(); | ||
|
||
// test if oracle is ready | ||
(bool increaseCardinalityRequired,, bool oldestObservationSatisfied) = oracle.getOracleState(_market, _twapDuration); | ||
// It's required to call IPMarket(market).increaseObservationsCardinalityNext(cardinalityRequired) and wait | ||
// for at least the twapDuration, to allow data population. | ||
// also | ||
// It's necessary to wait for at least the twapDuration, to allow data population. | ||
require(!increaseCardinalityRequired && oldestObservationSatisfied, 'Oracle not ready'); | ||
} | ||
|
||
function getResultWithValidity() external view returns (uint256 _resullt, bool _validity) {} | ||
|
||
function read() external view returns (uint256 _value) {} | ||
function symbol() external view returns (string memory _symbol) {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.0; | ||
|
||
import {IStandardizedYield} from '@interfaces/oracles/pendle/IStandardizedYield.sol'; | ||
import {IPPrincipalToken} from '@interfaces/oracles/pendle/IPPrincipalToken.sol'; | ||
import {IPYieldToken} from '@interfaces/oracles/pendle/IPYieldToken.sol'; | ||
|
||
interface IPMarket { | ||
/** | ||
* required functions: | ||
* getPtToSYRate | ||
* readTokens() | ||
*/ | ||
function getPtToSyRate(address market, uint32 duration) external view returns (uint256); | ||
function readTokens() external view returns (IStandardizedYield _SY, IPPrincipalToken _PT, IPYieldToken _YT); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.0; | ||
|
||
interface IPOracle { | ||
/** | ||
* required functions: | ||
*/ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.0; | ||
|
||
import {IERC20Metadata} from '@interfaces/utils/IERC20Metadata.sol'; | ||
|
||
interface IPPrincipalToken is IERC20Metadata { | ||
function burnByYT(address user, uint256 amount) external; | ||
|
||
function mintByYT(address user, uint256 amount) external; | ||
|
||
function initialize(address _YT) external; | ||
|
||
function SY() external view returns (address); | ||
|
||
function YT() external view returns (address); | ||
|
||
function factory() external view returns (address); | ||
|
||
function expiry() external view returns (uint256); | ||
|
||
function isExpired() external view returns (bool); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.0; | ||
|
||
import {IERC20Metadata} from '@interfaces/utils/IERC20Metadata.sol'; | ||
|
||
interface IRewardManager { | ||
function userReward(address token, address user) external view returns (uint128 index, uint128 accrued); | ||
} | ||
|
||
interface IPInterestManagerYT { | ||
event CollectInterestFee(uint256 amountInterestFee); | ||
|
||
function userInterest(address user) external view returns (uint128 lastPYIndex, uint128 accruedInterest); | ||
} | ||
|
||
interface IPYieldToken is IERC20Metadata, IRewardManager, IPInterestManagerYT { | ||
event NewInterestIndex(uint256 indexed newIndex); | ||
|
||
event Mint( | ||
address indexed caller, | ||
address indexed receiverPT, | ||
address indexed receiverYT, | ||
uint256 amountSyToMint, | ||
uint256 amountPYOut | ||
); | ||
|
||
event Burn(address indexed caller, address indexed receiver, uint256 amountPYToRedeem, uint256 amountSyOut); | ||
|
||
event RedeemRewards(address indexed user, uint256[] amountRewardsOut); | ||
|
||
event RedeemInterest(address indexed user, uint256 interestOut); | ||
|
||
event CollectRewardFee(address indexed rewardToken, uint256 amountRewardFee); | ||
|
||
function mintPY(address receiverPT, address receiverYT) external returns (uint256 amountPYOut); | ||
|
||
function redeemPY(address receiver) external returns (uint256 amountSyOut); | ||
|
||
function redeemPYMulti( | ||
address[] calldata receivers, | ||
uint256[] calldata amountPYToRedeems | ||
) external returns (uint256[] memory amountSyOuts); | ||
|
||
function redeemDueInterestAndRewards( | ||
address user, | ||
bool redeemInterest, | ||
bool redeemRewards | ||
) external returns (uint256 interestOut, uint256[] memory rewardsOut); | ||
|
||
function rewardIndexesCurrent() external returns (uint256[] memory); | ||
|
||
function pyIndexCurrent() external returns (uint256); | ||
|
||
function pyIndexStored() external view returns (uint256); | ||
|
||
function getRewardTokens() external view returns (address[] memory); | ||
|
||
function SY() external view returns (address); | ||
|
||
function PT() external view returns (address); | ||
|
||
function factory() external view returns (address); | ||
|
||
function expiry() external view returns (uint256); | ||
|
||
function isExpired() external view returns (bool); | ||
|
||
function doCacheIndexSameBlock() external view returns (bool); | ||
|
||
function pyIndexLastUpdatedBlock() external view returns (uint128); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
pragma solidity ^0.8.0; | ||
|
||
import {IERC20Metadata} from '@interfaces/utils/IERC20Metadata.sol'; | ||
|
||
interface IStandardizedYield is IERC20Metadata { | ||
/// @dev Emitted when any base tokens is deposited to mint shares | ||
event Deposit( | ||
address indexed caller, | ||
address indexed receiver, | ||
address indexed tokenIn, | ||
uint256 amountDeposited, | ||
uint256 amountSyOut | ||
); | ||
|
||
/// @dev Emitted when any shares are redeemed for base tokens | ||
event Redeem( | ||
address indexed caller, | ||
address indexed receiver, | ||
address indexed tokenOut, | ||
uint256 amountSyToRedeem, | ||
uint256 amountTokenOut | ||
); | ||
|
||
/// @dev check `assetInfo()` for more information | ||
enum AssetType { | ||
TOKEN, | ||
LIQUIDITY | ||
} | ||
|
||
/// @dev Emitted when (`user`) claims their rewards | ||
event ClaimRewards(address indexed user, address[] rewardTokens, uint256[] rewardAmounts); | ||
|
||
/** | ||
* @notice mints an amount of shares by depositing a base token. | ||
* @param receiver shares recipient address | ||
* @param tokenIn address of the base tokens to mint shares | ||
* @param amountTokenToDeposit amount of base tokens to be transferred from (`msg.sender`) | ||
* @param minSharesOut reverts if amount of shares minted is lower than this | ||
* @return amountSharesOut amount of shares minted | ||
* @dev Emits a {Deposit} event | ||
* | ||
* Requirements: | ||
* - (`tokenIn`) must be a valid base token. | ||
*/ | ||
function deposit( | ||
address receiver, | ||
address tokenIn, | ||
uint256 amountTokenToDeposit, | ||
uint256 minSharesOut | ||
) external payable returns (uint256 amountSharesOut); | ||
|
||
/** | ||
* @notice redeems an amount of base tokens by burning some shares | ||
* @param receiver recipient address | ||
* @param amountSharesToRedeem amount of shares to be burned | ||
* @param tokenOut address of the base token to be redeemed | ||
* @param minTokenOut reverts if amount of base token redeemed is lower than this | ||
* @param burnFromInternalBalance if true, burns from balance of `address(this)`, otherwise burns from `msg.sender` | ||
* @return amountTokenOut amount of base tokens redeemed | ||
* @dev Emits a {Redeem} event | ||
* | ||
* Requirements: | ||
* - (`tokenOut`) must be a valid base token. | ||
*/ | ||
function redeem( | ||
address receiver, | ||
uint256 amountSharesToRedeem, | ||
address tokenOut, | ||
uint256 minTokenOut, | ||
bool burnFromInternalBalance | ||
) external returns (uint256 amountTokenOut); | ||
|
||
/** | ||
* @notice exchangeRate * syBalance / 1e18 must return the asset balance of the account | ||
* @notice vice-versa, if a user uses some amount of tokens equivalent to X asset, the amount of sy | ||
* he can mint must be X * exchangeRate / 1e18 | ||
* @dev SYUtils's assetToSy & syToAsset should be used instead of raw multiplication | ||
* & division | ||
*/ | ||
function exchangeRate() external view returns (uint256 res); | ||
|
||
/** | ||
* @notice claims reward for (`user`) | ||
* @param user the user receiving their rewards | ||
* @return rewardAmounts an array of reward amounts in the same order as `getRewardTokens` | ||
* @dev | ||
* Emits a `ClaimRewards` event | ||
* See {getRewardTokens} for list of reward tokens | ||
*/ | ||
function claimRewards(address user) external returns (uint256[] memory rewardAmounts); | ||
|
||
/** | ||
* @notice get the amount of unclaimed rewards for (`user`) | ||
* @param user the user to check for | ||
* @return rewardAmounts an array of reward amounts in the same order as `getRewardTokens` | ||
*/ | ||
function accruedRewards(address user) external view returns (uint256[] memory rewardAmounts); | ||
|
||
function rewardIndexesCurrent() external returns (uint256[] memory indexes); | ||
|
||
function rewardIndexesStored() external view returns (uint256[] memory indexes); | ||
|
||
/** | ||
* @notice returns the list of reward token addresses | ||
*/ | ||
function getRewardTokens() external view returns (address[] memory); | ||
|
||
/** | ||
* @notice returns the address of the underlying yield token | ||
*/ | ||
function yieldToken() external view returns (address); | ||
|
||
/** | ||
* @notice returns all tokens that can mint this SY | ||
*/ | ||
function getTokensIn() external view returns (address[] memory res); | ||
|
||
/** | ||
* @notice returns all tokens that can be redeemed by this SY | ||
*/ | ||
function getTokensOut() external view returns (address[] memory res); | ||
|
||
function isValidTokenIn(address token) external view returns (bool); | ||
|
||
function isValidTokenOut(address token) external view returns (bool); | ||
|
||
function previewDeposit( | ||
address tokenIn, | ||
uint256 amountTokenToDeposit | ||
) external view returns (uint256 amountSharesOut); | ||
|
||
function previewRedeem(address tokenOut, uint256 amountSharesToRedeem) external view returns (uint256 amountTokenOut); | ||
|
||
/** | ||
* @notice This function contains information to interpret what the asset is | ||
* @return assetType the type of the asset (0 for ERC20 tokens, 1 for AMM liquidity tokens, | ||
* 2 for bridged yield bearing tokens like wstETH, rETH on Arbi whose the underlying asset doesn't exist on the chain) | ||
* @return assetAddress the address of the asset | ||
* @return assetDecimals the decimals of the asset | ||
*/ | ||
function assetInfo() external view returns (AssetType assetType, address assetAddress, uint8 assetDecimals); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.20; | ||
|
||
import {IERC20} from '@openzepplin/token/ERC20/IERC20.sol'; | ||
|
||
/** | ||
* @dev Interface for the optional metadata functions from the ERC-20 standard. | ||
*/ | ||
interface IERC20Metadata is IERC20 { | ||
/** | ||
* @dev Returns the name of the token. | ||
*/ | ||
function name() external view returns (string memory); | ||
|
||
/** | ||
* @dev Returns the symbol of the token. | ||
*/ | ||
function symbol() external view returns (string memory); | ||
|
||
/** | ||
* @dev Returns the decimals places of the token. | ||
*/ | ||
function decimals() external view returns (uint8); | ||
} |