Skip to content

Commit f889d01

Browse files
authored
Extract VaultValidators, VaultOsToken to libraries (#107)
1 parent a9b3fe9 commit f889d01

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1147
-730
lines changed

Diff for: contracts/base/ERC20Upgradeable.sol

+2-12
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
77
import {IERC20Permit} from '@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol';
88
import {IERC20Metadata} from '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';
99
import {Errors} from '../libraries/Errors.sol';
10+
import {EIP712Utils} from '../libraries/EIP712Utils.sol';
1011

1112
/**
1213
* @title ERC20 Upgradeable
@@ -128,18 +129,7 @@ abstract contract ERC20Upgradeable is Initializable, IERC20Permit, IERC20, IERC2
128129
* @dev This function is used to compute the hash of the EIP712 typed data
129130
*/
130131
function _computeDomainSeparator() private view returns (bytes32) {
131-
return
132-
keccak256(
133-
abi.encode(
134-
keccak256(
135-
'EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'
136-
),
137-
keccak256(bytes(name)),
138-
keccak256('1'),
139-
block.chainid,
140-
address(this)
141-
)
142-
);
132+
return EIP712Utils.computeDomainSeparator(name, address(this));
143133
}
144134

145135
/**

Diff for: contracts/interfaces/IVaultEthStaking.sol

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
pragma solidity ^0.8.22;
44

5-
import {IVaultState} from './IVaultState.sol';
65
import {IVaultValidators} from './IVaultValidators.sol';
76
import {IVaultEnterExit} from './IVaultEnterExit.sol';
87
import {IKeeperRewards} from './IKeeperRewards.sol';
@@ -13,7 +12,7 @@ import {IVaultMev} from './IVaultMev.sol';
1312
* @author StakeWise
1413
* @notice Defines the interface for the VaultEthStaking contract
1514
*/
16-
interface IVaultEthStaking is IVaultState, IVaultValidators, IVaultEnterExit, IVaultMev {
15+
interface IVaultEthStaking is IVaultValidators, IVaultEnterExit, IVaultMev {
1716
/**
1817
* @notice Deposit ETH to the Vault
1918
* @param receiver The address that will receive Vault's shares

Diff for: contracts/interfaces/IVaultState.sol

+14-9
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,21 @@ interface IVaultState is IVaultFee {
5757
function withdrawableAssets() external view returns (uint256);
5858

5959
/**
60-
* @notice Queued Shares
61-
* @return The total number of shares queued for exit
60+
* @notice Get exit queue data
61+
* @return queuedShares The number of shares in the exit queue
62+
* @return unclaimedAssets The amount of unclaimed assets in the exit queue
63+
* @return totalExitingAssets The total amount of exiting assets
64+
* @return totalTickets The total number of tickets in the exit queue
6265
*/
63-
function queuedShares() external view returns (uint128);
64-
65-
/**
66-
* @notice Total Exiting Assets (deprecated)
67-
* @return The total number of assets queued for exit
68-
*/
69-
function totalExitingAssets() external view returns (uint128);
66+
function getExitQueueData()
67+
external
68+
view
69+
returns (
70+
uint128 queuedShares,
71+
uint128 unclaimedAssets,
72+
uint128 totalExitingAssets,
73+
uint256 totalTickets
74+
);
7075

7176
/**
7277
* @notice Returns the number of shares held by an account

Diff for: contracts/libraries/EIP712Utils.sol

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
3+
pragma solidity ^0.8.22;
4+
5+
/**
6+
* @title EIP712Utils
7+
* @author StakeWise
8+
* @notice Includes functionality for calculating EIP712 hashes
9+
*/
10+
library EIP712Utils {
11+
/**
12+
* @notice Computes the hash of the EIP712 typed data
13+
* @dev This function is used to compute the hash of the EIP712 typed data
14+
* @param name The name of the domain
15+
* @param verifyingContract The address of the verifying contract
16+
* @return The hash of the EIP712 typed data
17+
*/
18+
function computeDomainSeparator(
19+
string memory name,
20+
address verifyingContract
21+
) external view returns (bytes32) {
22+
return
23+
keccak256(
24+
abi.encode(
25+
keccak256(
26+
'EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'
27+
),
28+
keccak256(bytes(name)),
29+
keccak256('1'),
30+
block.chainid,
31+
verifyingContract
32+
)
33+
);
34+
}
35+
}

Diff for: contracts/libraries/ExitQueue.sol

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ library ExitQueue {
5252
function getCheckpointIndex(
5353
History storage self,
5454
uint256 positionTicket
55-
) internal view returns (uint256) {
55+
) external view returns (uint256) {
5656
uint256 high = self.checkpoints.length;
5757
uint256 low;
5858
while (low < high) {
@@ -83,7 +83,7 @@ library ExitQueue {
8383
uint256 checkpointIdx,
8484
uint256 positionTicket,
8585
uint256 positionShares
86-
) internal view returns (uint256 burnedShares, uint256 exitedAssets) {
86+
) external view returns (uint256 burnedShares, uint256 exitedAssets) {
8787
uint256 length = self.checkpoints.length;
8888
// there are no exited assets for such checkpoint index or no shares to burn
8989
if (checkpointIdx >= length || positionShares == 0) return (0, 0);

Diff for: contracts/libraries/OsTokenUtils.sol

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
3+
pragma solidity ^0.8.22;
4+
5+
import {Math} from '@openzeppelin/contracts/utils/math/Math.sol';
6+
import {IOsTokenConfig} from '../interfaces/IOsTokenConfig.sol';
7+
import {IOsTokenVaultController} from '../interfaces/IOsTokenVaultController.sol';
8+
import {Errors} from './Errors.sol';
9+
10+
/**
11+
* @title OsTokenUtils
12+
* @author StakeWise
13+
* @notice Includes functionality for handling osToken redemptions
14+
*/
15+
library OsTokenUtils {
16+
uint256 private constant _wad = 1e18;
17+
uint256 private constant _hfLiqThreshold = 1e18;
18+
uint256 private constant _maxPercent = 1e18;
19+
uint256 private constant _disabledLiqThreshold = type(uint64).max;
20+
21+
/**
22+
* @dev Struct for storing redemption data
23+
* @param mintedAssets The amount of minted assets
24+
* @param depositedAssets The amount of deposited assets
25+
* @param redeemedOsTokenShares The amount of redeemed osToken shares
26+
* @param availableAssets The amount of available assets
27+
* @param isLiquidation Whether the redemption is a liquidation
28+
*/
29+
struct RedemptionData {
30+
uint256 mintedAssets;
31+
uint256 depositedAssets;
32+
uint256 redeemedOsTokenShares;
33+
uint256 availableAssets;
34+
bool isLiquidation;
35+
}
36+
37+
/**
38+
* @dev Calculates the amount of received assets during osToken redemption
39+
* @param osTokenConfig The address of the osToken config contract
40+
* @param osTokenVaultController The address of the osToken vault controller contract
41+
* @param data The redemption data
42+
* @return receivedAssets The amount of received assets
43+
*/
44+
function calculateReceivedAssets(
45+
IOsTokenConfig osTokenConfig,
46+
IOsTokenVaultController osTokenVaultController,
47+
RedemptionData memory data
48+
) external view returns (uint256 receivedAssets) {
49+
// SLOAD to memory
50+
IOsTokenConfig.Config memory config = osTokenConfig.getConfig(address(this));
51+
if (data.isLiquidation && config.liqThresholdPercent == _disabledLiqThreshold) {
52+
revert Errors.LiquidationDisabled();
53+
}
54+
55+
// calculate received assets
56+
if (data.isLiquidation) {
57+
receivedAssets = Math.mulDiv(
58+
osTokenVaultController.convertToAssets(data.redeemedOsTokenShares),
59+
config.liqBonusPercent,
60+
_maxPercent
61+
);
62+
} else {
63+
receivedAssets = osTokenVaultController.convertToAssets(data.redeemedOsTokenShares);
64+
}
65+
66+
{
67+
// check whether received assets are valid
68+
if (receivedAssets > data.depositedAssets || receivedAssets > data.availableAssets) {
69+
revert Errors.InvalidReceivedAssets();
70+
}
71+
72+
if (data.isLiquidation) {
73+
// check health factor violation in case of liquidation
74+
if (
75+
Math.mulDiv(
76+
data.depositedAssets * _wad,
77+
config.liqThresholdPercent,
78+
data.mintedAssets * _maxPercent
79+
) >= _hfLiqThreshold
80+
) {
81+
revert Errors.InvalidHealthFactor();
82+
}
83+
}
84+
}
85+
}
86+
}

0 commit comments

Comments
 (0)