@@ -29,7 +29,7 @@ abstract contract VaultBase is Controllable, ERC20Upgradeable, ReentrancyGuardUp
2929 /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
3030
3131 /// @dev Version of VaultBase implementation
32- string public constant VERSION_VAULT_BASE = "1.0.0 " ;
32+ string public constant VERSION_VAULT_BASE = "1.0.1 " ;
3333
3434 /// @dev Delay between deposits/transfers and withdrawals
3535 uint internal constant _WITHDRAW_REQUEST_BLOCKS = 5 ;
@@ -200,61 +200,18 @@ abstract contract VaultBase is Controllable, ERC20Upgradeable, ReentrancyGuardUp
200200 uint amountShares ,
201201 uint [] memory minAssetAmountsOut
202202 ) external virtual nonReentrant returns (uint [] memory ) {
203- if (amountShares == 0 ) {
204- revert IControllable.IncorrectZeroArgument ();
205- }
206- if (amountShares > balanceOf (msg .sender )) {
207- revert NotEnoughBalanceToPay ();
208- }
209- if (assets_.length != minAssetAmountsOut.length ) {
210- revert IControllable.IncorrectArrayLength ();
211- }
212-
213- VaultBaseStorage storage $ = _getVaultBaseStorage ();
214- _beforeWithdraw ($);
215-
216- IStrategy _strategy = $.strategy;
217- uint localTotalSupply = totalSupply ();
218- uint totalValue = _strategy.total ();
219-
220- uint [] memory amountsOut;
221- address underlying = _strategy.underlying ();
222- //nosemgrep
223- bool isUnderlyingWithdrawal = assets_.length == 1 && underlying != address (0 ) && underlying == assets_[0 ];
224-
225- // fuse is not triggered
226- if (totalValue > 0 ) {
227- uint value = amountShares * totalValue / localTotalSupply;
228- if (isUnderlyingWithdrawal) {
229- amountsOut = new uint [](1 );
230- amountsOut[0 ] = value;
231- $.strategy.withdrawUnderlying (amountsOut[0 ], msg .sender );
232- } else {
233- amountsOut = $.strategy.withdrawAssets (assets_, value, msg .sender );
234- }
235- } else {
236- if (isUnderlyingWithdrawal) {
237- amountsOut = new uint [](1 );
238- amountsOut[0 ] = amountShares * IERC20 (underlying).balanceOf (address (_strategy)) / localTotalSupply;
239- $.strategy.withdrawUnderlying (amountsOut[0 ], msg .sender );
240- } else {
241- amountsOut = $.strategy.transferAssets (amountShares, localTotalSupply, msg .sender );
242- }
243- }
244-
245- uint len = amountsOut.length ;
246- //nosemgrep
247- for (uint i; i < len; ++ i) {
248- if (amountsOut[i] < minAssetAmountsOut[i]) {
249- revert ExceedSlippageExactAsset (assets_[i], amountsOut[i], minAssetAmountsOut[i]);
250- }
251- }
252-
253- _burn (msg .sender , amountShares);
254-
255- emit WithdrawAssets (msg .sender , assets_, amountShares, amountsOut);
203+ return _withdrawAssets (assets_, amountShares, minAssetAmountsOut, msg .sender , msg .sender );
204+ }
256205
257- return amountsOut;
206+ /// @inheritdoc IVault
207+ function withdrawAssets (
208+ address [] memory assets_ ,
209+ uint amountShares ,
210+ uint [] memory minAssetAmountsOut ,
211+ address receiver ,
212+ address owner
213+ ) external virtual nonReentrant returns (uint [] memory ) {
214+ return _withdrawAssets (assets_, amountShares, minAssetAmountsOut, receiver, owner);
258215 }
259216
260217 /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
@@ -465,19 +422,88 @@ abstract contract VaultBase is Controllable, ERC20Upgradeable, ReentrancyGuardUp
465422 }
466423 }
467424
468- function _beforeWithdraw (VaultBaseStorage storage $) internal {
469- if ($.withdrawRequests[msg .sender ] + _WITHDRAW_REQUEST_BLOCKS >= block .number ) {
425+ function _withdrawAssets (
426+ address [] memory assets_ ,
427+ uint amountShares ,
428+ uint [] memory minAssetAmountsOut ,
429+ address receiver ,
430+ address owner
431+ ) internal virtual returns (uint [] memory ) {
432+ if (msg .sender != owner) {
433+ _spendAllowance (owner, msg .sender , amountShares);
434+ }
435+
436+ if (amountShares == 0 ) {
437+ revert IControllable.IncorrectZeroArgument ();
438+ }
439+ if (amountShares > balanceOf (owner)) {
440+ revert NotEnoughBalanceToPay ();
441+ }
442+ if (assets_.length != minAssetAmountsOut.length ) {
443+ revert IControllable.IncorrectArrayLength ();
444+ }
445+
446+ VaultBaseStorage storage $ = _getVaultBaseStorage ();
447+ _beforeWithdraw ($, owner);
448+
449+ IStrategy _strategy = $.strategy;
450+ uint localTotalSupply = totalSupply ();
451+ uint totalValue = _strategy.total ();
452+
453+ uint [] memory amountsOut;
454+
455+ {
456+ address underlying = _strategy.underlying ();
457+ //nosemgrep
458+ bool isUnderlyingWithdrawal = assets_.length == 1 && underlying != address (0 ) && underlying == assets_[0 ];
459+
460+ // fuse is not triggered
461+ if (totalValue > 0 ) {
462+ uint value = amountShares * totalValue / localTotalSupply;
463+ if (isUnderlyingWithdrawal) {
464+ amountsOut = new uint [](1 );
465+ amountsOut[0 ] = value;
466+ $.strategy.withdrawUnderlying (amountsOut[0 ], receiver);
467+ } else {
468+ amountsOut = $.strategy.withdrawAssets (assets_, value, receiver);
469+ }
470+ } else {
471+ if (isUnderlyingWithdrawal) {
472+ amountsOut = new uint [](1 );
473+ amountsOut[0 ] = amountShares * IERC20 (underlying).balanceOf (address (_strategy)) / localTotalSupply;
474+ $.strategy.withdrawUnderlying (amountsOut[0 ], receiver);
475+ } else {
476+ amountsOut = $.strategy.transferAssets (amountShares, localTotalSupply, receiver);
477+ }
478+ }
479+
480+ uint len = amountsOut.length ;
481+ //nosemgrep
482+ for (uint i; i < len; ++ i) {
483+ if (amountsOut[i] < minAssetAmountsOut[i]) {
484+ revert ExceedSlippageExactAsset (assets_[i], amountsOut[i], minAssetAmountsOut[i]);
485+ }
486+ }
487+ }
488+
489+ _burn (owner, amountShares);
490+
491+ emit WithdrawAssets (msg .sender , owner, assets_, amountShares, amountsOut);
492+
493+ return amountsOut;
494+ }
495+
496+ function _beforeWithdraw (VaultBaseStorage storage $, address owner ) internal {
497+ if ($.withdrawRequests[owner] + _WITHDRAW_REQUEST_BLOCKS >= block .number ) {
470498 revert WaitAFewBlocks ();
471499 }
472- $.withdrawRequests[msg . sender ] = block .number ;
500+ $.withdrawRequests[owner ] = block .number ;
473501 }
474502
475503 function _update (address from , address to , uint value ) internal virtual override {
476504 super ._update (from, to, value);
477505 VaultBaseStorage storage $ = _getVaultBaseStorage ();
478506 $.withdrawRequests[from] = block .number ;
479- if (to != IPlatform (platform ()).zap ()) {
480- $.withdrawRequests[to] = block .number ;
481- }
507+ $.withdrawRequests[to] = block .number ;
482508 }
483509}
0 commit comments