diff --git a/packages/deploy-configurations/configs/mainnet.conf.ts b/packages/deploy-configurations/configs/mainnet.conf.ts index e46b93f69..8a584cdba 100644 --- a/packages/deploy-configurations/configs/mainnet.conf.ts +++ b/packages/deploy-configurations/configs/mainnet.conf.ts @@ -86,7 +86,7 @@ export const config: SystemConfig = { }, Swap: { name: 'Swap', - deploy: true, + deploy: false, address: '0x826E9f2E79cEEA850dF4d4757e0D12115A720D74', serviceRegistryName: SERVICE_REGISTRY_NAMES.common.SWAP, history: [], @@ -139,7 +139,7 @@ export const config: SystemConfig = { }, SwapAction: { name: 'SwapAction', - deploy: true, + deploy: false, address: '0x313617D9CcBd96d66b2374c9bcB44b372D29b530', serviceRegistryName: SERVICE_REGISTRY_NAMES.common.SWAP_ACTION, history: ['0x7E7EB65A93441a2D2Bf0941216b4c1116B554d85'], diff --git a/packages/deploy-configurations/configs/tenderly.conf.ts b/packages/deploy-configurations/configs/tenderly.conf.ts index 0af0891f2..e46b93f69 100644 --- a/packages/deploy-configurations/configs/tenderly.conf.ts +++ b/packages/deploy-configurations/configs/tenderly.conf.ts @@ -1,8 +1,8 @@ -import { ADDRESS_ZERO, loadContractNames } from '@deploy-configurations/constants' +import { loadContractNames } from '@deploy-configurations/constants' import { SystemConfig } from '@deploy-configurations/types/deployment-config' import { Network } from '@deploy-configurations/types/network' -const SERVICE_REGISTRY_NAMES = loadContractNames(Network.TENDERLY) +const SERVICE_REGISTRY_NAMES = loadContractNames(Network.MAINNET) export const config: SystemConfig = { mpa: { @@ -87,9 +87,9 @@ export const config: SystemConfig = { Swap: { name: 'Swap', deploy: true, - address: '0xb779c4a8Df0054707F6E239159129bEd27b24878', + address: '0x826E9f2E79cEEA850dF4d4757e0D12115A720D74', serviceRegistryName: SERVICE_REGISTRY_NAMES.common.SWAP, - history: ['0x826E9f2E79cEEA850dF4d4757e0D12115A720D74'], + history: [], constructorArgs: [ '0x85f9b7408afE6CEb5E46223451f5d4b832B522dc', '0xc7b548ad9cf38721810246c079b2d8083aba8909', @@ -140,12 +140,9 @@ export const config: SystemConfig = { SwapAction: { name: 'SwapAction', deploy: true, - address: '0xab0b80b169D12A4De609C88E5069873b445c8227', + address: '0x313617D9CcBd96d66b2374c9bcB44b372D29b530', serviceRegistryName: SERVICE_REGISTRY_NAMES.common.SWAP_ACTION, - history: [ - '0x7E7EB65A93441a2D2Bf0941216b4c1116B554d85', - '0x313617D9CcBd96d66b2374c9bcB44b372D29b530', - ], + history: ['0x7E7EB65A93441a2D2Bf0941216b4c1116B554d85'], constructorArgs: ['address:ServiceRegistry'], }, TakeFlashloan: { @@ -1087,6 +1084,25 @@ export const config: SystemConfig = { }, }, }, + spark: { + Oracle: { + name: 'Oracle', + address: '0x8105f69D9C41644c6A0803fDA7D03Aa70996cFD9', + }, + LendingPool: { + name: 'LendingPool', + address: '0xC13e21B648A5Ee794902342038FF3aDAB66BE987', + serviceRegistryName: SERVICE_REGISTRY_NAMES.spark.LENDING_POOL, + }, + PoolDataProvider: { + name: 'PoolDataProvider', + address: '0xFc21d6d146E6086B8359705C8b28512a983db0cb', + }, + RewardsController: { + name: 'RewardsController', + address: '0x4370D3b6C9588E02ce9D22e684387859c7Ff5b34', + }, + }, maker: { common: { FlashMintModule: { diff --git a/packages/deploy-configurations/constants/operation-names.ts b/packages/deploy-configurations/constants/operation-names.ts index 05e9912c1..013fd4588 100644 --- a/packages/deploy-configurations/constants/operation-names.ts +++ b/packages/deploy-configurations/constants/operation-names.ts @@ -27,15 +27,15 @@ export type SparkOperationNames = export const OPERATION_NAMES = { aave: { v2: { - OPEN_POSITION: 'OpenAAVEPosition', - CLOSE_POSITION: 'CloseAAVEPosition_3', - INCREASE_POSITION: 'IncreaseAAVEPosition', - DECREASE_POSITION: 'DecreaseAAVEPosition', - DEPOSIT_BORROW: 'AAVEDepositBorrow', - OPEN_DEPOSIT_BORROW: 'AAVEOpenDepositBorrow', - DEPOSIT: 'AAVEDeposit', - BORROW: 'AAVEBorrow', - PAYBACK_WITHDRAW: 'AAVEPaybackWithdraw_2', + OPEN_POSITION: 'OpenAAVEPosition_v1', + CLOSE_POSITION: 'CloseAAVEPosition_v1', + INCREASE_POSITION: 'IncreaseAAVEPosition_v1', + DECREASE_POSITION: 'DecreaseAAVEPosition_v1', + DEPOSIT_BORROW: 'AAVEDepositBorrow_v1', + OPEN_DEPOSIT_BORROW: 'AAVEOpenDepositBorrow_v1', + DEPOSIT: 'AAVEDeposit_v1', + BORROW: 'AAVEBorrow_v1', + PAYBACK_WITHDRAW: 'AAVEPaybackWithdraw_v1', }, v3: { OPEN_POSITION: 'OpenAAVEV3Position_v3', diff --git a/packages/deploy-configurations/utils/wrappers/operations-registry.ts b/packages/deploy-configurations/utils/wrappers/operations-registry.ts index 3c383b560..e2eb1cec0 100644 --- a/packages/deploy-configurations/utils/wrappers/operations-registry.ts +++ b/packages/deploy-configurations/utils/wrappers/operations-registry.ts @@ -8,22 +8,50 @@ type Action = { export class OperationsRegistry { address: string signer: Signer + isTenderly: boolean + debug: boolean - constructor(address: string, signer: Signer) { + constructor( + address: string, + signer: Signer, + { isTenderly, debug }: { isTenderly?: boolean; debug?: boolean } = {}, + ) { this.address = address this.signer = signer + this.isTenderly = isTenderly || false + this.debug = debug || false } - async addOp(label: string, actions: Action[], debug = false): Promise { + async addOp(label: string, actions: Action[]): Promise { const ethers = (await import('hardhat')).ethers const entryHash = utils.keccak256(utils.toUtf8Bytes(label)) const registry = await ethers.getContractAt('OperationsRegistry', this.address, this.signer) const actionHashes = actions.map(a => a.hash) const optional = actions.map(a => a.optional) - await registry.addOperation({ name: label, actions: actionHashes, optional }) - if (debug) { - console.log(`DEBUG: Service '${label}' has been added with hash: ${entryHash}`) + if (this.isTenderly) { + const tx = await registry.populateTransaction.addOperation({ + name: label, + actions: actionHashes, + optional, + }) + const provider = new ethers.providers.JsonRpcProvider(process.env.TENDERLY_FORK_URL) + const txHash = await provider + ?.send('eth_sendTransaction', [ + { + ...tx, + from: process.env.IMPERSONATE_ADDRESS, + }, + ]) + .catch(e => { + console.log('Error in the transaction', e) + }) + await provider?.waitForTransaction(txHash) + } else { + await registry.addOperation({ name: label, actions: actionHashes, optional }) + } + if (this.debug) { + console.log(`DEBUG: Operation '${label}' has been added with hash: ${entryHash}`) console.log('DEBUG: Actions:', actionHashes) console.log('DEBUG: Optional:', optional) } diff --git a/packages/deploy-configurations/utils/wrappers/service-registry.ts b/packages/deploy-configurations/utils/wrappers/service-registry.ts index 8ce8c8fbd..b754c4fe2 100644 --- a/packages/deploy-configurations/utils/wrappers/service-registry.ts +++ b/packages/deploy-configurations/utils/wrappers/service-registry.ts @@ -5,10 +5,12 @@ export class ServiceRegistry { address: string signer: Signer registry: Contract | undefined + isTenderly: boolean - constructor(address: string, signer: Signer) { + constructor(address: string, signer: Signer, { isTenderly }: { isTenderly?: boolean } = {}) { this.address = address this.signer = signer + this.isTenderly = isTenderly || false } private async _getRegistry(): Promise { @@ -24,16 +26,11 @@ export class ServiceRegistry { return this._getRegistry() } - async addEntry( - label: ContractNames, - address: string, - debug = false, - { tenderly }: { tenderly: boolean } = { tenderly: false }, - ): Promise { + async addEntry(label: ContractNames, address: string, debug = false): Promise { const entryHash = utils.keccak256(utils.toUtf8Bytes(label)) const registry = await this._getRegistry() - if (tenderly) { + if (this.isTenderly) { const tx = await registry.populateTransaction.addNamedService(entryHash, address) const provider = new ethers.providers.JsonRpcProvider(process.env.TENDERLY_FORK_URL) const txHash = await provider diff --git a/packages/dma-contracts/contracts/actions/common/PullToken.sol b/packages/dma-contracts/contracts/actions/common/PullToken.sol index b762848ba..a87d828e4 100644 --- a/packages/dma-contracts/contracts/actions/common/PullToken.sol +++ b/packages/dma-contracts/contracts/actions/common/PullToken.sol @@ -4,7 +4,6 @@ pragma solidity ^0.8.15; import { Executable } from "../common/Executable.sol"; import { SafeERC20, IERC20 } from "../../libs/SafeERC20.sol"; import { PullTokenData } from "../../core/types/Common.sol"; -import "../../core/types/Common.sol"; /** * @title PullToken Action contract diff --git a/packages/dma-contracts/package.json b/packages/dma-contracts/package.json index 1514f39cd..23b5b380f 100644 --- a/packages/dma-contracts/package.json +++ b/packages/dma-contracts/package.json @@ -11,6 +11,7 @@ "dev:mainnet": "yarn ts-node scripts/update-block-number.ts && yarn hardhat node --max-memory 8192 --fork $(grep MAINNET_URL ../../.env | cut -d '=' -f2)", "dev:optimism": "yarn ts-node scripts/update-block-number.ts && yarn hardhat node --max-memory 8192 --fork $(grep OPTIMISM_URL ../../.env | cut -d '=' -f2)", "deploy:dev": "yarn compile && yarn hardhat deploy --network local", + "deploy:mainnet": "yarn hardhat run scripts/deployment/deploy-mainnet.ts", "deploy:morphoblue:integration": "yarn clean && yarn compile && yarn hardhat run scripts/morphoblue/deploy-morphoblue-integration.ts", "compile": "npx hardhat --config hardhat.config.base.ts compile", "clean": "rm -rf ./typechain && rm -rf ./artifacts && rm -rf ./cache", diff --git a/packages/dma-contracts/scripts/deployment/deploy-mainnet.ts b/packages/dma-contracts/scripts/deployment/deploy-mainnet.ts index 72e929e94..ccb635666 100644 --- a/packages/dma-contracts/scripts/deployment/deploy-mainnet.ts +++ b/packages/dma-contracts/scripts/deployment/deploy-mainnet.ts @@ -13,8 +13,8 @@ async function main() { await ds.loadConfig() await ds.deployCore() await ds.deployActions() - await ds.saveConfig() - // await ds.addOperationEntries() + // await ds.saveConfig() + await ds.addOperationEntries() // await ds.addAaveV3Operations() // await ds.addSparkOperations() } diff --git a/packages/dma-contracts/scripts/utils/deploy.ts b/packages/dma-contracts/scripts/utils/deploy.ts index d52c2b580..3d3e49376 100644 --- a/packages/dma-contracts/scripts/utils/deploy.ts +++ b/packages/dma-contracts/scripts/utils/deploy.ts @@ -30,6 +30,7 @@ import { getMorphoBlueAdjustDownOperationDefinition, getMorphoBlueAdjustUpOperationDefinition, getMorphoBlueBorrowOperationDefinition, + getMorphoBlueClaimRewardsOperationDefinition, getMorphoBlueCloseOperationDefinition, getMorphoBlueDepositBorrowOperationDefinition, getMorphoBlueDepositOperationDefinition, @@ -511,7 +512,6 @@ export class DeploymentSystem extends DeployedSystemHelpers { configItem.serviceRegistryName, contract.address, true, - { tenderly: this.isTenderly }, ) } catch (error: any) { console.log( @@ -558,7 +558,7 @@ export class DeploymentSystem extends DeployedSystemHelpers { async addRegistryEntry(configItem: ConfigEntry, address: string) { if (!this.serviceRegistryHelper) throw new Error('ServiceRegistryHelper not initialized') if (configItem.serviceRegistryName) { - await this.serviceRegistryHelper.addEntry(configItem.serviceRegistryName, address) + await this.serviceRegistryHelper.addEntry(configItem.serviceRegistryName, address, true) await this.postRegistryEntry(configItem, address) } } @@ -607,7 +607,9 @@ export class DeploymentSystem extends DeployedSystemHelpers { } if (systemConfigEntry.name === 'ServiceRegistry') { - this.serviceRegistryHelper = new ServiceRegistry(systemConfigEntry.address, this.signer) + this.serviceRegistryHelper = new ServiceRegistry(systemConfigEntry.address, this.signer, { + isTenderly: this.isTenderly, + }) if (this.isLocal) { if (!this.provider) throw new Error('No provider set') @@ -712,7 +714,9 @@ export class DeploymentSystem extends DeployedSystemHelpers { ) if (systemConfigEntry.name === 'ServiceRegistry') { - this.serviceRegistryHelper = new ServiceRegistry(contractInstance.address, this.signer) + this.serviceRegistryHelper = new ServiceRegistry(contractInstance.address, this.signer, { + isTenderly: this.isTenderly, + }) } this.deployedSystem[systemConfigEntry.name] = { @@ -922,6 +926,7 @@ export class DeploymentSystem extends DeployedSystemHelpers { const operationsRegistry = new OperationsRegistry( this.deployedSystem.OperationsRegistry.contract.address, this.signer, + { isTenderly: this.isTenderly, debug: true }, ) let network = this.network @@ -1162,6 +1167,14 @@ export class DeploymentSystem extends DeployedSystemHelpers { ) this.logOp(morphoblueAdjustDownOperationDefinition) + const morphoblueClaimRewardsOperationDefinition = + getMorphoBlueClaimRewardsOperationDefinition(network) + await operationsRegistry.addOp( + morphoblueClaimRewardsOperationDefinition.name, + morphoblueClaimRewardsOperationDefinition.actions, + ) + this.logOp(morphoblueClaimRewardsOperationDefinition) + const sparkMigrateOperationDefinition = getSparkMigrateOperationDefinition(network) await operationsRegistry.addOp( sparkMigrateOperationDefinition.name, diff --git a/packages/dma-library/src/strategies/aave-like/borrow/deposit-borrow/deposit-borrow.ts b/packages/dma-library/src/strategies/aave-like/borrow/deposit-borrow/deposit-borrow.ts index 8219ef363..1bd8bb567 100644 --- a/packages/dma-library/src/strategies/aave-like/borrow/deposit-borrow/deposit-borrow.ts +++ b/packages/dma-library/src/strategies/aave-like/borrow/deposit-borrow/deposit-borrow.ts @@ -28,7 +28,7 @@ export const depositBorrow: AaveLikeDepositBorrow = async (args, dependencies) = dependencies.addresses.tokens.WETH, ) - const deposit = await AaveCommon.buildDepositArgs( + const deposit = await AaveCommon.buildDepositBorrowArgs( entryToken, collateralToken, collateralTokenAddress, diff --git a/packages/dma-library/src/strategies/aave-like/borrow/open-deposit-borrow/open-deposit-borrow.ts b/packages/dma-library/src/strategies/aave-like/borrow/open-deposit-borrow/open-deposit-borrow.ts index 40de1f3f6..b5990115d 100644 --- a/packages/dma-library/src/strategies/aave-like/borrow/open-deposit-borrow/open-deposit-borrow.ts +++ b/packages/dma-library/src/strategies/aave-like/borrow/open-deposit-borrow/open-deposit-borrow.ts @@ -32,7 +32,7 @@ export const openDepositBorrow: AaveLikeOpenDepositBorrow = async (args, depende ) const alwaysReturnDepositArgs = true - const deposit = await AaveCommon.buildDepositArgs( + const deposit = await AaveCommon.buildDepositBorrowArgs( entryToken, collateralToken, collateralTokenAddress, diff --git a/packages/dma-library/src/strategies/aave-like/multiply/close/close.ts b/packages/dma-library/src/strategies/aave-like/multiply/close/close.ts index d61ff4ede..cb9650f9b 100644 --- a/packages/dma-library/src/strategies/aave-like/multiply/close/close.ts +++ b/packages/dma-library/src/strategies/aave-like/multiply/close/close.ts @@ -6,6 +6,7 @@ import { } from '@dma-library/strategies/aave/common' import { resolveProtocolData } from '@dma-library/strategies/aave-like/common' import * as StrategiesCommon from '@dma-library/strategies/common' +import { getPositionDataAaveLike } from '@dma-library/utils/fee-service' import { buildOperation } from './build-operation' import { generate } from './generate' @@ -112,6 +113,7 @@ async function getAaveSwapDataToCloseToCollateral( outstandingDebt: dependencies.currentPosition.debt.amount, slippage, getSwapData: dependencies.getSwapData, + positionData: getPositionDataAaveLike(dependencies), }) } @@ -144,5 +146,6 @@ async function getAaveSwapDataToCloseToDebt( slippage, swapAmountBeforeFees, getSwapData: dependencies.getSwapData, + positionData: getPositionDataAaveLike(dependencies), }) } diff --git a/packages/dma-library/src/strategies/aave-like/multiply/open/open.ts b/packages/dma-library/src/strategies/aave-like/multiply/open/open.ts index 3ebd44272..742ae7e9c 100644 --- a/packages/dma-library/src/strategies/aave-like/multiply/open/open.ts +++ b/packages/dma-library/src/strategies/aave-like/multiply/open/open.ts @@ -1,7 +1,6 @@ import { amountToWei } from '@dma-common/utils/common' import { getAaveTokenAddress } from '@dma-library/strategies/aave/common' import { AaveLikeTokens } from '@dma-library/types/aave-like' -import { getPositionDataAaveLike } from '@dma-library/utils/fee-service' import * as SwapUtils from '@dma-library/utils/swap' import BigNumber from 'bignumber.js' @@ -14,7 +13,7 @@ export const open: AaveLikeOpen = async (args, dependencies) => { const fee = await SwapUtils.feeResolver(args.collateralToken.symbol, args.debtToken.symbol, { isIncreasingRisk: true, isEarnPosition: dependencies.positionType === 'Earn', - positionData: getPositionDataAaveLike(dependencies), + isOpeningPosition: true, }) const estimatedSwapAmount = amountToWei(new BigNumber(1), args.debtToken.precision) diff --git a/packages/dma-library/src/strategies/aave/common/build-deposit-args.ts b/packages/dma-library/src/strategies/aave/common/build-deposit-borrow-args.ts similarity index 87% rename from packages/dma-library/src/strategies/aave/common/build-deposit-args.ts rename to packages/dma-library/src/strategies/aave/common/build-deposit-borrow-args.ts index 28178b6bc..aeaf9b674 100644 --- a/packages/dma-library/src/strategies/aave/common/build-deposit-args.ts +++ b/packages/dma-library/src/strategies/aave/common/build-deposit-borrow-args.ts @@ -1,25 +1,22 @@ import { Address } from '@deploy-configurations/types/address' -import type { Network } from '@deploy-configurations/types/network' import { ZERO } from '@dma-common/constants' import { DepositArgs } from '@dma-library/operations' -import { AaveLikeStrategyAddresses } from '@dma-library/operations/aave-like' import { getAaveTokenAddress } from '@dma-library/strategies/aave/common' import { AaveLikeTokens, SwapData } from '@dma-library/types' -import * as StrategyParams from '@dma-library/types/strategy-params' +import { getPositionDataAaveLike } from '@dma-library/utils/fee-service' import * as SwapUtils from '@dma-library/utils/swap' import BigNumber from 'bignumber.js' -export async function buildDepositArgs( +import type { AaveLikeDepositBorrowDependencies } from '../../aave-like/borrow/deposit-borrow' +import type { AaveLikeOpenDepositBorrowDependencies } from '../../aave-like/borrow/open-deposit-borrow' + +export async function buildDepositBorrowArgs( entryToken: { symbol: AaveLikeTokens }, collateralToken: { symbol: AaveLikeTokens }, collateralTokenAddress: Address, entryTokenAmount: BigNumber, slippage: BigNumber, - dependencies: { - user: Address - network: Network - addresses: AaveLikeStrategyAddresses - } & StrategyParams.WithOptionalGetSwap, + dependencies: AaveLikeDepositBorrowDependencies | AaveLikeOpenDepositBorrowDependencies, alwaysReturnArgs = false, ): Promise<{ swap: @@ -71,8 +68,9 @@ export async function buildDepositArgs( if (!dependencies.getSwapData) throw new Error('Swap data is required for swap to be performed') const collectFeeInFromToken = collectFeeFrom === 'sourceToken' - const fee = SwapUtils.percentageFeeResolver(entryToken.symbol, collateralSymbol, { + const fee = await SwapUtils.feeResolver(entryToken.symbol, collateralSymbol, { isEntrySwap: true, + positionData: getPositionDataAaveLike(dependencies), }) const { swapData } = await SwapUtils.getSwapDataHelper< diff --git a/packages/dma-library/src/strategies/aave/common/index.ts b/packages/dma-library/src/strategies/aave/common/index.ts index 9b1e14d2e..910f4d5b2 100644 --- a/packages/dma-library/src/strategies/aave/common/index.ts +++ b/packages/dma-library/src/strategies/aave/common/index.ts @@ -2,7 +2,7 @@ import { FlashloanDependencies, getFlashloanToken } from './get-flashloan-token' export { FlashloanDependencies, getFlashloanToken } export { buildBorrowArgs } from './build-borrow-args' -export { buildDepositArgs } from './build-deposit-args' +export { buildDepositBorrowArgs } from './build-deposit-borrow-args' export { buildSimulation } from './build-simulation' export { buildSwap } from './build-swap' export { buildTransaction } from './build-transaction' diff --git a/packages/dma-library/src/strategies/ajna/multiply/adjust.ts b/packages/dma-library/src/strategies/ajna/multiply/adjust.ts index 2c3bb0937..dcfd1cba0 100644 --- a/packages/dma-library/src/strategies/ajna/multiply/adjust.ts +++ b/packages/dma-library/src/strategies/ajna/multiply/adjust.ts @@ -17,6 +17,7 @@ import { SwapData, } from '@dma-library/types' import { AjnaCommonDMADependencies } from '@dma-library/types/ajna' +import { getPositionDataAjna } from '@dma-library/utils/fee-service' import * as SwapUtils from '@dma-library/utils/swap' import * as Domain from '@domain' import { isRiskIncreasing } from '@domain/utils' @@ -72,7 +73,7 @@ const adjustRiskUp: AjnaAdjustRiskStrategy = async (args, dependencies) => { ) // Prepare payload - return prepareAjnaMultiplyDMAPayload( + return await prepareAjnaMultiplyDMAPayload( args, dependencies, simulatedAdjustment, @@ -116,7 +117,7 @@ const adjustRiskDown: AjnaAdjustRiskStrategy = async (args, dependencies) => { ) // Prepare payload - return prepareAjnaMultiplyDMAPayload( + return await prepareAjnaMultiplyDMAPayload( args, dependencies, simulatedAdjustment, @@ -143,9 +144,13 @@ async function buildOperation( const fromTokenSymbol = riskIsIncreasing ? args.quoteTokenSymbol : args.collateralTokenSymbol const toTokenSymbol = riskIsIncreasing ? args.collateralTokenSymbol : args.quoteTokenSymbol - const fee = SwapUtils.percentageFeeResolver(fromTokenSymbol, toTokenSymbol, { + const fee = await SwapUtils.feeResolver(fromTokenSymbol, toTokenSymbol, { isIncreasingRisk: riskIsIncreasing, isEarnPosition: SwapUtils.isCorrelatedPosition(fromTokenSymbol, toTokenSymbol), + positionData: getPositionDataAjna({ + network: dependencies.network, + proxy: args.dpmProxyAddress, + }), }) // When adjusting risk up we need to flashloan the swap amount before deducting fees // Assuming an ETH/USDC position, we'd be Flashloaning USDC to swap for ETH diff --git a/packages/dma-library/src/strategies/ajna/multiply/close.ts b/packages/dma-library/src/strategies/ajna/multiply/close.ts index 66e5c9d77..5aa7cb8ec 100644 --- a/packages/dma-library/src/strategies/ajna/multiply/close.ts +++ b/packages/dma-library/src/strategies/ajna/multiply/close.ts @@ -19,6 +19,7 @@ import { AjnaCloseMultiplyPayload, AjnaCommonDMADependencies, } from '@dma-library/types/ajna/ajna-dependencies' +import { getPositionDataAjna } from '@dma-library/utils/fee-service' import { encodeOperation } from '@dma-library/utils/operation' import * as SwapUtils from '@dma-library/utils/swap' import * as Domain from '@domain' @@ -57,12 +58,16 @@ export const closeMultiply: AjnaCloseStrategy = async (args, dependencies) => { const targetPosition = args.position.close() - const fee = SwapUtils.percentageFeeResolver(args.collateralTokenSymbol, args.quoteTokenSymbol, { + const fee = await SwapUtils.feeResolver(args.collateralTokenSymbol, args.quoteTokenSymbol, { isEarnPosition: SwapUtils.isCorrelatedPosition( args.collateralTokenSymbol, args.quoteTokenSymbol, ), isIncreasingRisk: false, + positionData: getPositionDataAjna({ + proxy: args.dpmProxyAddress, + network: dependencies.network, + }), }) const postSwapFee = @@ -122,6 +127,10 @@ async function getAjnaSwapDataToCloseToDebt( slippage: args.slippage, swapAmountBeforeFees: swapAmountBeforeFees, getSwapData: dependencies.getSwapData, + positionData: getPositionDataAjna({ + proxy: args.dpmProxyAddress, + network: dependencies.network, + }), }) } @@ -156,6 +165,10 @@ async function getAjnaSwapDataToCloseToCollateral( slippage: args.slippage, outstandingDebt, getSwapData: dependencies.getSwapData, + positionData: getPositionDataAjna({ + proxy: args.dpmProxyAddress, + network: dependencies.network, + }), }) } @@ -188,12 +201,16 @@ async function buildOperation( address: position.pool.quoteToken, } - const fee = SwapUtils.percentageFeeResolver(args.collateralTokenSymbol, args.quoteTokenSymbol, { + const fee = await SwapUtils.feeResolver(args.collateralTokenSymbol, args.quoteTokenSymbol, { isEarnPosition: SwapUtils.isCorrelatedPosition( args.collateralTokenSymbol, args.quoteTokenSymbol, ), isIncreasingRisk: false, + positionData: getPositionDataAjna({ + network: dependencies.network, + proxy: args.dpmProxyAddress, + }), }) const collateralAmountToBeSwapped = args.shouldCloseToCollateral diff --git a/packages/dma-library/src/strategies/ajna/multiply/common.ts b/packages/dma-library/src/strategies/ajna/multiply/common.ts index a3604dd5a..876246f5b 100644 --- a/packages/dma-library/src/strategies/ajna/multiply/common.ts +++ b/packages/dma-library/src/strategies/ajna/multiply/common.ts @@ -20,6 +20,7 @@ import { SwapData, } from '@dma-library/types' import { AjnaCommonDMADependencies } from '@dma-library/types/ajna' +import { getPositionDataAjna } from '@dma-library/utils/fee-service' import { encodeOperation } from '@dma-library/utils/operation' import * as SwapUtils from '@dma-library/utils/swap' import * as Domain from '@domain' @@ -40,10 +41,14 @@ export async function simulateAdjustment( const fromToken = buildFromToken(args, riskIsIncreasing) const toToken = buildToToken(args, riskIsIncreasing) - const feeResult = SwapUtils.percentageFeeResolver(fromToken.symbol, toToken.symbol, { + const feeResult = await SwapUtils.feeResolver(fromToken.symbol, toToken.symbol, { isIncreasingRisk: riskIsIncreasing, // Strategy is called open multiply (not open earn) isEarnPosition: positionType === 'Earn', + positionData: getPositionDataAjna({ + network: dependencies.network, + proxy: args.dpmProxyAddress, + }), }) const fee = __feeOverride || feeResult.feeToCharge @@ -137,13 +142,17 @@ export async function getSwapData( __feeOverride?: BigNumber, ) { const swapAmountBeforeFees = simulatedAdjust.swap.fromTokenAmount - const feeResult = SwapUtils.percentageFeeResolver( + const feeResult = await SwapUtils.feeResolver( simulatedAdjust.position.collateral.symbol, simulatedAdjust.position.debt.symbol, { isIncreasingRisk: riskIsIncreasing, // Strategy is called open multiply (not open earn) isEarnPosition: positionType === 'Earn', + positionData: getPositionDataAjna({ + network: dependencies.network, + proxy: args.dpmProxyAddress, + }), }, ) const fee = __feeOverride || feeResult.feeToCharge @@ -169,7 +178,7 @@ export async function getSwapData( return { swapData, collectFeeFrom, preSwapFee } } -export function prepareAjnaMultiplyDMAPayload( +export async function prepareAjnaMultiplyDMAPayload( args: AjnaMultiplyPayload, dependencies: AjnaCommonDMADependencies, simulatedAdjustment: Domain.ISimulationV2 & Domain.WithSwap, @@ -213,9 +222,13 @@ export function prepareAjnaMultiplyDMAPayload( const txAmount = args.collateralAmount const fromTokenSymbol = riskIsIncreasing ? args.quoteTokenSymbol : args.collateralTokenSymbol const toTokenSymbol = riskIsIncreasing ? args.collateralTokenSymbol : args.quoteTokenSymbol - const fee = SwapUtils.percentageFeeResolver(fromTokenSymbol, toTokenSymbol, { + const fee = await SwapUtils.feeResolver(fromTokenSymbol, toTokenSymbol, { isIncreasingRisk: riskIsIncreasing, isEarnPosition: false, + positionData: getPositionDataAjna({ + network: dependencies.network, + proxy: args.dpmProxyAddress, + }), }) const postSwapFee = collectFeeFrom === 'sourceToken' diff --git a/packages/dma-library/src/strategies/ajna/multiply/open.ts b/packages/dma-library/src/strategies/ajna/multiply/open.ts index 8e661b841..a6a7bb211 100644 --- a/packages/dma-library/src/strategies/ajna/multiply/open.ts +++ b/packages/dma-library/src/strategies/ajna/multiply/open.ts @@ -18,6 +18,7 @@ import { SwapData, } from '@dma-library/types' import { AjnaCommonDMADependencies, AjnaPosition, SummerStrategy } from '@dma-library/types/ajna' +import { getPositionDataAjna } from '@dma-library/utils/fee-service' import * as SwapUtils from '@dma-library/utils/swap' import { views } from '@dma-library/views' import * as Domain from '@domain' @@ -64,7 +65,7 @@ export const openMultiply: AjnaOpenMultiplyStrategy = async (args, dependencies) riskIsIncreasing, ) - return prepareAjnaMultiplyDMAPayload( + return await prepareAjnaMultiplyDMAPayload( { ...args, position }, dependencies, simulatedAdjustment, @@ -124,9 +125,13 @@ async function simulateAdjustment( const preFlightSwapAmount = amountToWei(ONE, args.quoteTokenPrecision) const fromToken = buildFromToken({ ...args, position }, riskIsIncreasing) const toToken = buildToToken({ ...args, position }, riskIsIncreasing) - const fee = SwapUtils.percentageFeeResolver(fromToken.symbol, toToken.symbol, { + const fee = await SwapUtils.feeResolver(fromToken.symbol, toToken.symbol, { isIncreasingRisk: riskIsIncreasing, isEarnPosition: SwapUtils.isCorrelatedPosition(fromToken.symbol, toToken.symbol), + positionData: getPositionDataAjna({ + network: dependencies.network, + proxy: args.dpmProxyAddress, + }), }) const { swapData: preFlightSwapData } = await SwapUtils.getSwapDataHelper< typeof dependencies.addresses, @@ -213,9 +218,13 @@ async function buildOperation( const borrowAmount = simulatedAdjust.delta.debt.minus(debtTokensDeposited) const collateralTokenSymbol = simulatedAdjust.position.collateral.symbol.toUpperCase() const debtTokenSymbol = simulatedAdjust.position.debt.symbol.toUpperCase() - const fee = SwapUtils.percentageFeeResolver(collateralTokenSymbol, debtTokenSymbol, { + const fee = await SwapUtils.feeResolver(collateralTokenSymbol, debtTokenSymbol, { isIncreasingRisk: riskIsIncreasing, isEarnPosition: SwapUtils.isCorrelatedPosition(collateralTokenSymbol, debtTokenSymbol), + positionData: getPositionDataAjna({ + network: dependencies.network, + proxy: args.dpmProxyAddress, + }), }) const swapAmountBeforeFees = simulatedAdjust.swap.fromTokenAmount const collectFeeFrom = SwapUtils.acceptedFeeTokenBySymbol({ diff --git a/packages/dma-library/src/strategies/common/close-to-coll-swap-data.ts b/packages/dma-library/src/strategies/common/close-to-coll-swap-data.ts index 8a3b42e3e..3d965d9f4 100644 --- a/packages/dma-library/src/strategies/common/close-to-coll-swap-data.ts +++ b/packages/dma-library/src/strategies/common/close-to-coll-swap-data.ts @@ -1,8 +1,10 @@ import { Address } from '@deploy-configurations/types/address' +import type { Network } from '@deploy-configurations/types/network' import { FEE_BASE, ONE, TEN, ZERO } from '@dma-common/constants' import { calculatePercentageFee } from '@dma-common/utils/swap' import { SAFETY_MARGIN } from '@dma-library/strategies/aave-like/multiply/close/constants' import { GetSwapData } from '@dma-library/types/common' +import { ProtocolId } from '@dma-library/utils/fee-service' import * as SwapUtils from '@dma-library/utils/swap' import BigNumber from 'bignumber.js' @@ -23,6 +25,11 @@ interface GetSwapDataToCloseToCollateralArgs { slippage: BigNumber getSwapData: GetSwapData __feeOverride?: BigNumber + positionData: { + network: Network + protocolId: ProtocolId + proxyAddress: string + } } export async function getSwapDataForCloseToCollateral({ @@ -34,6 +41,7 @@ export async function getSwapDataForCloseToCollateral({ slippage, getSwapData, __feeOverride, + positionData, }: GetSwapDataToCloseToCollateralArgs) { // This covers off the situation where debt balances accrue interest const _outstandingDebt = outstandingDebt @@ -43,6 +51,9 @@ export async function getSwapDataForCloseToCollateral({ // We don't want to attempt a zero debt swap with 1inch as it'll fail const hasZeroDebt = outstandingDebt.isZero() + const resolvedFee = await SwapUtils.feeResolver(collateralToken.symbol, debtToken.symbol, { + positionData, + }) // 1.Use offset amount which will be used in the swap as well. // The idea is that after the debt is paid, the remaining will be transferred to the beneficiary // Debt is a complex number and interest rate is constantly applied. @@ -50,9 +61,8 @@ export async function getSwapDataForCloseToCollateral({ // so instead of charging the user a fee, we add an offset ( equal to the fee ) to the // collateral amount. This means irrespective of whether the fee is collected before // or after the swap, there will always be sufficient debt token remaining to cover the outstanding position debt. - const fee = - __feeOverride || - SwapUtils.percentageFeeResolver(collateralToken.symbol, debtToken.symbol).feeToCharge + + const fee = __feeOverride || resolvedFee.feeToCharge // 2. Calculated the needed amount of collateral to payback the debt // This value is calculated based on oracle prices. diff --git a/packages/dma-library/src/strategies/common/close-to-debt-swap-data.ts b/packages/dma-library/src/strategies/common/close-to-debt-swap-data.ts index 1026270a5..15f7ba2de 100644 --- a/packages/dma-library/src/strategies/common/close-to-debt-swap-data.ts +++ b/packages/dma-library/src/strategies/common/close-to-debt-swap-data.ts @@ -1,7 +1,9 @@ import { Address } from '@deploy-configurations/types/address' +import type { Network } from '@deploy-configurations/types/network' import { ZERO } from '@dma-common/constants' import { calculatePercentageFee } from '@dma-common/utils/swap' import { GetSwapData } from '@dma-library/types/common' +import { ProtocolId } from '@dma-library/utils/fee-service' import * as SwapUtils from '@dma-library/utils/swap' import BigNumber from 'bignumber.js' @@ -20,6 +22,11 @@ interface GetSwapDataForCloseToDebtArgs { swapAmountBeforeFees: BigNumber getSwapData: GetSwapData __feeOverride?: BigNumber + positionData: { + network: Network + protocolId: ProtocolId + proxyAddress: string + } } export async function getSwapDataForCloseToDebt({ @@ -29,14 +36,18 @@ export async function getSwapDataForCloseToDebt({ swapAmountBeforeFees, getSwapData, __feeOverride, + positionData, }: GetSwapDataForCloseToDebtArgs) { const collectFeeFrom = SwapUtils.acceptedFeeTokenByAddress({ fromTokenAddress: fromToken.address, toTokenAddress: toToken.address, }) - const fee = - __feeOverride || SwapUtils.percentageFeeResolver(fromToken.symbol, toToken.symbol).feeToCharge + const resolvedFee = await SwapUtils.feeResolver(fromToken.symbol, toToken.symbol, { + positionData, + }) + + const fee = __feeOverride || resolvedFee.feeToCharge const preSwapFee = collectFeeFrom === 'sourceToken' diff --git a/packages/dma-library/src/strategies/common/erc4626/deposit.ts b/packages/dma-library/src/strategies/common/erc4626/deposit.ts index 60a859a84..4b5925b6a 100644 --- a/packages/dma-library/src/strategies/common/erc4626/deposit.ts +++ b/packages/dma-library/src/strategies/common/erc4626/deposit.ts @@ -1,7 +1,7 @@ import { ADDRESSES, SystemKeys } from '@deploy-configurations/addresses' import { amountToWei } from '@dma-common/utils/common' import { operations } from '@dma-library/operations' -import { getGenericSwapData } from '@dma-library/strategies/common' +import { getGenericSwapDataErc4626 } from '@dma-library/strategies/common' import { encodeOperation } from '@dma-library/utils/operation' import { views } from '@dma-library/views' import BigNumber from 'bignumber.js' @@ -164,7 +164,7 @@ async function getSwapData(args: Erc4626DepositPayload, dependencies: Erc4626Com address: args.depositTokenAddress, } - return getGenericSwapData({ + return getGenericSwapDataErc4626({ fromToken, toToken, slippage: args.slippage, diff --git a/packages/dma-library/src/strategies/common/erc4626/withdraw.ts b/packages/dma-library/src/strategies/common/erc4626/withdraw.ts index 49c3ac07f..ecb16ad8b 100644 --- a/packages/dma-library/src/strategies/common/erc4626/withdraw.ts +++ b/packages/dma-library/src/strategies/common/erc4626/withdraw.ts @@ -1,7 +1,7 @@ import { ADDRESSES, SystemKeys } from '@deploy-configurations/addresses' import { amountToWei } from '@dma-common/utils/common' import { operations } from '@dma-library/operations' -import { getGenericSwapData } from '@dma-library/strategies/common' +import { getGenericSwapDataErc4626 } from '@dma-library/strategies/common' import { encodeOperation } from '@dma-library/utils/operation' import { views } from '@dma-library/views' import BigNumber from 'bignumber.js' @@ -172,7 +172,7 @@ async function getSwapData(args: Erc4626WithdrawPayload, dependencies: Erc4626Co address: args.returnTokenAddress, } - return getGenericSwapData({ + return getGenericSwapDataErc4626({ fromToken, toToken, slippage: args.slippage, diff --git a/packages/dma-library/src/strategies/common/generic-swap-data.ts b/packages/dma-library/src/strategies/common/generic-swap-data-erc4626.ts similarity index 97% rename from packages/dma-library/src/strategies/common/generic-swap-data.ts rename to packages/dma-library/src/strategies/common/generic-swap-data-erc4626.ts index d03805be8..162372b78 100644 --- a/packages/dma-library/src/strategies/common/generic-swap-data.ts +++ b/packages/dma-library/src/strategies/common/generic-swap-data-erc4626.ts @@ -21,7 +21,7 @@ interface GetGenericSwapDataArgs { getSwapData: GetSwapData __feeOverride?: BigNumber } -export async function getGenericSwapData({ +export async function getGenericSwapDataErc4626({ fromToken, toToken, slippage, diff --git a/packages/dma-library/src/strategies/common/index.ts b/packages/dma-library/src/strategies/common/index.ts index ce3b590c6..93c1438cb 100644 --- a/packages/dma-library/src/strategies/common/index.ts +++ b/packages/dma-library/src/strategies/common/index.ts @@ -7,7 +7,7 @@ import { migrate } from './migrate' export { getSwapDataForCloseToCollateral } from './close-to-coll-swap-data' export { getSwapDataForCloseToDebt } from './close-to-debt-swap-data' -export { getGenericSwapData } from './generic-swap-data' +export { getGenericSwapDataErc4626 } from './generic-swap-data-erc4626' export const common: { erc4626: { diff --git a/packages/dma-library/src/strategies/morphoblue/multiply/adjust.ts b/packages/dma-library/src/strategies/morphoblue/multiply/adjust.ts index 037d4d3b7..3834d434e 100644 --- a/packages/dma-library/src/strategies/morphoblue/multiply/adjust.ts +++ b/packages/dma-library/src/strategies/morphoblue/multiply/adjust.ts @@ -12,6 +12,7 @@ import { SwapData, } from '@dma-library/types' import { SummerStrategy } from '@dma-library/types/ajna/ajna-strategy' +import { getPositionDataMorpho } from '@dma-library/utils/fee-service/getPositionData' import * as SwapUtils from '@dma-library/utils/swap' import * as Domain from '@domain' import { isRiskIncreasing } from '@domain/utils' @@ -221,9 +222,13 @@ async function buildOperation( const borrowAmount = simulatedAdjust.delta.debt.minus(debtTokensDeposited) const collateralTokenSymbol = simulatedAdjust.position.collateral.symbol.toUpperCase() const debtTokenSymbol = simulatedAdjust.position.debt.symbol.toUpperCase() - const fee = SwapUtils.percentageFeeResolver(collateralTokenSymbol, debtTokenSymbol, { + const fee = SwapUtils.feeResolver(collateralTokenSymbol, debtTokenSymbol, { isIncreasingRisk: riskIsIncreasing, isEarnPosition: SwapUtils.isCorrelatedPosition(collateralTokenSymbol, debtTokenSymbol), + positionData: getPositionDataMorpho({ + network: dependencies.network, + proxy: args.dpmProxyAddress, + }), }) const swapAmountBeforeFees = simulatedAdjust.swap.fromTokenAmount const collectFeeFrom = SwapUtils.acceptedFeeTokenBySymbol({ diff --git a/packages/dma-library/src/strategies/morphoblue/multiply/close.ts b/packages/dma-library/src/strategies/morphoblue/multiply/close.ts index 6de858b7f..5e195258a 100644 --- a/packages/dma-library/src/strategies/morphoblue/multiply/close.ts +++ b/packages/dma-library/src/strategies/morphoblue/multiply/close.ts @@ -15,6 +15,7 @@ import { SwapData, } from '@dma-library/types' import { StrategyError, StrategyWarning } from '@dma-library/types/ajna/ajna-validations' +import { getPositionDataMorpho } from '@dma-library/utils/fee-service' import { encodeOperation } from '@dma-library/utils/operation' import * as SwapUtils from '@dma-library/utils/swap' import * as Domain from '@domain' @@ -81,9 +82,13 @@ export const closeMultiply: MorphoCloseStrategy = async (args, dependencies) => const targetPosition = args.position.close() - const fee = SwapUtils.percentageFeeResolver(collateralTokenSymbol, debtTokenSymbol, { + const fee = await SwapUtils.feeResolver(collateralTokenSymbol, debtTokenSymbol, { isEarnPosition: SwapUtils.isCorrelatedPosition(collateralTokenSymbol, debtTokenSymbol), isIncreasingRisk: false, + positionData: getPositionDataMorpho({ + network: dependencies.network, + proxy: args.dpmProxyAddress, + }), }) const postSwapFee = @@ -144,6 +149,10 @@ async function getMorphoSwapDataToCloseToDebt( slippage: args.slippage, swapAmountBeforeFees: swapAmountBeforeFees, getSwapData: dependencies.getSwapData, + positionData: getPositionDataMorpho({ + network: dependencies.network, + proxy: args.dpmProxyAddress, + }), }) } @@ -180,6 +189,10 @@ async function getMorphoSwapDataToCloseToCollateral( slippage: args.slippage, outstandingDebt, getSwapData: dependencies.getSwapData, + positionData: getPositionDataMorpho({ + network: dependencies.network, + proxy: args.dpmProxyAddress, + }), }) } @@ -215,9 +228,13 @@ async function buildOperation( address: position.marketParams.loanToken, } - const fee = SwapUtils.percentageFeeResolver(collateralTokenSymbol, debtTokenSymbol, { + const fee = await SwapUtils.feeResolver(collateralTokenSymbol, debtTokenSymbol, { isEarnPosition: SwapUtils.isCorrelatedPosition(collateralTokenSymbol, debtTokenSymbol), isIncreasingRisk: false, + positionData: getPositionDataMorpho({ + network: dependencies.network, + proxy: args.dpmProxyAddress, + }), }) const collateralAmountToBeSwapped = args.shouldCloseToCollateral diff --git a/packages/dma-library/src/strategies/morphoblue/multiply/open.ts b/packages/dma-library/src/strategies/morphoblue/multiply/open.ts index a51ea36b0..79286620a 100644 --- a/packages/dma-library/src/strategies/morphoblue/multiply/open.ts +++ b/packages/dma-library/src/strategies/morphoblue/multiply/open.ts @@ -31,6 +31,7 @@ import { SummerStrategy, } from '@dma-library/types/ajna' import { CommonDMADependencies, GetSwapData } from '@dma-library/types/common' +import { getPositionDataMorpho } from '@dma-library/utils/fee-service/getPositionData' import { encodeOperation } from '@dma-library/utils/operation' import * as SwapUtils from '@dma-library/utils/swap' import { GetCumulativesData, views } from '@dma-library/views' @@ -252,9 +253,13 @@ export async function simulateAdjustment( debtTokenSymbol, ) const preFlightSwapAmount = amountToWei(ONE, fromToken.precision) - const fee = SwapUtils.percentageFeeResolver(fromToken.symbol, toToken.symbol, { + const fee = await SwapUtils.feeResolver(fromToken.symbol, toToken.symbol, { isIncreasingRisk: riskIsIncreasing, isEarnPosition: SwapUtils.isCorrelatedPosition(fromToken.symbol, toToken.symbol), + positionData: getPositionDataMorpho({ + network: dependencies.network, + proxy: args.dpmProxyAddress, + }), }) const { swapData: preFlightSwapData } = await SwapUtils.getSwapDataHelper< @@ -338,9 +343,13 @@ async function buildOperation( const borrowAmount = simulatedAdjust.delta.debt.minus(debtTokensDeposited) const collateralTokenSymbol = simulatedAdjust.position.collateral.symbol.toUpperCase() const debtTokenSymbol = simulatedAdjust.position.debt.symbol.toUpperCase() - const fee = SwapUtils.percentageFeeResolver(collateralTokenSymbol, debtTokenSymbol, { + const fee = await SwapUtils.feeResolver(collateralTokenSymbol, debtTokenSymbol, { isIncreasingRisk: riskIsIncreasing, isEarnPosition: SwapUtils.isCorrelatedPosition(collateralTokenSymbol, debtTokenSymbol), + positionData: getPositionDataMorpho({ + network: dependencies.network, + proxy: args.dpmProxyAddress, + }), }) const swapAmountBeforeFees = simulatedAdjust.swap.fromTokenAmount const collectFeeFrom = SwapUtils.acceptedFeeTokenBySymbol({ @@ -420,13 +429,17 @@ export async function getSwapData( __feeOverride?: BigNumber, ) { const swapAmountBeforeFees = simulatedAdjust.swap.fromTokenAmount - const feeResult = SwapUtils.percentageFeeResolver( + const feeResult = await SwapUtils.feeResolver( simulatedAdjust.position.collateral.symbol, simulatedAdjust.position.debt.symbol, { isIncreasingRisk: riskIsIncreasing, // Strategy is called open multiply (not open earn) isEarnPosition: positionType === 'Earn', + positionData: getPositionDataMorpho({ + network: dependencies.network, + proxy: args.dpmProxyAddress, + }), }, ) const fee = __feeOverride || feeResult.feeToCharge @@ -509,7 +522,7 @@ export async function getTokenSymbol( } } -export function prepareMorphoMultiplyDMAPayload( +export async function prepareMorphoMultiplyDMAPayload( args: AdjustArgs, dependencies: MorphoMultiplyDependencies, simulatedAdjustment: Domain.ISimulationV2 & Domain.WithSwap, @@ -551,9 +564,13 @@ export function prepareMorphoMultiplyDMAPayload( const txAmount = args.collateralAmount const fromTokenSymbol = riskIsIncreasing ? debtTokenSymbol : collateralTokenSymbol const toTokenSymbol = riskIsIncreasing ? collateralTokenSymbol : debtTokenSymbol - const fee = SwapUtils.percentageFeeResolver(fromTokenSymbol, toTokenSymbol, { + const fee = await SwapUtils.feeResolver(fromTokenSymbol, toTokenSymbol, { isIncreasingRisk: riskIsIncreasing, isEarnPosition: false, + positionData: getPositionDataMorpho({ + network: dependencies.network, + proxy: args.dpmProxyAddress, + }), }) const postSwapFee = collectFeeFrom === 'sourceToken' diff --git a/packages/dma-library/src/utils/fee-service/getEarnMultiplyFee.ts b/packages/dma-library/src/utils/fee-service/getEarnMultiplyFee.ts index 8048cc396..080851640 100644 --- a/packages/dma-library/src/utils/fee-service/getEarnMultiplyFee.ts +++ b/packages/dma-library/src/utils/fee-service/getEarnMultiplyFee.ts @@ -27,7 +27,7 @@ export const getEarnMultiplyFee = async ({ position = await subgraphClient.GetPosition(proxyAddress) } catch (error) { throw new Error( - `Error fetching position with proxyAddress (${proxyAddress}) and protocol ${protocolId}`, + `Error fetching position for getEarnMultiplyFee with proxyAddress (${proxyAddress}) and protocol ${protocolId}.`, ) } diff --git a/packages/dma-library/src/utils/fee-service/getPositionData.ts b/packages/dma-library/src/utils/fee-service/getPositionData.ts index 30e6dfb8d..116ab3083 100644 --- a/packages/dma-library/src/utils/fee-service/getPositionData.ts +++ b/packages/dma-library/src/utils/fee-service/getPositionData.ts @@ -16,3 +16,25 @@ export const getPositionDataAaveLike = (dependencies: { proxyAddress: dependencies.proxy, } } + +export const getPositionDataMorpho = (dependencies: { + proxy: Address + network: Network +}): Parameters[0] => { + return { + network: dependencies.network, + protocolId: ProtocolId.MORPHO_BLUE, + proxyAddress: dependencies.proxy, + } +} + +export const getPositionDataAjna = (dependencies: { + proxy: Address + network: Network +}): Parameters[0] => { + return { + network: dependencies.network, + protocolId: ProtocolId.AJNA, + proxyAddress: dependencies.proxy, + } +} diff --git a/packages/dma-library/src/utils/fee-service/index.ts b/packages/dma-library/src/utils/fee-service/index.ts index b469effc0..29626155f 100644 --- a/packages/dma-library/src/utils/fee-service/index.ts +++ b/packages/dma-library/src/utils/fee-service/index.ts @@ -1 +1,2 @@ -export { getPositionDataAaveLike } from './getPositionData' +export * from './getPositionData' +export * from './ProtocolId' diff --git a/packages/dma-library/src/utils/swap/fee-resolver.ts b/packages/dma-library/src/utils/swap/fee-resolver.ts index e196fe550..a87a1bb52 100644 --- a/packages/dma-library/src/utils/swap/fee-resolver.ts +++ b/packages/dma-library/src/utils/swap/fee-resolver.ts @@ -15,6 +15,7 @@ export const feeResolver = async ( /** @deprecated Should rely on correlated asset matrix */ isEarnPosition?: boolean isEntrySwap?: boolean + isOpeningPosition?: boolean positionData?: { network: Network protocolId: ProtocolId @@ -26,7 +27,7 @@ export const feeResolver = async ( feeToCharge: BigNumber }> => { if (isCorrelatedPosition(fromToken, toToken) || options?.isEarnPosition) { - return fixedFeeResolver(options?.positionData) + return fixedFeeResolver(options?.positionData, options?.isOpeningPosition) } else { return percentageFeeResolver(fromToken, toToken, options) } diff --git a/packages/dma-library/src/utils/swap/fixed-fee-resolver.ts b/packages/dma-library/src/utils/swap/fixed-fee-resolver.ts index c90a4d913..93a2d2a07 100644 --- a/packages/dma-library/src/utils/swap/fixed-fee-resolver.ts +++ b/packages/dma-library/src/utils/swap/fixed-fee-resolver.ts @@ -1,21 +1,40 @@ import type { Network } from '@deploy-configurations/types/network' +import { NULL_ADDRESS } from '@dma-common/constants' import { SwapFeeType } from '@dma-library/types' import BigNumber from 'bignumber.js' import { getEarnMultiplyFee } from '../fee-service/getEarnMultiplyFee' import type { ProtocolId } from '../fee-service/ProtocolId' -export const fixedFeeResolver = async (positionData?: { - network: Network - protocolId: ProtocolId - proxyAddress: string -}): Promise<{ +export const fixedFeeResolver = async ( + positionData: + | { + network: Network + protocolId: ProtocolId + proxyAddress: string + } + | undefined, + isOpeningPosition?: boolean, +): Promise<{ feeType: SwapFeeType feeToCharge: BigNumber }> => { + if (isOpeningPosition) { + return { + feeType: SwapFeeType.Fixed, + feeToCharge: new BigNumber(0), + } + } + if (positionData === undefined) { throw new Error('Position data is required for earn multiply fee calculation') } + if (positionData.proxyAddress === NULL_ADDRESS) { + throw new Error( + `Proxy address is zero so if you're trying to open a new position, you should set isOpeningPosition to true when calculating a fee`, + ) + } + return { feeType: SwapFeeType.Fixed, feeToCharge: new BigNumber(await getEarnMultiplyFee(positionData)), diff --git a/packages/dma-library/src/utils/swap/percentage-fee-resolver.ts b/packages/dma-library/src/utils/swap/percentage-fee-resolver.ts index 565d5ad45..e5333f3c9 100644 --- a/packages/dma-library/src/utils/swap/percentage-fee-resolver.ts +++ b/packages/dma-library/src/utils/swap/percentage-fee-resolver.ts @@ -11,6 +11,7 @@ export const percentageFeeResolver = ( isIncreasingRisk?: boolean /** @deprecated Should rely on correlated asset matrix */ isEarnPosition?: boolean + /** if the swap is an entry swap */ isEntrySwap?: boolean }, ): {