Skip to content

[midnight adapter] Adapter#786

Draft
adhusson wants to merge 59 commits intomainfrom
feat/adapter-v2
Draft

[midnight adapter] Adapter#786
adhusson wants to merge 59 commits intomainfrom
feat/adapter-v2

Conversation

@adhusson
Copy link
Copy Markdown
Contributor

@adhusson adhusson commented Nov 7, 2025

TODO

  • events
  • check static vs dynamic castings (all static probably ok)
  • tests
  • specs

Things to decide

  • prev pointer hint vs another data structure (currently: prev pointer hint)
  • interest accrual gas: allow partial accruals or have a max that prevents DOS. Can do max number of active maturities, or a different data structure as above) (currently: nothing)
  • can the adapter get liquidity from an adapter or only from idle (currently: idle only)
  • how to decide whether a sell is allowed or not (currently: buffer check)
  • how to manange trading fee on force deallocate (currently: user loses the fee)

Copy link
Copy Markdown
Contributor

@peyha peyha left a comment

Choose a reason for hiding this comment

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

Nice 🔥 🔥 using a linked list to manage maturities is smart

If I understand correctly, the allocation workflow should be

An allocator creates a make offer for the vault
A taker takes this offer onchain
| morphoV2 calls onBuy on the adapter
| | the adapter updates its state
| | the adapter calls allocate on its parent vault
| | | the vault V2 calls allocate on the market V2 adapter
| | | | the adapter returns the corresponding ids and allocated assets

Comment thread src/adapters/MorphoMarketV2Adapter.sol Outdated
_positions[obligationId].growth += gainedGrowth;
_maturities[obligation.maturity].growthLostAtMaturity += gainedGrowth;
currentGrowth += gainedGrowth;
} else {
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.

what is this usecase for ? buying after maturity ? the vault is likely to get liquidated so not sure there is a huge usecase

Comment thread src/adapters/MorphoMarketV2Adapter.sol Outdated
Comment on lines +15 to +16
/// @dev Losses are immdiately accounted minus a discount applied to the remaining interest to be earned, in proportion
/// to the relative sizes of the loss and the adapter's position in the obligation hit by the loss.
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.

not very clear

Comment thread src/adapters/MorphoMarketV2Adapter.sol Outdated
/* ACCOUNTING */

uint256 public _totalAssets;
uint48 public lastUpdate;
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.

I guess uint48 is for packing, so why not uint64? It is much more likely to be handled by all EVM tools such as certora

Comment thread src/adapters/MorphoMarketV2Adapter.sol Outdated

// Do not cleanup the linked list if we end up at 0 growth
function withdraw(Obligation memory obligation, uint256 obligationUnits, uint256 shares) external {
require(IVaultV2(parentVault).isAllocator(msg.sender), NotAuthorized());
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.

shouldn't lenders also be able to trigger a withdraw on morpho V2 ?

Comment thread src/adapters/MorphoMarketV2Adapter.sol Outdated
accrueInterest();
if (obligation.maturity > block.timestamp) {
uint128 timeToMaturity = uint128(obligation.maturity - block.timestamp);
uint128 gainedGrowth = ((obligationUnits - buyerAssets) / timeToMaturity).toUint128();
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.

there could be some roundings by defining growth with this, not sure it's an issue though

Comment thread src/adapters/MorphoMarketV2Adapter.sol Outdated
nextMaturity = firstMaturity;
} else {
nextMaturity = _maturities[prevMaturity].nextMaturity;
require(nextMaturity != 0, IncorrectHint());
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.

not sure we should revert on this, a vault v2 could set multiple offers (with both sell and buy) and this could create some path dependency on the execution of these offers (what if the sell offer removes the prevMaturity for some buy)

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.

in this case, you could just use nextMaturity=firstMaturity

Comment thread src/adapters/MorphoMarketV2Adapter.sol Outdated

uint256 _totalAssetsBefore = _totalAssets;
removeUnits(obligation, obligationUnits);
require(vaultBuffer >= _totalAssetsBefore.zeroFloorSub(_totalAssets), BufferTooLow());
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.

as discussed during the bootcamp, using this specific buffer is the second idea but it lacks the ability to sell at a loss in a controlled way

@adhusson adhusson changed the title V2 Adapter [midnight adapter] Adapter Apr 17, 2026
/// @dev `data` is used for new maturity insertions.
/// @dev It should encode a maturity present in the linked list.
/// @dev That maturity should be earlier than the inserted obligation maturity.
function onBuy(
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.

would it be worth implementing a, additional callback in this function ? rationale is for rolling you might want to withdraw from the previous obligation in this call so the vault could do it in the callback. Two ways to achieve this

  • implement an arbitrary callback, essentially converting bytes memory data to (address callback, bytes memory callbackData)
  • implement a way to withdraw from one or more obligations, converting bytes memory data to (bytes32, amount)[] specifying a list of obligation ids and amount to withdraw

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.

2 participants