function borrowAllowed(address xToken, uint256 orderId, address borrower, uint256 borrowAmount) external whenNotPaused(xToken, 3){
require(poolStates[xToken].isListed, "token not listed"); // called from xETH, TRUE
orderAllowed(orderId, borrower);
(address _collection , , ) = xNFT.getOrderDetail(orderId);
CollateralState storage _collateralState = collateralStates[_collection];
require(_collateralState.isListed, "collection not exist"); // BAYC had been added to collateral list, TRUE
require(_collateralState.supportPools[xToken] || _collateralState.isSupportAllPools, "collection don't support this pool"); // xETH, ofc TRUE
address _lastXToken = orderDebtStates[orderId]; // mapping(uint256 => address) public orderDebtStates;
// It will be 0 for the first time for an Order, but will be set to xETH in the end.
require(_lastXToken == address(0) || _lastXToken == xToken, "only support borrowing of one xToken"); // easy, TRUE
(uint256 _price, bool valid) = oracle.getPrice(_collection, IXToken(xToken).underlying());
require(_price > 0 && valid, "price is not valid"); // oracle price feed, TRUE
// Borrow cap of 0 corresponds to unlimited borrowing
if (poolStates[xToken].borrowCap != 0) {
require(IXToken(xToken).totalBorrows().add(borrowAmount) < poolStates[xToken].borrowCap, "pool borrow cap reached"); // if pool have enough funds to borrow, TRUE
}
uint256 _maxBorrow = mulScalarTruncate(_price, _collateralState.collateralFactor);
uint256 _mayBorrowed = borrowAmount;
if (_lastXToken != address(0)){
_mayBorrowed = IXToken(_lastXToken).borrowBalanceStored(orderId).add(borrowAmount);
}
require(_mayBorrowed <= _maxBorrow, "borrow amount exceed"); //amount check. TRUE
if (_lastXToken == address(0)){
orderDebtStates[orderId] = xToken;
}
}