Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Staking USDS Integrations #1182

Merged
merged 5 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.22;

import { IHyperdrive } from "../../interfaces/IHyperdrive.sol";
import { IHyperdriveAdminController } from "../../interfaces/IHyperdriveAdminController.sol";
import { IHyperdriveCoreDeployer } from "../../interfaces/IHyperdriveCoreDeployer.sol";
import { IStakingUSDS } from "../../interfaces/IStakingUSDS.sol";
import { StakingUSDSHyperdrive } from "../../instances/staking-usds/StakingUSDSHyperdrive.sol";

/// @author DELV
/// @title StakingUSDSHyperdriveCoreDeployer
/// @notice The core deployer for the StakingUSDSHyperdrive implementation.
/// @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 StakingUSDSHyperdriveCoreDeployer is IHyperdriveCoreDeployer {
/// @notice Deploys a Hyperdrive instance with the given parameters.
/// @param __name The name of the Hyperdrive pool.
/// @param _config The configuration of the Hyperdrive pool.
/// @param _adminController The admin controller that will specify the
/// admin parameters for this instance.
/// @param _extraData The extra data containing the staking USDS address.
/// @param _target0 The target0 address.
/// @param _target1 The target1 address.
/// @param _target2 The target2 address.
/// @param _target3 The target3 address.
/// @param _target4 The target4 address.
/// @param _salt The create2 salt used in the deployment.
/// @return The address of the newly deployed StakingUSDSHyperdrive instance.
function deployHyperdrive(
string memory __name,
IHyperdrive.PoolConfig memory _config,
IHyperdriveAdminController _adminController,
bytes memory _extraData,
address _target0,
address _target1,
address _target2,
address _target3,
address _target4,
bytes32 _salt
) external returns (address) {
IStakingUSDS stakingUSDS = abi.decode(_extraData, (IStakingUSDS));
return (
address(
// NOTE: We hash the sender with the salt to prevent the
// front-running of deployments.
new StakingUSDSHyperdrive{
salt: keccak256(abi.encode(msg.sender, _salt))
}(
__name,
_config,
_adminController,
_target0,
_target1,
_target2,
_target3,
_target4,
stakingUSDS
)
)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.22;

import { ERC20 } from "openzeppelin/token/ERC20/ERC20.sol";
import { SafeERC20 } from "openzeppelin/token/ERC20/utils/SafeERC20.sol";
import { StakingUSDSConversions } from "../../instances/staking-usds/StakingUSDSConversions.sol";
import { IHyperdrive } from "../../interfaces/IHyperdrive.sol";
import { IHyperdriveDeployerCoordinator } from "../../interfaces/IHyperdriveDeployerCoordinator.sol";
import { IStakingUSDS } from "../../interfaces/IStakingUSDS.sol";
import { StakingUSDSConversions } from "../../instances/staking-usds/StakingUSDSConversions.sol";
import { STAKING_USDS_HYPERDRIVE_DEPLOYER_COORDINATOR_KIND } from "../../libraries/Constants.sol";
import { ONE } from "../../libraries/FixedPointMath.sol";
import { HyperdriveDeployerCoordinator } from "../HyperdriveDeployerCoordinator.sol";

/// @author DELV
/// @title StakingUSDSHyperdriveDeployerCoordinator
/// @notice The deployer coordinator for the StakingUSDSHyperdrive
/// implementation.
/// @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 StakingUSDSHyperdriveDeployerCoordinator is
HyperdriveDeployerCoordinator
{
using SafeERC20 for ERC20;

/// @notice The deployer coordinator's kind.
string public constant override kind =
STAKING_USDS_HYPERDRIVE_DEPLOYER_COORDINATOR_KIND;

/// @notice Instantiates the deployer coordinator.
/// @param _name The deployer coordinator's name.
/// @param _factory The factory that this deployer will be registered with.
/// @param _coreDeployer The core deployer.
/// @param _target0Deployer The target0 deployer.
/// @param _target1Deployer The target1 deployer.
/// @param _target2Deployer The target2 deployer.
/// @param _target3Deployer The target3 deployer.
/// @param _target4Deployer The target4 deployer.
constructor(
string memory _name,
address _factory,
address _coreDeployer,
address _target0Deployer,
address _target1Deployer,
address _target2Deployer,
address _target3Deployer,
address _target4Deployer
)
HyperdriveDeployerCoordinator(
_name,
_factory,
_coreDeployer,
_target0Deployer,
_target1Deployer,
_target2Deployer,
_target3Deployer,
_target4Deployer
)
{}

/// @dev Prepares the coordinator for initialization by drawing funds from
/// the LP, if necessary.
/// @param _hyperdrive The Hyperdrive instance that is being initialized.
/// @param _lp The LP that is initializing the pool.
/// @param _contribution The amount of capital to supply. The units of this
/// quantity are either base or vault shares, depending on the value
/// of `_options.asBase`.
/// @param _options The options that configure how the initialization is
/// settled.
/// @return value The value that should be sent in the initialize transaction.
function _prepareInitialize(
IHyperdrive _hyperdrive,
address _lp,
uint256 _contribution,
IHyperdrive.Options memory _options
) internal override returns (uint256 value) {
// Depositing with shares is not supported.
if (!_options.asBase) {
revert IHyperdrive.UnsupportedToken();
}

// Transfer base from the LP and approve the Hyperdrive pool.
ERC20 baseToken = ERC20(_hyperdrive.baseToken());
baseToken.safeTransferFrom(_lp, address(this), _contribution);
baseToken.forceApprove(address(_hyperdrive), _contribution);

// This yield source isn't payable, so we should always send 0 value.
return 0;
}

/// @notice Convert an amount of vault shares to an amount of base.
/// @param _shareAmount The vault shares amount.
/// @return The base amount.
function convertToBase(uint256 _shareAmount) public pure returns (uint256) {
return StakingUSDSConversions.convertToBase(_shareAmount);
}

/// @notice Convert an amount of base to an amount of vault shares.
/// @param _baseAmount The base amount.
/// @return The vault shares amount.
function convertToShares(
uint256 _baseAmount
) public pure returns (uint256) {
return StakingUSDSConversions.convertToShares(_baseAmount);
}

/// @dev We override the message value check since this integration is
/// not payable.
function _checkMessageValue() internal view override {
if (msg.value != 0) {
revert IHyperdriveDeployerCoordinator.NotPayable();
}
}

/// @notice Checks the pool configuration to ensure that it is valid.
/// @param _deployConfig The deploy configuration of the Hyperdrive pool.
/// @param _extraData The extra data. This contains the StakingUSDS vault
/// address.
function _checkPoolConfig(
IHyperdrive.PoolDeployConfig memory _deployConfig,
bytes memory _extraData
) internal view override {
// Perform the default checks.
super._checkPoolConfig(_deployConfig, _extraData);

// Ensure that the base token address is properly configured.
IStakingUSDS stakingUSDS = abi.decode(_extraData, (IStakingUSDS));
if (
address(_deployConfig.baseToken) !=
address(stakingUSDS.stakingToken())
) {
revert IHyperdriveDeployerCoordinator.InvalidBaseToken();
}

// Ensure that the vault shares token address is properly configured.
// Since the StakingUSDS vault doesn't support shares transfers, the
// vault shares token should be the zero address.
if (address(_deployConfig.vaultSharesToken) != address(0)) {
revert IHyperdriveDeployerCoordinator.InvalidVaultSharesToken();
}

// Ensure that the minimum share reserves are large enough to meet the
// minimum requirements for safety.
//
// NOTE: Some pools may require larger minimum share reserves to be
// considered safe. This is just a sanity check.
if (
_deployConfig.minimumShareReserves <
10 ** (_deployConfig.baseToken.decimals() - 3)
) {
revert IHyperdriveDeployerCoordinator.InvalidMinimumShareReserves();
}

// Ensure that the minimum transaction amount is large enough to meet
// the minimum requirements for safety.
//
// NOTE: Some pools may require larger minimum transaction amounts to be
// considered safe. This is just a sanity check.
if (
_deployConfig.minimumTransactionAmount <
10 ** (_deployConfig.baseToken.decimals() - 3)
) {
revert IHyperdriveDeployerCoordinator
.InvalidMinimumTransactionAmount();
}
}

/// @dev Gets the initial vault share price of the Hyperdrive pool.
/// @return The initial vault share price of the Hyperdrive pool.
function _getInitialVaultSharePrice(
IHyperdrive.PoolDeployConfig memory, // unused _deployConfig
bytes memory // unused _extraData
) internal pure override returns (uint256) {
return convertToBase(ONE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.22;

import { StakingUSDSTarget0 } from "../../instances/staking-usds/StakingUSDSTarget0.sol";
import { IHyperdrive } from "../../interfaces/IHyperdrive.sol";
import { IHyperdriveAdminController } from "../../interfaces/IHyperdriveAdminController.sol";
import { IHyperdriveTargetDeployer } from "../../interfaces/IHyperdriveTargetDeployer.sol";
import { IStakingUSDS } from "../../interfaces/IStakingUSDS.sol";

/// @author DELV
/// @title StakingUSDSTarget0Deployer
/// @notice The target0 deployer for the StakingUSDSHyperdrive implementation.
/// @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 StakingUSDSTarget0Deployer is IHyperdriveTargetDeployer {
/// @notice Deploys a target0 instance with the given parameters.
/// @param _config The configuration of the Hyperdrive pool.
/// @param _adminController The admin controller that will specify the
/// admin parameters for this instance.
/// @param _extraData The extra data containing the staking USDS address.
/// @param _salt The create2 salt used in the deployment.
/// @return The address of the newly deployed StakingUSDSTarget0 instance.
function deployTarget(
IHyperdrive.PoolConfig memory _config,
IHyperdriveAdminController _adminController,
bytes memory _extraData,
bytes32 _salt
) external returns (address) {
IStakingUSDS stakingUSDS = abi.decode(_extraData, (IStakingUSDS));
return
address(
// NOTE: We hash the sender with the salt to prevent the
// front-running of deployments.
new StakingUSDSTarget0{
salt: keccak256(abi.encode(msg.sender, _salt))
}(_config, _adminController, stakingUSDS)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.22;

import { StakingUSDSTarget1 } from "../../instances/staking-usds/StakingUSDSTarget1.sol";
import { IHyperdrive } from "../../interfaces/IHyperdrive.sol";
import { IHyperdriveAdminController } from "../../interfaces/IHyperdriveAdminController.sol";
import { IHyperdriveTargetDeployer } from "../../interfaces/IHyperdriveTargetDeployer.sol";
import { IStakingUSDS } from "../../interfaces/IStakingUSDS.sol";

/// @author DELV
/// @title StakingUSDSTarget1Deployer
/// @notice The target1 deployer for the StakingUSDSHyperdrive implementation.
/// @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 StakingUSDSTarget1Deployer is IHyperdriveTargetDeployer {
/// @notice Deploys a target1 instance with the given parameters.
/// @param _config The configuration of the Hyperdrive pool.
/// @param _adminController The admin controller that will specify the
/// admin parameters for this instance.
/// @param _extraData The extra data containing the staking USDS address.
/// @param _salt The create2 salt used in the deployment.
/// @return The address of the newly deployed StakingUSDSTarget1 instance.
function deployTarget(
IHyperdrive.PoolConfig memory _config,
IHyperdriveAdminController _adminController,
bytes memory _extraData,
bytes32 _salt
) external returns (address) {
IStakingUSDS stakingUSDS = abi.decode(_extraData, (IStakingUSDS));
return
address(
// NOTE: We hash the sender with the salt to prevent the
// front-running of deployments.
new StakingUSDSTarget1{
salt: keccak256(abi.encode(msg.sender, _salt))
}(_config, _adminController, stakingUSDS)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.22;

import { StakingUSDSTarget2 } from "../../instances/staking-usds/StakingUSDSTarget2.sol";
import { IHyperdrive } from "../../interfaces/IHyperdrive.sol";
import { IHyperdriveAdminController } from "../../interfaces/IHyperdriveAdminController.sol";
import { IHyperdriveTargetDeployer } from "../../interfaces/IHyperdriveTargetDeployer.sol";
import { IStakingUSDS } from "../../interfaces/IStakingUSDS.sol";

/// @author DELV
/// @title StakingUSDSTarget2Deployer
/// @notice The target2 deployer for the StakingUSDSHyperdrive implementation.
/// @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 StakingUSDSTarget2Deployer is IHyperdriveTargetDeployer {
/// @notice Deploys a target2 instance with the given parameters.
/// @param _config The configuration of the Hyperdrive pool.
/// @param _adminController The admin controller that will specify the
/// admin parameters for this instance.
/// @param _extraData The extra data containing the staking USDS address.
/// @param _salt The create2 salt used in the deployment.
/// @return The address of the newly deployed StakingUSDSTarget2 instance.
function deployTarget(
IHyperdrive.PoolConfig memory _config,
IHyperdriveAdminController _adminController,
bytes memory _extraData,
bytes32 _salt
) external returns (address) {
IStakingUSDS stakingUSDS = abi.decode(_extraData, (IStakingUSDS));
return
address(
// NOTE: We hash the sender with the salt to prevent the
// front-running of deployments.
new StakingUSDSTarget2{
salt: keccak256(abi.encode(msg.sender, _salt))
}(_config, _adminController, stakingUSDS)
);
}
}
Loading
Loading