Skip to content

Commit

Permalink
♻️ refactor leverager integration
Browse files Browse the repository at this point in the history
  • Loading branch information
JuampiRombola committed Sep 20, 2023
1 parent 5427ac2 commit 4e975ed
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 158 deletions.
14 changes: 2 additions & 12 deletions components/Leverager/Operation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@ import { ModalBox, ModalBoxCell, ModalBoxRow } from 'components/common/modal/Mod
import React from 'react';
import { useTranslation } from 'react-i18next';
import ArrowForwardRoundedIcon from '@mui/icons-material/ArrowForwardRounded';
import { PRICE_IMPACT_THRESHOLD, useLeveragerContext } from 'contexts/LeveragerContext';
import { useLeveragerContext } from 'contexts/LeveragerContext';
import MultiplierSlider from '../MultiplierSlider';
import LoopAPR from '../LoopAPR';
import HealthFactor from '../HealthFactor';
import AssetSelector from '../AssetSelector';
import ModalAlert from 'components/common/modal/ModalAlert';
import NetPosition from '../NetPosition';
import formatNumber from 'utils/formatNumber';
import { toPercentage } from 'utils/utils';

const Operation = () => {
const { t } = useTranslation();
Expand All @@ -28,12 +27,11 @@ const Operation = () => {
setViewSummary,
disabledSubmit,
isOverLeveraged,
isPriceImpactAboveThreshold,
} = useLeveragerContext();

return (
<Box>
<ModalBox sx={{ p: 2, mb: errorData?.status || isOverLeveraged || isPriceImpactAboveThreshold ? 1 : 4 }}>
<ModalBox sx={{ p: 2, mb: errorData?.status || isOverLeveraged ? 1 : 4 }}>
<ModalBoxRow>
<Grid container mb={1.5}>
<Grid item xs={7}>
Expand Down Expand Up @@ -89,14 +87,6 @@ const Operation = () => {
{isOverLeveraged && (
<ModalAlert message={t('You are currently over leveraged with the selected markets.')} variant="info" />
)}
{isPriceImpactAboveThreshold && (
<ModalAlert
message={t('Price impact is above {{ threshold }}, operation is too risky.', {
threshold: toPercentage(Number(PRICE_IMPACT_THRESHOLD) / 1e18),
})}
variant="warning"
/>
)}
{disabledSubmit ? (
<Button fullWidth variant="contained" disabled>
{t('Leverage')}
Expand Down
171 changes: 25 additions & 146 deletions contexts/LeveragerContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ type Input = {
export type ApprovalStatus = 'INIT' | 'ERC20' | 'ERC20-PERMIT2' | 'MARKET-IN' | 'MARKET-OUT' | 'APPROVED';

const DEFAULT_SLIPPAGE = 2n;
export const PRICE_IMPACT_THRESHOLD = 10n ** 18n;

const slippage = (value: bigint, up = true) => (value * (100n + (up ? 1n : -1n) * DEFAULT_SLIPPAGE)) / 100n;

Expand Down Expand Up @@ -125,7 +124,6 @@ type ContextValues = {
disabledConfirm: boolean;
blockModal: boolean;
isOverLeveraged: boolean;
isPriceImpactAboveThreshold: boolean;

getHealthFactorColor: (healthFactor?: string) => { color: string; bg: string };

Expand Down Expand Up @@ -229,7 +227,7 @@ export const LeveragerContextProvider: FC<PropsWithChildren> = ({ children }) =>
if (!_maOut) return undefined;

try {
const { result } = await debtPreviewer.simulate.leverage(
const result = await debtPreviewer.read.leverage(
[_maOut.market, _maOut.market, walletAddress, minHealthFactor(_maOut, _maOut)],
opts,
);
Expand Down Expand Up @@ -305,16 +303,6 @@ export const LeveragerContextProvider: FC<PropsWithChildren> = ({ children }) =>
return [_isOverleveraged, _isOverleveraged && leverageStatus.principal < 0n];
}, [leverageStatus]);

const isPriceImpactAboveThreshold = useMemo(() => {
if (!limit) {
return false;
}

const priceImpact =
limit.swapRatio > WEI_PER_ETHER ? limit.swapRatio - WEI_PER_ETHER : WEI_PER_ETHER - limit.swapRatio;
return priceImpact > PRICE_IMPACT_THRESHOLD;
}, [limit]);

const preview = useCallback(
async (cancelled: () => boolean) => {
if (!debtPreviewer || !maIn || !maOut || !walletAddress || !leverageStatus || !opts) {
Expand All @@ -327,23 +315,22 @@ export const LeveragerContextProvider: FC<PropsWithChildren> = ({ children }) =>
const args = [maIn.market, maOut.market, walletAddress, userInput, ratio, minHealthFactor(maIn, maOut)] as const;

try {
const { result: _limit } =
const _limit =
input.secondaryOperation === 'deposit'
? await debtPreviewer.simulate.previewLeverage(args, opts)
: await debtPreviewer.simulate.previewDeleverage(args, opts);

const _loopRates = await debtPreviewer.read.leverageRates(
[
maIn.market,
maOut.market,
walletAddress,
(input.secondaryOperation === 'deposit' ? 1n : -1n) * userInput,
ratio,
parseEther(String(depositAPR)),
input.collateralSymbol === 'wstETH' ? stETHNativeAPR : 0n,
],
opts,
);
? await debtPreviewer.read.previewLeverage(args, opts)
: await debtPreviewer.read.previewDeleverage(args, opts);

const leverageRatesArgs = [
maIn.market,
maOut.market,
walletAddress,
(input.secondaryOperation === 'deposit' ? 1n : -1n) * userInput,
ratio,
parseEther(String(depositAPR)),
input.collateralSymbol === 'wstETH' ? stETHNativeAPR : 0n,
input.collateralSymbol === 'wstETH' ? stETHNativeAPR : 0n,
] as const;
const _loopRates = await debtPreviewer.read.leverageRates(leverageRatesArgs, opts);

if (cancelled()) return;

Expand Down Expand Up @@ -543,7 +530,6 @@ export const LeveragerContextProvider: FC<PropsWithChildren> = ({ children }) =>
(principal ?? -1n) <= 0n ||
!leverageStatus ||
previewIsLoading ||
isPriceImpactAboveThreshold ||
blockModal,
[
input.collateralSymbol,
Expand All @@ -555,7 +541,6 @@ export const LeveragerContextProvider: FC<PropsWithChildren> = ({ children }) =>
principal,
leverageStatus,
previewIsLoading,
isPriceImpactAboveThreshold,
blockModal,
],
);
Expand Down Expand Up @@ -839,6 +824,7 @@ export const LeveragerContextProvider: FC<PropsWithChildren> = ({ children }) =>

const permit = {
account: walletAddress,
value,
deadline,
...{ v, r: r as Hex, s: s as Hex },
} as const;
Expand Down Expand Up @@ -916,16 +902,16 @@ export const LeveragerContextProvider: FC<PropsWithChildren> = ({ children }) =>

switch (assetPermit.type) {
case 'permit': {
args = [...args, borrowAssets, marketPermit.value, assetPermit.value];
const gasEstimation = await debtManager.estimateGas.leverage(args, opts);
hash = await debtManager.write.leverage(args, {
const _args = [marketIn.address, ratio, marketPermit.value, assetPermit.value] as const;
const gasEstimation = await debtManager.estimateGas.leverage(_args, opts);
hash = await debtManager.write.leverage(_args, {
...opts,
gasLimit: gasLimit(gasEstimation),
});
break;
}
case 'permit2': {
args = [...args, borrowAssets, marketPermit.value, assetPermit.value];
args = [...args, marketPermit.value, assetPermit.value];
const gasEstimation = await debtManager.estimateGas.leverage(args, opts);
hash = await debtManager.write.leverage(args, {
...opts,
Expand All @@ -937,7 +923,7 @@ export const LeveragerContextProvider: FC<PropsWithChildren> = ({ children }) =>
break;
}
case 'withdraw': {
let args: Params<'deleverage'> = [marketIn.address, userInput, ratio] as const;
const args: Params<'deleverage'> = [marketIn.address, userInput, ratio] as const;

if (isMultiSig) {
const gasEstimation = await debtManager.estimateGas.deleverage(args, opts);
Expand All @@ -958,115 +944,9 @@ export const LeveragerContextProvider: FC<PropsWithChildren> = ({ children }) =>
return;
}

args = [...args, permitAssets, marketPermit.value] as const;
const gasEstimation = await debtManager.estimateGas.deleverage(args, opts);
hash = await debtManager.write.deleverage(args, {
...opts,
gasLimit: gasLimit(gasEstimation),
});
break;
}
}
} else {
switch (input.secondaryOperation) {
case 'deposit': {
const priceLimit =
assetOut.address === leverageStatus.pool.token0
? slippage(leverageStatus.sqrtPriceX96, false)
: slippage(leverageStatus.sqrtPriceX96);
let args: Params<'crossLeverage'> = [
marketIn.address,
marketOut.address,
leverageStatus.pool.fee,
userInput,
ratio,
priceLimit,
] as const;

if (isMultiSig) {
const gasEstimation = await debtManager.estimateGas.crossLeverage(args, opts);
hash = await debtManager.write.crossLeverage(args, {
...opts,
gasLimit: gasLimit(gasEstimation),
});
break;
}

const borrowAssets = await marketOut.read.previewWithdraw(
[limit.borrow - leverageStatus.borrow + 100n],
opts,
);
const [assetPermit, marketPermit] = await Promise.all([
signPermit(userInput, 'assetIn'),
signPermit(borrowAssets, 'marketOut'),
]);
if (!assetPermit || !marketPermit || !leverageStatus || marketPermit.type === 'permit2') {
return;
}

switch (assetPermit.type) {
case 'permit': {
args = [...args, borrowAssets, marketPermit.value, assetPermit.value] as const;
const gasEstimation = await debtManager.estimateGas.crossLeverage(args, opts);
hash = await debtManager.write.crossLeverage(args, {
...opts,
gasLimit: gasLimit(gasEstimation),
});
break;
}
case 'permit2': {
args = [...args, borrowAssets, marketPermit.value, assetPermit.value] as const;
const gasEstimation = await debtManager.estimateGas.crossLeverage(args, opts);
hash = await debtManager.write.crossLeverage(args, {
...opts,
gasLimit: gasLimit(gasEstimation),
});
break;
}
}
break;
}
case 'withdraw': {
const priceLimit =
assetIn.address === leverageStatus.pool.token0
? slippage(leverageStatus.sqrtPriceX96, false)
: slippage(leverageStatus.sqrtPriceX96);
let args: Params<'crossDeleverage'> = [
marketIn.address,
marketOut.address,
leverageStatus.pool.fee,
userInput,
ratio,
priceLimit,
] as const;

if (isMultiSig) {
const gasEstimation = await debtManager.estimateGas.crossDeleverage(args, opts);
hash = await debtManager.write.crossDeleverage(args, {
...opts,
gasLimit: gasLimit(gasEstimation),
});
break;
}

const permitAssets = await marketIn.read.previewWithdraw(
[
slippage(
(maIn.floatingBorrowAssets < limit.borrow ? 0n : maIn.floatingBorrowAssets - limit.borrow) +
userInput,
),
],
opts,
);

const marketPermit = await signPermit(permitAssets, 'marketIn');
if (!marketPermit || !leverageStatus || marketPermit.type === 'permit2') {
return;
}

args = [...args, permitAssets, marketPermit.value] as const;
const gasEstimation = await debtManager.estimateGas.crossDeleverage(args, opts);
hash = await debtManager.write.crossDeleverage(args, {
const _args = [marketIn.address, ratio, permitAssets, marketPermit.value] as const;
const gasEstimation = await debtManager.estimateGas.deleverage(_args, opts);
hash = await debtManager.write.deleverage(_args, {
...opts,
gasLimit: gasLimit(gasEstimation),
});
Expand Down Expand Up @@ -1151,7 +1031,6 @@ export const LeveragerContextProvider: FC<PropsWithChildren> = ({ children }) =>
disabledConfirm,
blockModal,
isOverLeveraged,
isPriceImpactAboveThreshold,

getHealthFactorColor,

Expand Down

0 comments on commit 4e975ed

Please sign in to comment.