Vulnerability: When a D3MM pool repays all of the borrowed funds to vault using `D3Funding.sol repayAll`, an attacker can steal double the amount of those funds from vault
Severity: high

Description:
When a D3MM pool repays all of the borrowed funds to vault using D3Funding.sol repayAll, an attacker can steal double the amount of those funds from vault. This is because the balance of vault is not updated correctly in D3VaultFunding.sol _poolRepayAll.\\n`amount` should be added in `info.balance` instead of being subtracted.\\n```\\n    function _poolRepayAll(address pool, address token) internal {\\n        .\\n        .\\n        info.totalBorrows = info.totalBorrows - amount;\\n        info.balance = info.balance - amount; // amount should be added here\\n        .\\n        .\\n    }\\n```\\n\\nA `D3MM pool` can repay all of the borrowed funds from vault using the function D3Funding.sol repayAll which further calls D3VaultFunding.sol poolRepayAll and eventually D3VaultFunding.sol _poolRepayAll.\\n```\\n    function repayAll(address token) external onlyOwner nonReentrant poolOngoing {\\n        ID3Vault(state._D3_VAULT_).poolRepayAll(token);\\n        _updateReserve(token);\\n        require(checkSafe(), Errors.NOT_SAFE);\\n    }\\n```\\n\\nThe vault keeps a record of borrowed funds and its current token balance.\\n`_poolRepayAll()` is supposed to:\\nDecrease the borrowed funds by the repaid amount\\nIncrease the token balance by the same amount #vulnerability\\nTransfer the borrowed funds from pool to vault\\nHowever, `_poolRepayAll()` is decreasing the token balance instead.\\n```\\n    function _poolRepayAll(address pool, address token) internal {\\n        .\\n        .\\n        .\\n        .\\n\\n        info.totalBorrows = info.totalBorrows - amount;\\n        info.balance = info.balance - amount; // amount should be added here\\n\\n        IERC20(token).safeTransferFrom(pool, address(this), amount);\\n\\n        emit PoolRepay(pool, token, amount, interests);\\n    }\\n```\\n\\nLet's say a vault has 100,000 USDC A pool borrows 20,000 USDC from vault\\nWhen the pool calls `poolRepayAll()`, the asset info in vault will change as follows:\\n`totalBorrows => 20,000 - 20,000 => 0` // info.totalBorrows - amount\\n`balance => 100,000 - 20,000 => 80,000` // info.balance - amount\\n`tokens owned by vault => 100,000 + 20,000 => 120,000 USDC` // 20,000 USDC is transferred from pool to vault (repayment)\\nThe difference of recorded balance (80,000) and actual balance (120,000) is `40,000 USDC`\\nAn attacker waits for the `poolRepayAll()` function call by a pool.\\nWhen `poolRepayAll()` is executed, the attacker calls D3VaultFunding.sol userDeposit(), which deposits 40,000 USDC in vault on behalf of the attacker.\\nAfter this, the attacker withdraws the deposited amount using D3VaultFunding.sol userWithdraw() and thus gains 40,000 USDC.\\n```\\n    function userDeposit(address user, address token) external nonReentrant allowedToken(token) {\\n        .\\n        .\\n        .\\n        AssetInfo storage info = assetInfo[token];\\n        uint256 realBalance = IERC20(token).balanceOf(address(this)); // check tokens owned by vault\\n        uint256 amount = realBalance - info.balance; // amount = 120000-80000\\n        .\\n        .\\n        .\\n        IDToken(info.dToken).mint(user, dTokenAmount);\\n        info.balance = realBalance;\\n\\n        emit UserDeposit(user, token, amount);\\n    }\\n```\\n

Impact:
Loss of funds from vault. The loss will be equal to 2x amount of borrowed tokens that a D3MM pool repays using D3VaultFunding.sol poolRepayAll

Recommended mitigation:
Issue When a D3MM pool repays all of the borrowed funds to vault using `D3Funding.sol repayAll`, an attacker can steal double the amount of those funds from vault\\nIn D3VaultFunding.sol _poolRepayAll, do the following changes:\\nCurrent code: `info.balance = info.balance - amount;`\\nNew (replace '-' with '+'): `info.balance = info.balance + amount;`