Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ feat(with ops): create strategies for new withdraw-to-ltv operations for auto #23

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0da7250
feat: Add Aave borrow withdraw strategy
zerotucks Feb 28, 2024
c773556
feat: Add Aave V3 withdraw function and dependencies
zerotucks Feb 28, 2024
b65e836
refactor: Simplify withdraw function and handle different scenarios e…
zerotucks Feb 28, 2024
fe20208
feat: Update Aave withdrawal operations to use 'auto' namespace
zerotucks Feb 28, 2024
2cb94f8
Merge branch 'jt/sc-14561/sc-deploy-collectfee-action-add-new-ops-to'…
zerotucks Feb 28, 2024
86821b3
refactor: Update withdraw calculation with PositionBalance
zerotucks Feb 29, 2024
a02dcde
v0.5.21-dma-v2-workers.21-auto-withdraw-to-ltv
zerotucks Feb 29, 2024
b6be287
fix: Update transfer function to safeTransfer
zerotucks Feb 29, 2024
3099d83
Merge branch 'jt/sc-14561/sc-deploy-collectfee-action-add-new-ops-to'…
zerotucks Feb 29, 2024
69d3b2b
chore: bump version
zerotucks Feb 29, 2024
4c2cfcd
Merge branch 'jt/sc-14561/sc-deploy-collectfee-action-add-new-ops-to'…
zerotucks Feb 29, 2024
2bd3341
refactor: Update swap amount calculation with fees
zerotucks Feb 29, 2024
1428986
v0.5.21-dma-v2-workers.23-auto-withdraw-to-ltv
zerotucks Feb 29, 2024
c77ca9f
v0.5.21-dma-v2-workers.24-auto-withdraw-to-ltv
zerotucks Feb 29, 2024
b946652
fix: Update service registry name for SWAP in withdraw-to-debt op
zerotucks Feb 29, 2024
b602c4c
v0.5.21-dma-v2-workers.25-auto-withdraw-to-ltv
zerotucks Feb 29, 2024
07bedde
refactor: Update return type to use a named type
zerotucks Mar 1, 2024
2857e41
refactor: Rename spark/borrow to spark/auto
zerotucks Mar 1, 2024
7640124
feat: Add withdrawToLTV strategy in Spark auto module
zerotucks Mar 1, 2024
7173a77
chore: fix `WETH/ETH` issue
halaprix Mar 7, 2024
76c3080
Merge pull request #25 from OasisDEX/kk/sc-14667/bug-profit-to-collat…
halaprix Mar 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const OPERATION_NAMES = {
BORROW: 'AAVEV3Borrow',
PAYBACK_WITHDRAW: 'AAVEV3PaybackWithdraw',
WITHDRAW: 'AAVEV3Withdraw_3',
WITHDRAW_TO_DEBT: 'AAVEV3WithdrawToDebt_3',
WITHDRAW_TO_DEBT: 'AAVEV3WithdrawToDebt_4',
},
},
spark: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function getAaveV3WithdrawToDebtOperationDefinition(network: Network) {
optional: false,
},
{
hash: getActionHash(SERVICE_REGISTRY_NAMES.common.SWAP),
hash: getActionHash(SERVICE_REGISTRY_NAMES.common.SWAP_ACTION),
optional: false,
},
{
Expand Down
2 changes: 1 addition & 1 deletion packages/dma-library/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@oasisdex/dma-library",
"version": "0.5.21-dma-v2-workers.19-test.10",
"version": "0.5.21-dma-v2-workers.28-auto-withdraw-to-ltv",
"typings": "lib/index.d.ts",
"types": "lib/index.d.ts",
"main": "lib/index.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import BigNumber from 'bignumber.js'

type WithdrawToDebtArgs = {
withdrawAmount: BigNumber
swapAmount: BigNumber
receiveAtLeast: BigNumber
swapData: string
collateralTokenAddress: string
Expand Down Expand Up @@ -40,7 +41,7 @@ export const withdrawToDebt: AaveV3WithdrawToDebtOperation = async args => {
const swapCollateralTokensForDebtTokens = actions.common.swap(network, {
fromAsset: args.collateralTokenAddress,
toAsset: args.debtTokenAddress,
amount: args.withdrawAmount,
amount: args.swapAmount,
receiveAtLeast: args.receiveAtLeast,
fee: ZERO.toNumber(),
withData: args.swapData,
Expand Down
23 changes: 14 additions & 9 deletions packages/dma-library/src/operations/aave/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ import {
AaveV3PaybackWithdrawOperation,
paybackWithdraw as aaveV3PaybackWithdraw,
} from './borrow/v3/payback-withdraw'
import { type AaveV3WithdrawOperation, withdraw as aaveV3Withdraw } from './borrow/v3/withdraw'
import {
type AaveV3WithdrawToDebtOperation,
withdrawToDebt as aaveV3WithdrawToDebt,
} from './borrow/v3/withdraw-to-debt'
// Multiply
import {
AaveV2AdjustDownOperation,
Expand All @@ -53,6 +48,12 @@ import {
} from './multiply/v3/adjust-risk-up'
import { AaveV3CloseOperation, close as aaveV3Close } from './multiply/v3/close'
import { AaveV3OpenOperation, open as aaveV3Open } from './multiply/v3/open'
// Auto
import { type AaveV3WithdrawOperation, withdraw as aaveV3Withdraw } from './auto/withdraw'
import {
type AaveV3WithdrawToDebtOperation,
withdrawToDebt as aaveV3WithdrawToDebt,
} from './auto/withdraw-to-debt'

const borrow = {
v2: {
Expand All @@ -68,8 +69,6 @@ const borrow = {
depositBorrow: aaveV3DepositBorrow,
openDepositBorrow: aaveV3OpenDepositBorrow,
paybackWithdraw: aaveV3PaybackWithdraw,
withdraw: aaveV3Withdraw,
withdrawToDebt: aaveV3WithdrawToDebt,
},
}

Expand Down Expand Up @@ -102,8 +101,6 @@ export type AaveBorrowOperations = {
depositBorrow: AaveV3DepositBorrowOperation
openDepositBorrow: AaveV3OpenDepositBorrowOperation
paybackWithdraw: AaveV3PaybackWithdrawOperation
withdraw: AaveV3WithdrawOperation
withdrawToDebt: AaveV3WithdrawToDebtOperation
}
}

Expand All @@ -125,9 +122,17 @@ export type AaveMultiplyOperations = {
export type AaveOperations = {
borrow: AaveBorrowOperations
multiply: AaveMultiplyOperations
auto: {
withdraw: AaveV3WithdrawOperation
withdrawToDebt: AaveV3WithdrawToDebtOperation
}
}

export const aaveOperations: AaveOperations = {
borrow,
multiply,
auto: {
withdraw: aaveV3Withdraw,
withdrawToDebt: aaveV3WithdrawToDebt,
},
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import BigNumber from 'bignumber.js'

type WithdrawToDebtArgs = {
withdrawAmount: BigNumber
swapAmount: BigNumber
receiveAtLeast: BigNumber
swapData: string
collateralTokenAddress: string
Expand Down
30 changes: 22 additions & 8 deletions packages/dma-library/src/operations/spark/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import { AaveV3WithdrawOperation, withdraw as aaveV3Withdraw } from "@dma-library/operations/aave/auto/withdraw";
import {
AaveV3WithdrawToDebtOperation,
withdrawToDebt as aaveV3WithdrawToDebt
} from "@dma-library/operations/aave/auto/withdraw-to-debt";
import { borrow as sparkBorrow, SparkBorrowOperation } from './borrow/borrow'
import { deposit as sparkDeposit, SparkDepositOperation } from './borrow/deposit'
import {
Expand All @@ -12,14 +17,6 @@ import {
paybackWithdraw as sparkPaybackWithdraw,
SparkPaybackWithdrawOperation,
} from './borrow/payback-withdraw'
import {
withdraw as sparkWithdraw,
SparkWithdrawOperation,
} from './borrow/withdraw'
import {
withdrawToDebt as sparkWithdrawToDebt,
SparkWithdrawToDebtOperation,
} from './borrow/withdraw-to-debt'
import {
adjustRiskDown as sparkAdjustRiskDown,
SparkAdjustDownOperation,
Expand All @@ -30,6 +27,15 @@ import {
} from './multiply/adjust-risk-up'
import { close as sparkClose, SparkCloseOperation } from './multiply/close'
import { open as sparkOpen, SparkOpenOperation } from './multiply/open'
// Auto
import {
withdraw as sparkWithdraw,
SparkWithdrawOperation,
} from './auto/withdraw'
import {
withdrawToDebt as sparkWithdrawToDebt,
SparkWithdrawToDebtOperation,
} from './auto/withdraw-to-debt'

const borrow = {
borrow: sparkBorrow,
Expand Down Expand Up @@ -67,9 +73,17 @@ export type SparkMultiplyOperations = {
export type SparkOperations = {
borrow: SparkBorrowOperations
multiply: SparkMultiplyOperations
auto: {
withdraw: SparkWithdrawOperation
withdrawToDebt: SparkWithdrawToDebtOperation
}
}

export const sparkOperations: SparkOperations = {
borrow,
multiply,
auto: {
withdraw: sparkWithdraw,
withdrawToDebt: sparkWithdrawToDebt,
},
}
159 changes: 159 additions & 0 deletions packages/dma-library/src/strategies/aave/auto/withdraw-to-ltv/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { ONE, ZERO } from "@dma-common/constants";
import { withdraw as withdrawOp } from '@dma-library/operations/aave/auto/withdraw'
import { withdrawToDebt } from '@dma-library/operations/aave/auto/withdraw-to-debt'
import { getAaveTokenAddress } from '@dma-library/strategies/aave/common'
import { AaveLikeTokens } from '@dma-library/types'
import { WithV3Protocol } from '@dma-library/types/aave/protocol'
import * as Strategies from '@dma-library/types/strategies'
import * as StrategyParams from '@dma-library/types/strategy-params'
import { getSwapDataHelper } from '@dma-library/utils/swap'
import { PositionBalance } from '@domain'
import BigNumber from 'bignumber.js'

export type AaveV3WithdrawArgs = {
oraclePrice: BigNumber
targetLTV: BigNumber
slippage: BigNumber
shouldWithdrawToDebt: boolean
}

export type AaveV3WithdrawDependencies = Omit<
StrategyParams.WithAaveLikeStrategyDependencies,
'protocolType'
> &
StrategyParams.WithGetSwap &
WithV3Protocol

export type WithdrawToLTVStrategy = Omit<Strategies.IStrategy, 'simulation'>

export type AaveV3WithdrawToLTV = (
args: AaveV3WithdrawArgs,
dependencies: Omit<AaveV3WithdrawDependencies, 'protocol'>,
) => Promise<WithdrawToLTVStrategy>

export const withdraw: AaveV3WithdrawToLTV = async (args, dependencies) => {
const currentPosition = dependencies.currentPosition

const amountToWithdraw = determineWithdrawalAmount(
currentPosition.debt,
currentPosition.collateral,
args.targetLTV,
args.oraclePrice,
)

const collateralTokenSymbol = currentPosition.collateral.symbol
const debtTokenSymbol = currentPosition.debt.symbol

if (args.shouldWithdrawToDebt) {
const FEE = new BigNumber(20)
const FEE_BASIS = new BigNumber(10000)
const feeAmount = amountToWithdraw.times(FEE.div(FEE_BASIS)).integerValue(BigNumber.ROUND_FLOOR);
const amountToSwap = amountToWithdraw.minus(feeAmount)
const { swapData } = await getSwapDataHelper<typeof dependencies.addresses, AaveLikeTokens>({
args: {
fromToken: { symbol: collateralTokenSymbol as AaveLikeTokens },
toToken: { symbol: debtTokenSymbol as AaveLikeTokens },
slippage: args.slippage,
fee: ZERO,
// Before fees here refers to fees collected by the Swap contract
// not by CollectFee.sol
swapAmountBeforeFees: amountToSwap,
},
addresses: dependencies.addresses,
services: {
getSwapData: dependencies.getSwapData,
getTokenAddress: getAaveTokenAddress,
},
})

const operation = await withdrawToDebt({
withdrawAmount: amountToWithdraw,
collateralTokenAddress: getTokenAddressFromDependencies(
dependencies,
currentPosition.collateral.symbol,
),
receiveAtLeast: swapData.minToTokenAmount,
swapAmount: amountToSwap,
swapData: `${swapData.exchangeCalldata}`,
debtTokenAddress: getTokenAddressFromDependencies(dependencies, debtTokenSymbol),
debtIsEth: debtTokenSymbol === 'WETH',
proxy: dependencies.proxy,
addresses: dependencies.addresses,
network: dependencies.network,
})

return {
transaction: {
calls: operation.calls,
operationName: operation.operationName,
},
}
}

if (!args.shouldWithdrawToDebt) {
const operation = await withdrawOp({
withdrawAmount: amountToWithdraw,
collateralTokenAddress: getTokenAddressFromDependencies(
dependencies,
currentPosition.collateral.symbol,
),
collateralIsEth: collateralTokenSymbol === 'WETH',
proxy: dependencies.proxy,
addresses: dependencies.addresses,
network: dependencies.network,
})

return {
transaction: {
calls: operation.calls,
operationName: operation.operationName,
},
}
}

throw new Error('Should not be reached')
}

function determineWithdrawalAmount(
existingDebt: PositionBalance,
existingCollateral: PositionBalance,
targetLTV: BigNumber,
oraclePrice: BigNumber,
) {
const COLLATERAL_PRECISION = existingCollateral.precision
const DEBT_PRECISION = existingDebt.precision

// We scale down because BigNumber can handle precision maths
// with large floating point numbers
const scaledDownDebt = existingDebt.amount.div(new BigNumber(10).pow(DEBT_PRECISION))

// nextCollateral = existingDebt / (targetLTV * oraclePrice)
const scaledDownNextCollateral = scaledDownDebt.div(targetLTV.times(oraclePrice))
const nextCollateral = scaledDownNextCollateral.multipliedBy(
new BigNumber(10).pow(COLLATERAL_PRECISION),
)
const amountToWithdraw = existingCollateral.amount.minus(nextCollateral)

if (amountToWithdraw.lte(ZERO)) {
console.debug('next-collateral', nextCollateral.toString())
console.debug('amount-to-withdraw', amountToWithdraw.toString())
throw new Error('Cannot withdraw zero or less')
}

return amountToWithdraw
}

function getTokenAddressFromDependencies(
deps: Omit<AaveV3WithdrawDependencies, 'protocol'>,
symbol: string,
) {
const address = deps.addresses.tokens[symbol]

if (!address) {
console.debug('symbol:', symbol)
console.debug('tokens:', deps.addresses.tokens)
throw new Error('Could not get address from position token symbol')
}

return address
}
7 changes: 7 additions & 0 deletions packages/dma-library/src/strategies/aave/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
import { AaveV2Adjust, AaveV3Adjust, adjust } from './multiply/adjust'
import { AaveV2Close, AaveV3Close, close } from './multiply/close'
import { AaveV2Open, AaveV3Open, open } from './multiply/open'
import { AaveV3WithdrawToLTV, withdraw } from './auto/withdraw-to-ltv'

export const aave: {
borrow: {
Expand Down Expand Up @@ -45,6 +46,9 @@ export const aave: {
adjust: AaveV3Adjust
}
}
auto: {
withdraw: AaveV3WithdrawToLTV
}
} = {
borrow: {
v2: {
Expand Down Expand Up @@ -73,6 +77,9 @@ export const aave: {
adjust: (args, dependencies) => withV3Protocol(adjust, args, dependencies),
},
},
auto: {
withdraw: (args, dependencies) => withV3Protocol(withdraw, args, dependencies),
},
}

type DepsWithV2Protocol<T> = T & WithV2Protocol
Expand Down
Loading
Loading