@@ -5,41 +5,46 @@ pragma solidity ^0.8.0;
55import "../../token/ERC20/extensions/ERC4626Upgradeable.sol " ;
66import "../../proxy/utils/Initializable.sol " ;
77
8+ /// @dev ERC4626 vault with entry/exit fees expressed in https://en.wikipedia.org/wiki/Basis_point[basis point (bp)].
89abstract contract ERC4626FeesUpgradeable is Initializable , ERC4626Upgradeable {
910 using MathUpgradeable for uint256 ;
1011
12+ uint256 private constant _BASIS_POINT_SCALE = 1e4 ;
13+
1114 function __ERC4626Fees_init () internal onlyInitializing {
1215 }
1316
1417 function __ERC4626Fees_init_unchained () internal onlyInitializing {
1518 }
16- /** @dev See {IERC4626-previewDeposit}. */
19+ // === Overrides ===
20+
21+ /// @dev Preview taking an entry fee on deposit. See {IERC4626-previewDeposit}.
1722 function previewDeposit (uint256 assets ) public view virtual override returns (uint256 ) {
18- uint256 fee = _feeOnTotal (assets, _entryFeeBasePoint ());
23+ uint256 fee = _feeOnTotal (assets, _entryFeeBasisPoints ());
1924 return super .previewDeposit (assets - fee);
2025 }
2126
22- /** @dev See {IERC4626-previewMint}. */
27+ /// @dev Preview adding an entry fee on mint. See {IERC4626-previewMint}.
2328 function previewMint (uint256 shares ) public view virtual override returns (uint256 ) {
2429 uint256 assets = super .previewMint (shares);
25- return assets + _feeOnRaw (assets, _entryFeeBasePoint ());
30+ return assets + _feeOnRaw (assets, _entryFeeBasisPoints ());
2631 }
2732
28- /** @dev See {IERC4626-previewWithdraw}. */
33+ /// @dev Preview adding an exit fee on withdraw. See {IERC4626-previewWithdraw}.
2934 function previewWithdraw (uint256 assets ) public view virtual override returns (uint256 ) {
30- uint256 fee = _feeOnRaw (assets, _exitFeeBasePoint ());
35+ uint256 fee = _feeOnRaw (assets, _exitFeeBasisPoints ());
3136 return super .previewWithdraw (assets + fee);
3237 }
3338
34- /** @dev See {IERC4626-previewRedeem}. */
39+ /// @dev Preview taking an exit fee on redeem. See {IERC4626-previewRedeem}.
3540 function previewRedeem (uint256 shares ) public view virtual override returns (uint256 ) {
3641 uint256 assets = super .previewRedeem (shares);
37- return assets - _feeOnTotal (assets, _exitFeeBasePoint ());
42+ return assets - _feeOnTotal (assets, _exitFeeBasisPoints ());
3843 }
3944
40- /** @dev See {IERC4626-_deposit}. */
45+ /// @dev Send entry fee to {_entryFeeRecipient}. See {IERC4626-_deposit}.
4146 function _deposit (address caller , address receiver , uint256 assets , uint256 shares ) internal virtual override {
42- uint256 fee = _feeOnTotal (assets, _entryFeeBasePoint ());
47+ uint256 fee = _feeOnTotal (assets, _entryFeeBasisPoints ());
4348 address recipient = _entryFeeRecipient ();
4449
4550 super ._deposit (caller, receiver, assets, shares);
@@ -49,15 +54,15 @@ abstract contract ERC4626FeesUpgradeable is Initializable, ERC4626Upgradeable {
4954 }
5055 }
5156
52- /** @dev See {IERC4626-_deposit}. */
57+ /// @dev Send exit fee to {_exitFeeRecipient}. See {IERC4626-_deposit}.
5358 function _withdraw (
5459 address caller ,
5560 address receiver ,
5661 address owner ,
5762 uint256 assets ,
5863 uint256 shares
5964 ) internal virtual override {
60- uint256 fee = _feeOnRaw (assets, _exitFeeBasePoint ());
65+ uint256 fee = _feeOnRaw (assets, _exitFeeBasisPoints ());
6166 address recipient = _exitFeeRecipient ();
6267
6368 super ._withdraw (caller, receiver, owner, assets, shares);
@@ -67,28 +72,36 @@ abstract contract ERC4626FeesUpgradeable is Initializable, ERC4626Upgradeable {
6772 }
6873 }
6974
70- function _entryFeeBasePoint () internal view virtual returns (uint256 ) {
71- return 0 ;
75+ // === Fee configuration ===
76+
77+ function _entryFeeBasisPoints () internal view virtual returns (uint256 ) {
78+ return 0 ; // replace with e.g. 100 for 1%
7279 }
7380
74- function _entryFeeRecipient () internal view virtual returns (address ) {
75- return address ( 0 );
81+ function _exitFeeBasisPoints () internal view virtual returns (uint256 ) {
82+ return 0 ; // replace with e.g. 100 for 1%
7683 }
7784
78- function _exitFeeBasePoint () internal view virtual returns (uint256 ) {
79- return 0 ;
85+ function _entryFeeRecipient () internal view virtual returns (address ) {
86+ return address ( 0 ); // replace with e.g. a treasury address
8087 }
8188
8289 function _exitFeeRecipient () internal view virtual returns (address ) {
83- return address (0 );
90+ return address (0 ); // replace with e.g. a treasury address
8491 }
8592
86- function _feeOnRaw (uint256 assets , uint256 feeBasePoint ) private pure returns (uint256 ) {
87- return assets.mulDiv (feeBasePoint, 1e5 , MathUpgradeable.Rounding.Up);
93+ // === Fee operations ===
94+
95+ /// @dev Calculates the fees that should be added to an amount `assets` that does not already include fees.
96+ /// Used in {IERC4626-mint} and {IERC4626-withdraw} operations.
97+ function _feeOnRaw (uint256 assets , uint256 feeBasisPoints ) private pure returns (uint256 ) {
98+ return assets.mulDiv (feeBasisPoints, _BASIS_POINT_SCALE, MathUpgradeable.Rounding.Up);
8899 }
89100
90- function _feeOnTotal (uint256 assets , uint256 feeBasePoint ) private pure returns (uint256 ) {
91- return assets.mulDiv (feeBasePoint, feeBasePoint + 1e5 , MathUpgradeable.Rounding.Up);
101+ /// @dev Calculates the fee part of an amount `assets` that already includes fees.
102+ /// Used in {IERC4626-deposit} and {IERC4626-redeem} operations.
103+ function _feeOnTotal (uint256 assets , uint256 feeBasisPoints ) private pure returns (uint256 ) {
104+ return assets.mulDiv (feeBasisPoints, feeBasisPoints + _BASIS_POINT_SCALE, MathUpgradeable.Rounding.Up);
92105 }
93106
94107 /**
0 commit comments