Skip to content

Feat: Prevent Liquidations Resulting in Dust Debt#605

Merged
DhairyaSethi merged 46 commits intomainfrom
feat/399-liquidation-dust
Aug 14, 2025
Merged

Feat: Prevent Liquidations Resulting in Dust Debt#605
DhairyaSethi merged 46 commits intomainfrom
feat/399-liquidation-dust

Conversation

@yan-man
Copy link
Copy Markdown
Contributor

@yan-man yan-man commented Aug 6, 2025

  • prevent liquidations that result in dust debt unless all borrower's reserve collateral at hand is seized
  • if liquidator input debtToCover is insufficient, revert. Otherwise, adjust debt to liquidate to a value that prevents dust to result

closes #608
closes #399

@yan-man yan-man changed the title Feat/399 liquidation dust [WIP] Feat/399 liquidation dust Aug 6, 2025
maxLiquidatableDebt = maxLiquidatableDebt.min(debtToRestoreCloseFactor);
return debtToCover.min(maxLiquidatableDebt);
uint256 maxLiquidatableDebt = debtToCover.min(params.totalBorrowerReserveDebt);
uint256 actualDebtToLiquidate = maxLiquidatableDebt.min(params.debtToRestoreCloseFactor);
Copy link
Copy Markdown
Contributor Author

@yan-man yan-man Aug 7, 2025

Choose a reason for hiding this comment

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

for reference:

  • debtToCover is value input by liquidator
  • totalBorrowerReserveDebt is the total debt for the user being liquidated in the debt reserve being repaid
  • debtToRestoreCloseFactor is the amt of debt to repay to restore liquidated user to desired close factor

console.log('LL dust');

// revert if debtToCover is the min value and has been set too low
if (debtToCover == actualDebtToLiquidate) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this means debtToCover is set too low by liquidator, thus revert. debtToCover is a hard cap, and we can never liquidate more than this value

Copy link
Copy Markdown
Contributor

@avniculae avniculae Aug 13, 2025

Choose a reason for hiding this comment

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

it can be the case that params.debtToRestoreCloseFactor = debtToCover, in which case the liquidator will need to input 1 wei more just to pass this check, since actualDebtToLiquidate will remain the same. hence, I would rewrite this as:

if (debtToCover < params.debtToRestoreCloseFactor)

wdyt?

we don't need to consider params.totalBorrowerReserveDebt since we checked remainingDebtInBaseCurrency < MIN_LEFTOVER_BASE above, so it must be the case that min is either debtToCover or params.debtToRestoreCloseFactor, right?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It turns out that all that we care if there is any dust is for the debtCover to be >= totalDebt. This is bc even is the min value is the closeFactor, if debtToCover is < totalDebt then debtToCover must leave dust (bc closeFactor left dust, which is smaller). Simplified logic: 66deb06

debtToCover < params.totalBorrowerReserveDebt &&
((params.totalBorrowerReserveDebt - debtToCover) * params.debtAssetPrice).toWad() /
params.debtAssetUnit <
MIN_LEFTOVER_BASE
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

if it reaches this branch, it means that debtToRestoreCloseFactor is the min value. However, we are again hard capped by debtToCover so need to check if it is set to a value that is greater than debtToRestoreCloseFactor but still results in dust. If so revert

