Skip to content

Commit 52bd0ad

Browse files
committed
tweak arm renderer output
1 parent d69fb48 commit 52bd0ad

1 file changed

Lines changed: 34 additions & 39 deletions

File tree

  • src/notify/event/renderers

src/notify/event/renderers/arm.ts

Lines changed: 34 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ interface ArmConfig {
4747
symbol1: string
4848
token0: string
4949
token1: string
50-
// ERC4626 vault token whose rate needs converting (e.g. sUSDe)
51-
// When set, rates are adjusted by the vault's convertToAssets rate
50+
// ERC4626 vault token (e.g. sUSDe). When set, traderates are raw spread rates
51+
// and the vault's convertToAssets rate must be applied for output estimation.
5252
vaultToken?: string
5353
}
5454

@@ -95,7 +95,7 @@ registerArm({
9595
// Cache traderates per ARM address
9696
const traderateCache = new Map<string, { traderate0: bigint; traderate1: bigint }>()
9797

98-
// Cache vault exchange rate (e.g. sUSDe → USDe)
98+
// Cache vault exchange rate (e.g. sUSDe → USDe via convertToAssets)
9999
const vaultRateCache = new Map<string, bigint>()
100100
const ONE = 10n ** 18n
101101

@@ -116,8 +116,8 @@ async function getVaultRate(ctx: RendererCtx, block: RendererBlock, vaultToken:
116116
}
117117

118118
async function getTraderates(
119-
ctx: Parameters<Parameters<typeof registerEventRenderer>[1]>[0]['ctx'],
120-
block: Parameters<Parameters<typeof registerEventRenderer>[1]>[0]['log']['block'],
119+
ctx: RendererCtx,
120+
block: RendererBlock,
121121
armAddress: string,
122122
): Promise<{ traderate0: bigint; traderate1: bigint } | undefined> {
123123
const cached = traderateCache.get(armAddress)
@@ -133,7 +133,7 @@ async function getTraderates(
133133
}
134134
}
135135

136-
// TraderateChanged renderer
136+
// TraderateChanged renderer — shows raw ARM spread rates
137137
registerEventRenderer(TraderateChanged.topic, async (params) => {
138138
const arm = armConfigs.get(params.log.address.toLowerCase())
139139
if (!arm) return defaultEventRenderer(params)
@@ -146,18 +146,9 @@ registerEventRenderer(TraderateChanged.topic, async (params) => {
146146
traderate1: data.traderate1,
147147
})
148148

149-
// For vault tokens (e.g. sUSDe), adjust rates to show USDe-equivalent value
150-
let sellRate = 10n ** 72n / data.traderate0 // 1e36 precision
151-
let buyRate = data.traderate1 // 1e36 precision
152-
let rateLabel = `${arm.symbol1}/${arm.symbol0}`
153-
154-
if (arm.vaultToken) {
155-
const vaultRate = await getVaultRate(params.ctx, params.log.block, arm.vaultToken)
156-
// Multiply by vault rate to convert sUSDe amounts to USDe-equivalent
157-
sellRate = (sellRate * vaultRate) / ONE
158-
buyRate = (buyRate * vaultRate) / ONE
159-
rateLabel = `${arm.symbol0}/${arm.symbol0}` // e.g. USDe/USDe
160-
}
149+
const sellRate = 10n ** 72n / data.traderate0 // 1e36 precision
150+
const buyRate = data.traderate1 // 1e36 precision
151+
const rateLabel = `${arm.symbol1}/${arm.symbol0}`
161152

162153
renderEventDiscordEmbed(params, {
163154
fields: [
@@ -210,33 +201,37 @@ registerEventRenderer(erc20Abi.events.Transfer.topic, async (params) => {
210201
]
211202

212203
if (rates) {
213-
// traderate0 is inverted: sell price = 1e72 / traderate0 (in 1e36 precision)
214-
// traderate1 is direct: buy price = traderate1 (in 1e36 precision)
204+
// Traderates are raw spread rates (~1.0). For vault tokens (e.g. sUSDe),
205+
// the ARM contract applies the vault conversion internally during swaps,
206+
// so we must apply it here too for output estimation.
207+
//
208+
// traderate0: for 1 token0 from trader, how many token1 the pool sends (raw)
209+
// traderate1: for 1 token1 from trader, how many token0 the pool sends (raw)
215210
let outAmount: bigint
216-
let rate: number
211+
217212
if (isToken0In) {
218-
// Selling token0 → receive token1 at sell price
219-
const sellRate = 10n ** 72n / rates.traderate0
220-
outAmount = (data.value * sellRate) / 10n ** 36n
221-
rate = Number(sellRate) / 1e36
213+
// token0 → token1: outAmount = inAmount * traderate0 / 1e36
214+
// For vault: actual token1 out = raw output / vaultRate (fewer vault tokens)
215+
outAmount = (data.value * rates.traderate0) / 10n ** 36n
216+
if (arm.vaultToken) {
217+
const vaultRate = await getVaultRate(params.ctx, params.log.block, arm.vaultToken)
218+
outAmount = (outAmount * ONE) / vaultRate
219+
}
222220
} else {
223-
// Selling token1 → receive token0 at buy price
224-
outAmount = rates.traderate1 > 0n ? (data.value * 10n ** 36n) / rates.traderate1 : 0n
225-
rate = Number(rates.traderate1) / 1e36
226-
}
227-
228-
// For vault tokens, convert output to underlying-equivalent for rate display
229-
if (arm.vaultToken) {
230-
const vaultRate = await getVaultRate(params.ctx, params.log.block, arm.vaultToken)
231-
if (isToken0In) {
232-
// Output is in vault token (sUSDe), convert to USDe-equivalent for rate
233-
rate = (rate * Number(vaultRate)) / 1e18
234-
} else {
235-
// Input is vault token (sUSDe), adjust rate
236-
rate = (rate * 1e18) / Number(vaultRate)
221+
// token1 → token0: outAmount = inAmount * traderate1 / 1e36
222+
// For vault: actual token0 out = inAmount * vaultRate * traderate1 / 1e36 / 1e18
223+
outAmount = (data.value * rates.traderate1) / 10n ** 36n
224+
if (arm.vaultToken) {
225+
const vaultRate = await getVaultRate(params.ctx, params.log.block, arm.vaultToken)
226+
outAmount = (outAmount * vaultRate) / ONE
237227
}
238228
}
239229

230+
// Rate = token0/token1, derived from actual in/out amounts
231+
const rate = isToken0In
232+
? Number(data.value) / Number(outAmount)
233+
: Number(outAmount) / Number(data.value)
234+
240235
fields.push({
241236
name: formatAmount(outAmount, 18, { maximumFractionDigits: 6 }),
242237
value: `${outSymbol} out`,

0 commit comments

Comments
 (0)