https://github.com/blackhan-software/xpower-banq/tree/5f734cc14fd05afcf7ee221de0bb600f8ca2339c
_settle function of the Pool contract that lets users reduce their debt by more than the actual assets they deposit into the Vault. this happens because the burn function uses amount instead of assets, and when the Vault has an entry fee, it causes a collateral shortage, bankrupting the vault. github : https://github.com/blackhan-software/xpower-banq/blob/5f734cc14fd05afcf7ee221de0bb600f8ca2339c/source/contract/Pool.sol#L382 code :
function _settle(
address user,
IERC20 token,
uint256 amount
) private returns (uint256 assets) {
IVault vault = _vault[token];
token.safeTransferFrom(user, address(this), amount);
assert(token.approve(address(vault), amount));
uint256 shares = vault.deposit(amount, address(this));
assets = vault.convertToAssets(shares);
vault.borrow().burn(user, amount, false); // bug: should use assets, not amount
require(assets > 0, EmptySettle(user, token, amount));
}
line vault.borrow().burn(user, amount, false) is wrong. it burns amount (the tokens transferred) instead of assets (the actual value added to the Vault after fees). Vault can have an entry fee (handled by _entryFee()), so assets is less than amount. for example, if a user deposits 100 tokens with a 1% fee, assets is 99, but burn reduces the debt by 100. this over-reduces the user’s debt, leaving the Vault undercollateralized. over time, the Vault loses assets compared to recorded debts, leading to insolvency.
fix : update the _settle function to burn assets instead of amount
foundry:
function test_incorrect_debt_settlement() public {
// user borrows 100 tokens
uint256 borrowamount = 100 * 10**token.decimals();
pool.borrow(token, borrowamount, false, IFlash(address(0)), "");
// user settles with 100 tokens, vault has 1% entry fee
uint256 settleamount = 100 * 10**token.decimals();
uint256 assets = pool.settle(token, settleamount);
// debt reduced by 100, but vault only got 99
uint256 debt = vault.borrow().totalOf(user);
assert(debt == 0); // debt fully cleared, vault undercollateralized
}