Vulnerability: A malicious admin can steal all users collateral
Severity: medium

Description:
According to Taurus contest details, all roles, including the admin `Multisig`, should not be able to drain users collateral.\\n```\\n2. Multisig. Trusted with essentially everything but user collateral. \\n```\\n\\nAs shown of `updateWrapper()` function of `PriceOracleManager.sol`, the admin (onlyOwner) can update any price oracle `_wrapperAddress` for any `_underlying` collateral without any restrictions (such as timelock).\\n```\\nFile: taurus-contracts\\contracts\\Oracle\\PriceOracleManager.sol\\n    function updateWrapper(address _underlying, address _wrapperAddress) external override onlyOwner {\\n        if (!_wrapperAddress.isContract()) revert notContract();\\n        if (wrapperAddressMap[_underlying] == address(0)) revert wrapperNotRegistered(_wrapperAddress);\\n\\n        wrapperAddressMap[_underlying] = _wrapperAddress;\\n\\n        emit WrapperUpdated(_underlying, _wrapperAddress);\\n    }\\n```\\n\\nHence, admin can set a malicious price oracle like\\n```\\ncontract AttackOracleWrapper is IOracleWrapper, Ownable {\\n    address public attacker;\\n    IGLPManager public glpManager;\\n\\n    constructor(address _attacker, address glp) {\\n        attacker = _attacker;\\n        glpManager = IGLPManager(glp);\\n    }\\n\\n    function getExternalPrice(\\n        address _underlying,\\n        bytes calldata _flags\\n    ) external view returns (uint256 price, uint8 decimals, bool success) {\\n        if (tx.origin == attacker) {\\n            return (1, 18, true); // @audit a really low price resulting in the liquidation of all positions\\n        } else {\\n            uint256 price = glpManager.getPrice();\\n            return (price, 18, true);\\n        }\\n    }\\n}\\n```\\n\\nThen call `liquidate()` to drain out users collateral with negligible $TAU cost.\\n```\\nFile: taurus-contracts\\contracts\\Vault\\BaseVault.sol\\n    function liquidate(\\n        address _account,\\n        uint256 _debtAmount,\\n        uint256 _minExchangeRate\\n    ) external onlyLiquidator whenNotPaused updateReward(_account) returns (bool) {\\n        if (_debtAmount == 0) revert wrongLiquidationAmount();\\n\\n        UserDetails memory accDetails = userDetails[_account];\\n\\n        // Since Taurus accounts' debt continuously decreases, liquidators may pass in an arbitrarily large number in order to\\n        // request to liquidate the entire account.\\n        if (_debtAmount > accDetails.debt) {\\n            _debtAmount = accDetails.debt;\\n        }\\n\\n        // Get total fee charged to the user for this liquidation. Collateral equal to (liquidated taurus debt value * feeMultiplier) will be deducted from the user's account.\\n        // This call reverts if the account is healthy or if the liquidation amount is too large.\\n        (uint256 collateralToLiquidate, uint256 liquidationSurcharge) = _calcLiquidation(\\n            accDetails.collateral,\\n            accDetails.debt,\\n            _debtAmount\\n        );\\n\\n        // Check that collateral received is sufficient for liquidator\\n        uint256 collateralToLiquidator = collateralToLiquidate - liquidationSurcharge;\\n        if (collateralToLiquidator < (_debtAmount * _minExchangeRate) / Constants.PRECISION) {\\n            revert insufficientCollateralLiquidated(_debtAmount, collateralToLiquidator);\\n        }\\n\\n        // Update user info\\n        userDetails[_account].collateral = accDetails.collateral - collateralToLiquidate;\\n        userDetails[_account].debt = accDetails.debt - _debtAmount;\\n\\n        // Burn liquidator's Tau\\n        TAU(tau).burnFrom(msg.sender, _debtAmount);\\n\\n        // Transfer part of _debtAmount to liquidator and Taurus as fees for liquidation\\n        IERC20(collateralToken).safeTransfer(msg.sender, collateralToLiquidator);\\n        IERC20(collateralToken).safeTransfer(\\n            Controller(controller).addressMapper(Constants.FEE_SPLITTER),\\n            liquidationSurcharge\\n        );\\n\\n        emit AccountLiquidated(msg.sender, _account, collateralToLiquidate, liquidationSurcharge);\\n\\n        return true;\\n    }\\n```\\n

Impact:
A malicious admin can steal all users collateral

Recommended mitigation:
update of price oracle should be restricted with a `timelock`.