revert MustNotLeaveDust();
} else {
// if debtToCover is valid, return min(debtToCover, totalBorrowerReserveDebt)
actualDebtToLiquidate = maxLiquidatableDebt;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

if debtToCover doesn't result in dust, increase the actualDebtToLiquidate to the max upper cap. Can never exceed debtToCover or totalBorrowerReserveDebt

Copy link
Copy Markdown
Member

@DhairyaSethi DhairyaSethi Aug 12, 2025

Choose a reason for hiding this comment

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

at this point maxLiquidatableDebt is totalBorrowerReserveDebt (bc debtToCover > totalborrowerReserveDebt from the if part of this else branch, ie still respect liquidating within debtToCover input), right?
if we reach this branch, we are liquidating everything on that reserve and should not be left with dust, right?

Copy link
Copy Markdown
Contributor Author

@yan-man yan-man Aug 12, 2025

Choose a reason for hiding this comment

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

bc debtToCover > totalborrowerReserveDebt

based on the if branch, which is basically debtToCover < params.totalBorrowerReserveDebt && "remainingDebtFromDebtToCover leaving dust", then this branch is either: debtToCover > totalBorrowerReserveDebt || remainingDebtFromDebtToCover not leaving dust

so besides debtToCover > totalborrowerReserveDebt, it can also be that debtToCover < totalborrowerReserveDebt, but allows a remaining debt amount that doesn't leave dust, so a valid value.

So here, debtToRestoreCloseFactor < debtToCover < totalborrowerReserveDebt, where debtToRestoreCloseFactor would leave dust but debtToCover wouldn't leave dust. Therefore adjust the actualDebtToLiquidate to min(debtToCover, totalborrowerReserveDebt) if debtToCover is valid

Not necessarily all of totalborrowerReserveDebt

params.debtAssetUnit;

console.log('LL leftoverDebtBase %e', vars.leftoverDebtBase);
if (vars.leftoverDebtBase != 0 && vars.leftoverDebtBase < MIN_LEFTOVER_BASE) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

we must also do this check bc of the scenario where debt value exceeds collateral value. Therefore max debt is not possible to be liquidated.

Consider a multi-reserve case (assuming no liq bonus, no liq fee):
Collateral:

  • asset A: $8k
  • asset B: $5k (coll to seize)

Debt:

  • asset C: $8k
  • asset D: $5.4k (debt to liq)

if actualDebtToLiquidate ends up as $5.4k, ie liquidating all of asset D, by the time we come here to calc available collateral, there isn't enough collateral to liquidate to cover the whole debt and thus we can only liquidate $5k worth of asset D, leading to dust.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

resolved - this scenario is acceptable as long as all the reserve collateral is seized

@yan-man yan-man changed the title [WIP] Feat/399 liquidation dust feat: prevent liquidations that result in dust Aug 11, 2025
@yan-man yan-man changed the title feat: prevent liquidations that result in dust Feat: Prevent Liquidations Resulting in Dust Debt Aug 11, 2025
Comment thread src/contracts/Spoke.sol
@@ -318,13 +318,7 @@ contract Spoke is ISpoke, Multicall, AccessManaged {
uint256[] memory debtsToCover = new uint256[](1);
debtsToCover[0] = debtToCover;
Copy link
Copy Markdown
Contributor Author

@yan-man yan-man Aug 11, 2025

Choose a reason for hiding this comment

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

if we're also set on no parallel liqs, then can rm this array type input and the loop in liqCall (to be done in liquidation refactor)

@yan-man yan-man marked this pull request as ready for review August 12, 2025 02:54
* @dev This constant represents the minimum amount of assets in base currency that need to be leftover after a liquidation, if not clearing collateral on a position completely.
* @notice The default value assumes that the basePrice is usd denominated by 26 decimals.
*/
uint256 constant MIN_LEFTOVER_BASE = 1000e26;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

currently this is the only assumption of the spoke that the aave oracle uses 8 decimals. I think we should hardcode 1000e18 and then multiply it by 10^(oracle.decimals()), wdyt?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

it's a pretty safe assumption, we can avoid doing this in the src code but good to add a test for this to flag non standard oracle decimals

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comment thread src/libraries/logic/LiquidationLogic.sol Outdated
Comment thread src/libraries/types/DataTypes.sol Outdated
uint256 collateralToLiquidateInBaseCurrency;
uint256 debtToLiquidateInBaseCurrency;
bool hasDeficit;
uint256 leftoverDebtBase;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

is this used anywhere?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

) public {
params = bound(params);
DataTypes.LiquidationCallLocalVars memory params = _setStructFields(params);
vm.assume(debtToCover > params.totalBorrowerReserveDebt);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

here we could bound debtToCover instead of assuming, wdyt?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comment thread src/libraries/logic/LiquidationLogic.sol
@DhairyaSethi DhairyaSethi merged commit d11a708 into main Aug 14, 2025
1 check passed
@DhairyaSethi DhairyaSethi deleted the feat/399-liquidation-dust branch August 14, 2025 14:17
CheyenneAtapour added a commit that referenced this pull request Aug 15, 2025
* feat: Refactor flags (#553)

* feat: remove collateral flag

* feat: refactor hub flags

* feat: refactor spoke flags

* feat: update hub configurator

* fix: check spoke active on payFee

* fix: order operation nit

* fix: comments

* fix: nits

* fix: gas reports

* fix: comments

* feat: keep feeReceiver active flag constant in configurator

* fix: comments

* fix: comments

* fix: Address comments

* fix: address comments

* chore: gas snapshots

* fix: Fix draw validation

* chore: gas

---------

Co-authored-by: miguelmtzinf <miguelmtz.mail@gmail.com>
Co-authored-by: YBM <31329384+yan-man@users.noreply.github.com>

* feat: Allow DAO to update any user dynamic risk configuration (#564)

* feat: allow dao to upd user dyn config

* chore: reorder for readability

* fix: pr comments

* feat: Add Hub Conversion Functions (#540)

* feat: Add previews for basic actions

* feat: Add preview shares functions

* feat: Adjust conversion functions

* fix: Use preview functions in src

* fix: Use preview where possible

* fix: Remove using preview where unneeded

* fix: Internalize previewOffset

* fix: Pr comments

* fix: Add natspec to _previewOffset

* fix: Simplify dev comment

* fix: Revert natspec change on previewOffset

* fix: Rename other preview getters

* fix: fix docs

---------

Co-authored-by: miguelmtzinf <miguelmtz.mail@gmail.com>

* feat: update existing dyn config (#541)

* feat: update existing dyn config

* wip: config tests cleanup

* chore: snapshots

* chore: finalise merge

* fix: rename and tests

* fix: revert to uint16 input, cleanup

* chore: reorder

* chore: finalise merge

* feat: rm safeCast, resolve shadowing in tests

* feat: distinguish dyn conf update with new added event

* feat: rm abstraction, fix event on add reserve, natspec

* fix: apply explicit rounding direction on all math operations (#543)

* rft: explicit rounding

* fix: round up on getUserDebtInBaseCurrency

* chore: finalise merge

* fix: pr comments

* chore: rm dup

* fix: rename wadify -> toWad, dewadify -> fromWad

* feat: Add more equivalent fees calc in previewFeeShares (#458)

* feat: Add more equivalent fees calc in previewFeeShares

* chore: disables gas checks

* tmp: skip snapshot check (revert before merging)

* fix: separate impl of fee shares

* test: multi-user case

* fix: test

* feat: underestimate treasury fees and fix tests

* test: multi spoke

* fix: treasury spoke tests

* fix: treasury spoke tests

* fix: pr comment

---------

Co-authored-by: dhairya <55102840+DhairyaSethi@users.noreply.github.com>
Co-authored-by: YBM <31329384+yan-man@users.noreply.github.com>

* feat: Deficit accounting via dedicated hub method (#472)

* feat: simplify restore flow (#574)

* feat: simplify restore flow

* feat: make restore like its now

* feat: emit premium amt

* fix: hub._validateRestore after accrual & before state changes

* fix: settle premium debt in reportDeficit

* test: _checkDeficitReportedEvents

* chore: bring back test

* chore: consolidate settlePremiumDebt

* chore: bring back fee share comment

* feat: Eliminate deficit (#583)

* feat: clear deficit

* fix: pr comments

* chore: rename to eliminate deficit

* feat: simplify restore flow (#574)

* feat: simplify restore flow

* feat: make restore like its now

* feat: emit premium amt

* fix: hub._validateRestore after accrual & before state changes

* fix: settle premium debt in reportDeficit

* test: _checkDeficitReportedEvents

* chore: bring back test

* chore: consolidate settlePremiumDebt

* chore: bring back fee share comment

chore: finalise merge

* chore: disallow excess eliminate deficit in, reorder fn

* feat: rm reserve accounting on spoke (#468)

* feat: rm reserve accounting on spoke

* chore: snapshots

* chore: snapshot

* feat: rm reserve list

* chore: finalise merge

* fix: rm unnecessary liquidation accounting

---------

Co-authored-by: YBM <31329384+yan-man@users.noreply.github.com>

* feat: spoke/base minimal interfaces (#589)

* feat: Transfer added shares between spokes (#590)

* feat: rm reserve accounting on spoke

* chore: snapshots

* chore: snapshot

* feat: rm reserve list

* chore: finalise merge

* fix: rm unnecessary liquidation accounting

* feat: Initial implementation

* test: Basic tests

* test: Basic functionalities and reverts

* fix: Address pr comments

* fix: Address pr comments

* fix: Remove unchecked

* fix: pr comments

* feat: Internal helper for transfer shares

* fix: Move accrue outside helper

---------

Co-authored-by: DhairyaSethi <55102840+DhairyaSethi@users.noreply.github.com>
Co-authored-by: YBM <31329384+yan-man@users.noreply.github.com>

* rft: rename, cleanup (#563)

* rft: rename, cleanup

* feat: supplied -> added in hub

* fix: debt/borrow -> drawn; repay -> restore

* feat: baseDebt/premiumDebt rename

* fix: pr comments, cleanup

* feat: LH -> hub; cleanup

* chore: periods on natspec

* chore: final clean up

* fix: include deficit

* fix: more renaming

* fix: availableLiquidity -> liquidity

* fix: clean up PremiumDelta struct

* fix: debtIndex -> drawnIndex

* fix: baseDebt -> drawnDebt

* fix: base -> drawn; availLiq -> liq

* fix: base -> drawn; clarify shares

* test: hub -> hub1

* fix: ref correct input hub

* fix: rename liqHub

* chore: rm comment

* fix: pr comments

* fix: clean up, address pr comments

* fix: pr comments

* fix: availableliquidity -> liquidity

* fix: use preview conversions

* fix: link

* fix: base -> drawn, clean up

* feat: Pack Hub Structs (#591)

* Fix: present tense on events (#595)

* feat: Add Inflation Attack Protection (#588)

* feat: add inflation attack protection

* feat: add rounding test

* fix: comments

* chore: remove hub rp tests

* fix: added share price calculation

* fix: add cap tests

* fix: comments

* feat: Check existence when adding reserve (#593)

* test: Add Hub Configurator Tests (#575)

* feat: Remove existence check on spokes

* fix: Comments

* test: Can still withdraw from old fee receiver

* fix: Simplify test

* test: New fee receiver receiving funds

* chore: Clean tests

* fix: Pr comments

* fix: Keep old fee receiver config

* fix: Use existing fee receiver config

* fix: Address pr comments

* fix: Consistent fuzzing on access control tests

* chore: Cleanup test comments

* wip: Determine diff

* fix: Names and comments

* feat: Add natspec to addSpoke

* fix: Address pr comments

* fix: Address pr comments

* feat: Pack Spoke Structs (#602)

* feat: pack spoke structs

* fix: comments

* fix: cleanup

* fix: lint

* fix: small cleanup

* fix: use safecast in tests

* fix: lint

* fix: tests cleanup

* fix: comments

* feat: Add remaining configurator functions (#578)

* feat: add updateInterestRateData in HubConfigurator

* feat: Add updateLiquiationConfig in SpokeConfigurator

* feat: add updatePoisitionManager in SpokeConfigurator

* fix: change prefix to add for dyn config fns

* feat: add granular fns to update existing dyn config

* fix: comments

* fix: add missing hub configurator fns

* fix: comments

* feat: Add premiumDelta to Repay event (#610)

* fix: Stack too deep error

* style: Revert ternary condition change

* fix: fee share calc (#606)

* fix: fee share calc

* chore: cleanup

* test: more accurate accrual

* chore: rename smt script

* doc: AssetLogic.getFeeShares

* chore: snapshot

* doc: AssetLogic.getFeeShares

* feat: reinvestment (adds Sweep & Reclaim on Hub) (#619)

* feat: added reinvestment config vars

* feat: added sweeped to the shares accounting

* feat: updated addAsset() and tests

* feat: implemented implemented sweep and reclaim

* chore: fixed additional merge changes

* feat: fixed validation on sweep and reclaim

* refactor: renamed sweeped in swept

* chore: removed ILiquidityHub.sol leftover from merge

* feat: cleanup, events, upd borrow rate

* feat: fix restore preview, minor cleanup

* chore: fix failing test

* feat: remove reinvestment strat from addAsset

* chore: docs

* test: addAsset, updateReinvestmentStrategy on configurator

* chore: init tests

* feat: update borrow rate on hub.refresh, more tests for hub.sweep

* feat: disallow resetting reinvestment strategy if there is non zero amount reinvested

* chore: napspec, error name

* chore: natspec

* feat: rm updateBorrowRate on hub.refreshPremium

---------

Co-authored-by: frangellaemilio@gmail.com <frangellaemilio@gmail.com>

* feat: Prevent Liquidations Resulting in Dust Debt (#605)

* feat: initial impl of dust

* test: resolve current actualDebt, with assumption of no dust

* fix: refactor to minimimize internal calls; simplify testing

* test: cleanup

* test: dust tests

* test: test_calculateActualDebtToLiquidate_fuzz_debtToCover_dust

* test: dust scenario

* test: test_calculateActualDebtToLiquidate_fuzz_debtToRestoreCloseFactor_dust

* test: test_calculateActualDebtToLiquidate_fuzz_debtToRestoreCloseFactor_dust_totalBorrowerReserveDebt_lte_minLeftoverAmount

* test: test_calculateActualDebtToLiquidate_fuzz_debtToRestoreCloseFactor_dust_revertsWith_MustNotLeaveDust

* test: clean up

* fix: update liquidation event

* test: cleanup and dust tests

* test: debug prior tests

* test: resolve failing

* fix: resolve remaining tests

* test: initial fix for specific scenario

* test: resolve LiquidationAvailableCollateralToLiquidateTest

* test: fix test_calculateAvailableCollateralToLiquidate_fuzz_borrowerCollateralBalance_lt_maxCollateralToLiquidate

* chore: gas report

* fix: allow for debt reserve dust if collateral side is fully liq

* fix: comment

* test: initial dust scenarios

* test: test_liquidationCall_fuzz_dust_scenario1_revertsWith_MustNotLeaveDust

* test: clean up test_liquidationCall_fuzz_dust_scenario1_revertsWith_MustNotLeaveDust

* test: test_liquidationCall_fuzz_dust_scenario1_revertsWith_MustNotLeaveDust_debtToRestoreCloseFactor

* test: test_liquidationCall_fuzz_dust_scenario1_deficit

* test: isolate test scenarios

* test: deficits when debt is above the min leftover base threshold

* test: reverting on dust

* fix: emit reserveIds in event

* tests: additional LiquidationAvailableCollateralToLiquidateTest

* test: test_liquidationCall_borrowerReserveDebtThreshold_valid

* fix: test_calculateAvailableCollateralToLiquidate_fuzz_borrowerCollateralBalance_lt_maxCollateralToLiquidate

* test: remaining minLeftoverBase scenarios

* chore: clean up, rm logs, add comments

* chore: gas snapshot

* fix: rm logging

* chore: comments, cleanup

* fix: tests

* fix: comments

* fix: replace assume with bound

* fix: comments

---------

Co-authored-by: Alexandru Niculae <43644109+avniculae@users.noreply.github.com>

* opt: pack drawnRate within 96 bits (#623)

* opt: shrink drawn rate to 96 bits

* fix: revert unneeded

* chore: avoid caching if read once

* feat: Add deficit and swept to IR Strategy (#624)

* feat: added reinvestment config vars

* feat: added sweeped to the shares accounting

* feat: updated addAsset() and tests

* feat: implemented implemented sweep and reclaim

* chore: fixed additional merge changes

* feat: fixed validation on sweep and reclaim

* refactor: renamed sweeped in swept

* chore: removed ILiquidityHub.sol leftover from merge

* feat: cleanup, events, upd borrow rate

* feat: fix restore preview, minor cleanup

* chore: fix failing test

* feat: remove reinvestment strat from addAsset

* chore: docs

* test: addAsset, updateReinvestmentStrategy on configurator

* chore: init tests

* feat: update borrow rate on hub.refresh, more tests for hub.sweep

* feat: disallow resetting reinvestment strategy if there is non zero amount reinvested

* chore: napspec, error name

* chore: natspec

* feat: rm updateBorrowRate on hub.refreshPremium

* wip: Add swept and deficit to ir strategy

* chore: fix swept test, minor cleanup

* fix: Remove drawn from liquidity in tests

* fix: Pr comments

* fix: Change test name

---------

Co-authored-by: frangellaemilio@gmail.com <frangellaemilio@gmail.com>
Co-authored-by: DhairyaSethi <55102840+DhairyaSethi@users.noreply.github.com>

* wip: merge in main, debugging tests

* wip: Fix more tests

* wip: Fix tests

* feat: Fix tests

* fix: Restore tests

---------

Co-authored-by: Alexandru-Vlad Niculae <43644109+avniculae@users.noreply.github.com>
Co-authored-by: miguelmtzinf <miguelmtz.mail@gmail.com>
Co-authored-by: YBM <31329384+yan-man@users.noreply.github.com>
Co-authored-by: dhairya <55102840+DhairyaSethi@users.noreply.github.com>
Co-authored-by: miguelmtz <36620902+miguelmtzinf@users.noreply.github.com>
Co-authored-by: frangellaemilio@gmail.com <frangellaemilio@gmail.com>
DhairyaSethi added a commit that referenced this pull request Aug 15, 2025
* refactor: internal methods, errors, resolve tests

* test: hub remove

* test: debugging test_remove_all_with_interest

* test: resolve test_remove_all_with_interest

* test: resolve test_remove_fuzz

* test: resolve test_remove_fuzz_all_liquidity_with_interest

* test: test_remove_fuzz_multi_spoke_with_interest

* chore: gas report

* fix: hub names

* chore: pr comments

* chore: pr comments

* test: restore test_restore_revertsWith_SurplusAmountRestored

* chore: assertEq helpers

* test: resolve test_restore_partial_same_block

* test: resolve test_restore_revertsWith_SurplusAmountRestored_with_interest

* test: resolve

* test: resolve test_restore_full_amount_with_interest

* test: resolve test_restore_full_amount_with_interest_and_premium

* test: resolve test_restore_partial_base

* test: resolve test_restore_fuzz_full_amount_with_interest

* test: resolve test_restore_fuzz_full_amount_with_interest_and_premium

* test: rm unused tests

* test: resolve remaining restore tests

* fix: rm test struct; clean up

* fix: tests with premium debt, unchanged

* chore: comments, rm unused

* test: cleanup

* test: resolve

* Fix Hub Restore Tests (#629)

* feat: Refactor flags (#553)

* feat: remove collateral flag

* feat: refactor hub flags

* feat: refactor spoke flags

* feat: update hub configurator

* fix: check spoke active on payFee

* fix: order operation nit

* fix: comments

* fix: nits

* fix: gas reports

* fix: comments

* feat: keep feeReceiver active flag constant in configurator

* fix: comments

* fix: comments

* fix: Address comments

* fix: address comments

* chore: gas snapshots

* fix: Fix draw validation

* chore: gas

---------

Co-authored-by: miguelmtzinf <miguelmtz.mail@gmail.com>
Co-authored-by: YBM <31329384+yan-man@users.noreply.github.com>

* feat: Allow DAO to update any user dynamic risk configuration (#564)

* feat: allow dao to upd user dyn config

* chore: reorder for readability

* fix: pr comments

* feat: Add Hub Conversion Functions (#540)

* feat: Add previews for basic actions

* feat: Add preview shares functions

* feat: Adjust conversion functions

* fix: Use preview functions in src

* fix: Use preview where possible

* fix: Remove using preview where unneeded

* fix: Internalize previewOffset

* fix: Pr comments

* fix: Add natspec to _previewOffset

* fix: Simplify dev comment

* fix: Revert natspec change on previewOffset

* fix: Rename other preview getters

* fix: fix docs

---------

Co-authored-by: miguelmtzinf <miguelmtz.mail@gmail.com>

* feat: update existing dyn config (#541)

* feat: update existing dyn config

* wip: config tests cleanup

* chore: snapshots

* chore: finalise merge

* fix: rename and tests

* fix: revert to uint16 input, cleanup

* chore: reorder

* chore: finalise merge

* feat: rm safeCast, resolve shadowing in tests

* feat: distinguish dyn conf update with new added event

* feat: rm abstraction, fix event on add reserve, natspec

* fix: apply explicit rounding direction on all math operations (#543)

* rft: explicit rounding

* fix: round up on getUserDebtInBaseCurrency

* chore: finalise merge

* fix: pr comments

* chore: rm dup

* fix: rename wadify -> toWad, dewadify -> fromWad

* feat: Add more equivalent fees calc in previewFeeShares (#458)

* feat: Add more equivalent fees calc in previewFeeShares

* chore: disables gas checks

* tmp: skip snapshot check (revert before merging)

* fix: separate impl of fee shares

* test: multi-user case

* fix: test

* feat: underestimate treasury fees and fix tests

* test: multi spoke

* fix: treasury spoke tests

* fix: treasury spoke tests

* fix: pr comment

---------

Co-authored-by: dhairya <55102840+DhairyaSethi@users.noreply.github.com>
Co-authored-by: YBM <31329384+yan-man@users.noreply.github.com>

* feat: Deficit accounting via dedicated hub method (#472)

* feat: simplify restore flow (#574)

* feat: simplify restore flow

* feat: make restore like its now

* feat: emit premium amt

* fix: hub._validateRestore after accrual & before state changes

* fix: settle premium debt in reportDeficit

* test: _checkDeficitReportedEvents

* chore: bring back test

* chore: consolidate settlePremiumDebt

* chore: bring back fee share comment

* feat: Eliminate deficit (#583)

* feat: clear deficit

* fix: pr comments

* chore: rename to eliminate deficit

* feat: simplify restore flow (#574)

* feat: simplify restore flow

* feat: make restore like its now

* feat: emit premium amt

* fix: hub._validateRestore after accrual & before state changes

* fix: settle premium debt in reportDeficit

* test: _checkDeficitReportedEvents

* chore: bring back test

* chore: consolidate settlePremiumDebt

* chore: bring back fee share comment

chore: finalise merge

* chore: disallow excess eliminate deficit in, reorder fn

* feat: rm reserve accounting on spoke (#468)

* feat: rm reserve accounting on spoke

* chore: snapshots

* chore: snapshot

* feat: rm reserve list

* chore: finalise merge

* fix: rm unnecessary liquidation accounting

---------

Co-authored-by: YBM <31329384+yan-man@users.noreply.github.com>

* feat: spoke/base minimal interfaces (#589)

* feat: Transfer added shares between spokes (#590)

* feat: rm reserve accounting on spoke

* chore: snapshots

* chore: snapshot

* feat: rm reserve list

* chore: finalise merge

* fix: rm unnecessary liquidation accounting

* feat: Initial implementation

* test: Basic tests

* test: Basic functionalities and reverts

* fix: Address pr comments

* fix: Address pr comments

* fix: Remove unchecked

* fix: pr comments

* feat: Internal helper for transfer shares

* fix: Move accrue outside helper

---------

Co-authored-by: DhairyaSethi <55102840+DhairyaSethi@users.noreply.github.com>
Co-authored-by: YBM <31329384+yan-man@users.noreply.github.com>

* rft: rename, cleanup (#563)

* rft: rename, cleanup

* feat: supplied -> added in hub

* fix: debt/borrow -> drawn; repay -> restore

* feat: baseDebt/premiumDebt rename

* fix: pr comments, cleanup

* feat: LH -> hub; cleanup

* chore: periods on natspec

* chore: final clean up

* fix: include deficit

* fix: more renaming

* fix: availableLiquidity -> liquidity

* fix: clean up PremiumDelta struct

* fix: debtIndex -> drawnIndex

* fix: baseDebt -> drawnDebt

* fix: base -> drawn; availLiq -> liq

* fix: base -> drawn; clarify shares

* test: hub -> hub1

* fix: ref correct input hub

* fix: rename liqHub

* chore: rm comment

* fix: pr comments

* fix: clean up, address pr comments

* fix: pr comments

* fix: availableliquidity -> liquidity

* fix: use preview conversions

* fix: link

* fix: base -> drawn, clean up

* feat: Pack Hub Structs (#591)

* Fix: present tense on events (#595)

* feat: Add Inflation Attack Protection (#588)

* feat: add inflation attack protection

* feat: add rounding test

* fix: comments

* chore: remove hub rp tests

* fix: added share price calculation

* fix: add cap tests

* fix: comments

* feat: Check existence when adding reserve (#593)

* test: Add Hub Configurator Tests (#575)

* feat: Remove existence check on spokes

* fix: Comments

* test: Can still withdraw from old fee receiver

* fix: Simplify test

* test: New fee receiver receiving funds

* chore: Clean tests

* fix: Pr comments

* fix: Keep old fee receiver config

* fix: Use existing fee receiver config

* fix: Address pr comments

* fix: Consistent fuzzing on access control tests

* chore: Cleanup test comments

* wip: Determine diff

* fix: Names and comments

* feat: Add natspec to addSpoke

* fix: Address pr comments

* fix: Address pr comments

* feat: Pack Spoke Structs (#602)

* feat: pack spoke structs

* fix: comments

* fix: cleanup

* fix: lint

* fix: small cleanup

* fix: use safecast in tests

* fix: lint

* fix: tests cleanup

* fix: comments

* feat: Add remaining configurator functions (#578)

* feat: add updateInterestRateData in HubConfigurator

* feat: Add updateLiquiationConfig in SpokeConfigurator

* feat: add updatePoisitionManager in SpokeConfigurator

* fix: change prefix to add for dyn config fns

* feat: add granular fns to update existing dyn config

* fix: comments

* fix: add missing hub configurator fns

* fix: comments

* feat: Add premiumDelta to Repay event (#610)

* fix: Stack too deep error

* style: Revert ternary condition change

* fix: fee share calc (#606)

* fix: fee share calc

* chore: cleanup

* test: more accurate accrual

* chore: rename smt script

* doc: AssetLogic.getFeeShares

* chore: snapshot

* doc: AssetLogic.getFeeShares

* feat: reinvestment (adds Sweep & Reclaim on Hub) (#619)

* feat: added reinvestment config vars

* feat: added sweeped to the shares accounting

* feat: updated addAsset() and tests

* feat: implemented implemented sweep and reclaim

* chore: fixed additional merge changes

* feat: fixed validation on sweep and reclaim

* refactor: renamed sweeped in swept

* chore: removed ILiquidityHub.sol leftover from merge

* feat: cleanup, events, upd borrow rate

* feat: fix restore preview, minor cleanup

* chore: fix failing test

* feat: remove reinvestment strat from addAsset

* chore: docs

* test: addAsset, updateReinvestmentStrategy on configurator

* chore: init tests

* feat: update borrow rate on hub.refresh, more tests for hub.sweep

* feat: disallow resetting reinvestment strategy if there is non zero amount reinvested

* chore: napspec, error name

* chore: natspec

* feat: rm updateBorrowRate on hub.refreshPremium

---------

Co-authored-by: frangellaemilio@gmail.com <frangellaemilio@gmail.com>

* feat: Prevent Liquidations Resulting in Dust Debt (#605)

* feat: initial impl of dust

* test: resolve current actualDebt, with assumption of no dust

* fix: refactor to minimimize internal calls; simplify testing

* test: cleanup

* test: dust tests

* test: test_calculateActualDebtToLiquidate_fuzz_debtToCover_dust

* test: dust scenario

* test: test_calculateActualDebtToLiquidate_fuzz_debtToRestoreCloseFactor_dust

* test: test_calculateActualDebtToLiquidate_fuzz_debtToRestoreCloseFactor_dust_totalBorrowerReserveDebt_lte_minLeftoverAmount

* test: test_calculateActualDebtToLiquidate_fuzz_debtToRestoreCloseFactor_dust_revertsWith_MustNotLeaveDust

* test: clean up

* fix: update liquidation event

* test: cleanup and dust tests

* test: debug prior tests

* test: resolve failing

* fix: resolve remaining tests

* test: initial fix for specific scenario

* test: resolve LiquidationAvailableCollateralToLiquidateTest

* test: fix test_calculateAvailableCollateralToLiquidate_fuzz_borrowerCollateralBalance_lt_maxCollateralToLiquidate

* chore: gas report

* fix: allow for debt reserve dust if collateral side is fully liq

* fix: comment

* test: initial dust scenarios

* test: test_liquidationCall_fuzz_dust_scenario1_revertsWith_MustNotLeaveDust

* test: clean up test_liquidationCall_fuzz_dust_scenario1_revertsWith_MustNotLeaveDust

* test: test_liquidationCall_fuzz_dust_scenario1_revertsWith_MustNotLeaveDust_debtToRestoreCloseFactor

* test: test_liquidationCall_fuzz_dust_scenario1_deficit

* test: isolate test scenarios

* test: deficits when debt is above the min leftover base threshold

* test: reverting on dust

* fix: emit reserveIds in event

* tests: additional LiquidationAvailableCollateralToLiquidateTest

* test: test_liquidationCall_borrowerReserveDebtThreshold_valid

* fix: test_calculateAvailableCollateralToLiquidate_fuzz_borrowerCollateralBalance_lt_maxCollateralToLiquidate

* test: remaining minLeftoverBase scenarios

* chore: clean up, rm logs, add comments

* chore: gas snapshot

* fix: rm logging

* chore: comments, cleanup

* fix: tests

* fix: comments

* fix: replace assume with bound

* fix: comments

---------

Co-authored-by: Alexandru Niculae <43644109+avniculae@users.noreply.github.com>

* opt: pack drawnRate within 96 bits (#623)

* opt: shrink drawn rate to 96 bits

* fix: revert unneeded

* chore: avoid caching if read once

* feat: Add deficit and swept to IR Strategy (#624)

* feat: added reinvestment config vars

* feat: added sweeped to the shares accounting

* feat: updated addAsset() and tests

* feat: implemented implemented sweep and reclaim

* chore: fixed additional merge changes

* feat: fixed validation on sweep and reclaim

* refactor: renamed sweeped in swept

* chore: removed ILiquidityHub.sol leftover from merge

* feat: cleanup, events, upd borrow rate

* feat: fix restore preview, minor cleanup

* chore: fix failing test

* feat: remove reinvestment strat from addAsset

* chore: docs

* test: addAsset, updateReinvestmentStrategy on configurator

* chore: init tests

* feat: update borrow rate on hub.refresh, more tests for hub.sweep

* feat: disallow resetting reinvestment strategy if there is non zero amount reinvested

* chore: napspec, error name

* chore: natspec

* feat: rm updateBorrowRate on hub.refreshPremium

* wip: Add swept and deficit to ir strategy

* chore: fix swept test, minor cleanup

* fix: Remove drawn from liquidity in tests

* fix: Pr comments

* fix: Change test name

---------

Co-authored-by: frangellaemilio@gmail.com <frangellaemilio@gmail.com>
Co-authored-by: DhairyaSethi <55102840+DhairyaSethi@users.noreply.github.com>

* wip: merge in main, debugging tests

* wip: Fix more tests

* wip: Fix tests

* feat: Fix tests

* fix: Restore tests

---------

Co-authored-by: Alexandru-Vlad Niculae <43644109+avniculae@users.noreply.github.com>
Co-authored-by: miguelmtzinf <miguelmtz.mail@gmail.com>
Co-authored-by: YBM <31329384+yan-man@users.noreply.github.com>
Co-authored-by: dhairya <55102840+DhairyaSethi@users.noreply.github.com>
Co-authored-by: miguelmtz <36620902+miguelmtzinf@users.noreply.github.com>
Co-authored-by: frangellaemilio@gmail.com <frangellaemilio@gmail.com>

* fix: Rename variables in tests

* fix: Namings

* test: Paused and frozen restore cases

* test: Premium deltas differing

* fix: Pr comments

* chore: Remove health factor tests

* fix: Remove todo comments

---------

Co-authored-by: Cheyenne Atapour <cheyenneatapour@gmail.com>
Co-authored-by: Alexandru-Vlad Niculae <43644109+avniculae@users.noreply.github.com>
Co-authored-by: miguelmtzinf <miguelmtz.mail@gmail.com>
Co-authored-by: dhairya <55102840+DhairyaSethi@users.noreply.github.com>
Co-authored-by: miguelmtz <36620902+miguelmtzinf@users.noreply.github.com>
Co-authored-by: frangellaemilio@gmail.com <frangellaemilio@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

spoke: emit reserve id instead of asset id in liquidation call event research - implement MIN_LEFTOVER_BASE threshold

4 participants