-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathHyperdriveTarget0.sol
More file actions
555 lines (504 loc) · 21.5 KB
/
HyperdriveTarget0.sol
File metadata and controls
555 lines (504 loc) · 21.5 KB
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.24;
import { IERC20 } from "../interfaces/IERC20.sol";
import { IHyperdrive } from "../interfaces/IHyperdrive.sol";
import { IHyperdriveAdminController } from "../interfaces/IHyperdriveAdminController.sol";
import { IHyperdriveRead } from "../interfaces/IHyperdriveRead.sol";
import { HyperdriveAdmin } from "../internal/HyperdriveAdmin.sol";
import { HyperdriveCheckpoint } from "../internal/HyperdriveCheckpoint.sol";
import { HyperdriveLong } from "../internal/HyperdriveLong.sol";
import { HyperdriveLP } from "../internal/HyperdriveLP.sol";
import { HyperdriveMultiToken } from "../internal/HyperdriveMultiToken.sol";
import { HyperdrivePair } from "../internal/HyperdrivePair.sol";
import { HyperdriveShort } from "../internal/HyperdriveShort.sol";
import { HyperdriveStorage } from "../internal/HyperdriveStorage.sol";
import { AssetId } from "../libraries/AssetId.sol";
import { VERSION } from "../libraries/Constants.sol";
import { FixedPointMath } from "../libraries/FixedPointMath.sol";
import { LPMath } from "../libraries/LPMath.sol";
/// @author DELV
/// @title HyperdriveTarget0
/// @notice Hyperdrive's target 0 logic contract.
/// @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.
abstract contract HyperdriveTarget0 is
IHyperdriveRead,
HyperdriveAdmin,
HyperdriveMultiToken,
HyperdriveLP,
HyperdriveLong,
HyperdriveShort,
HyperdrivePair,
HyperdriveCheckpoint
{
using FixedPointMath for uint256;
/// @notice Instantiates target0.
/// @param _config The configuration of the Hyperdrive pool.
/// @param __adminController The admin controller that will specify the
/// admin parameters for this contract.
constructor(
IHyperdrive.PoolConfig memory _config,
IHyperdriveAdminController __adminController
) HyperdriveStorage(_config, __adminController) {}
/// Admin ///
// TODO: This function doesn't do anything anymore and is only here for
// backwards compatability. This can be removed when the factory is upgraded.
//
/// @notice A stub for the old setPauser functions that doesn't do anything
/// anymore.
/// @dev Don't call this. It doesn't do anything.
function setGovernance(address) external {}
// TODO: This function doesn't do anything anymore and is only here for
// backwards compatability. This can be removed when the factory is upgraded.
//
/// @notice A stub for the old setPauser functions that doesn't do anything
/// anymore.
/// @dev Don't call this. It doesn't do anything.
function setPauser(address, bool) external {}
/// @notice This function collects the governance fees accrued by the pool.
/// @param _options The options that configure how the fees are settled.
/// @return proceeds The governance fees collected. The units of this
/// quantity are either base or vault shares, depending on the value
/// of `_options.asBase`.
function collectGovernanceFee(
IHyperdrive.Options calldata _options
) external returns (uint256 proceeds) {
return _collectGovernanceFee(_options);
}
/// @notice Allows an authorized address to pause this contract.
/// @param _status True to pause all deposits and false to unpause them.
function pause(bool _status) external {
_pause(_status);
}
/// @notice Transfers the contract's balance of a target token to the sweep
/// collector address.
/// @dev WARN: It is unlikely but possible that there is a selector overlap
/// with 'transfer'. Any integrating contracts should be checked
/// for that, as it may result in an unexpected call from this address.
/// @param _target The target token to sweep.
function sweep(IERC20 _target) external {
_sweep(_target);
}
/// MultiToken ///
/// @notice Permissioned transfer for the bridge to access, only callable by
/// the ERC20 linking bridge.
/// @param tokenID The token identifier.
/// @param from The address whose balance will be reduced.
/// @param to The address whose balance will be increased.
/// @param amount The amount of token to move.
/// @param caller The msg.sender from the bridge.
function transferFromBridge(
uint256 tokenID,
address from,
address to,
uint256 amount,
address caller
) external onlyLinker(tokenID) {
// Route to our internal transfer
_transferFrom(tokenID, from, to, amount, caller);
}
/// @notice Allows the compatibility linking contract to forward calls to
/// set asset approvals.
/// @param tokenID The asset to approve the use of.
/// @param operator The address who will be able to use the tokens.
/// @param amount The max tokens the approved person can use, setting to
/// uint256.max will cause the value to never decrement [saving gas
/// on transfer].
/// @param caller The eth address which called the linking contract.
function setApprovalBridge(
uint256 tokenID,
address operator,
uint256 amount,
address caller
) external onlyLinker(tokenID) {
_setApproval(tokenID, operator, amount, caller);
}
/// @notice Allows a user to approve an operator to use all of their assets.
/// @param operator The eth address which can access the caller's assets.
/// @param approved True to approve, false to remove approval.
function setApprovalForAll(address operator, bool approved) external {
// set the appropriate state
_isApprovedForAll[msg.sender][operator] = approved;
// Emit an event to track approval
emit ApprovalForAll(msg.sender, operator, approved);
}
/// @notice Allows a user to set an approval for an individual asset with
/// specific amount.
/// @param tokenID The asset to approve the use of.
/// @param operator The address who will be able to use the tokens.
/// @param amount The max tokens the approved person can use, setting to
/// uint256.max will cause the value to never decrement (saving gas
/// on transfer).
function setApproval(
uint256 tokenID,
address operator,
uint256 amount
) external {
_setApproval(tokenID, operator, amount, msg.sender);
}
/// @dev Safely transfers multiple tokens in a batch.
/// @param _from The source address.
/// @param _to The destination address.
/// @param _ids Array of token identifiers.
/// @param _amounts Array of amounts to transfer for each token.
/// @param _data Additional data to pass to recipient if it's a contract.
function safeBatchTransferFrom(
address _from,
address _to,
uint256[] calldata _ids,
uint256[] calldata _amounts,
bytes calldata _data
) external {
_safeBatchTransferFrom(_from, _to, _ids, _amounts, _data);
}
/// @notice Allows a caller who is not the owner of an account to execute
/// the functionality of 'approve' for all assets with the owner's
/// signature.
/// @param domainSeparator The EIP712 domain separator of the contract.
/// @param permitTypeHash The EIP712 domain separator of the contract.
/// @param owner The owner of the account which is having the new approval set.
/// @param spender The address which will be allowed to spend owner's tokens.
/// @param _approved A boolean of the approval status to set to.
/// @param deadline The timestamp which the signature must be submitted by
/// to be valid.
/// @param v Extra ECDSA data which allows public key recovery from
/// signature assumed to be 27 or 28.
/// @param r The r component of the ECDSA signature.
/// @param s The s component of the ECDSA signature.
/// @dev The signature for this function follows EIP 712 standard and should
/// be generated with the eth_signTypedData JSON RPC call instead of
/// the eth_sign JSON RPC call. If using out of date parity signing
/// libraries the v component may need to be adjusted. Also it is very
/// rare but possible for v to be other values, those values are not
/// supported.
function permitForAll(
bytes32 domainSeparator,
bytes32 permitTypeHash,
address owner,
address spender,
bool _approved,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external {
_permitForAll(
domainSeparator,
permitTypeHash,
owner,
spender,
_approved,
deadline,
v,
r,
s
);
}
/// Getters ///
/// @notice Gets the instance's name.
/// @return The instance's name.
function name() external view returns (string memory) {
_revert(abi.encode(_name));
}
/// @notice Gets the instance's kind.
/// @return The instance's kind.
function kind() external pure virtual returns (string memory);
/// @notice Gets the instance's version.
/// @return The instance's version.
function version() external pure returns (string memory) {
_revert(abi.encode(VERSION));
}
/// @notice Gets the address that contains the admin configuration for this
/// instance.
/// @return The admin controller address.
function adminController() external view returns (address) {
_revert(abi.encode(_adminController));
}
/// @notice Gets the pauser status of an address.
/// @param _account The account to check.
/// @return The pauser status.
function isPauser(address _account) external view returns (bool) {
_revert(abi.encode(_isPauser(_account)));
}
/// @notice Gets the base token.
/// @return The base token address.
function baseToken() external view returns (address) {
_revert(abi.encode(_baseToken));
}
/// @notice Gets the vault shares token.
/// @return The vault shares token address.
function vaultSharesToken() external view returns (address) {
_revert(abi.encode(_vaultSharesToken));
}
/// @notice Gets a specified checkpoint.
/// @param _checkpointTime The checkpoint time.
/// @return The checkpoint.
function getCheckpoint(
uint256 _checkpointTime
) external view returns (IHyperdrive.Checkpoint memory) {
_revert(abi.encode(_checkpoints[_checkpointTime]));
}
/// @notice Gets the checkpoint exposure at a specified time.
/// @param _checkpointTime The checkpoint time.
/// @return The checkpoint exposure.
function getCheckpointExposure(
uint256 _checkpointTime
) external view returns (int256) {
_revert(
abi.encode(_nonNettedLongs(_checkpointTime + _positionDuration))
);
}
/// @notice Gets the pool's configuration parameters.
/// @dev These parameters are immutable, so this should only need to be
/// called once.
/// @return The PoolConfig struct.
function getPoolConfig()
external
view
returns (IHyperdrive.PoolConfig memory)
{
_revert(
abi.encode(
IHyperdrive.PoolConfig({
baseToken: _baseToken,
vaultSharesToken: _vaultSharesToken,
linkerFactory: _linkerFactory,
linkerCodeHash: _linkerCodeHash,
initialVaultSharePrice: _initialVaultSharePrice,
minimumShareReserves: _minimumShareReserves,
minimumTransactionAmount: _minimumTransactionAmount,
circuitBreakerDelta: _circuitBreakerDelta,
positionDuration: _positionDuration,
checkpointDuration: _checkpointDuration,
timeStretch: _timeStretch,
governance: _adminController.hyperdriveGovernance(),
feeCollector: _adminController.feeCollector(),
sweepCollector: _adminController.sweepCollector(),
checkpointRewarder: _adminController.checkpointRewarder(),
fees: IHyperdrive.Fees(
_curveFee,
_flatFee,
_governanceLPFee,
_governanceZombieFee
)
})
)
);
}
/// @notice Gets info about the pool's reserves and other state that is
/// important to evaluate potential trades.
/// @return The pool info.
function getPoolInfo() external view returns (IHyperdrive.PoolInfo memory) {
uint256 vaultSharePrice = _pricePerVaultShare();
uint256 lpTotalSupply = _totalSupply[AssetId._LP_ASSET_ID] +
_totalSupply[AssetId._WITHDRAWAL_SHARE_ASSET_ID] -
_withdrawPool.readyToWithdraw;
uint256 presentValue;
if (vaultSharePrice > 0) {
(presentValue, ) = LPMath.calculatePresentValueSafe(
_getPresentValueParams(vaultSharePrice)
);
presentValue = presentValue.mulDown(vaultSharePrice);
}
IHyperdrive.PoolInfo memory poolInfo = IHyperdrive.PoolInfo({
shareReserves: _marketState.shareReserves,
shareAdjustment: _marketState.shareAdjustment,
zombieBaseProceeds: _marketState.zombieBaseProceeds,
zombieShareReserves: _marketState.zombieShareReserves,
bondReserves: _marketState.bondReserves,
vaultSharePrice: vaultSharePrice,
longsOutstanding: _marketState.longsOutstanding,
longAverageMaturityTime: _marketState.longAverageMaturityTime,
shortsOutstanding: _marketState.shortsOutstanding,
shortAverageMaturityTime: _marketState.shortAverageMaturityTime,
lpTotalSupply: lpTotalSupply,
lpSharePrice: lpTotalSupply == 0
? 0
: presentValue.divDown(lpTotalSupply),
withdrawalSharesReadyToWithdraw: _withdrawPool.readyToWithdraw,
withdrawalSharesProceeds: _withdrawPool.proceeds,
longExposure: _marketState.longExposure
});
_revert(abi.encode(poolInfo));
}
/// @notice Gets information about the withdrawal pool.
/// @return Hyperdrive's withdrawal pool information.
function getWithdrawPool()
external
view
returns (IHyperdrive.WithdrawPool memory)
{
_revert(
abi.encode(
IHyperdrive.WithdrawPool({
readyToWithdraw: _withdrawPool.readyToWithdraw,
proceeds: _withdrawPool.proceeds
})
)
);
}
/// @notice Gets info about the fees presently accrued by the pool.
/// @return Governance fees denominated in shares yet to be collected.
function getUncollectedGovernanceFees() external view returns (uint256) {
_revert(abi.encode(_governanceFeesAccrued));
}
/// @notice Gets the market state.
/// @return The market state.
function getMarketState()
external
view
returns (IHyperdrive.MarketState memory)
{
_revert(abi.encode(_marketState));
}
/// @notice Allows plugin data libs to provide getters or other complex
/// logic instead of the main.
/// @param _slots The storage slots the caller wants the data from.
/// @return A raw array of loaded data.
function load(
uint256[] calldata _slots
) external view returns (bytes32[] memory) {
bytes32[] memory loaded = new bytes32[](_slots.length);
// Iterate on requested loads and then do them.
for (uint256 i = 0; i < _slots.length; i++) {
uint256 slot = _slots[i];
bytes32 data;
assembly ("memory-safe") {
data := sload(slot)
}
loaded[i] = data;
}
_revert(abi.encode(loaded));
}
/// @notice Convert an amount of vault shares to an amount of base.
/// @dev This is a convenience method that allows developers to convert from
/// vault shares to base without knowing the specifics of the
/// integration.
/// @param _shareAmount The vault shares amount.
/// @return baseAmount The base amount.
function convertToBase(
uint256 _shareAmount
) external view returns (uint256) {
_revert(abi.encode(_convertToBase(_shareAmount)));
}
/// @notice Convert an amount of base to an amount of vault shares.
/// @dev This is a convenience method that allows developers to convert from
/// base to vault shares without knowing the specifics of the
/// integration.
/// @param _baseAmount The base amount.
/// @return shareAmount The vault shares amount.
function convertToShares(
uint256 _baseAmount
) external view returns (uint256) {
_revert(abi.encode(_convertToShares(_baseAmount)));
}
/// @notice Gets the total amount of vault shares held by Hyperdrive.
/// @dev This is a convenience method that allows developers to get the
/// total amount of vault shares without knowing the specifics of the
/// integration.
/// @return The total amount of vault shares held by Hyperdrive.
function totalShares() external view returns (uint256) {
_revert(abi.encode(_totalShares()));
}
/// @notice Gets an account's balance of a sub-token.
/// @param _tokenId The sub-token id.
/// @param _account The account.
/// @return The balance.
function balanceOf(
uint256 _tokenId,
address _account
) external view returns (uint256) {
_revert(abi.encode(_balanceOf[_tokenId][_account]));
}
/// @notice Gets multiple accounts' balances for multiple token IDs.
/// @param _accounts Array of addresses to check balances for.
/// @param _ids Array of token IDs to check balances of.
/// @return Array of token balances.
function balanceOfBatch(
address[] calldata _accounts,
uint256[] calldata _ids
) external view returns (uint256[] memory) {
// Check that input arrays match in length.
if (_accounts.length != _ids.length) {
revert IHyperdrive.BatchInputLengthMismatch();
}
// Load the balances.
uint256[] memory batchBalances = new uint256[](_accounts.length);
uint256 length = _accounts.length;
for (uint256 i = 0; i < length; ++i) {
batchBalances[i] = _balanceOf[_ids[i]][_accounts[i]];
}
_revert(abi.encode(batchBalances));
}
/// @notice Gets the total supply of a sub-token.
/// @param tokenId The sub-token id.
/// @return The total supply.
function totalSupply(uint256 tokenId) external view returns (uint256) {
_revert(abi.encode(_totalSupply[tokenId]));
}
/// @notice Gets the approval status of an operator for an account.
/// @param account The account.
/// @param operator The operator.
/// @return The approval status.
function isApprovedForAll(
address account,
address operator
) external view returns (bool) {
_revert(abi.encode(_isApprovedForAll[account][operator]));
}
/// @notice Gets the approval status of an operator for an account.
/// @param tokenId The sub-token id.
/// @param account The account.
/// @param spender The spender.
/// @return The approval status.
function perTokenApprovals(
uint256 tokenId,
address account,
address spender
) external view returns (uint256) {
_revert(abi.encode(_perTokenApprovals[tokenId][account][spender]));
}
/// @notice Gets the decimals of the MultiToken. This is the same as the
/// decimals used by the base token.
/// @return The decimals of the MultiToken.
function decimals() external view virtual returns (uint8) {
_revert(abi.encode(_baseToken.decimals()));
}
/// @notice Gets the name of a sub-token.
/// @param tokenId The sub-token id.
/// @return The name.
function name(uint256 tokenId) external pure returns (string memory) {
_revert(abi.encode(AssetId.assetIdToName(tokenId)));
}
/// @notice Gets the symbol of a sub-token.
/// @param tokenId The sub-token id.
/// @return The symbol.
function symbol(uint256 tokenId) external pure returns (string memory) {
_revert(abi.encode(AssetId.assetIdToSymbol(tokenId)));
}
/// @notice Gets the permitForAll signature nonce for an account.
/// @param account The account.
/// @return The signature nonce.
function nonces(address account) external view returns (uint256) {
_revert(abi.encode(_nonces[account]));
}
/// @notice Returns whether or not an interface is supported.
/// @param interfaceId The ID of the interface.
/// @return A flag indicating whether or not the interface is supported.
function supportsInterface(
bytes4 interfaceId
) external pure returns (bool) {
if (interfaceId == bytes4(0xd9b67a26)) {
return true;
}
return false;
}
/// Helpers ///
/// @dev Reverts with the provided bytes. This is useful in getters used
/// with the force-revert delegatecall pattern.
/// @param _bytes The bytes to revert with.
function _revert(bytes memory _bytes) internal pure {
revert IHyperdrive.ReturnData(_bytes);
}
}