Skip to content

Commit dc9c900

Browse files
Amxxernestognwarr00
authored
Refactor ERC4626-maxWithdraw to reflect other functions overrides (#5130)
Co-authored-by: Ernesto García <[email protected]> Co-authored-by: Arr00 <[email protected]>
1 parent 8f8d61c commit dc9c900

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

.changeset/shiny-dolphins-lick.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'openzeppelin-solidity': minor
3+
---
4+
5+
`ERC4626`: compute `maxWithdraw` using `maxRedeem` and `previewRedeem` so that changes to the preview functions affect the max functions.

contracts/token/ERC20/extensions/ERC4626.sol

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,26 @@ import {Math} from "../../../utils/math/Math.sol";
4646
*
4747
* To learn more, check out our xref:ROOT:erc4626.adoc[ERC-4626 guide].
4848
* ====
49+
*
50+
* [NOTE]
51+
* ====
52+
* When overriding this contract, some elements must to be considered:
53+
*
54+
* * When overriding the behavior of the deposit or withdraw mechanisms, it is recommended to override the internal
55+
* functions. Overriding {_deposit} automatically affects both {deposit} and {mint}. Similarly, overriding {_withdraw}
56+
* automatically affects both {withdraw} and {redeem}. Overall it is not recommended to override the public facing
57+
* functions since that could lead to inconsistent behaviors between the {deposit} and {mint} or between {withdraw} and
58+
* {redeem}, which is documented to have lead to loss of funds.
59+
*
60+
* * Overrides to the deposit or withdraw mechanism must be reflected in the preview functions as well.
61+
*
62+
* * {maxWithdraw} depends on {maxRedeem}. Therefore, overriding {maxRedeem} only is enough. On the other hand,
63+
* overriding {maxWithdraw} only would have no effect on {maxRedeem}, and could create an inconsistency between the two
64+
* functions.
65+
*
66+
* * If {previewRedeem} is overridden to revert, {maxWithdraw} must be overridden as necessary to ensure it
67+
* always return successfully.
68+
* ====
4969
*/
5070
abstract contract ERC4626 is ERC20, IERC4626 {
5171
using Math for uint256;
@@ -142,7 +162,7 @@ abstract contract ERC4626 is ERC20, IERC4626 {
142162

143163
/// @inheritdoc IERC4626
144164
function maxWithdraw(address owner) public view virtual returns (uint256) {
145-
return _convertToAssets(balanceOf(owner), Math.Rounding.Floor);
165+
return previewRedeem(maxRedeem(owner));
146166
}
147167

148168
/// @inheritdoc IERC4626

0 commit comments

Comments
 (0)