diff --git a/.gitmodules b/.gitmodules index 726eb059..81632e76 100644 --- a/.gitmodules +++ b/.gitmodules @@ -8,6 +8,7 @@ [submodule "lib/chainlink"] path = lib/chainlink url = https://github.com/smartcontractkit/chainlink + ignore = untracked [submodule "lib/openzeppelin-contracts-upgradeable"] path = lib/openzeppelin-contracts-upgradeable url = https://github.com/openzeppelin/openzeppelin-contracts-upgradeable diff --git a/scripts/deploy-perp-only-market.s.sol b/scripts/deploy-perp-only-market.s.sol index 6f7a3a5b..459707a7 100644 --- a/scripts/deploy-perp-only-market.s.sol +++ b/scripts/deploy-perp-only-market.s.sol @@ -71,7 +71,6 @@ contract DeployPerpOnlyMarket is Utils { PMRM(_getContract("BTC", "pmrm")).setWhitelistedCallee(address(market.iapFeed), true); PMRM(_getContract("BTC", "pmrm")).setWhitelistedCallee(address(market.ibpFeed), true); PMRM(_getContract("BTC", "pmrm")).setWhitelistedCallee(address(market.perpFeed), true); - } else { _transferOwner(market, vm.envAddress("MAINNET_OWNER")); } diff --git a/src/risk-managers/StandardManager.sol b/src/risk-managers/StandardManager.sol index c1642c04..911ebf2b 100644 --- a/src/risk-managers/StandardManager.sol +++ b/src/risk-managers/StandardManager.sol @@ -306,8 +306,8 @@ contract StandardManager is IStandardManager, ILiquidatableManager, BaseManager, riskAdding = true; } } - } else if (detail.assetType == AssetType.Option) { - // if the user is shorting more options, we need to check margin + } else { + // if the user is shorting more options, or removing collateral, we need to check margin if (assetDeltas[i].delta < 0) { riskAdding = true; } diff --git a/test/deploy-lrt-market-fork.t.sol b/test/deploy-lrt-market-fork.t.sol index 504dfdc4..1272d46e 100644 --- a/test/deploy-lrt-market-fork.t.sol +++ b/test/deploy-lrt-market-fork.t.sol @@ -1,4 +1,4 @@ -pragma solidity 0.8.20; +pragma solidity ^0.8.18; import "forge-std/console.sol"; import "../scripts/types.sol"; diff --git a/test/risk-managers/unit-tests/StandardManager/TestStandardManager_Misc.t.sol b/test/risk-managers/unit-tests/StandardManager/TestStandardManager_Misc.t.sol index 11665ffd..4fca9724 100644 --- a/test/risk-managers/unit-tests/StandardManager/TestStandardManager_Misc.t.sol +++ b/test/risk-managers/unit-tests/StandardManager/TestStandardManager_Misc.t.sol @@ -57,6 +57,28 @@ contract UNIT_TestStandardManager_Misc is TestStandardManagerBase { assertEq(_getCashBalance(bobAcc), -int(btcSpot / 2)); } + function testCannotWithdrawBaseIfNegativeCash() public { + manager.setBorrowingEnabled(true); + cash.deposit(aliceAcc, uint(50000e18)); + + // can only borrow 50% of base asset's value + manager.setBaseAssetMarginFactor(btcMarketId, 0.5e18, 1e18); + + // bob deposit 1 WBTC + wbtc.mint(address(this), 1e18); + wbtc.approve(address(wbtcAsset), 1e18); + wbtcAsset.deposit(bobAcc, uint(1e18)); + + vm.startPrank(bob); + // bob can borrow against this spot asset + cash.withdraw(bobAcc, uint(btcSpot / 2), bob); + + assertEq(_getCashBalance(bobAcc), -int(btcSpot / 2)); + + vm.expectRevert(IStandardManager.SRM_PortfolioBelowMargin.selector); + wbtcAsset.withdraw(bobAcc, uint(1e18), bob); + } + function testCannotTradeMoreThanMaxAccountSize() public { manager.setMaxAccountSize(10);