Skip to content

feat: LLAMMA concept - window oracle, partial liquidation, one-way AMM - #256

Open
phil-svg wants to merge 2 commits into
curvefi:masterfrom
phil-svg:llamma-concept
Open

phil-svg wants to merge 2 commits into
curvefi:masterfrom
phil-svg:llamma-concept

Conversation

@phil-svg

Copy link
Copy Markdown
  • price_oracles/v2/WindowOracle.vy (new): reads its own pool's EMA, follows the highs and lows of the last 36 s and moves at most 0.2 % per 12 s
  • controller.vy: a third-party liquidation repays only enough to bring health back to +100 % (TARGET_HEALTH); the bonus slides from 0.5 % at the line to 1.5 % at health -5 % and below
  • AMM.vy: one-way AMM (DL off): collateral sold as the price falls is never bought back; bands holding converted crvUSD stay usable for new loans. DL on: original APP.vy
  • ControllerView.vy: previews follow the controller (debt repaid from the loan's own crvUSD, the liquidation cap)

- price_oracles/v2/WindowOracle.vy (new): reads its own pool's EMA, follows the
  highs and lows of the last 36 s and moves at most 0.2 % per 12 s
- controller.vy: a third-party liquidation repays only enough to bring health
  back to +100 % (TARGET_HEALTH); the bonus slides from 0.5 % at the line to
  1.5 % at health -5 % and below
- AMM.vy: one-way AMM (DL off): collateral sold as the price falls is never
  bought back; bands holding converted crvUSD stay usable for new loans
- ControllerView.vy: previews follow the controller (debt repaid from the
  loan's own crvUSD, the liquidation cap)
A lend market lets out at most 15 % of its borrow_cap at once, and 5 % of
borrow_cap frees up per day. A repay frees room at once. A borrow above
the limit reverts with "Borrow limit exceeded". On a $50M cap an attacker
with mispriced collateral takes $7.5M in one tx and $10M in 24 h instead
of $50M at once; emptying the market takes 17 days.

- LendController.vy: one packed slot _recent_debt_packed
  (timestamp | (core.repaid + recent debt) << 40) and a transient
  stashed_amount written in on_borrowed_token_transfer_out and read in
  _on_debt_increased, so collect_fees never counts. No repay hook:
  repaying moves core.repaid. New view max_borrowable_now(_d_collateral,
  _N, _user) forwards the slot to the view contract.
- LendControllerView.vy: max_borrowable_now = min(max_borrowable,
  room under the limit). max_borrowable and tokens_to_shrink unchanged.
- ILendController.vyi: max_borrowable_now entry.
- controller.vy: `loans` moved to the end of the storage block and
  `initializes: core` moved below LendController's own variables, so they
  take small slots (bytes only, no behaviour change). MintController's
  ABI lists `loans` at a different index, same entries.

Sizes: LendController blueprint 24,575 (EIP-170 24,576), LendControllerView
13,804. Gas: create_loan, borrow_more +7,612; first borrow in a market
+24,712; repay, liquidate 0; Vault withdraw, redeem -11; a few views +1
(core._view moved slot). ABI: two additions (max_borrowable_now on
LendController and LendControllerView), nothing else changes.

Replayed on every borrow in the crvUSD markets with a ceiling of $50M or
more (Jun 2023 - Oct 2026): 0 of 28,043 real borrows stopped, all 12
Conic-exploit flash borrows stopped. Known limit: a repay frees room, so
an attacker holding good debt opened earlier can roll it onto a bad
position in the same tx (cannot be flash funded). Front ends should read
max_borrowable_now; max_borrowable ignores the limit.

This branch has not been deployed

No deployments
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.

1 participant