Skip to content

Commit

Permalink
fix: debt withdraw
Browse files Browse the repository at this point in the history
  • Loading branch information
Schlagonia committed Aug 18, 2023
1 parent 1e6bc67 commit 73dbdb3
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
15 changes: 13 additions & 2 deletions contracts/VaultV3.vy
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ interface IStrategy:
def balanceOf(owner: address) -> uint256: view
def maxDeposit(receiver: address) -> uint256: view
def maxWithdraw(owner: address) -> uint256: view
def withdraw(amount: uint256, receiver: address, owner: address) -> uint256: nonpayable
def redeem(shares: uint256, receiver: address, owner: address) -> uint256: nonpayable
def deposit(assets: uint256, receiver: address) -> uint256: nonpayable
def totalAssets() -> (uint256): view
Expand Down Expand Up @@ -640,6 +639,18 @@ def _assess_share_of_unrealised_losses(strategy: address, assets_needed: uint256

return losses_user_share

@internal
def _withdraw_from_strategy(strategy: address, assets_to_withdraw: uint256):
# WITHDRAW FROM STRATEGY
# Need to get shares since we use redeem to be able to take on losses.
shares_to_withdraw: uint256 = min(
# Use previewWithdraw since it should round up.
IStrategy(strategy).previewWithdraw(assets_to_withdraw),
# And check against our actual balance.
IStrategy(strategy).balanceOf(self)
)
IStrategy(strategy).redeem(shares_to_withdraw, self, self)

@internal
def _redeem(
sender: address,
Expand Down Expand Up @@ -943,7 +954,7 @@ def _update_debt(strategy: address, target_debt: uint256) -> uint256:

# Always check the actual amount withdrawn.
pre_balance: uint256 = ASSET.balanceOf(self)
IStrategy(strategy).withdraw(assets_to_withdraw, self, self)
self._withdraw_from_strategy(strategy, assets_to_withdraw)
post_balance: uint256 = ASSET.balanceOf(self)

# making sure we are changing according to the real result no matter what.
Expand Down
18 changes: 18 additions & 0 deletions contracts/test/mocks/ERC4626/FaultyStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,22 @@ contract ERC4626FaultyStrategy is ERC4626BaseStrategyMock {

return shares;
}

function redeem(
uint256 _shares,
address _receiver,
address _owner
) public override returns (uint256) {
require(
_shares <= maxRedeem(_owner),
"ERC4626: withdraw more than max"
);

// this will simulate withdrawing less than the vault wanted to
uint256 toRedeem = _shares / 2;
uint256 assets = previewRedeem(toRedeem);
_withdraw(_msgSender(), _receiver, _owner, toRedeem, assets);

return assets;
}
}
10 changes: 10 additions & 0 deletions contracts/test/mocks/ERC4626/LockedStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ contract ERC4626LockedStrategy is ERC4626BaseStrategyMock {
}
}

function maxRedeem(address) public view override returns (uint256) {
uint256 balance = IERC20(asset()).balanceOf(address(this));
if (block.timestamp < lockedUntil) {
return convertToShares(balance - lockedBalance);
} else {
// no locked assets, withdraw all
return convertToShares(balance);
}
}

function migrate(address _newStrategy) external override {
require(lockedBalance == 0, "strat not liquid");
IERC20(asset()).safeTransfer(
Expand Down

0 comments on commit 73dbdb3

Please sign in to comment.