-
Notifications
You must be signed in to change notification settings - Fork 3
/
ERC4626HyperdriveDeployerCoordinator.sol
154 lines (140 loc) · 6.16 KB
/
ERC4626HyperdriveDeployerCoordinator.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.20;
import { ERC20 } from "openzeppelin/token/ERC20/ERC20.sol";
import { SafeERC20 } from "openzeppelin/token/ERC20/utils/SafeERC20.sol";
import { IERC4626 } from "../../interfaces/IERC4626.sol";
import { IHyperdrive } from "../../interfaces/IHyperdrive.sol";
import { IHyperdriveDeployerCoordinator } from "../../interfaces/IHyperdriveDeployerCoordinator.sol";
import { ONE } from "../../libraries/FixedPointMath.sol";
import { HyperdriveDeployerCoordinator } from "../HyperdriveDeployerCoordinator.sol";
/// @author DELV
/// @title ERC4626HyperdriveDeployerCoordinator
/// @notice The deployer coordinator for the ERC4626Hyperdrive 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 ERC4626HyperdriveDeployerCoordinator is HyperdriveDeployerCoordinator {
using SafeERC20 for ERC20;
/// @notice The deployer coordinator's name.
string public constant override name =
"ERC4626HyperdriveDeployerCoordinator";
/// @notice Instantiates the deployer coordinator.
/// @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.
constructor(
address _factory,
address _coreDeployer,
address _target0Deployer,
address _target1Deployer,
address _target2Deployer,
address _target3Deployer
)
HyperdriveDeployerCoordinator(
_factory,
_coreDeployer,
_target0Deployer,
_target1Deployer,
_target2Deployer,
_target3Deployer
)
{}
/// @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 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) {
// If base is the deposit asset, the initialization will be paid in the
// base token.
address token;
if (_options.asBase) {
token = _hyperdrive.baseToken();
}
// Otherwise, the initialization will be paid in vault shares.
else {
token = _hyperdrive.vaultSharesToken();
}
// Take custody of the contribution and approve Hyperdrive to pull the
// tokens.
ERC20(token).safeTransferFrom(_lp, address(this), _contribution);
ERC20(token).forceApprove(address(_hyperdrive), _contribution);
// NOTE: Return zero since this yield source isn't payable.
return 0;
}
/// @dev Prevents the contract from receiving ether.
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.
function _checkPoolConfig(
IHyperdrive.PoolDeployConfig memory _deployConfig
) internal view override {
// Perform the default checks.
super._checkPoolConfig(_deployConfig);
// Ensure that the vault shares token address is non-zero.
if (address(_deployConfig.vaultSharesToken) == address(0)) {
revert IHyperdriveDeployerCoordinator.InvalidVaultSharesToken();
}
// Ensure that the base token address is properly configured.
if (
address(_deployConfig.baseToken) !=
IERC4626(address(_deployConfig.vaultSharesToken)).asset()
) {
revert IHyperdriveDeployerCoordinator.InvalidBaseToken();
}
// 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() - 4)
) {
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() - 4)
) {
revert IHyperdriveDeployerCoordinator
.InvalidMinimumTransactionAmount();
}
}
/// @dev Gets the initial vault share price of the Hyperdrive pool.
/// @param _deployConfig The deploy config that will be used to deploy the
/// pool.
/// @return The initial vault share price of the Hyperdrive pool.
function _getInitialVaultSharePrice(
IHyperdrive.PoolDeployConfig memory _deployConfig,
bytes memory // unused extra data
) internal view override returns (uint256) {
// Return the vault's current share price.
return
IERC4626(address(_deployConfig.vaultSharesToken)).convertToAssets(
ONE
);
}
}