@@ -41,6 +41,7 @@ import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
4141import "@openzeppelin/contracts/utils/Create2.sol " ;
4242
4343import "./lib/Entitlements.sol " ;
44+ import "./lib/VaultAuthenticator.sol " ;
4445import "./lib/BeaconSalts.sol " ;
4546
4647import "./interfaces/IHookOptionExercisableVaultValidator.sol " ;
@@ -70,7 +71,6 @@ contract HookAmericanOptionImplV1 is
7071 /// @param expiration The expiration time of the put option
7172 /// @param assetId the asset id of the cash within the vault. This cash is the strike price
7273 /// @param vaultAddress the address of the vault holding the cash securing the put
73- /// @param exercisableAssetAddress the address of the asset that can be used to exercise the put
7474 /// @param exercisableAssetIdStart the first token id that can be used to exercise the put (inclusive)
7575 /// @param exercisableAssetIdEnd the last token id that can be used to exercise the put (inclusive)
7676 /// @param settled a flag that marks when a settlement action has taken place successfully. Once this flag is set, ETH should not
@@ -80,7 +80,7 @@ contract HookAmericanOptionImplV1 is
8080 uint32 expiration;
8181 address considerationAssetVaultAddress;
8282 uint32 considerationAssetVaultId;
83- bytes32 exercisableAssetVaultParameter;
83+ bytes exercisableAssetVaultParameter;
8484 bool settled;
8585 }
8686
@@ -90,15 +90,17 @@ contract HookAmericanOptionImplV1 is
9090 /// the associated option instrument NFT.
9191 Counters.Counter private _optionIds;
9292
93+ /// @dev the address of the factory in the Hook protocol that can be used to generate ERC721 vaults
94+ address private _erc721VaultFactory;
95+ address private _erc20VaultFactory;
96+
9397 /// @dev the address of the deployed hook protocol contract, which has permissions and access controls
9498 IHookProtocol private _protocol;
9599
96100 /// @dev storage of all existing options contracts.
97101 mapping (uint256 => Option) public optionParams;
98102
99103 address public collateralAssetAddress;
100-
101- address public exercisableAssetAddress;
102104
103105 /// @dev storage of current active put option secured by a specific asset
104106 /// mapping(vaultAddress => mapping(assetId => Options))
@@ -134,15 +136,19 @@ contract HookAmericanOptionImplV1 is
134136 function initialize (
135137 address protocol ,
136138 address _collateralAssetAddress ,
137- address _exercisableAssetAddress ,
138139 address validator ,
139- address preApprovedMarketplace
140+ address preApprovedMarketplace ,
141+ address erc20VaultFactory ,
142+ address erc721VaultFactory
140143 ) public initializer {
141144 _protocol = IHookProtocol (protocol);
142145 _preApprovedMarketplace = preApprovedMarketplace;
146+
143147 vaultValidator = IHookOptionExercisableVaultValidator (validator);
144148 collateralAssetAddress = _collateralAssetAddress;
145- exercisableAssetAddress = _exercisableAssetAddress;
149+
150+ _erc20VaultFactory = erc20VaultFactory;
151+ _erc721VaultFactory = erc721VaultFactory;
146152
147153 /// Initialize basic configuration.
148154 /// Even though these are defaults, we cannot set them in the constructor because
@@ -157,7 +163,7 @@ contract HookAmericanOptionImplV1 is
157163 function mintWithVault (
158164 address vaultAddress ,
159165 uint32 assetId ,
160- bytes32 vaultValidatorParams ,
166+ bytes calldata vaultValidatorParams ,
161167 uint32 expirationTime ,
162168 Signatures.Signature calldata signature
163169 ) external nonReentrant whenNotPaused returns (uint256 ) {
@@ -170,7 +176,8 @@ contract HookAmericanOptionImplV1 is
170176 require (
171177 _allowedVaultImplementation (
172178 vaultAddress,
173- collateralAssetAddress
179+ collateralAssetAddress,
180+ assetId
174181 ),
175182 "mWV-can only mint with protocol vaults "
176183 );
@@ -194,13 +201,13 @@ contract HookAmericanOptionImplV1 is
194201 );
195202
196203 return
197- _mintOptionWithVault (writer, vault, assetId, vaultValidatorParams, expirationTime );
204+ _mintOptionWithVault (writer, vault, assetId, expirationTime, vaultValidatorParams );
198205 }
199206
200207 function mintWithEntitledVault (
201208 address vaultAddress ,
202209 uint32 assetId ,
203- bytes32 vaultValidatorParams ,
210+ bytes calldata vaultValidatorParams ,
204211 uint32 expirationTime
205212 ) external nonReentrant whenNotPaused returns (uint256 ) {
206213 IHookVault vault = IHookVault (vaultAddress);
@@ -225,7 +232,8 @@ contract HookAmericanOptionImplV1 is
225232 require (
226233 _allowedVaultImplementation (
227234 vaultAddress,
228- collateralAssetAddress
235+ collateralAssetAddress,
236+ assetId
229237 ),
230238 "mWEV-only protocol vaults allowed "
231239 );
@@ -240,7 +248,7 @@ contract HookAmericanOptionImplV1 is
240248 );
241249
242250 return
243- _mintOptionWithVault (writer, vault, assetId, vaultValidatorParams, expirationTime );
251+ _mintOptionWithVault (writer, vault, assetId, expirationTime, vaultValidatorParams );
244252 }
245253
246254 /// @notice internal use function to record the option and mint it
@@ -254,8 +262,8 @@ contract HookAmericanOptionImplV1 is
254262 address writer ,
255263 IHookVault vault ,
256264 uint32 assetId ,
257- bytes32 param ,
258- uint32 expirationTime
265+ uint32 expirationTime ,
266+ bytes calldata param
259267 ) private returns (uint256 ) {
260268 // NOTE: The settlement auction always occurs one day before expiration
261269 require (
@@ -314,24 +322,10 @@ contract HookAmericanOptionImplV1 is
314322 /// @param underlyingAddress address of underlying asset
315323 function _allowedVaultImplementation (
316324 address vaultAddress ,
317- address underlyingAddress
325+ address underlyingAddress ,
326+ uint32 assetId
318327 ) internal view returns (bool ) {
319- // First check if the multiVault is the one to save a bit of gas
320- // in the case the user is optimizing for gas savings (by using MultiVault)
321- // if (
322- // //todo: create an erc20 vault
323- // // vaultAddress ==
324- // // Create2.computeAddress(
325- // // BeaconSalts.erc20VaultSalt(underlyingAddress),
326- // // BeaconSalts.ByteCodeHash,
327- // // address(_erc20VaultFactory)
328- // // )
329- // ) {
330- // return true;
331- // }
332-
333- // return false;
334- return true ;
328+ return VaultAuthenticator.isHookERC20Vault (_erc20VaultFactory, underlyingAddress, vaultAddress) || VaultAuthenticator.isHookERC721Vault (_erc721VaultFactory, underlyingAddress, vaultAddress, assetId);
335329 }
336330
337331
@@ -348,9 +342,7 @@ return true;
348342 address optionOwner = ownerOf (optionId);
349343 require (msg .sender == optionOwner, "e-only the option owner can exercise " );
350344
351- /// TODO: use validator to ensure that the excercise vault is good
352- /// TODO: validate that excercise vault is a protocol vault
353- /// TODO: validate that the underlying asset in the vault is valid.
345+ require (vaultValidator.validate (exerciseAssetVaultAddress, assetId, put.exercisableAssetVaultParameter), "exerciseAsset invalid " );
354346
355347 // Send the option writer the underlying asset
356348 IHookVault (exerciseAssetVaultAddress).setBeneficialOwner (assetId, put.writer);
@@ -363,7 +355,7 @@ return true;
363355 _burn (optionId);
364356
365357 // set settled to prevent an additional attempt to exercise the option
366- optionParams[optionId].settled = true ;
358+ optionParams[optionId].settled = true ;
367359
368360 // TODO: settled event
369361 // emit PutSettled(optionId);
0 commit comments