Description:
Multi-signature wallet contract requiring multiple confirmations for transaction execution.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"altitude-v2/contracts/strategies/farming/strategies/pendle/StrategyPendlePT.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
import "./StrategyPendleBase.sol";
import "../../../../libraries/uniswap-v3/TransferHelper.sol";
/**
* @title StrategyPendlePT Contract
* @dev Contract for holding Pendle PT tokens
* @author Altitude Labs
**/
contract StrategyPendlePT is StrategyPendleBase {
constructor(
address farmDispatcherAddress_,
address swapStrategy_,
address router_,
address routerStatic_,
address oracle_,
address market_,
address farmAsset_,
uint256 slippage_,
address rewardsAddress_,
address[] memory rewardAssets_,
address[] memory nonSkimAssets_
)
StrategyPendleBase(
farmDispatcherAddress_,
swapStrategy_,
router_,
routerStatic_,
oracle_,
market_,
farmAsset_,
slippage_,
rewardsAddress_,
rewardAssets_,
nonSkimAssets_
)
{}
/// @notice Acquires Pendle PT tokens
/// @param amount Amount of asset to deposit
function _deposit(uint256 amount) internal override {
if (market.isExpired()) {
revert PFS_MARKET_EXPIRED();
}
amount = _swap(asset, farmAsset, amount);
uint256 twapRate = oracle.getPtToSyRate(address(market), twapDuration);
TransferHelper.safeApprove(farmAsset, address(router), amount);
(uint256 netPtOut, , ) = router.swapExactTokenForPt(
address(this),
address(market),
0,
_emptyApproxParams(),
_createTokenInputStruct(amount),
_emptyLimit()
);
_validateRate((SY.previewDeposit(farmAsset, amount) * 1e18) / twapRate, netPtOut);
}
function _exitExpiredMarket() internal returns (bool) {
if (market.isExpired()) {
// Exit an expired market
uint256 ptBalance = PT.balanceOf(address(this));
if (ptBalance > 0) {
PT.approve(address(router), ptBalance);
router.redeemPyToToken(address(this), address(YT), ptBalance, _emptyTokenOutputStruct());
}
return true;
}
return false;
}
/// @notice Sells Pendle PT tokens
/// @param amountToWithdraw Amount of asset to withdraw
function _withdraw(uint256 amountToWithdraw) internal override {
if (!_exitExpiredMarket()) {
if (farmAsset != asset) {
// If a conversion is happening, we substitute the requested sum with the
// input amount we'd need to provide to get it in a swap
amountToWithdraw = swapStrategy.getAmountIn(farmAsset, asset, amountToWithdraw);
}
uint256 ptBalance = PT.balanceOf(address(this));
// amountToWithdraw is going to be reassigned as amount of PT tokens needed to receive requested amount of farm asset
try
routerStatic.swapPtForExactSyStatic(address(market), SY.previewDeposit(farmAsset, amountToWithdraw))
returns (uint256 netPtIn, uint256, uint256, uint256) {
if (netPtIn > ptBalance) {
// If requested amount is more than we have - withdraw all
amountToWithdraw = ptBalance;
} else {
amountToWithdraw = netPtIn;
}
} catch {
// The call can revert if there's not enough liquidity
amountToWithdraw = ptBalance;
}
uint256 twapRate = oracle.getPtToSyRate(address(market), twapDuration);
PT.approve(address(router), amountToWithdraw);
(uint256 netTokenOut, , ) = router.swapExactPtForToken(
address(this),
address(market),
amountToWithdraw,
_emptyTokenOutputStruct(),
_emptyLimit()
);
_validateRate((amountToWithdraw * twapRate) / 1e18, SY.previewDeposit(farmAsset, netTokenOut));
}
// Swap the farm asset to borrow asset (if required)
_swap(farmAsset, asset, type(uint256).max);
}
/// @notice Withdraw the whole balance without slippage checks
function _emergencyWithdraw() internal override {
if (_exitExpiredMarket()) {
return;
}
uint256 ptAmount = PT.balanceOf(address(this));
if (ptAmount > 0) {
PT.approve(address(router), ptAmount);
router.swapExactPtForToken(
address(this),
address(market),
ptAmount,
_emptyTokenOutputStruct(),
_emptyLimit()
);
}
}
/// @notice Return farm asset amount specific for the farm provider
function _getFarmAssetAmount() internal view virtual override returns (uint256) {
uint256 ptBalance = PT.balanceOf(address(this));
if (ptBalance > 0) {
if (market.isExpired()) {
ptBalance = routerStatic.redeemPyToTokenStatic(address(YT), ptBalance, farmAsset);
} else {
(ptBalance, , , , ) = routerStatic.swapExactPtForTokenStatic(address(market), ptBalance, farmAsset);
}
}
return ptBalance;
}
}
"
},
"altitude-v2/contracts/strategies/farming/strategies/pendle/StrategyPendleBase.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
import "../FarmDropStrategy.sol";
import "../../../SkimStrategy.sol";
import "../../../../libraries/uniswap-v3/TransferHelper.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@pendle/core-v2/contracts/interfaces/IPAllActionV3.sol";
import "@pendle/core-v2/contracts/interfaces/IPMarket.sol";
import "@pendle/core-v2/contracts/interfaces/IPPYLpOracle.sol";
import "@pendle/core-v2/contracts/interfaces/IPRouterStatic.sol";
import "../../../../interfaces/internal/strategy/farming/IPendleFarmStrategy.sol";
/**
* @title StrategyPendleBase Contract
* @dev Contract for interacting with Pendle protocol
* @author Altitude Labs
**/
abstract contract StrategyPendleBase is FarmDropStrategy, SkimStrategy, IPendleFarmStrategy {
IPAllActionV3 public immutable router;
IPRouterStatic public immutable routerStatic;
IPPYLpOracle public immutable oracle;
IPMarket public immutable market;
IStandardizedYield public immutable SY;
IPPrincipalToken public immutable PT;
IPYieldToken public immutable YT;
/// @dev Pendle exchange rates are 18 decimals. We need to mind the underlying decimals.
uint8 internal immutable SY_DECIMALS;
uint256 public constant SLIPPAGE_BASE = 1_000_000;
/// @notice Price slippage tolerance, where 1e6 = 100%
uint256 public slippage;
/// @notice TWAP duration in seconds, used to check `slippage`
uint32 public twapDuration = 1800;
constructor(
address farmDispatcherAddress_,
address swapStrategy_,
address router_,
address routerStatic_,
address oracle_,
address market_,
address farmAsset_,
uint256 slippage_,
address rewardsAddress_,
address[] memory rewardAssets_,
address[] memory nonSkimAssets_
)
FarmDropStrategy(farmAsset_, farmDispatcherAddress_, rewardsAddress_, rewardAssets_, swapStrategy_)
SkimStrategy(nonSkimAssets_)
{
router = IPAllActionV3(router_);
routerStatic = IPRouterStatic(routerStatic_);
oracle = IPPYLpOracle(oracle_);
market = IPMarket(market_);
if (market.isExpired()) {
revert PFS_MARKET_EXPIRED();
}
if (slippage_ > SLIPPAGE_BASE) {
revert PFS_INVALID_SLIPPAGE();
}
(SY, PT, YT) = IPMarket(market).readTokens();
slippage = slippage_;
SY_DECIMALS = SY.decimals();
_validateTwapDuration(twapDuration);
}
/// @notice Set the twap duration
/// @param twapDuration_ New duration in seconds
function setTwapDuration(uint32 twapDuration_) external override onlyOwner {
_validateTwapDuration(twapDuration_);
emit SetTwapDuration(twapDuration, twapDuration_);
twapDuration = twapDuration_;
}
/// @notice Set the acceptable slippage for market operations
/// @param slippage_ New slippage value, where SLIPPAGE_BASE = 1e6 = 100%
function setSlippage(uint256 slippage_) external override onlyOwner {
if (slippage_ > SLIPPAGE_BASE) {
revert PFS_SLIPPAGE(slippage, slippage_);
}
emit SetSlippage(slippage, slippage_);
slippage = slippage_;
}
/// @notice Internal reusable function
function _recogniseRewardsInBase() internal override {
SY.claimRewards(address(this));
YT.redeemDueInterestAndRewards(address(this), true, true);
market.redeemRewards(address(this));
/// @dev YT interest is in SY
uint256 syBalance = SY.balanceOf(address(this));
if (syBalance > 0) {
SY.redeem(address(this), syBalance, farmAsset, 0, false);
}
for (uint256 i; i < rewardAssets.length; ++i) {
_swap(rewardAssets[i], asset, type(uint256).max);
}
// Update drop percentage
super._recogniseRewardsInBase();
}
function _validateTwapDuration(uint32 twapDuration_) internal view {
// Make sure the oracle has enough TWAP data
(bool increaseCardinalityRequired, uint16 cardinalityRequired, bool oldestObservationSatisfied) = oracle
.getOracleState(address(market), twapDuration_);
if (increaseCardinalityRequired) {
// Oracle requires cardinality increase
revert PFS_ORACLE_CARDINALITY(cardinalityRequired);
}
if (!oldestObservationSatisfied) {
// Wait at least TWAP_DURATION seconds to populate observations
revert PFS_ORACLE_UNPOPULATED();
}
}
function _emptyLimit() internal pure returns (LimitOrderData memory) {}
function _emptySwap() internal pure returns (SwapData memory) {}
function _emptyApproxParams() internal pure returns (ApproxParams memory) {
return ApproxParams(0, type(uint256).max, 0, 256, 1e14);
}
function _createTokenInputStruct(uint256 amountIn) internal view returns (TokenInput memory) {
return
TokenInput({
tokenIn: farmAsset,
netTokenIn: amountIn,
tokenMintSy: farmAsset,
pendleSwap: address(0),
swapData: _emptySwap()
});
}
function _emptyTokenOutputStruct() internal view returns (TokenOutput memory) {
return
TokenOutput({
tokenOut: farmAsset,
minTokenOut: 0,
tokenRedeemSy: farmAsset,
pendleSwap: address(0),
swapData: _emptySwap()
});
}
/// @notice Validate the difference for input and output value for market operations is within our tolerance
function _validateRate(uint256 input, uint256 output) internal view {
uint256 delta = (input * slippage) / SLIPPAGE_BASE;
if (slippage > 0 && delta == 0) {
/// @dev If the amount is so small that slippage didn't have an effect due to rounding
delta = 1;
}
if (input - delta > output) {
revert PFS_SLIPPAGE(input, output);
}
}
}
"
},
"altitude-v2/contracts/libraries/uniswap-v3/TransferHelper.sol": {
"content": "// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity 0.8.28;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/**
* @title Transfer Helper Library
* @dev Contains helper methods for interacting with ERC20 tokens that do not consistently return true/false
* @author Uniswap
**/
library TransferHelper {
// Tranfer helper library Errors
error TH_SAFE_TRANSFER_FAILED();
error TH_SAFE_TRANSFER_FROM_FAILED();
error TH_SAFE_TRANSFER_NATIVE_FAILED();
error TH_SAFE_APPROVE();
error TH_SAFE_APPROVE_RESET();
function safeTransfer(address token, address to, uint256 value) internal {
bool toThrow = _call(token, abi.encodeWithSelector(IERC20.transfer.selector, to, value));
if (toThrow) {
revert TH_SAFE_TRANSFER_FAILED();
}
}
function safeTransferFrom(address token, address from, address to, uint256 value) internal {
bool toThrow = _call(token, abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));
if (toThrow) {
revert TH_SAFE_TRANSFER_FROM_FAILED();
}
}
/// @notice Approves the stipulated contract to spend the given allowance in the given token
/// @dev Errors with 'SA' if transfer fails
/// @param token The contract address of the token to be approved
/// @param to The target of the approval
/// @param value The amount of the given token the target will be allowed to spend
function safeApprove(address token, address to, uint256 value) internal {
// Reset approval first
bool toThrow = _call(token, abi.encodeWithSelector(IERC20.approve.selector, to, 0));
if (toThrow) {
revert TH_SAFE_APPROVE_RESET();
}
toThrow = _call(token, abi.encodeWithSelector(IERC20.approve.selector, to, value));
if (toThrow) {
revert TH_SAFE_APPROVE();
}
}
function _call(address token, bytes memory data) internal returns (bool) {
(bool success, bytes memory resultData) = token.call(data);
if (!success || (resultData.length > 0 && !abi.decode(resultData, (bool)))) {
return true;
}
return false;
}
function safeTransferNative(address to, uint256 value) internal {
(bool success, ) = to.call{value: value}(new bytes(0));
if (!success) {
revert TH_SAFE_TRANSFER_NATIVE_FAILED();
}
}
}
"
},
"altitude-v2/contracts/strategies/farming/strategies/FarmDropStrategy.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "./FarmStrategy.sol";
import "../../../interfaces/internal/strategy/farming/IFarmDropStrategy.sol";
/**
* @title FarmDropStrategy Contract
* @dev Provides tools to monitor drops in the farm balance value
* @author Altitude Labs
**/
abstract contract FarmDropStrategy is Ownable, FarmStrategy, IFarmDropStrategy {
uint256 public override expectedBalance;
uint256 public override dropPercentage;
uint256 public constant override DROP_UNITS = 1e18;
/// @notice Default drop threshold to revert deposit/withdraw calls is 5%
uint256 public override dropThreshold = (DROP_UNITS * 5) / 100;
constructor(
address farmAssetAddress,
address farmDispatcherAddress,
address rewardsAddress,
address[] memory rewardAssets_,
address swapStrategyAddress
) FarmStrategy(farmAssetAddress, farmDispatcherAddress, rewardsAddress, rewardAssets_, swapStrategyAddress) {}
/// @notice Set the threshold for reverting deposit/withdraw
/// @param dropThreshold_ The new threshold in percentage (of DROP_UNITS, 1e18)
function setDropThreshold(uint256 dropThreshold_) external onlyOwner {
if (dropThreshold_ > DROP_UNITS) {
revert FDS_OUT_OF_BOUNDS();
}
dropThreshold = dropThreshold_;
}
/// @notice Deal with a farm drop during deposit
/// If a farm drop is detected, the deposit will be reverted
/// @param amount The amount to deposit
function deposit(uint256 amount) public override(FarmStrategy, IFarmStrategy) {
uint256 currentBalance = balance();
_updateDropPercentage(currentBalance, 0);
if (dropPercentage > dropThreshold) {
revert FDS_DROP_EXCEEDED(dropPercentage, dropThreshold);
}
// deposit and check for any deposit fees
expectedBalance = currentBalance;
super.deposit(amount);
currentBalance = balance();
_updateDropPercentage(currentBalance, amount);
expectedBalance = currentBalance;
}
/// @notice Track and handle any possible farm drop on withdraw
/// If a farm drop is detected, the withdraw will be reverted
/// @param amountRequested The amount to withdraw
function withdraw(
uint256 amountRequested
) public override(FarmStrategy, IFarmStrategy) returns (uint256 amountWithdrawn) {
_updateDropPercentage(balance(), 0);
if (dropPercentage > dropThreshold) {
revert FDS_DROP_EXCEEDED(dropPercentage, dropThreshold);
}
amountWithdrawn = super.withdraw(amountRequested);
expectedBalance = balance();
}
/// @notice Update the drop percentage on emergencyWithdraw
function emergencyWithdraw() public override(FarmStrategy, IFarmStrategy) {
_updateDropPercentage(balance(), 0);
super.emergencyWithdraw();
expectedBalance = balance();
}
/// @notice Update the drop percentage on emergencySwap
/// @param assets The assets to swap
function emergencySwap(
address[] calldata assets
) public override(FarmStrategy, IFarmStrategy) returns (uint256 amountWithdrawn) {
_updateDropPercentage(balance(), 0);
amountWithdrawn = super.emergencySwap(assets);
expectedBalance = balance();
}
/// @notice Account for increase/decrease in the farm drop percentage
/// @param amount Expected balance increase
function _updateDropPercentage(uint256 currentBalance, uint256 amount) internal {
dropPercentage = _calculateDropPercentage(currentBalance, expectedBalance + amount, dropPercentage);
}
/// @notice Calculates the current drop in farm value as percentage
/// @return percentage The total drop in farm value as a percentage
function currentDropPercentage() public view override returns (uint256) {
return _calculateDropPercentage(balance(), expectedBalance, dropPercentage);
}
/// @notice Decrease drop percentage with the rewards that are used to restore it
function _recogniseRewardsInBase() internal virtual override {
/// @dev It is assumed the balance to be bigger than the expected one
// as the rewards have been recognised from the inherited contract
// The drop percentage is to be decreased with the new rewards
_updateDropPercentage(balance(), 0);
}
/// @notice Track and handle any possible farm drop on recogniseRewardsInBase
/// @return rewards The amount of rewards recognised
function recogniseRewardsInBase() public virtual override(FarmStrategy, IFarmStrategy) returns (uint256 rewards) {
rewards = super.recogniseRewardsInBase();
expectedBalance = balance();
}
/// @notice Calculates the drop in farm value as percentage
/// @param currentBalance_ The current amount in farming
/// @param expectedBalance_ The expected amount in farming
/// @param accumulatedDrop_ The drop percentage accumulated so far
/// @return amount The total drop in farm value as a percentage
function _calculateDropPercentage(
uint256 currentBalance_,
uint256 expectedBalance_,
uint256 accumulatedDrop_
) private pure returns (uint256) {
if (expectedBalance_ == 0) {
// If we expect the farm to be empty there can be no drop
return 0;
}
if (currentBalance_ > expectedBalance_) {
// Gained value
uint256 percentage = ((currentBalance_ - expectedBalance_) * DROP_UNITS) / expectedBalance_;
uint256 percentageAdjustment = (accumulatedDrop_ + ((accumulatedDrop_ * percentage) / DROP_UNITS));
if (percentageAdjustment > percentage) {
accumulatedDrop_ = percentageAdjustment - percentage;
} else {
// Farm is at net gain, new peak from where we will start tracking losses
accumulatedDrop_ = 0;
}
} else {
if (currentBalance_ == 0) {
// Lost everything shortcut
accumulatedDrop_ = DROP_UNITS;
} else {
// Lost some
uint256 percentage = ((expectedBalance_ - currentBalance_) * DROP_UNITS) / expectedBalance_;
accumulatedDrop_ = (accumulatedDrop_ - ((accumulatedDrop_ * percentage) / DROP_UNITS)) + percentage;
}
}
return accumulatedDrop_;
}
/// @notice Reset drop percentage
function reset() external override onlyOwner {
dropPercentage = 0;
expectedBalance = balance();
emit ResetDropPercentage();
}
}
"
},
"altitude-v2/contracts/strategies/SkimStrategy.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../libraries/uniswap-v3/TransferHelper.sol";
import "../interfaces/internal/strategy/ISkimStrategy.sol";
/**
* @title SkimStrategy
* @dev Contract for skiming assets
* @author Altitude Labs
**/
contract SkimStrategy is Ownable, ISkimStrategy {
/** @notice Assets that are not allowed for skim */
mapping(address => bool) public nonSkimAssets;
/// @param assets Assets that are not allowed for skim
constructor(address[] memory assets) {
uint256 assetsLength = assets.length;
for (uint256 i; i < assetsLength; ) {
nonSkimAssets[assets[i]] = true;
unchecked {
++i;
}
}
}
/** @notice Transfer tokens out of the strategy
* @dev Used to even out distributions when rewards accrue in batches
* @param assets Token addresses
* @param receiver Receiving account
*/
function skim(address[] calldata assets, address receiver) public override onlyOwner {
if (receiver == address(0)) {
revert SK_INVALID_RECEIVER();
}
uint256 assetsLength = assets.length;
for (uint256 i; i < assetsLength; ) {
if (nonSkimAssets[assets[i]]) {
revert SK_NON_SKIM_ASSET();
}
TransferHelper.safeTransfer(assets[i], receiver, IERC20(assets[i]).balanceOf(address(this)));
unchecked {
++i;
}
}
}
}
"
},
"altitude-v2/node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
"
},
"altitude-v2/node_modules/@pendle/core-v2/contracts/interfaces/IPAllActionV3.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;
import "./IPActionAddRemoveLiqV3.sol";
import "./IPActionSwapPTV3.sol";
import "./IPActionSwapYTV3.sol";
import "./IPActionMiscV3.sol";
import "./IPActionCallbackV3.sol";
import "./IPActionStorageV4.sol";
import "./IPActionSimple.sol";
interface IPAllActionV3 is
IPActionAddRemoveLiqV3,
IPActionSwapPTV3,
IPActionSwapYTV3,
IPActionMiscV3,
IPActionCallbackV3,
IPActionStorageV4,
IPActionSimple
{}
"
},
"altitude-v2/node_modules/@pendle/core-v2/contracts/interfaces/IPMarket.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "./IPPrincipalToken.sol";
import "./IPYieldToken.sol";
import "./IStandardizedYield.sol";
import "./IPGauge.sol";
import "../core/Market/MarketMathCore.sol";
interface IPMarket is IERC20Metadata, IPGauge {
event Mint(address indexed receiver, uint256 netLpMinted, uint256 netSyUsed, uint256 netPtUsed);
event Burn(
address indexed receiverSy,
address indexed receiverPt,
uint256 netLpBurned,
uint256 netSyOut,
uint256 netPtOut
);
event Swap(
address indexed caller,
address indexed receiver,
int256 netPtOut,
int256 netSyOut,
uint256 netSyFee,
uint256 netSyToReserve
);
event UpdateImpliedRate(uint256 indexed timestamp, uint256 lnLastImpliedRate);
event IncreaseObservationCardinalityNext(
uint16 observationCardinalityNextOld,
uint16 observationCardinalityNextNew
);
function mint(
address receiver,
uint256 netSyDesired,
uint256 netPtDesired
) external returns (uint256 netLpOut, uint256 netSyUsed, uint256 netPtUsed);
function burn(
address receiverSy,
address receiverPt,
uint256 netLpToBurn
) external returns (uint256 netSyOut, uint256 netPtOut);
function swapExactPtForSy(
address receiver,
uint256 exactPtIn,
bytes calldata data
) external returns (uint256 netSyOut, uint256 netSyFee);
function swapSyForExactPt(
address receiver,
uint256 exactPtOut,
bytes calldata data
) external returns (uint256 netSyIn, uint256 netSyFee);
function redeemRewards(address user) external returns (uint256[] memory);
function readState(address router) external view returns (MarketState memory market);
function observe(uint32[] memory secondsAgos) external view returns (uint216[] memory lnImpliedRateCumulative);
function increaseObservationsCardinalityNext(uint16 cardinalityNext) external;
function readTokens() external view returns (IStandardizedYield _SY, IPPrincipalToken _PT, IPYieldToken _YT);
function getRewardTokens() external view returns (address[] memory);
function isExpired() external view returns (bool);
function expiry() external view returns (uint256);
function observations(
uint256 index
) external view returns (uint32 blockTimestamp, uint216 lnImpliedRateCumulative, bool initialized);
function _storage()
external
view
returns (
int128 totalPt,
int128 totalSy,
uint96 lastLnImpliedRate,
uint16 observationIndex,
uint16 observationCardinality,
uint16 observationCardinalityNext
);
}
"
},
"altitude-v2/node_modules/@pendle/core-v2/contracts/interfaces/IPPYLpOracle.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;
interface IPPYLpOracle {
event SetBlockCycleNumerator(uint16 newBlockCycleNumerator);
function getPtToAssetRate(address market, uint32 duration) external view returns (uint256);
function getYtToAssetRate(address market, uint32 duration) external view returns (uint256);
function getLpToAssetRate(address market, uint32 duration) external view returns (uint256);
function getPtToSyRate(address market, uint32 duration) external view returns (uint256);
function getYtToSyRate(address market, uint32 duration) external view returns (uint256);
function getLpToSyRate(address market, uint32 duration) external view returns (uint256);
function getOracleState(
address market,
uint32 duration
)
external
view
returns (bool increaseCardinalityRequired, uint16 cardinalityRequired, bool oldestObservationSatisfied);
}
"
},
"altitude-v2/node_modules/@pendle/core-v2/contracts/interfaces/IPRouterStatic.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;
import "./IPActionMarketAuxStatic.sol";
import "./IPActionMintRedeemStatic.sol";
import "./IPActionInfoStatic.sol";
import "./IPActionMarketCoreStatic.sol";
import "./IPActionVePendleStatic.sol";
import "./IPMiniDiamond.sol";
import "./IPActionStorageStatic.sol";
//solhint-disable-next-line no-empty-blocks
interface IPRouterStatic is
IPActionMintRedeemStatic,
IPActionInfoStatic,
IPActionMarketAuxStatic,
IPActionMarketCoreStatic,
IPActionVePendleStatic,
IPMiniDiamond,
IPActionStorageStatic
{}
"
},
"altitude-v2/contracts/interfaces/internal/strategy/farming/IPendleFarmStrategy.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;
import "./IFarmStrategy.sol";
import "@pendle/core-v2/contracts/interfaces/IPAllActionV3.sol";
import "@pendle/core-v2/contracts/interfaces/IPMarket.sol";
import "@pendle/core-v2/contracts/interfaces/IPPYLpOracle.sol";
import "@pendle/core-v2/contracts/interfaces/IPRouterStatic.sol";
/**
* @author Altitude Protocol
**/
interface IPendleFarmStrategy is IFarmStrategy {
function router() external view returns (IPAllActionV3);
function routerStatic() external view returns (IPRouterStatic);
function oracle() external view returns (IPPYLpOracle);
function market() external view returns (IPMarket);
function SY() external view returns (IStandardizedYield);
function PT() external view returns (IPPrincipalToken);
function YT() external view returns (IPYieldToken);
function SLIPPAGE_BASE() external view returns (uint256);
function slippage() external view returns (uint256);
function twapDuration() external view returns (uint32);
event SetTwapDuration(uint32 oldDuration, uint32 newDuration);
event SetSlippage(uint256 oldSlippage, uint256 newSlippage);
error PFS_ORACLE_CARDINALITY(uint16 cardinalityRequired);
error PFS_ORACLE_UNPOPULATED();
error PFS_SLIPPAGE(uint256 twapRate, uint256 currentRate);
error PFS_MARKET_EXPIRED();
error PFS_INVALID_SLIPPAGE();
function setTwapDuration(uint32 twapDuration_) external;
function setSlippage(uint256 slippage_) external;
}
"
},
"altitude-v2/node_modules/@openzeppelin/contracts/access/Ownable.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
"
},
"altitude-v2/contracts/strategies/farming/strategies/FarmStrategy.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../../swap/SwapStrategyConfiguration.sol";
import "../../../libraries/uniswap-v3/TransferHelper.sol";
import "../../../interfaces/internal/access/IIngress.sol";
import "../../../interfaces/internal/vault/IVaultCore.sol";
import "../../../interfaces/internal/strategy/farming/IFarmStrategy.sol";
import "../../../interfaces/internal/strategy/farming/IFarmDispatcher.sol";
/**
* @title FarmStrategy Contract
* @author Altitude Labs
**/
abstract contract FarmStrategy is Ownable, SwapStrategyConfiguration, IFarmStrategy {
address public override asset; // baseAsset of farmDispatcher
address public override farmAsset; // asset of the farm
address public override farmDispatcher; // farmDispatcher address
address[] public override rewardAssets; // reward tokens to recognise
address public override rewardsRecipient; // where to send rewards
modifier onlyDispatcher() {
if (msg.sender != farmDispatcher) {
revert FS_ONLY_DISPATCHER();
}
_;
}
/// @param farmAssetAddress The address of the token we are farming with
/// @param farmDispatcherAddress The manager of the strategy
/// @param rewardsAddress Where to send any reward tokens
/// @param rewardAssets_ Reward tokens to recognise
/// @param swapStrategyAddress Swap strategy needed in case farmAsset != baseAsset
constructor(
address farmAssetAddress,
address farmDispatcherAddress,
address rewardsAddress,
address[] memory rewardAssets_,
address swapStrategyAddress
) SwapStrategyConfiguration(swapStrategyAddress) {
farmAsset = farmAssetAddress;
farmDispatcher = farmDispatcherAddress;
rewardsRecipient = rewardsAddress;
rewardAssets = rewardAssets_;
asset = IFarmDispatcher(farmDispatcher).asset();
}
/// @notice Sets the reward tokens to be recognised
/// @param rewardAssets_ Token addresses
function setRewardAssets(address[] memory rewardAssets_) external onlyOwner {
emit SetRewardAssets(rewardAssets, rewardAssets_);
rewardAssets = rewardAssets_;
}
/// @notice Deposits own funds into the Farm Provider
/// @param amount amount to deposit
function deposit(uint256 amount) public virtual override onlyDispatcher {
if (amount > 0) {
// Transfer funds from dispatcher
TransferHelper.safeTransferFrom(asset, msg.sender, address(this), amount);
_deposit(IERC20(asset).balanceOf(address(this)));
emit Deposit(amount);
}
}
/// @notice Withdraws from the Farm Provider
/// @param amountRequested The amount to withdraw
/// @return amountWithdrawn The amount actually withdrawn
function withdraw(
uint256 amountRequested
) public virtual override onlyDispatcher returns (uint256 amountWithdrawn) {
if (amountRequested > 0) {
// When trying to withdraw all
if (amountRequested == type(uint256).max) {
// balanceAvailable() skips the swap slippage check, as that will happen in the actual withdraw
amountRequested = balanceAvailable();
}
_withdraw(amountRequested);
amountWithdrawn = IERC20(asset).balanceOf(address(this));
if (amountWithdrawn > 0) {
TransferHelper.safeTransfer(asset, msg.sender, amountWithdrawn);
}
emit Withdraw(amountWithdrawn);
}
}
/// @notice Withdraw everything from the farm with minimal constraints
/// @dev Should be invoked via protected rpc
/// @dev We may want to perform intermediate actions, so this is step one of a two step process
/// @dev Step two is emergencySwap()
function emergencyWithdraw() public virtual onlyOwner {
_emergencyWithdraw();
emit EmergencyWithdraw();
}
/// @notice Swap specified tokens to asset
/// @param assets The assets to swap
/// @return amountWithdrawn The amount withdrawn after swap
function emergencySwap(
address[] calldata assets
) public virtual override onlyOwner returns (uint256 amountWithdrawn) {
_emergencySwap(assets);
amountWithdrawn = IERC20(asset).balanceOf(address(this));
TransferHelper.safeTransfer(asset, farmDispatcher, amountWithdrawn);
emit EmergencySwap();
}
/// @notice Claim and swap reward tokens to base asset. Then transfer to the dispatcher for compounding
/// @return rewards An amount of rewards being recognised
function recogniseRewardsInBase() public virtual override returns (uint256 rewards) {
_recogniseRewardsInBase();
rewards = IERC20(asset).balanceOf(address(this));
TransferHelper.safeTransfer(asset, rewardsRecipient, rewards);
emit RewardsRecognition(rewards);
}
/// @notice Return the balance in borrow asset excluding rewards (includes slippage validations)
/// @dev Reverts if slippage is too high
/// @return balance that can be withdrawn from the farm
function balance() public view virtual returns (uint256) {
// Get amount of tokens
uint256 farmAssetAmount = _getFarmAssetAmount();
(uint256 totalBalance, uint256 swapAmount) = _balance(farmAssetAmount);
if (swapAmount > 0) {
// Validate slippage
uint256 minimumAssetAmount = swapStrategy.getMinimumAmountOut(farmAsset, asset, farmAssetAmount);
if (swapAmount < minimumAssetAmount) {
// Amount is no good since slippage is too high.
// @dev harvest() earnings calculation relies on .balance() so it is important to revert on a bad value
revert SSC_SWAP_AMOUNT(minimumAssetAmount, swapAmount);
}
}
return totalBalance;
}
/// @notice Return the balance in borrow asset excluding rewards (no slippage validations)
/// @dev Function will not revert on high slippage, should used with care in transactions
/// @return availableBalance Balance that can be withdrawn from the farm
function balanceAvailable() public view virtual returns (uint256 availableBalance) {
// No slippage validations
(availableBalance, ) = _balance(_getFarmAssetAmount());
}
/// @notice Return the max amount that can be withdrawn at the moment
/// @param farmAssetAmount The amount from the farm provider
/// @return totalBalance The amount available to be withdrawn (including amount swapped)
/// @return swapAmount Amount of totalBalance that is subject to swapping
function _balance(
uint256 farmAssetAmount
) internal view virtual returns (uint256 totalBalance, uint256 swapAmount) {
totalBalance = IERC20(asset).balanceOf(address(this));
if (farmAssetAmount > 0) {
if (farmAsset == asset) {
totalBalance += farmAssetAmount;
} else {
// amount of borrow asset we'd get if we swap
swapAmount = swapStrategy.getAmountOut(farmAsset, asset, farmAssetAmount);
totalBalance += swapAmount;
}
}
}
function _getFarmAssetAmount() internal view virtual returns (uint256);
function _deposit(uint256 amount) internal virtual;
function _withdraw(uint256 amount) internal virtual;
function _emergencyWithdraw() internal virtual;
function _recogniseRewardsInBase() internal virtual;
/// @notice Swap assets to borrow asset
/// @param assets Array of assets to swap
function _emergencySwap(address[] calldata assets) internal virtual {
for (uint256 i; i < assets.length; ++i) {
_swap(assets[i], asset, type(uint256).max);
}
}
/// @notice Swap between different assets
/// @param inputAsset Input asset address
/// @param outputAsset Output asset address
/// @param amount Amount to swap
function _swap(address inputAsset, address outputAsset, uint256 amount) internal virtual returns (uint256) {
if (inputAsset != outputAsset) {
if (amount == type(uint256).max) {
amount = IERC20(inputAsset).balanceOf(address(this));
}
if (amount > 0) {
TransferHelper.safeApprove(inputAsset, address(swapStrategy), amount);
amount = swapStrategy.swapInBase(inputAsset, outputAsset, amount);
}
}
return amount;
}
}
"
},
"altitude-v2/contracts/interfaces/internal/strategy/farming/IFarmDropStrategy.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;
import "./IFarmStrategy.sol";
/**
* @author Altitude Protocol
**/
interface IFarmDropStrategy is IFarmStrategy {
event ResetDropPercentage();
error FDS_DROP_EXCEEDED(uint256 current, uint256 threshold);
error FDS_OUT_OF_BOUNDS();
function dropThreshold() external view returns (uint256);
function dropPercentage() external view returns (uint256);
function expectedBalance() external view returns (uint256);
function currentDropPercentage() external view returns (uint256);
function DROP_UNITS() external view returns (uint256);
function setDropThreshold(uint256 dropThreshold_) external;
function reset() external;
}
"
},
"altitude-v2/contracts/interfaces/internal/strategy/ISkimStrategy.sol": {
"content": "// SPDX-License-Identifier: AGPL-3.0.
pragma solidity 0.8.28;
/**
* @author Altitude Protocol
**/
interface ISkimStrategy {
/** @notice Emitted when an asset is not allowed for skim */
error SK_NON_SKIM_ASSET();
/** @notice Emitted when the receiver address is invalid */
error SK_INVALID_RECEIVER();
function nonSkimAssets(address asset) external view returns (bool);
function skim(address[] calldata assets, address receiver) external;
}
"
},
"altitude-v2/node_modules/@pendle/core-v2/contracts/interfaces/IPActionAddRemoveLiqV3.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;
import "../router/math/MarketApproxLib.sol";
import "./IPAllActionTypeV3.sol";
import {IPAllEventsV3} from "./IPAllEventsV3.sol";
/// Refer to IPAllActionTypeV3.sol for details on the parameters
interface IPActionAddRemoveLiqV3 is IPAllEventsV3 {
function addLiquidityDualTokenAndPt(
address receiver,
address market,
TokenInput calldata input,
uint256 netPtDesired,
uint256 minLpOut
) external payable returns (uint256 netLpOut, uint256 netPtUsed, uint256 netSyInterm);
function addLiquidityDualSyAndPt(
address receiver,
address market,
uint256 netSyDesired,
uint256 netPtDesired,
uint256 minLpOut
) external returns (uint256 netLpOut, uint256 netSyUsed, uint256 netPtUsed);
function addLiquiditySinglePt(
address receiver,
address market,
uint256 netPtIn,
uint256 minLpOut,
ApproxParams calldata guessPtSwapToSy,
LimitOrderData calldata limit
) external returns (uint256 netLpOut, uint256 netSyFee);
function addLiquiditySingleToken(
address receiver,
address market,
uint256 minLpOut,
ApproxParams calldata guessPtReceivedFromSy,
TokenInput calldata input,
LimitOrderData calldata limit
) external payable returns (uint256 netLpOut, uint256 netSyFee, uint256 netSyInterm);
function addLiquiditySingleSy(
address receiver,
address market,
uint256 netSyIn,
uint256 minLpOut,
ApproxParams calldata guessPtReceivedFromSy,
LimitOrderData calldata limit
) external returns (uint256 netLpOut, uint256 netSyFee);
function addLiquiditySingleTokenKeepYt(
address receiver,
address market,
uint256 minLpOut,
uint256 minYtOut,
TokenInput calldata input
) external payable returns (uint256 netLpOut, uint256 netYtOut, uint256 netSyMintPy, uint256 netSyInterm);
function addLiquiditySingleSyKeepYt(
address receiver,
address market,
uint256 netSyIn,
uint256 minLpOut,
uint256 minYtOut
) external returns (uint256 netLpOut, uint256 netYtOut, uint256 netSyMintPy);
function removeLiquidityDualTokenAndPt(
address receiver,
address market,
uint256 netLpToRemove,
TokenOutput calldata output,
uint256 minPtOut
) external returns (uint256 netTokenOut, uint256 netPtOut, uint256 netSyInterm);
function removeLiquidityDualSyAndPt(
address receiver,
address market,
uint256 netLpToRemove,
uint256 minSyOut,
uint256 minPtOut
) external returns (uint256 netSyOut, uint256 netPtOut);
function removeLiquiditySinglePt(
address receiver,
address market,
uint256 netLpToRemove,
uint256 minPtOut,
ApproxParams calldata guessPtReceivedFromSy,
LimitOrderData calldata limit
) external returns (uint256 netPtOut, uint256 netSyFee);
function removeLiquiditySingleToken(
address receiver,
address market,
uint256 netLpToRemove,
TokenOutput calldata output,
LimitOrderData calldata limit
) external returns (uint256 netTokenOut, uint256 netSyFee, uint256 netSyInterm);
function removeLiquiditySingleSy(
address receiver,
address market,
uint256 netLpToRemove,
uint256 minSyOut,
LimitOrderData calldata limit
) external returns (uint256 netSyOut, uint256 netSyFee);
}
"
},
"altitude-v2/node_modules/@pendle/core-v2/contracts/interfaces/IPActionSwapPTV3.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;
import "../router/math/MarketApproxLib.sol";
import "./IPAllActionTypeV3.sol";
import {IPAllEventsV3} from "./IPAllEventsV3.sol";
/// Refer to IPAllActionTypeV3.sol for details on the parameters
interface IPActionSwapPTV3 is IPAllEventsV3 {
function swapExactTokenForPt(
address receiver,
address market,
uint256 minPtOut,
ApproxParams calldata guessPtOut,
TokenInput calldata input,
LimitOrderData calldata limit
) external payable returns (uint256 netPtOut, uint256 netSyFee, uint256 netSyInterm);
function swapExactSyForPt(
address receiver,
address market,
uint256 exactSyIn,
uint256 minPtOut,
ApproxParams calldata guessPtOut,
LimitOrderData calldata limit
) external returns (uint256 netPtOut, uint256 netSyFee);
function swapExactPtForToken(
address receiver,
address market,
uint256 exactPtIn,
TokenOutput calldata output,
LimitOrderData calldata limit
) external returns (uint256 netTokenOut, uint256 netSyFee, uint256 netSyInterm);
function swapExactPtForSy(
address receiver,
address market,
uint256 exactPtIn,
uint256 minSyOut,
LimitOrderData calldata limit
) external returns (uint256 netSyOut, uint256 netSyFee);
}
"
},
"altitude-v2/node_modules/@pendle/core-v2/contracts/interfaces/IPActionSwapYTV3.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;
import "../router/math/MarketApproxLib.sol";
import "./IPAllActionTypeV3.sol";
import {IPAllEventsV3} from "./IPAllEventsV3.sol";
/// Refer to IPAllActionTypeV3.sol for details on the parameters
interface IPActionSwapYTV3 is IPAllEventsV3 {
function swapExactTokenForYt(
address receiver,
address market,
uint256 minYtOut,
ApproxParams calldata guessYtOut,
TokenInput calldata input,
LimitOrderData calldata limit
) external payable returns (uint256 netYtOut, uint256 netSyFee, uint256 netSyInterm);
function swapExactSyForYt(
address receiver,
address market,
uint256 exactSyIn,
uint256 minYtOut,
ApproxParams calldata guessYtOut,
LimitOrderData calldata limit
) external returns (uint256 netYtOut, uint256 netSyFee);
function swapExactYtForToken(
address receiver,
address market,
uint256 exactYtIn,
TokenOutput calldata output,
LimitOrderData calldata limit
) external returns (uint256 netTokenOut, uint256 netSyFee, uint256 netSyInterm);
function swapExactYtForSy(
address receiver,
address market,
uint256 exactYtIn,
uint256 minSyOut,
LimitOrderData calldata limit
) external returns (uint256 netSyOut, uint256 netSyFee);
function swapExactPtForYt(
address receiver,
address market,
uint256 exactPtIn,
uint256 minYtOut,
ApproxParams calldata guessTotalPtToSwap
) external returns (uint256 netYtOut, uint256 netSyFee);
function swapExactYtForPt(
address receiver,
address market,
uint256 exactYtIn,
uint256 minPtOut,
ApproxParams calldata guessTotalPtFromSwap
) external returns (uint256 netPtOut, uint256 netSyFee);
}
"
},
"altitude-v2/node_modules/@pendle/core-v2/contracts/interfaces/IPActionMiscV3.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;
import "../router/math/MarketApproxLib.sol";
import "./IPAllActionTypeV3.sol";
import {IPAllEventsV3} from "./IPAllEventsV3.sol";
import "./IStandardizedYield.sol";
import "./IPMarket.sol";
/// Refer to IPAllActionTypeV3.sol for details on the parameters
interface IPActionMiscV3 is IPAllEventsV3 {
struct Call3 {
bool allowFailure;
bytes callData;
}
struct Result {
bool success;
bytes returnData;
}
function mintSyFromToken(
address receiver,
address SY,
uint256 minSyOut,
TokenInput calldata input
) external payable returns (uint256 netSyOut);
function redeemSyToToken(
address receiver,
address SY,
uint256 netSyIn,
TokenOutput calldata output
) external returns (uint256 netTokenOut);
function mintPyFromToken(
address receiver,
address YT,
uint256 minPyOut,
TokenInput calldata input
) external payable returns (uint256 netPyOut, uint256 netSyInterm);
function redeemPyToToken(
address receiver,
address YT,
uint256 netPyIn,
TokenOutput calldata output
) external returns (uint256 netTokenOut, uint256 netSyInterm);
function mintPyFromSy(
address receiver,
address YT,
uint256 netSyIn,
uint256 minPyOut
) external returns (uint256 netPyOut);
function redeemPyToSy(
address receiver,
address YT,
uint256 netPyIn,
uint256 minSyOut
) external returns (uint256 netSyOut);
function redeemDueInterestAndRewards(
address user,
address[] calldata sys,
address[] calldata yts,
address[] calldata markets
) external;
function redeemDueInterestAndRewardsV2(
IStandardizedYield[] calldata SYs,
RedeemYtIncomeToTokenStruct[] calldata YTs,
IPMarket[] calldata markets,
IPSwapAggregator pendleSwap,
SwapDataExtra[] calldata swaps
) external returns (uint256[] memory netOutFromSwaps, uint256[] memory netInterests);
function swapTokensToTokens(
IPSwapAggregator pendleSwap,
SwapDataExtra[] calldata swaps,
uint256[] calldata netSwaps
) external payable returns (uint256[] memory netOutFromSwaps);
function swapTokenToToken(
address receiver,
uint256 minTokenOut,
TokenInput calldata inp
) external payable returns (uint256 netTokenOut);
function swapTokenToTokenViaSy(
address receiver,
address SY,
TokenInput calldata input,
address tokenRedeemSy,
uint256 minTokenOut
) external payable returns (uint256 netTokenOut, uint256 netSyInterm);
function exitPreExpToToken(
address receiver,
address market,
uint256 netPtIn,
uint256 netYtIn,
uint256 netLpIn,
TokenOutput calldata output,
LimitOrderData calldata limit
) external returns (uint256 netTokenOut, ExitPreExpReturnParams memory params);
function exitPreExpToSy(
address receiver,
address market,
uint256 netPtIn,
uint256 netYtIn,
uint256 netLpIn,
uint256 minSyOut,
LimitOrderData calldata limit
) external returns (ExitPreExpReturnParams memory params);
function exitPostExpToToken(
address receiver,
address market,
uint256 netPtIn,
uint256 netLpIn,
TokenOutput calldata output
) external returns (uint256 netTokenOut, ExitPostExpReturnParams memory params);
function exitPostExpToSy(
address receiver,
address market,
uint256 netPtIn,
uint256 netLpIn,
uint256 minSyOut
) external returns (ExitPostExpReturnParams memory params);
function callAndReflect(
address payable reflector,
bytes calldata selfCall1,
bytes calldata selfCall2,
bytes calldata reflectCall
) external payable returns (bytes memory selfRes1, bytes memory selfRes2, bytes memory reflectRes);
function boostMarkets(address[] memory markets) external;
function multicall(Call3[] calldata calls) external payable returns (Result[] memory res);
function simulate(address target, bytes calldata data) external payable;
}
"
},
"altitude-v2/node_modules/@pendle/core-v2/contracts/interfaces/IPActionCallbackV3.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;
import "./IPMarketSwapCallback.sol";
import "./IPLimitRouter.sol";
interface IPActionCallbackV3 is IPMarketSwapCallback, IPLimitRouterCallback {}
"
},
"altitude-v2/node_modules/@pendle/core-v2/contracts/interfaces/IPActionStorageV4.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;
import {IPAllEventsV3} from "./IPAllEventsV3.sol";
interface IPActionStorageV4 is IPAllEventsV3 {
struct SelectorsToFacet {
address facet;
bytes4[] selectors;
}
function owner() external view returns (address);
function pendingOwner() external view returns (address);
function transferOwnership(address newOwner, bool direct, bool renounce) external;
function claimOwnership() external;
function setSelectorToFacets(SelectorsToFacet[] calldata arr) external;
function selectorToFacet(bytes4 selector) external view returns (address);
}
"
},
"altitude-v2/node_modules/@pendle/core-v2/contracts/interfaces/IPActionSimple.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;
import {TokenInput} from "./IPAllActionTypeV3.sol";
import {IPAllEventsV3} from "./IPAllEventsV3.sol";
import "./IPAllActionTypeV3.sol";
/// All of these functions are for internal router use only and should not be called directly.
interface IPActionSimple is IPAllEventsV3 {
function addLiquiditySinglePtSimple(
address receiver,
address market,
uint256 netPtIn,
uint256 minLpOut
) external returns (uint256 netLpOut, uint256 netSyFee);
function addLiquiditySingleTokenSimple(
address receiver,
address market,
uint256 minLpOut,
TokenInput calldata input
) external payable returns (uint256 netLpOut, uint256 netSyFee, uint256 netSyInterm);
function addLiquiditySingleSySimple(
address receiver,
address market,
uint256 netSyIn,
uint256 minLpOut
) external returns (uint256 netLpOut, uint256 netSyFee);
function removeLiquiditySinglePtSimple(
address receiver,
address market,
uint256 netLpToRemove,
uint256 minPtOut
) external returns (uint256 netPtOut, uint256 netSyFee);
function swapExactTokenForPtSimple(
address receiver,
address market,
uint256 minPtOut,
TokenInput calldata input
) external payable returns (uint256 netPtOut, uint256 netSyFee, uint256 netSyInterm);
function swapExactSyForPtSimple(
address receiver,
address market,
uint256 exactSyIn,
uint256 minPtOut
) external returns (uint256 netPtOut, uint256 netSyFee);
function swapExactTokenForYtSimple(
address receiver,
address market,
uint256 minYtOut,
TokenInput calldata input
) external payable returns (uint256 netYtOut, uint256 netSyFee, uint256 netSyInterm);
function swapExactSyForYtSimple(
address receiver,
address market,
uint256 exactSyIn,
uint256 minYtOut
) external returns (uint256 netYtOut, uint256 netSyFee);
}
"
},
"altitude-v2/node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
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);
}
"
},
"altitude-v2/node_modules/@pendle/core-v2/contracts/interfaces/IPPrincipalToken.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/extensions/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);
}
"
},
"altitude-v2/node_modules/@pendle/core-v2/contracts/interfaces/IPYieldToken.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "./IRewardManager.sol";
import "./IPInterestManagerYT.sol";
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);
Submitted on: 2025-09-24 16:07:07
Comments
Log in to comment.
No comments yet.