• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

delvtech / hyperdrive / 13125162639

03 Feb 2025 11:47PM UTC coverage: 89.245% (-0.2%) from 89.489%
13125162639

Pull #1238

github

web-flow
Merge bd5af51f4 into 34976504d
Pull Request #1238: ERC1155 Compatibility

70 of 82 new or added lines in 5 files covered. (85.37%)

1 existing line in 1 file now uncovered.

3037 of 3403 relevant lines covered (89.24%)

325497.25 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.96
/contracts/src/external/HyperdriveTarget0.sol
1
// SPDX-License-Identifier: Apache-2.0
2
pragma solidity 0.8.24;
3

4
import { IERC20 } from "../interfaces/IERC20.sol";
5
import { IHyperdrive } from "../interfaces/IHyperdrive.sol";
6
import { IHyperdriveAdminController } from "../interfaces/IHyperdriveAdminController.sol";
7
import { IHyperdriveRead } from "../interfaces/IHyperdriveRead.sol";
8
import { HyperdriveAdmin } from "../internal/HyperdriveAdmin.sol";
9
import { HyperdriveCheckpoint } from "../internal/HyperdriveCheckpoint.sol";
10
import { HyperdriveLong } from "../internal/HyperdriveLong.sol";
11
import { HyperdriveLP } from "../internal/HyperdriveLP.sol";
12
import { HyperdriveMultiToken } from "../internal/HyperdriveMultiToken.sol";
13
import { HyperdrivePair } from "../internal/HyperdrivePair.sol";
14
import { HyperdriveShort } from "../internal/HyperdriveShort.sol";
15
import { HyperdriveStorage } from "../internal/HyperdriveStorage.sol";
16
import { AssetId } from "../libraries/AssetId.sol";
17
import { VERSION } from "../libraries/Constants.sol";
18
import { FixedPointMath } from "../libraries/FixedPointMath.sol";
19
import { LPMath } from "../libraries/LPMath.sol";
20

21
/// @author DELV
22
/// @title HyperdriveTarget0
23
/// @notice Hyperdrive's target 0 logic contract.
24
/// @custom:disclaimer The language used in this code is for coding convenience
25
///                    only, and is not intended to, and does not, have any
26
///                    particular legal or regulatory significance.
27
abstract contract HyperdriveTarget0 is
28
    IHyperdriveRead,
29
    HyperdriveAdmin,
30
    HyperdriveMultiToken,
31
    HyperdriveLP,
32
    HyperdriveLong,
33
    HyperdriveShort,
34
    HyperdrivePair,
35
    HyperdriveCheckpoint
