Skip to content

Commit c255b72

Browse files
committed
Provide two variant of ERC4626Fees with different models
1 parent 0a3b295 commit c255b72

File tree

1 file changed

+50
-7
lines changed

1 file changed

+50
-7
lines changed

contracts/token/ERC4626Fees.sol

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@ import {ERC4626} from "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.so
77
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
88
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
99

10-
/// @dev ERC-4626 vault with entry/exit fees expressed in https://en.wikipedia.org/wiki/Basis_point[basis point (bp)].
10+
/**
11+
* @dev ERC-4626 vault with entry/exit fees expressed in https://en.wikipedia.org/wiki/Basis_point[basis point (bp)].
12+
*
13+
* The `_feeOnRaw` and `_feeOnTotal` function are left unimplemented. See {ERC4626FeesOnTaxed} and
14+
* {ERC4626FeesOnUntaxed} for possible implementations
15+
*/
1116
abstract contract ERC4626Fees is ERC4626 {
12-
using Math for uint256;
13-
14-
uint256 private constant _BASIS_POINT_SCALE = 1e4;
17+
uint256 internal constant _BASIS_POINT_SCALE = 1e4;
1518

1619
// === Overrides ===
1720

@@ -87,17 +90,57 @@ abstract contract ERC4626Fees is ERC4626 {
8790
return address(0); // replace with e.g. a treasury address
8891
}
8992

90-
// === Fee operations ===
93+
/// @dev Calculates the fees that should be added to an amount `assets` that does not already include fees.
94+
/// Used in {IERC4626-mint} and {IERC4626-withdraw} operations.
95+
function _feeOnRaw(uint256 assets, uint256 feeBasisPoints) internal view virtual returns (uint256);
96+
97+
/// @dev Calculates the fee part of an amount `assets` that already includes fees.
98+
/// Used in {IERC4626-deposit} and {IERC4626-redeem} operations.
99+
function _feeOnTotal(uint256 assets, uint256 feeBasisPoints) internal view virtual returns (uint256);
100+
}
101+
102+
/**
103+
*@dev Variant of ERC4626Fees where the fee is expressed as a fraction of the total amount paid.
104+
*
105+
* In this version if the fee is set to 20%, and a user deposits 100 assets, then 80 assets go toward the price of the
106+
* shares, and 20 assets go toward the payment of fees. In this case, fees correspond to 20% ot the total paid price
107+
* and 25% of the value of the shares bought.
108+
*/
109+
abstract contract ERC4626FeesOnTaxed is ERC4626Fees {
110+
using Math for uint256;
111+
112+
/// @dev Calculates the fees that should be added to an amount `assets` that does not already include fees.
113+
/// Used in {IERC4626-mint} and {IERC4626-withdraw} operations.
114+
function _feeOnRaw(uint256 assets, uint256 feeBasisPoints) internal view virtual override returns (uint256) {
115+
return assets.mulDiv(feeBasisPoints, _BASIS_POINT_SCALE - feeBasisPoints, Math.Rounding.Ceil);
116+
}
117+
118+
/// @dev Calculates the fee part of an amount `assets` that already includes fees.
119+
/// Used in {IERC4626-deposit} and {IERC4626-redeem} operations.
120+
function _feeOnTotal(uint256 assets, uint256 feeBasisPoints) internal view virtual override returns (uint256) {
121+
return assets.mulDiv(feeBasisPoints, _BASIS_POINT_SCALE, Math.Rounding.Ceil);
122+
}
123+
}
124+
125+
/**
126+
* @dev Variant of ERC4626Fees where the fee is expressed as a fraction of the value of value being converted.
127+
*
128+
* In this version if the fee is set to 20%, and a user deposits 100 assets, then 83.33 assets go toward the price of
129+
* the shares, and 16.66 assets go toward the payment of fees. In this case, fees correspond to 16.66% ot the total
130+
* paid price and 20% of the value of the shares bought.
131+
*/
132+
abstract contract ERC4626FeesOnUntaxed is ERC4626Fees {
133+
using Math for uint256;
91134

92135
/// @dev Calculates the fees that should be added to an amount `assets` that does not already include fees.
93136
/// Used in {IERC4626-mint} and {IERC4626-withdraw} operations.
94-
function _feeOnRaw(uint256 assets, uint256 feeBasisPoints) private pure returns (uint256) {
137+
function _feeOnRaw(uint256 assets, uint256 feeBasisPoints) internal view virtual override returns (uint256) {
95138
return assets.mulDiv(feeBasisPoints, _BASIS_POINT_SCALE, Math.Rounding.Ceil);
96139
}
97140

98141
/// @dev Calculates the fee part of an amount `assets` that already includes fees.
99142
/// Used in {IERC4626-deposit} and {IERC4626-redeem} operations.
100-
function _feeOnTotal(uint256 assets, uint256 feeBasisPoints) private pure returns (uint256) {
143+
function _feeOnTotal(uint256 assets, uint256 feeBasisPoints) internal view virtual override returns (uint256) {
101144
return assets.mulDiv(feeBasisPoints, feeBasisPoints + _BASIS_POINT_SCALE, Math.Rounding.Ceil);
102145
}
103146
}

0 commit comments

Comments
 (0)