Skip to content

Commit

Permalink
Merge pull request #240 from Ithil-protocol/audit-fix-h1
Browse files Browse the repository at this point in the history
audit fix h1
  • Loading branch information
lsqrl authored Jan 10, 2024
2 parents d01d51f + d995e87 commit dc6c47b
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 9 deletions.
17 changes: 14 additions & 3 deletions src/Vault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,19 @@ contract Vault is IVault, ERC4626, ERC20Permit {
return super.totalAssets() - _calculateLockedProfits();
}

function previewWithdraw(uint256 assets) public view override(ERC4626, IERC4626) returns (uint256) {
uint256 freeLiq = freeLiquidity();
uint256 supply = totalSupply();
return assets.mulDiv(supply, freeLiq + netLoans + _calculateLockedLosses());
}

function previewRedeem(uint256 shares) public view override(ERC4626, IERC4626) returns (uint256) {
uint256 freeLiq = freeLiquidity();
uint256 totalAssetsCache = freeLiq + netLoans + _calculateLockedLosses();
uint256 supply = totalSupply();
return shares.mulDiv(totalAssetsCache, supply);
}

// Assets include netLoans but they are not available for withdraw
// Therefore we need to cap with the current free liquidity
function maxWithdraw(address owner) public view override(ERC4626, IERC4626) returns (uint256) {
Expand Down Expand Up @@ -228,9 +241,7 @@ contract Vault is IVault, ERC4626, ERC20Permit {
if (loan > assets) revert LoanHigherThanAssetsInBorrow();
uint256 freeLiq = freeLiquidity();

// We do not allow loans higher than the free liquidity
// This prevents the vault to go into unhealthy state
if (assets >= freeLiq) revert InsufficientFreeLiquidity();
if (assets > freeLiq) revert InsufficientFreeLiquidity();

netLoans += loan;
currentProfits = _calculateLockedProfits();
Expand Down
2 changes: 1 addition & 1 deletion src/services/credit/CallOption.sol
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ contract CallOption is CreditService {
// To do this, we take liquidity from the vault and register the loss
// If we incur a loss and the freeLiquidity is not enough, we cannot make the exit fail
// Otherwise we would have positions impossible to close: thus we withdraw what we can
freeLiquidity = vault.freeLiquidity() - 1;
freeLiquidity = vault.freeLiquidity();
toBorrow = toTransfer - redeemed > freeLiquidity ? freeLiquidity : toTransfer - redeemed;
}
// We will always have ithil.balanceOf(address(this)) >= toCall, so the following succeeds
Expand Down
2 changes: 1 addition & 1 deletion src/services/credit/FixedYieldService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ contract FixedYieldService is CreditService {
if (toTransfer > redeemed) {
// Since this service is senior, we need to pay the user even if redeemable is too low
// To do this, we take liquidity from the vault and register the loss (no loan)
uint256 freeLiquidity = vault.freeLiquidity() - 1;
uint256 freeLiquidity = vault.freeLiquidity();
if (freeLiquidity > 0) {
manager.borrow(
agreement.loans[0].token,
Expand Down
6 changes: 4 additions & 2 deletions test/Vault.test.sol
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,9 @@ contract VaultTest is Test {
vm.stopPrank();

uint256 vaultBalance = token.balanceOf(address(vault));
vm.expectRevert(IVault.InsufficientFreeLiquidity.selector);
vault.borrow(vaultBalance, vaultBalance, address(this));
if (vaultBalance < type(uint256).max) {
vm.expectRevert(IVault.InsufficientFreeLiquidity.selector);
vault.borrow(vaultBalance + 1, vaultBalance + 1, address(this));
}
}
}
4 changes: 2 additions & 2 deletions test/services/SeniorCallOption.test.sol
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ contract CallOptionTest is BaseIntegrationServiceTest {
vm.stopPrank();
uint256 assets = IVault(manager.vaults(loanTokens[0])).convertToAssets(collaterals[0].amount);
vm.warp(block.timestamp + 8 * 30 * 86500);
if (assets >= IVault(manager.vaults(loanTokens[0])).freeLiquidity()) {
if (assets > IVault(manager.vaults(loanTokens[0])).freeLiquidity()) {
vm.expectRevert(bytes4(keccak256(abi.encodePacked("InsufficientLiquidity()"))));
service.close(0, abi.encode(1e17, 0));
} else {
Expand All @@ -123,7 +123,7 @@ contract CallOptionTest is BaseIntegrationServiceTest {
vm.stopPrank();
uint256 assets = IVault(manager.vaults(loanTokens[0])).convertToAssets(collaterals[0].amount);
vm.warp(block.timestamp + 8 * 30 * 86500);
if (assets >= IVault(manager.vaults(loanTokens[0])).freeLiquidity()) {
if (assets > IVault(manager.vaults(loanTokens[0])).freeLiquidity()) {
vm.expectRevert(bytes4(keccak256(abi.encodePacked("InsufficientLiquidity()"))));
service.close(0, abi.encode(1e17, 0));
} else {
Expand Down

0 comments on commit dc6c47b

Please sign in to comment.