Skip to content

Commit

Permalink
refactor to make contracts and tests strategy-centric
Browse files Browse the repository at this point in the history
  • Loading branch information
mcclurejt committed Nov 15, 2024
1 parent af6aff0 commit 0d85c1d
Show file tree
Hide file tree
Showing 25 changed files with 996 additions and 3,566 deletions.
698 changes: 0 additions & 698 deletions contracts/Everlong.sol

This file was deleted.

202 changes: 142 additions & 60 deletions contracts/Strategy.sol โ†’ contracts/EverlongStrategy.sol

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.22;

import { Strategy } from "./Strategy.sol";
import { EverlongStrategy } from "./EverlongStrategy.sol";
import { IEverlongStrategy } from "./interfaces/IEverlongStrategy.sol";
import { IEverlongStrategyFactory } from "./interfaces/IEverlongStrategyFactory.sol";
import { EVERLONG_KIND, EVERLONG_VERSION } from "./libraries/Constants.sol";

contract StrategyFactory {
event NewStrategy(address indexed strategy, address indexed asset);
/// @author DELV
/// @title EverlongStrategyFactory
/// @notice A factory for creating Everlong instances.
/// @custom:disclaimer The language used in this code is for coding convenience
/// only, and is not intended to, and does not, have any
/// particular legal or regulatory significance.
contract EverlongStrategyFactory is IEverlongStrategyFactory {
/// @inheritdoc IEverlongStrategyFactory
string public constant name = "EverlongStrategyFactory";

address public immutable emergencyAdmin;
/// @inheritdoc IEverlongStrategyFactory
string public constant kind = EVERLONG_KIND;

/// @inheritdoc IEverlongStrategyFactory
string public constant version = EVERLONG_VERSION;

address public immutable emergencyAdmin;
address public management;
address public performanceFeeRecipient;
address public keeper;
Expand Down Expand Up @@ -43,7 +57,7 @@ contract StrategyFactory {
) external virtual returns (address) {
// tokenized strategies available setters.
IEverlongStrategy _newStrategy = IEverlongStrategy(
address(new Strategy(_asset, _name, _hyperdrive, _asBase))
address(new EverlongStrategy(_asset, _name, _hyperdrive, _asBase))
);

_newStrategy.setPerformanceFeeRecipient(performanceFeeRecipient);
Expand Down
80 changes: 0 additions & 80 deletions contracts/interfaces/IEverlong.sol

This file was deleted.

16 changes: 13 additions & 3 deletions contracts/interfaces/IEverlongPortfolio.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import { IEverlong } from "./IEverlong.sol";
import { IEverlongStrategy } from "./IEverlongStrategy.sol";

interface IEverlongPortfolio {
// โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
Expand All @@ -10,7 +10,9 @@ interface IEverlongPortfolio {

/// @notice Rebalances the Everlong bond portfolio if needed.
/// @param _options Options to control the rebalance behavior.
function rebalance(IEverlong.RebalanceOptions memory _options) external;
function rebalance(
IEverlongStrategy.RebalanceOptions memory _options
) external;

/// @notice Closes mature positions in the Everlong portfolio.
/// @param _limit The maximum number of positions to close.
Expand All @@ -33,12 +35,20 @@ interface IEverlongPortfolio {
/// @return The position.
function positionAt(
uint256 _index
) external view returns (IEverlong.Position memory);
) external view returns (IEverlongStrategy.Position memory);

/// @notice Determines whether any positions are matured.
/// @return True if any positions are matured, false otherwise.
function hasMaturedPositions() external view returns (bool);

/// @notice Weighted average maturity timestamp of the portfolio.
/// @return Weighted average maturity timestamp of the portfolio.
function avgMaturityTime() external view returns (uint128);

/// @notice Total quantity of bonds held in the portfolio.
/// @return Total quantity of bonds held in the portfolio.
function totalBonds() external view returns (uint128);

/// @notice Determines whether Everlong's portfolio can currently be rebalanced.
/// @return True if the portfolio can be rebalanced, false otherwise.
function canRebalance() external view returns (bool);
Expand Down
75 changes: 55 additions & 20 deletions contracts/interfaces/IEverlongStrategy.sol
Original file line number Diff line number Diff line change
@@ -1,23 +1,58 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.18;
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import { IStrategy } from "tokenized-strategy/interfaces/IStrategy.sol";
import { IEverlong } from "./IEverlong.sol";

interface IEverlongStrategy is IStrategy {
// โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
// โ”‚ VIEW FUNCTIONS โ”‚
// โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

/// @notice Gets the number of positions managed by the Everlong instance.
/// @return The number of positions.
function positionCount() external view returns (uint256);

/// @notice Gets the position at an index.
/// Position `maturityTime` increases with each index.
/// @param _index The index of the position.
/// @return The position.
function positionAt(
uint256 _index
) external view returns (IEverlong.Position memory);
import { IEverlongEvents } from "./IEverlongEvents.sol";
import { IEverlongPortfolio } from "./IEverlongPortfolio.sol";

interface IEverlongStrategy is IStrategy, IEverlongEvents, IEverlongPortfolio {
// โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
// โ”‚ Structs โ”‚
// โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

/// @notice Contains the information needed to identify an open Hyperdrive position.
struct Position {
/// @notice Time when the position matures.
uint128 maturityTime;
/// @notice Amount of bonds in the position.
uint128 bondAmount;
}

// TODO: Revisit position closure limit to see what POSITION_DURATION would
// be needed to run out of gas.
//
/// @notice Parameters to specify how a rebalance will be performed.
struct RebalanceOptions {
/// @notice Limit on the amount of idle to spend on a new position.
/// @dev A value of zero indicates no limit.
uint256 spendingLimit;
/// @notice Minimum amount of bonds to receive when opening a position.
uint256 minOutput;
/// @notice Minimum vault share price when opening a position.
uint256 minVaultSharePrice;
/// @notice Maximum amount of mature positions that can be closed.
/// @dev A value of zero indicates no limit.
uint256 positionClosureLimit;
/// @notice Passed to hyperdrive `openLong()` and `closeLong()`.
bytes extraData;
}

// โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
// โ”‚ Views โ”‚
// โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

/// @notice Gets the address of the underlying Hyperdrive Instance
function hyperdrive() external view returns (address);

/// @notice Gets the Everlong instance's kind.
/// @return The Everlong instance's kind.
function kind() external pure returns (string memory);

/// @notice Gets the Everlong instance's version.
/// @return The Everlong instance's version.
function version() external pure returns (string memory);

/// @notice Gets whether Everlong uses hyperdrive's base token.
/// @return True if using hyperdrive's base token, false otherwise.
function asBase() external view returns (bool);
}
51 changes: 51 additions & 0 deletions contracts/interfaces/IEverlongStrategyFactory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

/// @author DELV
/// @title IEverlongStrategyFactory
/// @notice Interface for an EverlongStrategyFactory.
/// @custom:disclaimer The language used in this code is for coding convenience
/// only, and is not intended to, and does not, have any
/// particular legal or regulatory significance.
interface IEverlongStrategyFactory {
// โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
// โ”‚ Stateful โ”‚
// โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

/**
* @notice Deploy a new Strategy.
* @param _asset The underlying asset for the strategy to use.
* @param _hyperdrive The underlying hyperdrive pool for the strategy to use.
* @param _asBase Whether to use hyperdrive's base asset.
* @return . The address of the new strategy.
*/
function newStrategy(
address _asset,
string calldata _name,
address _hyperdrive,
bool _asBase
) external returns (address);

// โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
// โ”‚ Views โ”‚
// โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

/// @notice Gets the Everlong factory's name.
/// @return The Everlong instance's kind.
function name() external pure returns (string memory);

/// @notice Gets the Everlong factory's kind.
/// @return The Everlong factory's kind.
function kind() external pure returns (string memory);

/// @notice Gets the Everlong factory's version.
/// @return The Everlong factory's version.
function version() external pure returns (string memory);

// โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
// โ”‚ Events โ”‚
// โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

/// @notice Emitted when a new EverlongStrategy is created.
event NewStrategy(address indexed strategy, address indexed asset);
}
Loading

0 comments on commit 0d85c1d

Please sign in to comment.