// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import "forge-std/Test.sol";
import { PartnershipBondV3Safe } from "../../contracts/bonds/PartnershipBondV3Safe.sol";
import { ThresholdConsensusV3 } from "../../contracts/consensus/ThresholdConsensusV3.sol";
import { DisputeRegistryV3 } from "../../contracts/disputes/DisputeRegistryV3.sol";

/// @notice Invariant #14 — Forced (selfdestruct or misdirected) transfers must
///         NOT be counted as user principal. `skimSurplus` lets governance
///         evacuate donations to the treasury; user credits are unchanged.
contract Inv14_ForcedTransferSafe is Test {
    PartnershipBondV3Safe internal bonds;
    address internal owner = address(0xBEEF);
    address internal treasury = address(0xCAFE);
    ThresholdConsensusV3 internal consensus;
    DisputeRegistryV3 internal disputes;

    function setUp() public {
        consensus = new ThresholdConsensusV3(owner, 2);
        disputes = new DisputeRegistryV3(owner);
        bonds = new PartnershipBondV3Safe(
            owner, address(0), address(consensus), address(disputes), 10 ether, 20 ether, 100 ether, address(0)
        );
    }

    function test_skim_moves_donations_leaves_credits_alone() external {
        // Force-donate 1 ether via a suicider contract.
        Suicider s = new Suicider{ value: 1 ether }();
        s.blow(payable(address(bonds)));
        assertEq(address(bonds).balance, 1 ether);

        // Non-owner cannot skim.
        vm.expectRevert(PartnershipBondV3Safe.NotOwner.selector);
        bonds.skimSurplus(address(0), treasury, 1 ether);

        // Owner can skim; user credits are untouched because none were ever recorded.
        vm.prank(owner);
        bonds.skimSurplus(address(0), treasury, 1 ether);
        assertEq(treasury.balance, 1 ether);
        assertEq(address(bonds).balance, 0);
    }
}

contract Suicider {
    constructor() payable { }

    function blow(address payable to) external {
        selfdestruct(to);
    }
}
