diff --git a/docs/ACTIONS.md b/docs/ACTIONS.md index 9576cfe0..b1073612 100644 --- a/docs/ACTIONS.md +++ b/docs/ACTIONS.md @@ -43,13 +43,12 @@ range, tolerance, and quote-amount flags apply to every selected base. ## EtherFi ARM — mainnet -| Action | Cron | Description | -| ---------------------------- | --------------- | -------------------------------------------- | -| `autoRequestEtherFiWithdraw` | `10,40 * * * *` | Request EtherFi withdrawals from EtherFi ARM | -| `autoClaimEtherFiWithdraw` | `40 * * * *` | Claim EtherFi withdrawals from EtherFi ARM | -| `collectEtherFiFees` | `45 23 * * *` | Collect fees from EtherFi ARM | -| `allocateEtherFi` | `52 * * * *` | Allocate liquidity for EtherFi ARM | -| `setPricesEtherFi` | `2,32 * * * *` | Set prices for EtherFi ARM | +| Action | Cron | Description | +| -------------------------- | -------------- | ------------------------------------------ | +| `autoClaimEtherFiWithdraw` | `40 * * * *` | Claim EtherFi withdrawals from EtherFi ARM | +| `collectEtherFiFees` | `45 23 * * *` | Collect fees from EtherFi ARM | +| `allocateEtherFi` | `52 * * * *` | Allocate liquidity for EtherFi ARM | +| `setPricesEtherFi` | `2,32 * * * *` | Set prices for EtherFi ARM | ## Ethena ARM — mainnet @@ -73,15 +72,16 @@ range, tolerance, and quote-amount flags apply to every selected base. ## WETH ARM — mainnet -| Action | Cron | Description | -| -------------------------------- | ----------------------- | ---------------------------------------------- | -| `autoRequestWETHLidoWithdraw` | `29,58 12-23,0-8 * * *` | Request stETH/wstETH withdrawals from WETH ARM | -| `autoClaimWETHLidoWithdraw` | `32 0,12 * * *` | Claim stETH/wstETH withdrawals for WETH ARM | -| `autoRequestWETHEtherFiWithdraw` | `10,40 * * * *` | Request eETH/weETH withdrawals from WETH ARM | -| `autoClaimWETHEtherFiWithdraw` | `40 * * * *` | Claim eETH/weETH withdrawals for WETH ARM | -| `collectWETHFees` | `30 12 * * *` | Collect fees from WETH ARM | -| `allocateWETH` | `38,08 * * * *` | Allocate liquidity for WETH ARM | -| `setPricesWETH` | `*/30 * * * *` | Set prices for all four WETH ARM base assets | +| Action | Cron | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------- | ---------------------------------------------- | +| `autoRequestWETHLidoWithdraw` | `29,58 12-23,0-8 * * *` | Request stETH/wstETH withdrawals from WETH ARM | +| `autoClaimWETHLidoWithdraw` | `32 0,12 * * *` | Claim stETH/wstETH withdrawals for WETH ARM | +| `autoRequestWETHEtherFiWithdraw` | `10,40 * * * *` | Request eETH/weETH withdrawals from WETH ARM | +| `autoClaimWETHEtherFiWithdraw` | `40 * * * *` | Claim eETH/weETH withdrawals for WETH ARM | +| `collectWETHFees` | `30 12 * * *` | Collect fees from WETH ARM | +| `allocateWETH` | `38,08 * * * *` | Allocate liquidity for WETH ARM | +| `setPricesWETH --bases STETH,WSTETH --fee 0.6 --inch false --kyber true --tolerance 0.1 --amount 30 --offset 0.3 --max-buy-price 0.99996 --min-sell-price 0.99998` | `*/10 * * * *` | Set WETH ARM prices for Lido base assets | +| `setPricesWETH --bases EETH,WEETH --fee 0.6 --inch false --kyber true --tolerance 0.1 --amount 30 --offset 0.3 --max-buy-price 0.99996 --min-sell-price 0.99998` | `2-59/10 * * * *` | Set WETH ARM prices for Ether.fi base assets | ## Origin ARM — Sonic diff --git a/migrations/seed_schedules.sql b/migrations/seed_schedules.sql index b091952d..9bf55e44 100644 --- a/migrations/seed_schedules.sql +++ b/migrations/seed_schedules.sql @@ -13,6 +13,8 @@ WHERE product = 'arm-oeth' 'mainnet_collect_usd_fees', 'mainnet_allocate_usd', 'mainnet_set_prices_usd', + 'mainnet_set_prices_weth', + 'mainnet_auto_request_etherfi_withdraw', 'mainnet_pause_usd', 'mainnet_pause_lido', 'mainnet_pause_etherfi', @@ -24,7 +26,6 @@ INSERT INTO schedules (product, name, command, cron_expr, timezone, enabled, not ('arm-oeth', 'healthcheck', 'cd /app && pnpm hardhat healthcheck', '*/5 * * * *', 'UTC', false, NULL), ('arm-oeth', 'mainnet_auto_request_lido_withdraw', 'cd /app && pnpm hardhat autoRequestLidoWithdraw --network mainnet', '29,58 12-23,0-8 * * *', 'UTC', false, NULL), ('arm-oeth', 'mainnet_auto_claim_lido_withdraw', 'cd /app && pnpm hardhat autoClaimLidoWithdraw --network mainnet', '32 0,12 * * *', 'UTC', false, NULL), -('arm-oeth', 'mainnet_auto_request_etherfi_withdraw','cd /app && pnpm hardhat autoRequestEtherFiWithdraw --network mainnet', '10,40 * * * *', 'UTC', false, NULL), ('arm-oeth', 'mainnet_auto_claim_etherfi_withdraw', 'cd /app && pnpm hardhat autoClaimEtherFiWithdraw --network mainnet', '40 * * * *', 'UTC', false, NULL), ('arm-oeth', 'mainnet_auto_request_ethena_withdraw', 'cd /app && pnpm hardhat autoRequestEthenaWithdraw --network mainnet', '12 * * * *', 'UTC', false, NULL), ('arm-oeth', 'mainnet_auto_claim_ethena_withdraw', 'cd /app && pnpm hardhat autoClaimEthenaWithdraw --network mainnet', '40 * * * *', 'UTC', false, NULL), @@ -48,7 +49,8 @@ INSERT INTO schedules (product, name, command, cron_expr, timezone, enabled, not ('arm-oeth', 'mainnet_auto_claim_weth_etherfi_withdraw', 'cd /app && pnpm hardhat autoClaimWETHEtherFiWithdraw --network mainnet', '40 * * * *', 'UTC', false, NULL), ('arm-oeth', 'mainnet_collect_weth_fees', 'cd /app && pnpm hardhat collectWETHFees --network mainnet', '30 12 * * *', 'UTC', false, NULL), ('arm-oeth', 'mainnet_allocate_weth', 'cd /app && pnpm hardhat allocateWETH --network mainnet', '38,08 * * * *', 'UTC', false, NULL), -('arm-oeth', 'mainnet_set_prices_weth', 'cd /app && pnpm hardhat setPricesWETH --network mainnet', '*/30 * * * *', 'UTC', false, NULL), +('arm-oeth', 'mainnet_set_prices_weth_lido', 'cd /app && pnpm hardhat setPricesWETH --bases STETH,WSTETH --network mainnet --fee 0.6 --inch false --kyber true --tolerance 0.1 --amount 30 --offset 0.3 --max-buy-price 0.99996 --min-sell-price 0.99998', '*/10 * * * *', 'UTC', false, NULL), +('arm-oeth', 'mainnet_set_prices_weth_etherfi', 'cd /app && pnpm hardhat setPricesWETH --bases EETH,WEETH --network mainnet --fee 0.6 --inch false --kyber true --tolerance 0.1 --amount 30 --offset 0.3 --max-buy-price 0.99996 --min-sell-price 0.99998', '2-59/10 * * * *', 'UTC', false, NULL), -- Emergency pause action: manual-only (enabled=false). Edit `--arm` before -- using "Run now". The supported Ethereum ARMs are lido, etherfi, ethena, -- oeth, usdc, and weth. cron_expr is a placeholder and never fires while disabled. diff --git a/src/js/tasks/armPrices.js b/src/js/tasks/armPrices.js index 15821620..a709beb4 100644 --- a/src/js/tasks/armPrices.js +++ b/src/js/tasks/armPrices.js @@ -18,6 +18,7 @@ const { rangeSellPrice, rangeBuyPrice, } = require("../utils/pricing"); +const { haveSwapCapsChanged } = require("../utils/priceUpdate"); const log = require("../utils/logger")("task:prices"); @@ -360,11 +361,32 @@ const setPrices = async (options) => { const toleranceScaled = parseUnits(tolerance.toString(), 36 - 4); log(`tolerance : ${formatUnits(toleranceScaled, 32)} basis points`); + const targetBuyAmount = parseSwapCap(buyAmount); + const targetSellAmount = parseSwapCap(sellAmount); + const swapCapsChanged = haveSwapCapsChanged( + baseContext, + targetBuyAmount, + targetSellAmount, + ); + if (baseContext.version === "multiBase") { + log(`current buy amount : ${config.buyLiquidityRemaining}`); + log(`target buy amount : ${targetBuyAmount}`); + log(`current sell amount: ${config.sellLiquidityRemaining}`); + log(`target sell amount : ${targetSellAmount}`); + } + // decide if rates need to be updated - if (diffSellPrice > toleranceScaled || diffBuyPrice > toleranceScaled) { + if ( + diffSellPrice > toleranceScaled || + diffBuyPrice > toleranceScaled || + swapCapsChanged + ) { console.log(`About to update ARM prices`); console.log(`sell: ${formatUnits(targetSellPrice, 36)}`); console.log(`buy : ${formatUnits(targetBuyPrice, 36)}`); + if (swapCapsChanged) { + console.log(`Buy or sell amount has changed`); + } if (dryrun) { console.log(`Dry run mode - not calling setPrices`); @@ -376,8 +398,8 @@ const setPrices = async (options) => { signer, buyPrice: targetBuyPrice, sellPrice: targetSellPrice, - buyAmount: parseSwapCap(buyAmount), - sellAmount: parseSwapCap(sellAmount), + buyAmount: targetBuyAmount, + sellAmount: targetSellAmount, }); await logTxDetails(tx, "setPrices", options.confirm); diff --git a/src/js/utils/priceUpdate.js b/src/js/utils/priceUpdate.js new file mode 100644 index 00000000..abb0d3ff --- /dev/null +++ b/src/js/utils/priceUpdate.js @@ -0,0 +1,8 @@ +const haveSwapCapsChanged = (baseContext, buyAmount, sellAmount) => + baseContext.version === "multiBase" && + (buyAmount !== baseContext.config.buyLiquidityRemaining || + sellAmount !== baseContext.config.sellLiquidityRemaining); + +module.exports = { + haveSwapCapsChanged, +}; diff --git a/test/js/armPrices.test.js b/test/js/armPrices.test.js new file mode 100644 index 00000000..ed44d553 --- /dev/null +++ b/test/js/armPrices.test.js @@ -0,0 +1,37 @@ +const assert = require("assert"); + +const { haveSwapCapsChanged } = require("../../src/js/utils/priceUpdate"); + +const multiBaseContext = (buyLiquidityRemaining, sellLiquidityRemaining) => ({ + version: "multiBase", + config: { + buyLiquidityRemaining, + sellLiquidityRemaining, + }, +}); + +assert.strictEqual( + haveSwapCapsChanged(multiBaseContext(10n, 20n), 10n, 20n), + false, + "unchanged buy and sell amounts should not trigger an update", +); + +assert.strictEqual( + haveSwapCapsChanged(multiBaseContext(9n, 20n), 10n, 20n), + true, + "a changed buy amount should trigger an update", +); + +assert.strictEqual( + haveSwapCapsChanged(multiBaseContext(10n, 19n), 10n, 20n), + true, + "a changed sell amount should trigger an update", +); + +assert.strictEqual( + haveSwapCapsChanged({ version: "legacy" }, 10n, 20n), + false, + "legacy ARMs do not support buy and sell amounts", +); + +console.log("ARM price tests passed");