-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added the skeleton for the Corn integration * Implemented the `CornBase` contract * Wired up the Corn Hyperdrive instance * Added an instance test for the Corn integration * Added deployment scripts for the Corn integration * Addressed review feedback from @jrhea and @mcclurejt
- Loading branch information
1 parent
8e32d2f
commit 2cdddd9
Showing
44 changed files
with
1,584 additions
and
43 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
71 changes: 71 additions & 0 deletions
71
contracts/src/deployers/corn/CornHyperdriveCoreDeployer.sol
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: Apache-2.0 | ||
pragma solidity 0.8.22; | ||
|
||
import { ICornSilo } from "../../interfaces/ICornSilo.sol"; | ||
import { IHyperdrive } from "../../interfaces/IHyperdrive.sol"; | ||
import { IHyperdriveAdminController } from "../../interfaces/IHyperdriveAdminController.sol"; | ||
import { IHyperdriveCoreDeployer } from "../../interfaces/IHyperdriveCoreDeployer.sol"; | ||
import { CornHyperdrive } from "../../instances/corn/CornHyperdrive.sol"; | ||
|
||
/// @author DELV | ||
/// @title CornHyperdriveCoreDeployer | ||
/// @notice The core deployer for the CornHyperdrive 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 CornHyperdriveCoreDeployer is IHyperdriveCoreDeployer { | ||
/// @dev The Corn Silo contract. This is where the base token will be | ||
/// deposited. | ||
ICornSilo internal immutable cornSilo; | ||
|
||
/// @notice Instantiates the CornHyperdrive base contract. | ||
/// @param _cornSilo The Corn Silo contract. | ||
constructor(ICornSilo _cornSilo) { | ||
cornSilo = _cornSilo; | ||
} | ||
|
||
/// @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 _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 CornHyperdrive instance. | ||
function deployHyperdrive( | ||
string memory __name, | ||
IHyperdrive.PoolConfig memory _config, | ||
IHyperdriveAdminController _adminController, | ||
bytes memory, // unused _extraData, | ||
address _target0, | ||
address _target1, | ||
address _target2, | ||
address _target3, | ||
address _target4, | ||
bytes32 _salt | ||
) external returns (address) { | ||
return ( | ||
address( | ||
// NOTE: We hash the sender with the salt to prevent the | ||
// front-running of deployments. | ||
new CornHyperdrive{ | ||
salt: keccak256(abi.encode(msg.sender, _salt)) | ||
}( | ||
__name, | ||
_config, | ||
_adminController, | ||
_target0, | ||
_target1, | ||
_target2, | ||
_target3, | ||
_target4, | ||
cornSilo | ||
) | ||
) | ||
); | ||
} | ||
} |
168 changes: 168 additions & 0 deletions
168
contracts/src/deployers/corn/CornHyperdriveDeployerCoordinator.sol
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,168 @@ | ||
// 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 { CornConversions } from "../../instances/corn/CornConversions.sol"; | ||
import { IHyperdrive } from "../../interfaces/IHyperdrive.sol"; | ||
import { IHyperdriveDeployerCoordinator } from "../../interfaces/IHyperdriveDeployerCoordinator.sol"; | ||
import { CORN_HYPERDRIVE_DEPLOYER_COORDINATOR_KIND } from "../../libraries/Constants.sol"; | ||
import { ONE } from "../../libraries/FixedPointMath.sol"; | ||
import { HyperdriveDeployerCoordinator } from "../HyperdriveDeployerCoordinator.sol"; | ||
|
||
/// @author DELV | ||
/// @title CornHyperdriveDeployerCoordinator | ||
/// @notice The deployer coordinator for the CornHyperdrive | ||
/// 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 CornHyperdriveDeployerCoordinator is HyperdriveDeployerCoordinator { | ||
using SafeERC20 for ERC20; | ||
|
||
/// @notice The deployer coordinator's kind. | ||
string public constant override kind = | ||
CORN_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 CornConversions.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 CornConversions.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 empty extra data. | ||
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. | ||
if (address(_deployConfig.baseToken) == address(0)) { | ||
revert IHyperdriveDeployerCoordinator.InvalidBaseToken(); | ||
} | ||
|
||
// Ensure that the vault shares token address is properly configured. | ||
// Since the CornSilo 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); | ||
} | ||
} |
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,48 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity 0.8.22; | ||
|
||
import { CornTarget0 } from "../../instances/corn/CornTarget0.sol"; | ||
import { ICornSilo } from "../../interfaces/ICornSilo.sol"; | ||
import { IHyperdrive } from "../../interfaces/IHyperdrive.sol"; | ||
import { IHyperdriveAdminController } from "../../interfaces/IHyperdriveAdminController.sol"; | ||
import { IHyperdriveTargetDeployer } from "../../interfaces/IHyperdriveTargetDeployer.sol"; | ||
|
||
/// @author DELV | ||
/// @title CornTarget0Deployer | ||
/// @notice The target0 deployer for the CornHyperdrive 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 CornTarget0Deployer is IHyperdriveTargetDeployer { | ||
/// @dev The Corn Silo contract. This is where the base token will be | ||
/// deposited. | ||
ICornSilo internal immutable cornSilo; | ||
|
||
/// @notice Instantiates the CornHyperdrive base contract. | ||
/// @param _cornSilo The Corn Silo contract. | ||
constructor(ICornSilo _cornSilo) { | ||
cornSilo = _cornSilo; | ||
} | ||
|
||
/// @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 _salt The create2 salt used in the deployment. | ||
/// @return The address of the newly deployed CornTarget0 instance. | ||
function deployTarget( | ||
IHyperdrive.PoolConfig memory _config, | ||
IHyperdriveAdminController _adminController, | ||
bytes memory, // unused _extraData | ||
bytes32 _salt | ||
) external returns (address) { | ||
return | ||
address( | ||
// NOTE: We hash the sender with the salt to prevent the | ||
// front-running of deployments. | ||
new CornTarget0{ | ||
salt: keccak256(abi.encode(msg.sender, _salt)) | ||
}(_config, _adminController, cornSilo) | ||
); | ||
} | ||
} |
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,48 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity 0.8.22; | ||
|
||
import { CornTarget1 } from "../../instances/corn/CornTarget1.sol"; | ||
import { ICornSilo } from "../../interfaces/ICornSilo.sol"; | ||
import { IHyperdrive } from "../../interfaces/IHyperdrive.sol"; | ||
import { IHyperdriveAdminController } from "../../interfaces/IHyperdriveAdminController.sol"; | ||
import { IHyperdriveTargetDeployer } from "../../interfaces/IHyperdriveTargetDeployer.sol"; | ||
|
||
/// @author DELV | ||
/// @title CornTarget1Deployer | ||
/// @notice The target1 deployer for the CornHyperdrive 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 CornTarget1Deployer is IHyperdriveTargetDeployer { | ||
/// @dev The Corn Silo contract. This is where the base token will be | ||
/// deposited. | ||
ICornSilo internal immutable cornSilo; | ||
|
||
/// @notice Instantiates the CornHyperdrive base contract. | ||
/// @param _cornSilo The Corn Silo contract. | ||
constructor(ICornSilo _cornSilo) { | ||
cornSilo = _cornSilo; | ||
} | ||
|
||
/// @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 _salt The create2 salt used in the deployment. | ||
/// @return The address of the newly deployed CornTarget1 instance. | ||
function deployTarget( | ||
IHyperdrive.PoolConfig memory _config, | ||
IHyperdriveAdminController _adminController, | ||
bytes memory, // unused _extraData | ||
bytes32 _salt | ||
) external returns (address) { | ||
return | ||
address( | ||
// NOTE: We hash the sender with the salt to prevent the | ||
// front-running of deployments. | ||
new CornTarget1{ | ||
salt: keccak256(abi.encode(msg.sender, _salt)) | ||
}(_config, _adminController, cornSilo) | ||
); | ||
} | ||
} |
Oops, something went wrong.