-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
319 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
import { StrategyShortId } from "./strategies"; | ||
import { getTokenData } from "./assets"; | ||
|
||
export type IlDetails = { | ||
rate: number; | ||
title: string; | ||
desc: string; | ||
color: string; | ||
}; | ||
|
||
export const IL /*: {[ilId: string]: IlDetails}*/ = { | ||
ALM_FILLUP_AGGRESSIVE: { | ||
rate: 10, | ||
title: "Very high", | ||
desc: "This preset of an ALM provides liquidity in the very narrow range, and very often re-balancing it by Fill-Up algo. Every re-balancing results in a loss. The higher the volatility of the pair, the more re-balancing and the greater the loss.", | ||
color: "#ff0000", | ||
}, | ||
ALM_FILLUP_NARROW: { | ||
rate: 8, | ||
title: "High", | ||
desc: "This preset of an ALM provides liquidity in the narrow range, and often re-balancing it by Fill-Up algo. Every re-balancing results in a loss. The higher the volatility of the pair, the more re-balancing and the greater the loss.", | ||
color: "#f55e11", | ||
}, | ||
ALM_VOLATILE_HIGH: { | ||
rate: 7, | ||
title: "HIGH", | ||
desc: "Significant impermanent loss was noted during re-balancing with this ALM in volatile pools.", | ||
color: "#f55e11", | ||
}, | ||
ALM_FILLUP_WIDE: { | ||
rate: 5, | ||
title: "Medium", | ||
desc: "This preset of an ALM provides liquidity in the wide range, re-balancing the position infrequently. Every re-balancing results in a loss. The higher the volatility of the pair, the more re-balancing and the greater the loss.", | ||
color: "#F5DA5B", | ||
}, | ||
ALM_STABLE_DEPEG_MEDIUM: { | ||
rate: 5, | ||
title: "Medium", | ||
desc: "We catch significant IL in stablecoin pairs with this strategy when depeg become..", | ||
color: "#F5DA5B", | ||
}, | ||
ALM_SINGLE_SIDED: { | ||
rate: 4, | ||
title: "Medium", | ||
desc: "The strategy of the underlying ALM provides liquidity in the very wide range, not often re-balancing the position.", | ||
color: "#F5DA5B", | ||
}, | ||
ALM_STRETCHED: { | ||
rate: 3, | ||
title: "Low", | ||
desc: "We expect low impermanent loss for such stretched range.", | ||
color: "#D7F55B", | ||
}, | ||
CLASSIC_vAMM: { | ||
rate: 3, | ||
title: "Low", | ||
desc: "Low impermanent loss is expected for UniswapV2-like and similar not CL AMMs.", | ||
color: "#D7F55B", | ||
}, | ||
ALM_PEGGED: { | ||
rate: 3, | ||
title: "Low", | ||
desc: "The strategy of the underlying liquidity provider developed for pegged assets.", | ||
color: "#D7F55B", | ||
}, | ||
ALM_STABLE_EXPAND: { | ||
rate: 1, | ||
title: "Zero exp", | ||
desc: "The strategy of the underlying liquidity provider can re-balance the position by expanding it, but this happens extremely rarely, only at times of high volatility of the assets in the pool.", | ||
color: "#7af996", | ||
}, | ||
CL_STABLE_FIXED: { | ||
rate: 1, | ||
title: "Zero exp", | ||
desc: "Liquidity in the form of stablecoins is provided in a fixed range, there are no re-balances, so there are no impermanent losses.", | ||
color: "#7af996", | ||
}, | ||
STABLE_SWAP: { | ||
rate: 1, | ||
title: "Zero exp", | ||
desc: "If asset prices in the stable pool are kept pegged, there are no impermanent losses.", | ||
color: "#7af996", | ||
}, | ||
LENDING: { | ||
rate: 0, | ||
title: "None", | ||
desc: "Providing assets to the lending protocol does not incur impermanent losses.", | ||
color: "#4aff71", | ||
}, | ||
}; | ||
|
||
export const getIL = ( | ||
strategyShortId: StrategyShortId, | ||
specific: string, | ||
assets: `0x${string}`[], | ||
): IlDetails | undefined => { | ||
if ( | ||
[ | ||
StrategyShortId.SiF, | ||
StrategyShortId.Y, | ||
StrategyShortId.SL, | ||
StrategyShortId.SiL, | ||
StrategyShortId.CF, | ||
].includes(strategyShortId) | ||
) { | ||
return IL.LENDING; | ||
} | ||
|
||
if ( | ||
[ | ||
StrategyShortId.IQMF, | ||
StrategyShortId.IRMF, | ||
StrategyShortId.IRBMF, | ||
StrategyShortId.IPF, | ||
StrategyShortId.IRF, | ||
StrategyShortId.ISF, | ||
StrategyShortId.IEF, | ||
].includes(strategyShortId) | ||
) { | ||
return IL.ALM_SINGLE_SIDED; | ||
} | ||
|
||
if ( | ||
[ | ||
StrategyShortId.GQMF, | ||
StrategyShortId.GUMF, | ||
StrategyShortId.GRMF, | ||
StrategyShortId.GEF, | ||
].includes(strategyShortId) | ||
) { | ||
if (specific.toLowerCase() === "narrow") { | ||
return IL.ALM_FILLUP_NARROW; | ||
} | ||
if (specific.toLowerCase() === "wide") { | ||
return IL.ALM_FILLUP_WIDE; | ||
} | ||
if (specific.toLowerCase() === "stable") { | ||
return IL.ALM_STABLE_EXPAND; | ||
} | ||
if (specific.toLowerCase() === "pegged") { | ||
return IL.ALM_PEGGED; | ||
} | ||
} | ||
|
||
if ([StrategyShortId.BSF, StrategyShortId.CCF].includes(strategyShortId)) { | ||
return IL.STABLE_SWAP; | ||
} | ||
|
||
if (strategyShortId == StrategyShortId.QSMF) { | ||
return IL.CL_STABLE_FIXED; | ||
} | ||
|
||
if (strategyShortId == StrategyShortId.TPF) { | ||
let onlyStables = true; | ||
for (const asset of assets) { | ||
const tokenData = getTokenData(asset); | ||
if (!tokenData || !tokenData.tags?.includes("stablecoin")) { | ||
onlyStables = false; | ||
} | ||
} | ||
return onlyStables ? IL.ALM_STABLE_DEPEG_MEDIUM : IL.ALM_VOLATILE_HIGH; | ||
} | ||
|
||
if ([StrategyShortId.SF, StrategyShortId.EF].includes(strategyShortId)) { | ||
return specific.toLowerCase() == "slp" ? IL.STABLE_SWAP : IL.CLASSIC_vAMM; | ||
} | ||
|
||
if (strategyShortId == StrategyShortId.BWF) { | ||
return IL.CLASSIC_vAMM; | ||
} | ||
|
||
if (strategyShortId == StrategyShortId.ASF) { | ||
if (specific.toLowerCase().match(/aggressive$/)) { | ||
return IL.ALM_FILLUP_AGGRESSIVE; | ||
} | ||
if (specific.toLowerCase().match(/narrow$/)) { | ||
return IL.ALM_FILLUP_NARROW; | ||
} | ||
if (specific.toLowerCase().match(/stretched$/)) { | ||
return IL.ALM_STRETCHED; | ||
} | ||
} | ||
|
||
if (strategyShortId == StrategyShortId.DQMF) { | ||
return IL.ALM_VOLATILE_HIGH; | ||
} | ||
|
||
return undefined; | ||
}; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import { getIL, StrategyShortId } from "../src"; | ||
|
||
describe("testing risk", () => { | ||
test("getIL", () => { | ||
const data = [ | ||
["DQMF", "Narrow 0x29f1..e22d", []], | ||
["IQMF", "0x5d1b..ccb3", []], | ||
["CF", "", []], | ||
["Y", "", []], | ||
["GRMF", "Narrow", []], | ||
["QSMF", "276300 276360", []], | ||
["GQMF", "Stable", []], | ||
["CCF", "", []], | ||
["IRMF", "0xe9bd..8283", []], | ||
["GQMF", "Narrow", []], | ||
["GQMF", "Narrow", []], | ||
["ISF", "stS", []], | ||
["SF", "vLP", []], | ||
["SF", "sLP", []], | ||
["ASF", "Fill-Up Narrow", []], | ||
["SiL", "3 stS x17.4", []], | ||
["EF", "vLP", []], | ||
["ASF", "Fill-Up Aggressive", []], | ||
["GUMF", "Narrow", []], | ||
["BSF", "", []], | ||
["BWF", "", []], | ||
["SiF", "", []], | ||
["ASF", "Fill-Up Stretched", []], | ||
["GUMF", "Pegged", []], | ||
["GUMF", "Stable", []], | ||
["GUMF", "wide", []], | ||
[ | ||
"TPF", | ||
"", | ||
[ | ||
"0x25ea98ac87A38142561eA70143fd44c4772A16b6", | ||
"0x83feDBc0B85c6e29B589aA6BdefB1Cc581935ECD", | ||
], | ||
], | ||
[ | ||
"TPF", | ||
"", | ||
[ | ||
"0x6B2e0fACD2F2A8f407aC591067Ac06b5d29247E4", | ||
"0x90c6E93849E06EC7478ba24522329d14A5954Df4", | ||
], | ||
], | ||
[ | ||
"TPF", | ||
"", | ||
[ | ||
"0x75d0cBF342060b14c2fC756fd6E717dFeb5B1B70", | ||
"0xc518A88c67CECA8B3f24c4562CB71deeB2AF86B7", | ||
], | ||
], | ||
[ | ||
"TPF", | ||
"", | ||
[ | ||
"0x75d0cBF342060b14c2fC756fd6E717dFeb5B1B70", | ||
"0x83feDBc0B85c6e29B589aA6BdefB1Cc581935ECD", | ||
], | ||
], | ||
[ | ||
"TPF", | ||
"", | ||
[ | ||
"0x83feDBc0B85c6e29B589aA6BdefB1Cc581935ECD", | ||
"0x90c6E93849E06EC7478ba24522329d14A5954Df4", | ||
], | ||
], | ||
[ | ||
"TPF", | ||
"", | ||
[ | ||
"0x83feDBc0B85c6e29B589aA6BdefB1Cc581935ECD", | ||
"0xAEC9e50e3397f9ddC635C6c429C8C7eca418a143", | ||
], | ||
], | ||
[ | ||
"TPF", | ||
"", | ||
[ | ||
"0x90c6E93849E06EC7478ba24522329d14A5954Df4", | ||
"0xc518A88c67CECA8B3f24c4562CB71deeB2AF86B7", | ||
], | ||
], | ||
[ | ||
"TPF", | ||
"", | ||
[ | ||
"0x25ea98ac87A38142561eA70143fd44c4772A16b6", | ||
"0xc518A88c67CECA8B3f24c4562CB71deeB2AF86B7", | ||
], | ||
], | ||
]; | ||
for (const item of data) { | ||
const il = getIL( | ||
item[0] as StrategyShortId, | ||
item[1] as string, | ||
item[2] as `0x${string}`[], | ||
); | ||
if (!il) { | ||
console.log(item); | ||
} | ||
expect(!!il).toEqual(true); | ||
} | ||
const und = getIL("AAA_UNKN" as StrategyShortId, "", []); | ||
expect(und).toEqual(undefined); | ||
}); | ||
}); |