Skip to content

Commit ca2245c

Browse files
committed
fix: settle ARM withdrawal yield accounting at claim for escrow-generation ARMs
The Ethena and multi-asset ARMs escrow shares at requestRedeem (they stay in totalSupply and totalAssets is unchanged) and only reduce totalAssets when claimRedeem pays out. Booking totalWithdrawals into totalYield at request time therefore created a phantom +amount yield at request and a matching -amount at claim — seen as negative daily yield on the sUSDe ARM on 2026-07-27 (10.0042 USDe requested 7/26 16:40, claimed 7/27 01:55). Legacy ARMs (Lido/EtherFi/OS) deduct queued assets from totalAssets at request time, so they keep request-time accounting.
1 parent 5c8a0a5 commit ca2245c

1 file changed

Lines changed: 11 additions & 1 deletion

File tree

src/templates/origin-arm/origin-arm.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export const createOriginARMProcessors = ({
7575
}): Processor[] => {
7676
const isMultiAsset = armType === 'multi-asset'
7777
if (!isMultiAsset && !token1) throw new Error(`${name}: token1 is required for a legacy ARM`)
78+
const withdrawalsSettleAtClaim = isMultiAsset || armType === 'ethena'
7879
const redeemRequestedFilter = logFilter({
7980
address: [armAddress],
8081
topic0: [originLidoArmAbi.events.RedeemRequested.topic],
@@ -618,8 +619,16 @@ export const createOriginARMProcessors = ({
618619
redemptionMap.set(row.id, row)
619620
}
620621
}
622+
// Add withdrawals back when the contract's totalAssets() stops counting them. Legacy ARMs
623+
// (Lido/EtherFi/OS) deduct the queued assets at requestRedeem, so redemptions are added back
624+
// from request time. Escrow-generation ARMs (Ethena, multi-asset) keep queued shares in
625+
// totalSupply and only reduce totalAssets when claimRedeem pays out — request-time accounting
626+
// there books a phantom +amount yield at request and a matching -amount at claim (seen as
627+
// negative daily yield on the sUSDe ARM on 2026-07-27).
621628
const calculateTotalYield = (state: ArmState) =>
622-
state.totalAssets - state.totalDeposits + state.totalWithdrawals
629+
state.totalAssets -
630+
state.totalDeposits +
631+
(withdrawalsSettleAtClaim ? state.totalWithdrawalsClaimed : state.totalWithdrawals)
623632
// Accumulate a swap's trading profit + liquidity-terms volume into the per-(date:asset)
624633
// running total that feeds ArmDailyAssetYield.tradingYield.
625634
const accrueTradingYield = (block: Block, asset: string, spread: bigint, token0Volume: bigint) => {
@@ -829,6 +838,7 @@ export const createOriginARMProcessors = ({
829838
const event = originLidoArmAbi.events.RedeemClaimed.decode(log)
830839
const state = await getCurrentState(block)
831840
state.totalWithdrawalsClaimed += event.assets
841+
state.totalYield = calculateTotalYield(state)
832842
}
833843
if (feeCollectedFilter.matches(log)) {
834844
const event = originLidoArmAbi.events.FeeCollected.decode(log)

0 commit comments

Comments
 (0)