36
{
37
    using FixedPointMath for uint256;
38

39
    /// @notice Instantiates target0.
40
    /// @param _config The configuration of the Hyperdrive pool.
41
    /// @param __adminController The admin controller that will specify the
42
    ///        admin parameters for this contract.
43
    constructor(
44
        IHyperdrive.PoolConfig memory _config,
45
        IHyperdriveAdminController __adminController
46
    ) HyperdriveStorage(_config, __adminController) {}
47

48
    /// Admin ///
49

50
    // TODO: This function doesn't do anything anymore and is only here for
51
    // backwards compatability. This can be removed when the factory is upgraded.
52
    //
53
    /// @notice A stub for the old setPauser functions that doesn't do anything
54
    ///         anymore.
55
    /// @dev Don't call this. It doesn't do anything.
56
    function setGovernance(address) external {}
57

58
    // TODO: This function doesn't do anything anymore and is only here for
59
    // backwards compatability. This can be removed when the factory is upgraded.
60
    //
61
    /// @notice A stub for the old setPauser functions that doesn't do anything
62
    ///         anymore.
63
    /// @dev Don't call this. It doesn't do anything.
64
    function setPauser(address, bool) external {}
65

66
    /// @notice This function collects the governance fees accrued by the pool.
67
    /// @param _options The options that configure how the fees are settled.
68
    /// @return proceeds The governance fees collected. The units of this
69
    ///         quantity are either base or vault shares, depending on the value
70
    ///         of `_options.asBase`.
71
    function collectGovernanceFee(
72
        IHyperdrive.Options calldata _options
73
    ) external returns (uint256 proceeds) {
74
        return _collectGovernanceFee(_options);
5✔
75
    }
76

77
    /// @notice Allows an authorized address to pause this contract.
78
    /// @param _status True to pause all deposits and false to unpause them.
79
    function pause(bool _status) external {
80
        _pause(_status);
11✔
81
    }
82

83
    /// @notice Transfers the contract's balance of a target token to the sweep
84
    ///         collector address.
85
    /// @dev WARN: It is unlikely but possible that there is a selector overlap
86
    ///      with 'transfer'. Any integrating contracts should be checked
87
    ///      for that, as it may result in an unexpected call from this address.
88
    /// @param _target The target token to sweep.
89
    function sweep(IERC20 _target) external {
90
        _sweep(_target);
77✔
91
    }
92

93
    /// MultiToken ///
94

95
    /// @notice Permissioned transfer for the bridge to access, only callable by
96
    ///         the ERC20 linking bridge.
97
    /// @param tokenID The token identifier.
98
    /// @param from The address whose balance will be reduced.
99
    /// @param to The address whose balance will be increased.
100
    /// @param amount The amount of token to move.
101
    /// @param caller The msg.sender from the bridge.
102
    function transferFromBridge(
103
        uint256 tokenID,
104
        address from,
105
        address to,
106
        uint256 amount,
107
        address caller
108
    ) external onlyLinker(tokenID) {
109
        // Route to our internal transfer
110
        _transferFrom(tokenID, from, to, amount, caller);
101✔
111
    }
112

113
    /// @notice Allows the compatibility linking contract to forward calls to
114
    ///         set asset approvals.
115
    /// @param tokenID The asset to approve the use of.
116
    /// @param operator The address who will be able to use the tokens.
117
    /// @param amount The max tokens the approved person can use, setting to
118
    ///        uint256.max will cause the value to never decrement [saving gas
119
    ///        on transfer].
120
    /// @param caller The eth address which called the linking contract.
121
    function setApprovalBridge(
122
        uint256 tokenID,
123
        address operator,
124
        uint256 amount,
125
        address caller
126
    ) external onlyLinker(tokenID) {
127
        _setApproval(tokenID, operator, amount, caller);
4✔
128
    }
129

130
    /// @notice Allows a user to approve an operator to use all of their assets.
131
    /// @param operator The eth address which can access the caller's assets.
132
    /// @param approved True to approve, false to remove approval.
133
    function setApprovalForAll(address operator, bool approved) external {
134
        // set the appropriate state
135
        _isApprovedForAll[msg.sender][operator] = approved;
66✔
136
        // Emit an event to track approval
137
        emit ApprovalForAll(msg.sender, operator, approved);
66✔
138
    }
139

140
    /// @notice Allows a user to set an approval for an individual asset with
141
    ///         specific amount.
142
    /// @param tokenID The asset to approve the use of.
143
    /// @param operator The address who will be able to use the tokens.
144
    /// @param amount The max tokens the approved person can use, setting to
145
    ///        uint256.max will cause the value to never decrement (saving gas
146
    ///        on transfer).
147
    function setApproval(
148
        uint256 tokenID,
149
        address operator,
150
        uint256 amount
151
    ) external {
152
        _setApproval(tokenID, operator, amount, msg.sender);
189✔
153
    }
154

155
    /// @dev Safely transfers tokens, checking if recipient is a contract and
156
    ///      can handle ERC1155 tokens.
157
    /// @param _from The source address.
158
    /// @param _to The destination address.
159
    /// @param _id The token identifier.
160
    /// @param _amount The amount to transfer.
161
    /// @param _data Additional data to pass to recipient if it's a contract.
162
    function safeTransferFrom(
163
        address _from,
164
        address _to,
165
        uint256 _id,
166
        uint256 _amount,
167
        bytes calldata _data
168
    ) external {
169
        _safeTransferFrom(_from, _to, _id, _amount, _data);
27✔
170
    }
171

172
    /// @dev Safely transfers multiple tokens in a batch.
173
    /// @param _from The source address.
174
    /// @param _to The destination address.
175
    /// @param _ids Array of token identifiers.
176
    /// @param _amounts Array of amounts to transfer for each token.
177
    /// @param _data Additional data to pass to recipient if it's a contract.
178
    function safeBatchTransferFrom(
179
        address _from,
180
        address _to,
181
        uint256[] calldata _ids,
182
        uint256[] calldata _amounts,
183
        bytes calldata _data
184
    ) external {
185
        _safeBatchTransferFrom(_from, _to, _ids, _amounts, _data);
10✔
186
    }
187

188
    /// @notice Allows a caller who is not the owner of an account to execute
189
    ///         the functionality of 'approve' for all assets with the owner's
190
    ///         signature.
191
    /// @param domainSeparator The EIP712 domain separator of the contract.
192
    /// @param permitTypeHash The EIP712 domain separator of the contract.
193
    /// @param owner The owner of the account which is having the new approval set.
194
    /// @param spender The address which will be allowed to spend owner's tokens.
195
    /// @param _approved A boolean of the approval status to set to.
196
    /// @param deadline The timestamp which the signature must be submitted by
197
    ///        to be valid.
198
    /// @param v Extra ECDSA data which allows public key recovery from
199
    ///        signature assumed to be 27 or 28.
200
    /// @param r The r component of the ECDSA signature.
201
    /// @param s The s component of the ECDSA signature.
202
    /// @dev The signature for this function follows EIP 712 standard and should
203
    ///      be generated with the eth_signTypedData JSON RPC call instead of
204
    ///      the eth_sign JSON RPC call. If using out of date parity signing
205
    ///      libraries the v component may need to be adjusted. Also it is very
206
    ///      rare but possible for v to be other values, those values are not
207
    ///      supported.
208
    function permitForAll(
209
        bytes32 domainSeparator,
210
        bytes32 permitTypeHash,
211
        address owner,
212
        address spender,
213
        bool _approved,
214
        uint256 deadline,
215
        uint8 v,
216
        bytes32 r,
217
        bytes32 s
218
    ) external {
219
        _permitForAll(
8✔
220
            domainSeparator,
221
            permitTypeHash,
222
            owner,
223
            spender,
224
            _approved,
225
            deadline,
226
            v,
227
            r,
228
            s
229
        );
230
    }
231

232
    /// Getters ///
233

234
    /// @notice Gets the instance's name.
235
    /// @return The instance's name.
236
    function name() external view returns (string memory) {
237
        _revert(abi.encode(_name));
171✔
238
    }
239

240
    /// @notice Gets the instance's kind.
241
    /// @return The instance's kind.
242
    function kind() external pure virtual returns (string memory);
243

244
    /// @notice Gets the instance's version.
245
    /// @return The instance's version.
246
    function version() external pure returns (string memory) {
247
        _revert(abi.encode(VERSION));
111✔
248
    }
249

250
    /// @notice Gets the address that contains the admin configuration for this
251
    ///         instance.
252
    /// @return The admin controller address.
253
    function adminController() external view returns (address) {
254
        _revert(abi.encode(_adminController));
×
255
    }
256

257
    /// @notice Gets the pauser status of an address.
258
    /// @param _account The account to check.
259
    /// @return The pauser status.
260
    function isPauser(address _account) external view returns (bool) {
261
        _revert(abi.encode(_isPauser(_account)));
5✔
262
    }
263

264
    /// @notice Gets the base token.
265
    /// @return The base token address.
266
    function baseToken() external view returns (address) {
267
        _revert(abi.encode(_baseToken));
16,686✔
268
    }
269

270
    /// @notice Gets the vault shares token.
271
    /// @return The vault shares token address.
272
    function vaultSharesToken() external view returns (address) {
273
        _revert(abi.encode(_vaultSharesToken));
5,859✔
274
    }
275

276
    /// @notice Gets a specified checkpoint.
277
    /// @param _checkpointTime The checkpoint time.
278
    /// @return The checkpoint.
279
    function getCheckpoint(
280
        uint256 _checkpointTime
281
    ) external view returns (IHyperdrive.Checkpoint memory) {
282
        _revert(abi.encode(_checkpoints[_checkpointTime]));
21,422✔
283
    }
284

285
    /// @notice Gets the checkpoint exposure at a specified time.
286
    /// @param _checkpointTime The checkpoint time.
287
    /// @return The checkpoint exposure.
288
    function getCheckpointExposure(
289
        uint256 _checkpointTime
290
    ) external view returns (int256) {
291
        _revert(
69,515✔
292
            abi.encode(_nonNettedLongs(_checkpointTime + _positionDuration))
293
        );
294
    }
295

296
    /// @notice Gets the pool's configuration parameters.
297
    /// @dev These parameters are immutable, so this should only need to be
298
    ///      called once.
299
    /// @return The PoolConfig struct.
300
    function getPoolConfig()
301
        external
302
        view
303
        returns (IHyperdrive.PoolConfig memory)
304
    {
305
        _revert(
2,092,531✔
306
            abi.encode(
307
                IHyperdrive.PoolConfig({
308
                    baseToken: _baseToken,
309
                    vaultSharesToken: _vaultSharesToken,
310
                    linkerFactory: _linkerFactory,
311
                    linkerCodeHash: _linkerCodeHash,
312
                    initialVaultSharePrice: _initialVaultSharePrice,
313
                    minimumShareReserves: _minimumShareReserves,
314
                    minimumTransactionAmount: _minimumTransactionAmount,
315
                    circuitBreakerDelta: _circuitBreakerDelta,
316
                    positionDuration: _positionDuration,
317
                    checkpointDuration: _checkpointDuration,
318
                    timeStretch: _timeStretch,
319
                    governance: _adminController.hyperdriveGovernance(),
320
                    feeCollector: _adminController.feeCollector(),
321
                    sweepCollector: _adminController.sweepCollector(),
322
                    checkpointRewarder: _adminController.checkpointRewarder(),
323
                    fees: IHyperdrive.Fees(
324
                        _curveFee,
325
                        _flatFee,
326
                        _governanceLPFee,
327
                        _governanceZombieFee
328
                    )
329
                })
330
            )
331
        );
332
    }
333

334
    /// @notice Gets info about the pool's reserves and other state that is
335
    ///         important to evaluate potential trades.
336
    /// @return The pool info.
337
    function getPoolInfo() external view returns (IHyperdrive.PoolInfo memory) {
338
        uint256 vaultSharePrice = _pricePerVaultShare();
242,780✔
339
        uint256 lpTotalSupply = _totalSupply[AssetId._LP_ASSET_ID] +
242,780✔
340
            _totalSupply[AssetId._WITHDRAWAL_SHARE_ASSET_ID] -
341
            _withdrawPool.readyToWithdraw;
342
        uint256 presentValue;
242,780✔
343
        if (vaultSharePrice > 0) {
242,780✔
344
            (presentValue, ) = LPMath.calculatePresentValueSafe(
242,180✔
345
                _getPresentValueParams(vaultSharePrice)
346
            );
347
            presentValue = presentValue.mulDown(vaultSharePrice);
242,180✔
348
        }
349
        IHyperdrive.PoolInfo memory poolInfo = IHyperdrive.PoolInfo({
242,780✔
350
            shareReserves: _marketState.shareReserves,
351
            shareAdjustment: _marketState.shareAdjustment,
352
            zombieBaseProceeds: _marketState.zombieBaseProceeds,
353
            zombieShareReserves: _marketState.zombieShareReserves,
354
            bondReserves: _marketState.bondReserves,
355
            vaultSharePrice: vaultSharePrice,
356
            longsOutstanding: _marketState.longsOutstanding,
357
            longAverageMaturityTime: _marketState.longAverageMaturityTime,
358
            shortsOutstanding: _marketState.shortsOutstanding,
359
            shortAverageMaturityTime: _marketState.shortAverageMaturityTime,
360
            lpTotalSupply: lpTotalSupply,
361
            lpSharePrice: lpTotalSupply == 0
362
                ? 0
363
                : presentValue.divDown(lpTotalSupply),
364
            withdrawalSharesReadyToWithdraw: _withdrawPool.readyToWithdraw,
365
            withdrawalSharesProceeds: _withdrawPool.proceeds,
366
            longExposure: _marketState.longExposure
367
        });
368
        _revert(abi.encode(poolInfo));
242,780✔
369
    }
370

371
    /// @notice Gets information about the withdrawal pool.
372
    /// @return Hyperdrive's withdrawal pool information.
373
    function getWithdrawPool()
374
        external
375
        view
376
        returns (IHyperdrive.WithdrawPool memory)
377
    {
378
        _revert(
2✔
379
            abi.encode(
380
                IHyperdrive.WithdrawPool({
381
                    readyToWithdraw: _withdrawPool.readyToWithdraw,
382
                    proceeds: _withdrawPool.proceeds
383
                })
384
            )
385
        );
386
    }
387

388
    /// @notice Gets info about the fees presently accrued by the pool.
389
    /// @return Governance fees denominated in shares yet to be collected.
390
    function getUncollectedGovernanceFees() external view returns (uint256) {
391
        _revert(abi.encode(_governanceFeesAccrued));
3,425✔
392
    }
393

394
    /// @notice Gets the market state.
395
    /// @return The market state.
396
    function getMarketState()
397
        external
398
        view
399
        returns (IHyperdrive.MarketState memory)
400
    {
401
        _revert(abi.encode(_marketState));
13✔
402
    }
403

404
    /// @notice Allows plugin data libs to provide getters or other complex
405
    ///         logic instead of the main.
406
    /// @param _slots The storage slots the caller wants the data from.
407
    /// @return A raw array of loaded data.
408
    function load(
409
        uint256[] calldata _slots
410
    ) external view returns (bytes32[] memory) {
411
        bytes32[] memory loaded = new bytes32[](_slots.length);
1✔
412

413
        // Iterate on requested loads and then do them.
414
        for (uint256 i = 0; i < _slots.length; i++) {
1✔
415
            uint256 slot = _slots[i];
2✔
416
            bytes32 data;
2✔
417
            assembly ("memory-safe") {
418
                data := sload(slot)
2✔
419
            }
420
            loaded[i] = data;
2✔
421
        }
422

423
        _revert(abi.encode(loaded));
1✔
424
    }
425

426
    /// @notice Convert an amount of vault shares to an amount of base.
427
    /// @dev This is a convenience method that allows developers to convert from
428
    ///      vault shares to base without knowing the specifics of the
429
    ///      integration.
430
    /// @param _shareAmount The vault shares amount.
431
    /// @return baseAmount The base amount.
432
    function convertToBase(
433
        uint256 _shareAmount
434
    ) external view returns (uint256) {
435
        _revert(abi.encode(_convertToBase(_shareAmount)));
32,314✔
436
    }
437

438
    /// @notice Convert an amount of base to an amount of vault shares.
439
    /// @dev This is a convenience method that allows developers to convert from
440
    ///      base to vault shares without knowing the specifics of the
441
    ///      integration.
442
    /// @param _baseAmount The base amount.
443
    /// @return shareAmount The vault shares amount.
444
    function convertToShares(
445
        uint256 _baseAmount
446
    ) external view returns (uint256) {
447
        _revert(abi.encode(_convertToShares(_baseAmount)));
50,498✔
448
    }
449

450
    /// @notice Gets the total amount of vault shares held by Hyperdrive.
451
    /// @dev This is a convenience method that allows developers to get the
452
    ///      total amount of vault shares without knowing the specifics of the
453
    ///      integration.
454
    /// @return The total amount of vault shares held by Hyperdrive.
455
    function totalShares() external view returns (uint256) {
456
        _revert(abi.encode(_totalShares()));
3,034✔
457
    }
458

459
    /// @notice Gets an account's balance of a sub-token.
460
    /// @param _tokenId The sub-token id.
461
    /// @param _account The account.
462
    /// @return The balance.
463
    function balanceOf(
464
        uint256 _tokenId,
465
        address _account
466
    ) external view returns (uint256) {
467
        _revert(abi.encode(_balanceOf[_tokenId][_account]));
26,042✔
468
    }
469

470
    /// @notice Gets multiple accounts' balances for multiple token IDs.
471
    /// @param _accounts Array of addresses to check balances for.
472
    /// @param _ids Array of token IDs to check balances of.
473
    /// @return Array of token balances.
474
    function balanceOfBatch(
475
        address[] calldata _accounts,
476
        uint256[] calldata _ids
477
    ) external view returns (uint256[] memory) {
478
        // Check that input arrays match in length.
NEW
479
        if (_accounts.length != _ids.length) {
×
NEW
480
            revert IHyperdrive.BatchInputLengthMismatch();
×
481
        }
482

483
        // Load the balances.
NEW
484
        uint256[] memory batchBalances = new uint256[](_accounts.length);
×
NEW
485
        uint256 length = _accounts.length;
×
NEW
486
        for (uint256 i = 0; i < length; ++i) {
×
NEW
487
            batchBalances[i] = _balanceOf[_ids[i]][_accounts[i]];
×
488
        }
489

NEW
490
        _revert(abi.encode(batchBalances));
×
491
    }
492

493
    /// @notice Gets the total supply of a sub-token.
494
    /// @param tokenId The sub-token id.
495
    /// @return The total supply.
496
    function totalSupply(uint256 tokenId) external view returns (uint256) {
497
        _revert(abi.encode(_totalSupply[tokenId]));
46,459✔
498
    }
499

500
    /// @notice Gets the approval status of an operator for an account.
501
    /// @param account The account.
502
    /// @param operator The operator.
503
    /// @return The approval status.
504
    function isApprovedForAll(
505
        address account,
506
        address operator
507
    ) external view returns (bool) {
508
        _revert(abi.encode(_isApprovedForAll[account][operator]));
10✔
509
    }
510

511
    /// @notice Gets the approval status of an operator for an account.
512
    /// @param tokenId The sub-token id.
513
    /// @param account The account.
514
    /// @param spender The spender.
515
    /// @return The approval status.
516
    function perTokenApprovals(
517
        uint256 tokenId,
518
        address account,
519
        address spender
520
    ) external view returns (uint256) {
521
        _revert(abi.encode(_perTokenApprovals[tokenId][account][spender]));
72✔
522
    }
523

524
    /// @notice Gets the decimals of the MultiToken. This is the same as the
525
    ///         decimals used by the base token.
526
    /// @return The decimals of the MultiToken.
527
    function decimals() external view virtual returns (uint8) {
528
        _revert(abi.encode(_baseToken.decimals()));
44✔
529
    }
530

531
    /// @notice Gets the name of a sub-token.
532
    /// @param tokenId The sub-token id.
533
    /// @return The name.
534
    function name(uint256 tokenId) external pure returns (string memory) {
535
        _revert(abi.encode(AssetId.assetIdToName(tokenId)));
2✔
536
    }
537

538
    /// @notice Gets the symbol of a sub-token.
539
    /// @param tokenId The sub-token id.
540
    /// @return The symbol.
541
    function symbol(uint256 tokenId) external pure returns (string memory) {
542
        _revert(abi.encode(AssetId.assetIdToSymbol(tokenId)));
2✔
543
    }
544

545
    /// @notice Gets the permitForAll signature nonce for an account.
546
    /// @param account The account.
547
    /// @return The signature nonce.
548
    function nonces(address account) external view returns (uint256) {
549
        _revert(abi.encode(_nonces[account]));
9✔
550
    }
551

552
    /// Helpers ///
553

554
    /// @dev Reverts with the provided bytes. This is useful in getters used
555
    ///      with the force-revert delegatecall pattern.
556
    /// @param _bytes The bytes to revert with.
557
    function _revert(bytes memory _bytes) internal pure {
558
        revert IHyperdrive.ReturnData(_bytes);
2,613,019✔
559
    }
560
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc