Skip to content

Conversation

IliaZyrin
Copy link
Contributor

@IliaZyrin IliaZyrin commented Jul 2, 2025

Bankruptcy handling: logic, tests, and docs

What this does

  • Implements full bankruptcy flow for users and banks, including super-bankruptcy handling (clamps loss and kills the bank when bad debt exceeds assets). Introduces a dedicated error code to reflect this terminal state.

  • Adds a user & bank bankruptcy guide (how it triggers, discharge order, and outcomes): BANKRUPTCY.md.

  • Hardens instruction paths with additional bank state validation (e.g., during borrow) to prevent actions on paused/reduced/killed banks.

Notable changes

  • New/updated program errors
    BankKilledByBankruptcy (code 6082).
    Quick lookup: BankKilledByBankruptcy.

  • Instruction changes

handle_bankruptcy logic (bank-level settlement, socialized losses, kill path on super-bankruptcy).

borrow as well as the other ixes (deposit repay, withdraw) now validates that the bank is not in a paused or reduced state.

  • Tests & fuzz

New spec: tests/zb01_bankruptcy.spec.ts (see Files changed).

Fuzz harness updates and additional logging/assertions to surface unexpected liquidation errors.

How it works (short)

  • Liquidation exhausts remaining assets of the insolvent user.

  • handle_bankruptcy settles bad debt:

Use insurance if sufficient.

Otherwise, socialize via asset-share value reduction.

If still insufficient (super-bankruptcy), kill the bank (asset share value to zero; bank permanently disabled).

Test plan

  • Unit/integration tests in zb01_bankruptcy.spec.ts cover user bankruptcy, bank bankruptcy, and super-bankruptcy kill path.

  • Fuzz tests updated to assert allowed error surface and reject unexpected outcomes; reproducible logs added for triage.

@IliaZyrin IliaZyrin self-assigned this Jul 2, 2025
@IliaZyrin IliaZyrin changed the base branch from main to 0.1.4-main July 2, 2025 22:52
@IliaZyrin IliaZyrin marked this pull request as ready for review July 11, 2025 14:33
* Remove silly hybrid withdraw/borrow and deposit/repay hybrid functions which serve no purpose except to act as a tremendous footgun

* WIP removing the flipping logic from liquidation

* Resolve liquidation logic without balance-flipping functions

* Fix fuzz fix rust test suite
@jgur-psyops jgur-psyops mentioned this pull request Jul 16, 2025
29 tasks
@jgur-psyops jgur-psyops changed the base branch from 0.1.4-main to 0.1.5-main July 16, 2025 05:20
# Conflicts:
#	programs/marginfi/src/instructions/marginfi_account/liquidate.rs
#	programs/marginfi/src/instructions/marginfi_group/handle_bankruptcy.rs
#	programs/marginfi/src/state/marginfi_group.rs
#	programs/marginfi/src/utils.rs
#	type-crate/src/types/bank.rs
@IliaZyrin
Copy link
Contributor Author

@jgur-psyops let's merge this one?

@IliaZyrin IliaZyrin requested a review from Henry-E August 11, 2025 15:09
@Henry-E
Copy link
Contributor

Henry-E commented Aug 18, 2025

Not a fan of adding another arbitrary validation function validate_bank_state

@Henry-E
Copy link
Contributor

Henry-E commented Aug 18, 2025

Not a fan of adding bypass_util_ratio as a top level option that isn't even clear what it is since it's just "true, false". I assume that is someone passes true by accident something pretty bad could happen?

@IliaZyrin
Copy link
Contributor Author

Not a fan of adding another arbitrary validation function validate_bank_state

I expect it to look better once this TODO is addressed. But I would do it in a separate PR to only focus on this.

Not a fan of adding bypass_util_ratio as a top level option that isn't even clear what it is since it's just "true, false". I assume that is someone passes true by accident something pretty bad could happen?

Yeah, so basically it is the main change to bankruptcy. It is what will allow us to deal with super-bankruptcies, which are currently non-solvable. Although, I see your point about the risk of accidentally putting a true there.
It makes sense to separate it. I'll do it.

@Henry-E
Copy link
Contributor

Henry-E commented Aug 18, 2025

From the meeting earlier it sounds like we're adding a much bigger solution for a problem that we're unlikely to have in the future that is very specifically for dealing with Arena banks that are in a weird state. Would it not be possible to add something that is self contained to specifically arena banks and doesn't expose the other banks to these changes.

Agreed that, yes in the long term, users shouldn't be able to get into a state where they can't even get into the state in the first place. And we should be able to handle bankruptcies. Though I don't know what kind of priority this direction is for the product where banks are potentially ending up like this.

// TODO remove redundant checks for these elsewhere in the program (they are nested many laters deep
// in various value delta functions)
/// Validate the bank's state does not forbid the execution of an instruction
pub fn validate_bank_state(bank: &Bank, kind: InstructionKind) -> MarginfiResult {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this different from assert_operational_mode?

Copy link
Contributor

@Henry-E Henry-E Aug 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the high level idea is to enforce which states a bank is allowed to be in when an instruction is run? Since this wasn't really enforced before, except implicitly by assert_operational_mode?

Maybe it's a nit pick but I wonder if the positive is easier to understand
bank.load().allowed_states([PAUSED, REDUCE])
and we can put that in the constraints above the bank's account in a given instruction context.

@Henry-E
Copy link
Contributor

Henry-E commented Sep 7, 2025

Nothing left to say on this

Copy link
Contributor

@Henry-E Henry-E left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jgur-psyops jgur-psyops merged commit b8135e2 into 0.1.5-main Sep 8, 2025
2 checks passed
@jgur-psyops jgur-psyops deleted the bankruptcy branch September 8, 2025 22:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants