Created
June 13, 2025 15:53
-
-
Save leanazulyoro/88d28d69136d3b7891360bf954340acc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { buildSwapParams } from 'swapper/src' | |
import { | |
Address, | |
Chain, | |
getContract, | |
PublicClient, | |
Transport | |
} from 'viem' | |
import { borrowStrategyABI } from '../../metadata/abis' | |
import { StrategyIds } from '../../metadata/strategyIds' | |
import { TAddresses } from '../../metadata/types' | |
import { FlashLoanExecutorEncoder } from '../encoders/flashLoanExecutorEncoder' | |
import { | |
IPosition, | |
IBorrowStrategyEncoder, | |
Execution | |
} from '../types' | |
import { getContracts } from '../contracts' | |
import { ONE_ETHER } from '../constants' | |
export type BorrowWithLeverageParams = { | |
borrowAmount: bigint | |
} | |
export type BorrowWithLeverageOptions = { | |
flashBorrowToken?: Address | |
maxSlippage?: bigint | |
} | |
async function borrowStrategy<chain extends Chain>( | |
client: PublicClient<Transport, chain>, | |
addresses: TAddresses, | |
strategies: StrategyIds, | |
position: IPosition<IBorrowStrategyEncoder>, | |
params: BorrowWithLeverageParams, | |
options?: BorrowWithLeverageOptions | |
) { | |
const positionContract = | |
position.contract || | |
getContract({ | |
abi: borrowStrategyABI, | |
address: position.address, | |
client: client as PublicClient | |
}) | |
const depositToken = await positionContract.read.asset() | |
const borrowToken = await positionContract.read.borrowToken() | |
const { oracleContract, flashLoanExecutorContract } = getContracts(addresses) | |
const oracle = getContract({ | |
...oracleContract, | |
client: client as PublicClient | |
}) | |
const flashLoanExecutor = getContract({ | |
...flashLoanExecutorContract, | |
client: client as PublicClient | |
}) | |
const { borrowAmount } = params | |
const maxSlippage = options?.maxSlippage || BigInt(0.005e18) | |
const flashBorrowToken = options?.flashBorrowToken || depositToken | |
const flashLoanAmount = await oracle.read.quote([ | |
borrowToken, | |
flashBorrowToken, | |
(borrowAmount * ONE_ETHER) / (ONE_ETHER + maxSlippage) | |
]) as bigint | |
const flashLoanRepayAmount = await flashLoanExecutor.read.getRepayAmount([ | |
flashBorrowToken, | |
flashLoanAmount | |
]) | |
const flashLoanRepayAmountInBorrowToken = (await oracle.read.quote([ | |
depositToken, | |
borrowToken, | |
flashLoanRepayAmount | |
])) as bigint | |
const flashLoanRepayAmountInBorrowTokenWithSlippage = | |
(flashLoanRepayAmountInBorrowToken * (ONE_ETHER + maxSlippage)) / ONE_ETHER | |
const zapOutParams = await buildSwapParams(client, { | |
amountIn: flashLoanRepayAmountInBorrowTokenWithSlippage, | |
from: position.address, | |
to: flashLoanExecutor.address, | |
tokenIn: borrowToken, | |
tokenOut: flashBorrowToken | |
}) | |
const featureCallData = position.encoder.encodeBorrowCallData({ | |
borrowAmount | |
}) | |
const executions: Execution[] = [ | |
// deposit the flashBorrowAmount into the position | |
{ | |
callData: position.encoder.encodeDepositCallData({ | |
depositAmount: flashLoanAmount | |
}), | |
target: position.address, | |
value: 0n | |
}, | |
// borrow | |
{ | |
callData: featureCallData, | |
target: position.address, | |
value: 0n | |
}, | |
// transfer to FlashLoanExecutor | |
{ | |
callData: position.encoder.encodeTransferOutCallData({ | |
amountOut: flashLoanRepayAmountInBorrowTokenWithSlippage, | |
to: flashLoanExecutor.address, | |
token: borrowToken, | |
zapOutParams | |
}), | |
target: position.address, | |
value: 0n | |
} | |
] | |
const zapInParams = await buildSwapParams(client, { | |
amountIn: flashLoanAmount, | |
from: flashLoanExecutor.address, | |
to: position.address, | |
tokenIn: flashBorrowToken, | |
tokenOut: depositToken | |
}) | |
const callData = FlashLoanExecutorEncoder.encodeStartCallData({ | |
executions, | |
flashBorrowAmount: flashLoanAmount, | |
flashBorrowToken, | |
position: position.address, | |
zapInParams | |
}) | |
return { callData, target: flashLoanExecutor.address, value: 0n } | |
} | |
/* | |
type SynthBorrowWithLeverageParams = BorrowWithLeverageParams & { | |
tokenIn?: Address | |
depositToken: Address | |
} | |
async function synthStrategy<chain extends Chain>( | |
client: PublicClient<Transport, chain>, | |
addresses: TAddresses, | |
strategies: StrategyIds, | |
position: IPosition<ISynthStrategyEncoder>, | |
params: SynthBorrowWithLeverageParams, | |
options?: BorrowWithLeverageOptions | |
) { | |
// TODO: implement borrow for synth strategy | |
} | |
*/ | |
export async function borrowWithLeverage<chain extends Chain>( | |
client: PublicClient<Transport, chain>, | |
addresses: TAddresses, | |
strategies: StrategyIds, | |
position: IPosition, | |
params: BorrowWithLeverageParams, | |
options?: BorrowWithLeverageOptions | |
) { | |
/*const { SYNTH_STRATEGY_ID } = strategies | |
if (position.strategyId === SYNTH_STRATEGY_ID) { | |
return synthStrategy( | |
client, | |
addresses, | |
strategies, | |
<IPosition<ISynthStrategyEncoder>>position, | |
params as SynthBorrowWithLeverageParams, | |
options | |
) | |
}*/ | |
return borrowStrategy( | |
client, | |
addresses, | |
strategies, | |
<IPosition<IBorrowStrategyEncoder>>position, | |
params, | |
options | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment