From dea0e4a0c6711905f7907cd28111571b6bc11a45 Mon Sep 17 00:00:00 2001 From: itofarina Date: Tue, 21 Nov 2023 17:32:41 -0300 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20market-update:=20monitor=20global?= =?UTF-8?q?=20utilization?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- actions/onMarketUpdate.ts | 33 +++++++ test/onMarketUpdate.spec.ts | 1 + test/payloads/payload.json | 169 ++++++++++++++++++++++++++++-------- 3 files changed, 167 insertions(+), 36 deletions(-) diff --git a/actions/onMarketUpdate.ts b/actions/onMarketUpdate.ts index 2ee59c2..f978572 100755 --- a/actions/onMarketUpdate.ts +++ b/actions/onMarketUpdate.ts @@ -31,6 +31,7 @@ export default (async ({ storage, secrets, gateways }, { 5: 'https://goerli.etherscan.io', 10: 'https://optimistic.etherscan.io', }[chainId] ?? 'https://etherscan.io'; + const app = 'https://app.exact.ly'; const [{ address: previewerAddress }, rpc] = await Promise.all([ import(`@exactly/protocol/deployments/${network}/Previewer.json`) as Promise<{ address: string }>, @@ -53,6 +54,7 @@ export default (async ({ storage, secrets, gateways }, { const [exactly] = previewer.interface.decodeFunctionResult('exactly', exactlyData) as [Previewer.MarketAccountStructOutput[]]; const [ icons, slack, monitoring, whaleAlert, transactions, whaleThreshold = 0, + utilizationThreshold = 0, ] = await Promise.all([ getIcons(storage, exactly.map(({ assetSymbol }) => assetSymbol)), getSecret(secrets, 'SLACK_TOKEN').then((token) => new WebClient(token)), @@ -60,6 +62,7 @@ export default (async ({ storage, secrets, gateways }, { getSecret(secrets, `SLACK_WHALE_ALERT@${chainId}`), getSecret(secrets, `SLACK_TRANSACTIONS@${chainId}`), storage.getNumber('WHALE_USD_THRESHOLD'), + storage.getNumber('UTILIZATION_THRESHOLD'), ]); const ethPrice = findMarket(exactly, ({ assetSymbol }) => assetSymbol === 'WETH')!.usdPrice.toBigInt(); @@ -72,6 +75,7 @@ export default (async ({ storage, secrets, gateways }, { if (log.name === 'MarketUpdate') { const { assetSymbol, fixedPools, totalFloatingDepositAssets, totalFloatingDepositShares, + totalFloatingBorrowAssets, } = findMarket(exactly, address)!; const { totalFloatingDepositAssets: prevAssets, totalFloatingDepositShares: prevShares, @@ -85,6 +89,35 @@ export default (async ({ storage, secrets, gateways }, { if (!monitoring) continue; + const assets = totalFloatingDepositAssets.toBigInt(); + const floatingDebt = totalFloatingBorrowAssets.toBigInt(); + const fixedAssets = fixedPools.reduce((total, { supplied, borrowed }) => ( + total + supplied.toBigInt() - borrowed.toBigInt()), 0n); + const debt = floatingDebt - (fixedAssets < 0n ? fixedAssets : 0n); + const utilization = Number((debt * WAD) / assets) / 10 ** 18; + + if (utilization >= utilizationThreshold) { + parallel.push(slack.chat.postMessage({ + channel: monitoring, + attachments: [{ + color: 'warning', + title: `${assetSymbol} utilization above threshold`, + title_link: `${app}/${assetSymbol}`, + fields: [ + { + short: true, + title: 'global utilization', + value: utilization.toLocaleString(undefined, { style: 'percent', maximumFractionDigits: 2 }), + }, + { short: true, title: 'floating utilization', value: formatBigInt((floatingDebt * WAD) / assets, '%') }, + ], + footer_icon: icons[assetSymbol], + footer: network, + ts: ts.toString(), + }], + })); + } + const arbs = fixedPools.map(({ maturity, depositRate, minBorrowRate }) => ( depositRate.gt(minBorrowRate) ? [ formatMaturity(maturity), diff --git a/test/onMarketUpdate.spec.ts b/test/onMarketUpdate.spec.ts index 890ff28..b4e7a4c 100644 --- a/test/onMarketUpdate.spec.ts +++ b/test/onMarketUpdate.spec.ts @@ -18,6 +18,7 @@ describe('on market update', () => { runtime.context.secrets.put('RPC_10', RPC_10); runtime.context.gateways.setConfig('', { accessKey: GATEWAY_ACCESS_KEY }); await runtime.context.storage.putStr('OP.icon', 'https://cryptologos.cc/logos/optimism-ethereum-op-logo.png'); + await runtime.context.storage.putStr('UTILIZATION_THRESHOLD', '0.8'); if (SLACK_TOKEN) runtime.context.secrets.put('SLACK_TOKEN', SLACK_TOKEN); for (const [key, value] of Object.entries(env)) { if (key.startsWith('SLACK_')) runtime.context.secrets.put(`${key}@${payload.network}`, value!); diff --git a/test/payloads/payload.json b/test/payloads/payload.json index 13b569c..1641391 100644 --- a/test/payloads/payload.json +++ b/test/payloads/payload.json @@ -1,60 +1,157 @@ { "network": "10", - "blockHash": "0x3fab48ae82245bd93737491ee59552945f0aff6930570903ae4f380a631bf2e3", - "blockNumber": 79574078, - "hash": "0xa0b04fb18201bfb72af6cb11774683a8badb6a585de38846f42ae8d1bce7149e", - "from": "0x9333c471fb0aBb0A189189933bfC0D1A4584c9f7", - "to": "0xa430A427bd00210506589906a71B54d6C256CEdb", + "blockHash": "0x5ef5ccae0c964caee44e60fbe881fda8d7591472a641dbc26f9ac92892b88ecb", + "blockNumber": 112495494, + "hash": "0xef7b4649602933c1f79ebd963844e0ddda585a4cf3df30f2d7bfe8aa898394a5", + "from": "0xd8d9323157d74f34c7d3c4891e117c24f339e2d4", + "to": "0x81c9a7b55a4df39a9b7b5f781ec0e53539694873", "logs": [ { - "address": "0xa430A427bd00210506589906a71B54d6C256CEdb", + "address": "0xbd1ba78a3976cab420a9203e6ef14d18c2b2e031", "topics": [ - "0xd9900507c64720c1a5e11858a42769b599616268b832495aa6afe8b9dc566e76", - "0x0000000000000000000000000000000000000000000000000000000064125c00", - "0x0000000000000000000000009333c471fb0abb0a189189933bfc0d1a4584c9f7", - "0x0000000000000000000000009333c471fb0abb0a189189933bfc0d1a4584c9f7" + "0x1be815035b13056fba0f0dcbaec5d30add5d95e5f1b6990581607fbccdc93050", + "0x00000000000000000000000081c9a7b55a4df39a9b7b5f781ec0e53539694873", + "0x0000000000000000000000004200000000000000000000000000000000000042" ], - "data": "0x000000000000000000000000000000000000000000000003a11e2e48a06700000000000000000000000000000000000000000000000000000000000000000000" + "data": "0x000000000000000000000000000000000000000000000000001740271ff0f137000000000000000000000000000000000000000000000000001ddc6433d1bb4e00000000000000000000000000000000000000000000000ec2467ea6ea75531900000000000000000000000000000000000000000000000000000000655cf0c5" }, { - "address": "0xa430A427bd00210506589906a71B54d6C256CEdb", - "topics": ["0x7a71b92e3ef471c5ad18359e076f3df1c563d92e9ea1e33aa4761dbbc9b7ae40"], - "data": "0x00000000000000000000000000000000000000000000000000000000640a1bc5000000000000000000000000000000000000000000000258fe6a336fcd07afc10000000000000000000000000000000000000000000002590d9a2c14e0b1be0b000000000000000000000000000000000000000000000084560abd728345d3ec00000000000000000000000000000000000000000000008462bf652c1de7c6d0000000000000000000000000000000000000000000000000070f3d26584c5cd2" + "address": "0xbd1ba78a3976cab420a9203e6ef14d18c2b2e031", + "topics": [ + "0xc4278cd1497fedb2697092108a0141a0cbecdd1472913b6e803010998aa63537", + "0x00000000000000000000000081c9a7b55a4df39a9b7b5f781ec0e53539694873", + "0x0000000000000000000000004200000000000000000000000000000000000042", + "0x000000000000000000000000d8d9323157d74f34c7d3c4891e117c24f339e2d4" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000001740271e34ae24000000000000000000000000000000000000000000000000001740271ff0f1370000000000000000000000000000000000000000000000000000002580e996c4" + }, + { + "address": "0xbd1ba78a3976cab420a9203e6ef14d18c2b2e031", + "topics": [ + "0x1be815035b13056fba0f0dcbaec5d30add5d95e5f1b6990581607fbccdc93050", + "0x00000000000000000000000081c9a7b55a4df39a9b7b5f781ec0e53539694873", + "0x0000000000000000000000001e925de1c68ef83bd98ee3e130ef14a50309c01b" + ], + "data": "0x0000000000000000000000000000000000000000000000000001ac4e4d8c174700000000000000000000000000000000000000000000000000026062fe1b8395000000000000000000000000000000000000000000000000b295e0288b73b23e00000000000000000000000000000000000000000000000000000000655cf0c5" + }, + { + "address": "0xbd1ba78a3976cab420a9203e6ef14d18c2b2e031", + "topics": [ + "0xc4278cd1497fedb2697092108a0141a0cbecdd1472913b6e803010998aa63537", + "0x00000000000000000000000081c9a7b55a4df39a9b7b5f781ec0e53539694873", + "0x0000000000000000000000001e925de1c68ef83bd98ee3e130ef14a50309c01b", + "0x000000000000000000000000d8d9323157d74f34c7d3c4891e117c24f339e2d4" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000001ac4e4ccf8e3f0000000000000000000000000000000000000000000000000001ac4e4d8c17470000000000000000000000000000000000000000000000000000000fea6beabb" + }, + { + "address": "0xbd1ba78a3976cab420a9203e6ef14d18c2b2e031", + "topics": [ + "0x1be815035b13056fba0f0dcbaec5d30add5d95e5f1b6990581607fbccdc93050", + "0x00000000000000000000000081c9a7b55a4df39a9b7b5f781ec0e53539694873", + "0x000000000000000000000000bea586a167853adddef12818f264f1f9823fbc18" + ], + "data": "0x000000000000000000000000000000000000000000000000000b9674fc06e853000000000000000000000000000000000000000000000000000d734fc60880430000000000000000000000000000000000000000000001456978a5fd4894bf7e00000000000000000000000000000000000000000000000000000000655cf0c5" + }, + { + "address": "0xbd1ba78a3976cab420a9203e6ef14d18c2b2e031", + "topics": [ + "0xc4278cd1497fedb2697092108a0141a0cbecdd1472913b6e803010998aa63537", + "0x00000000000000000000000081c9a7b55a4df39a9b7b5f781ec0e53539694873", + "0x000000000000000000000000bea586a167853adddef12818f264f1f9823fbc18", + "0x000000000000000000000000d8d9323157d74f34c7d3c4891e117c24f339e2d4" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000b965041ceca84000000000000000000000000000000000000000000000000000b9674fc06e853000000000000000000000000000000000000000000000000000319b6a4c583c5" + }, + { + "address": "0x81c9a7b55a4df39a9b7b5f781ec0e53539694873", + "topics": [ + "0x582b129106eba35020853cdae92ceb413a0227befcce433b67b23a630219b35f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000655cf0c5000000000000000000000000000000000000000000000000078f60cb4aa8cdb2" + }, + { + "address": "0xbd1ba78a3976cab420a9203e6ef14d18c2b2e031", + "topics": [ + "0xc4278cd1497fedb2697092108a0141a0cbecdd1472913b6e803010998aa63537", + "0x00000000000000000000000081c9a7b55a4df39a9b7b5f781ec0e53539694873", + "0x0000000000000000000000004200000000000000000000000000000000000042", + "0x00000000000000000000000023fd464e0b0ee21cedeb929b19cabf9bd5215019" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ddc643311f4f9000000000000000000000000000000000000000000000000001ddc6433d1bb4e0000000000000000000000000000000000000000000000000000000bd5bf5dab" + }, + { + "address": "0xbd1ba78a3976cab420a9203e6ef14d18c2b2e031", + "topics": [ + "0xc4278cd1497fedb2697092108a0141a0cbecdd1472913b6e803010998aa63537", + "0x00000000000000000000000081c9a7b55a4df39a9b7b5f781ec0e53539694873", + "0x0000000000000000000000001e925de1c68ef83bd98ee3e130ef14a50309c01b", + "0x00000000000000000000000023fd464e0b0ee21cedeb929b19cabf9bd5215019" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000026062fdca209000000000000000000000000000000000000000000000000000026062fe1b83950000000000000000000000000000000000000000000000000000000505c9720c" + }, + { + "address": "0xbd1ba78a3976cab420a9203e6ef14d18c2b2e031", + "topics": [ + "0xc4278cd1497fedb2697092108a0141a0cbecdd1472913b6e803010998aa63537", + "0x00000000000000000000000081c9a7b55a4df39a9b7b5f781ec0e53539694873", + "0x000000000000000000000000bea586a167853adddef12818f264f1f9823fbc18", + "0x00000000000000000000000023fd464e0b0ee21cedeb929b19cabf9bd5215019" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d733feb4eed8e000000000000000000000000000000000000000000000000000d734fc60880430000000000000000000000000000000000000000000000000000fa79a574a62f" + }, + { + "address": "0x81c9a7b55a4df39a9b7b5f781ec0e53539694873", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000023fd464e0b0ee21cedeb929b19cabf9bd5215019" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000005f91" + }, + { + "address": "0x81c9a7b55a4df39a9b7b5f781ec0e53539694873", + "topics": [ + "0xe4a1ae657f49cb1fb1c7d3a94ae6093565c4c8c0e03de488f79c377c3c3a24e0", + "0x000000000000000000000000d8d9323157d74f34c7d3c4891e117c24f339e2d4", + "0x000000000000000000000000d8d9323157d74f34c7d3c4891e117c24f339e2d4" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000152c519140000000000000000000000000000000000000000000000000000000149c1abe4" }, { - "address": "0xa430A427bd00210506589906a71B54d6C256CEdb", + "address": "0x81c9a7b55a4df39a9b7b5f781ec0e53539694873", "topics": [ - "0xa2e6044136bec58e0605f40ac11a7bf87f1a8bdf3e2588b11b2cfae5acd9109f", - "0x0000000000000000000000000000000000000000000000000000000064125c00" + "0x7a71b92e3ef471c5ad18359e076f3df1c563d92e9ea1e33aa4761dbbc9b7ae40" ], - "data": "0x00000000000000000000000000000000000000000000000000000000640a1bc50000000000000000000000000000000000000000000000000000000000000000" + "data": "0x00000000000000000000000000000000000000000000000000000000655cf0c50000000000000000000000000000000000000000000000000000070ec905de6600000000000000000000000000000000000000000000000000000731aff10478000000000000000000000000000000000000000000000000000003cf4c04e14f000000000000000000000000000000000000000000000000000003e9f486e6bd0000000000000000000000000000000000000000000000000000000ba8b7c6b7" }, { - "address": "0x4200000000000000000000000000000000000042", + "address": "0x7f5c764cbc14f9669b88837ca1490cca17c31607", "topics": [ "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000009333c471fb0abb0a189189933bfc0d1a4584c9f7", - "0x000000000000000000000000a430a427bd00210506589906a71b54d6c256cedb" + "0x000000000000000000000000d8d9323157d74f34c7d3c4891e117c24f339e2d4", + "0x00000000000000000000000081c9a7b55a4df39a9b7b5f781ec0e53539694873" ], - "data": "0x000000000000000000000000000000000000000000000003a11e2e48a0670000" + "data": "0x0000000000000000000000000000000000000000000000000000000152c51914" }, { - "address": "0x4200000000000000000000000000000000000042", + "address": "0x7f5c764cbc14f9669b88837ca1490cca17c31607", "topics": [ - "0xdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a724", - "0x0000000000000000000000009333c471fb0abb0a189189933bfc0d1a4584c9f7" + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + "0x000000000000000000000000d8d9323157d74f34c7d3c4891e117c24f339e2d4", + "0x00000000000000000000000081c9a7b55a4df39a9b7b5f781ec0e53539694873" ], - "data": "0x0000000000000000000000000000000000000000000000065717576c8f34e6e6000000000000000000000000000000000000000000000002b5f92923eecde6e6" + "data": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffff5ec6561af" } ], - "input": "0x34f7d1f20000000000000000000000000000000000000000000000000000000064125c00000000000000000000000000000000000000000000000003a11e2e48a067000000000000000000000000000000000000000000000000000372a978c4fec840000000000000000000000000009333c471fb0abb0a189189933bfc0d1a4584c9f7", - "value": "0x0", - "nonce": "0x3db", - "gas": "0x3746c", - "gasUsed": "0x2b7c1", - "cumulativeGasUsed": "0x2b7c1", - "gasPrice": "0xf4240", - "gasTipCap": "0x", - "gasFeeCap": "0x", + "input": "0x7ad226dc0000000000000000000000000000000000000000000000000000000152c51893000000000000000000000000d8d9323157d74f34c7d3c4891e117c24f339e2d4", + "value": "0x", + "nonce": "0x104", + "gas": "0xb1748", + "gasUsed": "0xad916", + "cumulativeGasUsed": "0x1713fc2", + "gasPrice": "0x02205986", + "gasTipCap": "0x0ecd10", + "gasFeeCap": "0x062f2288", "alertId": null -} +} \ No newline at end of file