Skip to content

Commit 8a560f4

Browse files
authored
Added a Deployed event to HyperdriveFactory (#341)
* Added an event to `HyperdriveFactory` and updated the way that the linkers are used * Test the factory events for the Aave and stETH instances * Added testing for events for the remaining factories * Adds tests for the new `HyperdriveFactory` admin functionality
1 parent 7233c4d commit 8a560f4

File tree

11 files changed

+328
-73
lines changed

11 files changed

+328
-73
lines changed

contracts/src/factory/AaveHyperdriveFactory.sol

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,37 +25,37 @@ contract AaveHyperdriveFactory is HyperdriveFactory {
2525
/// @param _feeCollector The address which should be set as the fee collector in new deployments
2626
/// @param _fees The fees each deployed instance from this contract will have
2727
/// @param _defaultPausers The default addresses which will be set to have the pauser role
28+
/// @param _linkerFactory The address of the linker factory
29+
/// @param _linkerCodeHash The hash of the linker contract's constructor code.
2830
constructor(
2931
address _governance,
3032
IHyperdriveDeployer _deployer,
3133
address _hyperdriveGovernance,
3234
address _feeCollector,
3335
IHyperdrive.Fees memory _fees,
34-
address[] memory _defaultPausers
36+
address[] memory _defaultPausers,
37+
address _linkerFactory,
38+
bytes32 _linkerCodeHash
3539
)
3640
HyperdriveFactory(
3741
_governance,
3842
_deployer,
3943
_hyperdriveGovernance,
4044
_feeCollector,
4145
_fees,
42-
_defaultPausers
46+
_defaultPausers,
47+
_linkerFactory,
48+
_linkerCodeHash
4349
)
4450
{}
4551

4652
/// @notice Deploys a copy of hyperdrive with the given params
4753
/// @param _config The configuration of the Hyperdrive pool.
48-
/// @param _linkerCodeHash The hash of the ERC20 linker contract's
49-
/// constructor code.
50-
/// @param _linkerFactory The address of the factory which is used to deploy
51-
/// the ERC20 linker contracts.
5254
/// @param _contribution Base token to call init with
5355
/// @param _apr The apr to call init with
5456
/// @return The hyperdrive address deployed
5557
function deployAndInitialize(
5658
IHyperdrive.PoolConfig memory _config,
57-
bytes32 _linkerCodeHash,
58-
address _linkerFactory,
5959
bytes32[] memory,
6060
uint256 _contribution,
6161
uint256 _apr
@@ -81,14 +81,7 @@ contract AaveHyperdriveFactory is HyperdriveFactory {
8181

8282
// Deploy and initialize the hyperdrive instance.
8383
return
84-
super.deployAndInitialize(
85-
_config,
86-
_linkerCodeHash,
87-
_linkerFactory,
88-
extraData,
89-
_contribution,
90-
_apr
91-
);
84+
super.deployAndInitialize(_config, extraData, _contribution, _apr);
9285
}
9386

9487
/// @notice This deploys a data provider for the aave hyperdrive instance

contracts/src/factory/DsrHyperdriveFactory.sol

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ contract DsrHyperdriveFactory is HyperdriveFactory {
2525
/// @param _feeCollector The address which should be set as the fee collector in new deployments
2626
/// @param _fees The fees each deployed instance from this contract will have
2727
/// @param _defaultPausers The default addresses which will be set to have the pauser role
28+
/// @param _linkerFactory The address of the linker factory
29+
/// @param _linkerCodeHash The hash of the linker contract's constructor code.
2830
/// @param dsrManager The Maker DSR manger contract address
2931
constructor(
3032
address _governance,
@@ -33,6 +35,8 @@ contract DsrHyperdriveFactory is HyperdriveFactory {
3335
address _feeCollector,
3436
IHyperdrive.Fees memory _fees,
3537
address[] memory _defaultPausers,
38+
address _linkerFactory,
39+
bytes32 _linkerCodeHash,
3640
address dsrManager
3741
)
3842
HyperdriveFactory(
@@ -41,7 +45,9 @@ contract DsrHyperdriveFactory is HyperdriveFactory {
4145
_hyperdriveGovernance,
4246
_feeCollector,
4347
_fees,
44-
_defaultPausers
48+
_defaultPausers,
49+
_linkerFactory,
50+
_linkerCodeHash
4551
)
4652
{
4753
manager = DsrManager(dsrManager);

contracts/src/factory/ERC4626HyperdriveFactory.sol

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ contract ERC4626HyperdriveFactory is HyperdriveFactory {
2525
/// @param _feeCollector The address which should be set as the fee collector in new deployments
2626
/// @param _fees The fees each deployed instance from this contract will have
2727
/// @param _defaultPausers The default addresses which will be set to have the pauser role
28+
/// @param _linkerFactory The address of the linker factory
29+
/// @param _linkerCodeHash The hash of the linker contract's constructor code.
2830
/// @param _pool The Maker ERC4626 manger contract address
2931
constructor(
3032
address _governance,
@@ -33,6 +35,8 @@ contract ERC4626HyperdriveFactory is HyperdriveFactory {
3335
address _feeCollector,
3436
IHyperdrive.Fees memory _fees,
3537
address[] memory _defaultPausers,
38+
address _linkerFactory,
39+
bytes32 _linkerCodeHash,
3640
IERC4626 _pool
3741
)
3842
HyperdriveFactory(
@@ -41,7 +45,9 @@ contract ERC4626HyperdriveFactory is HyperdriveFactory {
4145
_hyperdriveGovernance,
4246
_feeCollector,
4347
_fees,
44-
_defaultPausers
48+
_defaultPausers,
49+
_linkerFactory,
50+
_linkerCodeHash
4551
)
4652
{
4753
pool = _pool;

contracts/src/factory/HyperdriveFactory.sol

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ abstract contract HyperdriveFactory {
2626
// The address which should control hyperdrive instances
2727
address public hyperdriveGovernance;
2828

29+
// The linker factory which is used to deploy the ERC20 linker contracts.
30+
address public linkerFactory;
31+
32+
// The hash of the ERC20 linker contract's constructor code.
33+
bytes32 public linkerCodeHash;
34+
2935
// The address which should receive hyperdriveFees
3036
address public feeCollector;
3137

@@ -38,20 +44,34 @@ abstract contract HyperdriveFactory {
3844
// A constant for the ETH value
3945
address internal constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
4046

47+
// An event that is emitted when a new Hyperdrive instance is deployed.
48+
event Deployed(
49+
uint256 indexed version,
50+
address hyperdrive,
51+
IHyperdrive.PoolConfig config,
52+
address linkerFactory,
53+
bytes32 linkerCodeHash,
54+
bytes32[] extraData
55+
);
56+
4157
/// @notice Deploys the contract
4258
/// @param _governance The address which can update this factory.
4359
/// @param _deployer The contract which holds the bytecode and deploys new versions.
4460
/// @param _hyperdriveGovernance The address which is set as the governor of hyperdrive
4561
/// @param _feeCollector The address which should be set as the fee collector in new deployments
4662
/// @param _fees The fees each deployed instance from this contract will have
4763
/// @param _defaultPausers The default addresses which will be set to have the pauser role
64+
/// @param _linkerFactory The address of the linker factory
65+
/// @param _linkerCodeHash The hash of the linker contract's constructor code.
4866
constructor(
4967
address _governance,
5068
IHyperdriveDeployer _deployer,
5169
address _hyperdriveGovernance,
5270
address _feeCollector,
5371
IHyperdrive.Fees memory _fees,
54-
address[] memory _defaultPausers
72+
address[] memory _defaultPausers,
73+
address _linkerFactory,
74+
bytes32 _linkerCodeHash
5575
) {
5676
governance = _governance;
5777
hyperdriveDeployer = _deployer;
@@ -60,6 +80,8 @@ abstract contract HyperdriveFactory {
6080
feeCollector = _feeCollector;
6181
fees = _fees;
6282
defaultPausers = _defaultPausers;
83+
linkerFactory = _linkerFactory;
84+
linkerCodeHash = _linkerCodeHash;
6385
}
6486

6587
modifier onlyGovernance() {
@@ -94,6 +116,25 @@ abstract contract HyperdriveFactory {
94116
hyperdriveGovernance = newGovernance;
95117
}
96118

119+
/// @notice Allows governance to change the linker factory.
120+
/// @param newLinkerFactory The new linker code hash.
121+
function updateLinkerFactory(
122+
address newLinkerFactory
123+
) external onlyGovernance {
124+
// Update the linker factory
125+
linkerFactory = newLinkerFactory;
126+
}
127+
128+
/// @notice Allows governance to change the linker code hash. This allows
129+
/// governance to update the implementation of the ERC20Forwarder.
130+
/// @param newLinkerCodeHash The new linker code hash.
131+
function updateLinkerCodeHash(
132+
bytes32 newLinkerCodeHash
133+
) external onlyGovernance {
134+
// Update the linker code hash
135+
linkerCodeHash = newLinkerCodeHash;
136+
}
137+
97138
/// @notice Allows governance to change the fee collector address
98139
/// @param newFeeCollector The new governor address
99140
function updateFeeCollector(
@@ -123,18 +164,12 @@ abstract contract HyperdriveFactory {
123164

124165
/// @notice Deploys a copy of hyperdrive with the given params
125166
/// @param _config The configuration of the Hyperdrive pool.
126-
/// @param _linkerCodeHash The hash of the ERC20 linker contract's
127-
/// constructor code.
128-
/// @param _linkerFactory The address of the factory which is used to deploy
129-
/// the ERC20 linker contracts.
130167
/// @param _extraData The extra data is used by some factories
131168
/// @param _contribution Base token to call init with
132169
/// @param _apr The apr to call init with
133170
/// @return The hyperdrive address deployed
134171
function deployAndInitialize(
135172
IHyperdrive.PoolConfig memory _config,
136-
bytes32 _linkerCodeHash,
137-
address _linkerFactory,
138173
bytes32[] memory _extraData,
139174
uint256 _contribution,
140175
uint256 _apr
@@ -149,17 +184,17 @@ abstract contract HyperdriveFactory {
149184
address dataProvider = deployDataProvider(
150185
_config,
151186
_extraData,
152-
_linkerCodeHash,
153-
_linkerFactory
187+
linkerCodeHash,
188+
linkerFactory
154189
);
155190

156191
// Then we call the simplified factory
157192
IHyperdrive hyperdrive = IHyperdrive(
158193
hyperdriveDeployer.deploy(
159194
_config,
160195
dataProvider,
161-
_linkerCodeHash,
162-
_linkerFactory,
196+
linkerCodeHash,
197+
linkerFactory,
163198
_extraData
164199
)
165200
);
@@ -197,7 +232,18 @@ abstract contract HyperdriveFactory {
197232
// Mark as a version
198233
isOfficial[address(hyperdrive)] = versionCounter;
199234

200-
return (hyperdrive);
235+
// Emit a deployed event.
236+
_config.governance = hyperdriveGovernance;
237+
emit Deployed(
238+
versionCounter,
239+
address(hyperdrive),
240+
_config,
241+
linkerFactory,
242+
linkerCodeHash,
243+
_extraData
244+
);
245+
246+
return hyperdrive;
201247
}
202248

203249
/// @notice This should deploy a data provider which matches the type of the hyperdrives

contracts/src/factory/StethHyperdriveFactory.sol

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ contract StethHyperdriveFactory is HyperdriveFactory {
2727
/// @param _feeCollector The address which should be set as the fee collector in new deployments
2828
/// @param _fees The fees each deployed instance from this contract will have
2929
/// @param _defaultPausers The default addresses which will be set to have the pauser role
30+
/// @param _linkerFactory The address of the linker factory
31+
/// @param _linkerCodeHash The hash of the linker contract's constructor code.
3032
/// @param _lido The Lido contract.
3133
constructor(
3234
address _governance,
@@ -35,6 +37,8 @@ contract StethHyperdriveFactory is HyperdriveFactory {
3537
address _feeCollector,
3638
IHyperdrive.Fees memory _fees,
3739
address[] memory _defaultPausers,
40+
address _linkerFactory,
41+
bytes32 _linkerCodeHash,
3842
ILido _lido
3943
)
4044
HyperdriveFactory(
@@ -43,7 +47,9 @@ contract StethHyperdriveFactory is HyperdriveFactory {
4347
_hyperdriveGovernance,
4448
_feeCollector,
4549
_fees,
46-
_defaultPausers
50+
_defaultPausers,
51+
_linkerFactory,
52+
_linkerCodeHash
4753
)
4854
{
4955
lido = _lido;

test/integrations/ERC4626.t.sol

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { IHyperdriveDeployer } from "contracts/src/interfaces/IHyperdriveDeploye
1010
import { AssetId } from "contracts/src/libraries/AssetId.sol";
1111
import { Errors } from "contracts/src/libraries/Errors.sol";
1212
import { FixedPointMath } from "contracts/src/libraries/FixedPointMath.sol";
13+
import { ForwarderFactory } from "contracts/src/token/ForwarderFactory.sol";
1314
import { HyperdriveTest } from "../utils/HyperdriveTest.sol";
1415
import { Mock4626, ERC20 } from "../mocks/Mock4626.sol";
1516
import { MockERC4626Hyperdrive } from "../mocks/Mock4626Hyperdrive.sol";
@@ -27,7 +28,7 @@ contract HyperdriveER4626Test is HyperdriveTest {
2728
function setUp() public override __mainnet_fork(16_685_972) {
2829
vm.startPrank(deployer);
2930

30-
// Deploy a new yield source
31+
// Deploy the ERC4626Hyperdrive factory and deployer.
3132
pool = IERC4626(
3233
address(new Mock4626(ERC20(address(dai)), "yearn dai", "yDai"))
3334
);
@@ -37,19 +38,20 @@ contract HyperdriveER4626Test is HyperdriveTest {
3738
);
3839
address[] memory defaults = new address[](1);
3940
defaults[0] = bob;
40-
41+
forwarderFactory = new ForwarderFactory();
4142
factory = new ERC4626HyperdriveFactory(
4243
alice,
4344
simpleDeployer,
4445
bob,
4546
bob,
4647
IHyperdrive.Fees(0, 0, 0),
4748
defaults,
49+
address(forwarderFactory),
50+
forwarderFactory.ERC20LINK_HASH(),
4851
pool
4952
);
5053

5154
address daiWhale = 0x075e72a5eDf65F0A5f44699c7654C1a76941Ddc8;
52-
5355
whaleTransfer(daiWhale, dai, alice);
5456

5557
IHyperdrive.PoolConfig memory config = IHyperdrive.PoolConfig({
@@ -88,6 +90,9 @@ contract HyperdriveER4626Test is HyperdriveTest {
8890
dai.approve(address(hyperdrive), type(uint256).max);
8991
dai.approve(address(mockHyperdrive), type(uint256).max);
9092
vm.stopPrank();
93+
94+
// Start recording events.
95+
vm.recordLogs();
9196
}
9297

9398
function test_erc4626_deposit() external {
@@ -105,7 +110,7 @@ contract HyperdriveER4626Test is HyperdriveTest {
105110
assertEq(sharesMinted, 666666666666666666);
106111
assertEq(pool.balanceOf(address(mockHyperdrive)), 666666666666666666);
107112

108-
//Now we try to do a deposit from alice's shares
113+
// Now we try to do a deposit from alice's shares
109114
pool.approve(address(mockHyperdrive), type(uint256).max);
110115
(sharesMinted, sharePrice) = mockHyperdrive.deposit(3e18, false);
111116
assertEq(sharePrice, 1.5e18 + 1);
@@ -149,7 +154,8 @@ contract HyperdriveER4626Test is HyperdriveTest {
149154
function test_erc4626_testDeploy() external {
150155
setUp();
151156
vm.startPrank(alice);
152-
uint256 apr = 1e16; // 1% apr
157+
uint256 apr = 0.01e18; // 1% apr
158+
uint256 contribution = 2_500e18;
153159
IHyperdrive.PoolConfig memory config = IHyperdrive.PoolConfig({
154160
baseToken: dai,
155161
initialSharePrice: FixedPointMath.ONE_18,
@@ -165,10 +171,8 @@ contract HyperdriveER4626Test is HyperdriveTest {
165171
dai.approve(address(factory), type(uint256).max);
166172
hyperdrive = factory.deployAndInitialize(
167173
config,
168-
bytes32(0),
169-
address(0),
170174
new bytes32[](0),
171-
2500e18,
175+
contribution,
172176
apr
173177
);
174178

@@ -180,5 +184,14 @@ contract HyperdriveER4626Test is HyperdriveTest {
180184
);
181185
// lp shares should equal number of share reserves initialized with
182186
assertEq(createdShares, 2500e18);
187+
188+
// Verify that the correct events were emitted.
189+
verifyFactoryEvents(
190+
factory,
191+
alice,
192+
contribution,
193+
apr,
194+
new bytes32[](0)
195+
);
183196
}
184197
}

0 commit comments

Comments
 (0)