What can we do instead?
For example, suppose a PartyB's locked balance is $200. If their balance falls below $200, we can still perform a hard liquidation as before.
But we can introduce earlier "warning" stages:
-
At $350, we send the PartyB an on-chain notice:
"You're running low on funds — take action."
- At $300, we send another on-chain notice, this time with a penalty:
"You're still not addressing this — we're deducting $50."
The tiers at which warnings and penalties trigger, as well as the penalty amounts, will be configurable off-chain. This allows us to treat new PartyBs differently from well-established ones, being more lenient with well-established ones.
Even if the PartyB reaches the $200 hard-liquidation threshold, we may still choose to apply another soft-liquidation cycle instead of immediately hard liquidating — up until a final limit such as $150.
Why are we doing this?
Hard liquidations cause major disruptions to user experience across all frontends. We know these solvers are reliable and will eventually replenish their funds—they just may be delayed for trivial reasons. A softer, tiered approach stabilizes the system without punishing them excessively.
Contract Implementation
We add a method in ClearingHouseFacet that emits an event and charges a penalty. This method is callable by
addresses with the SOFT_LIQUIDATOR_ROLE.
Method Signature
function softPartyBLiquidation(
address partyB,
address partyA,
uint256 penaltyFromAllocated,
uint256 penaltyFromBalance
) external
Parameters
| Parameter | Type | Description |
|---|---|---|
partyB |
address |
The PartyB being soft liquidated |
partyA |
address |
The specific PartyA whose allocation to deduct from. Pass address(0) for cross-mode PartyBs |
penaltyFromAllocated |
uint256 |
Amount to deduct from the allocated balance |
penaltyFromBalance |
uint256 |
Amount to deduct from the unallocated balance |
Behavior
-
Cross-mode PartyBs (
partyA = address(0)): Penalties are deducted from the PartyB's cross-allocated balance and/or unallocated balance -
Non-cross-mode PartyBs (
partyA = specific address): Penalties are deducted from the PartyB's allocation for that specific PartyA and/or their unallocated balance
Penalty amounts are transferred to the configured softLiquidationPenaltyCollector address.
Event
event SoftPartyBLiquidation(
address indexed partyB,
address indexed partyA,
uint256 penaltyFromAllocated,
uint256 penaltyFromBalance
)