Skip to content

Commit

Permalink
🚦 getIL
Browse files Browse the repository at this point in the history
  • Loading branch information
a17 committed Feb 16, 2025
1 parent 7c8ffef commit c0bd329
Show file tree
Hide file tree
Showing 4 changed files with 319 additions and 0 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,21 @@ import { tokenlist } from "@stabilitydao/stability";

</details>

### 🚦 Risk

<details>
<summary>what is included</summary>

#### Types

- `IlDetails`

#### Methods

- `getIL = (strategyShortId: StrategyShortId, specific: string, assets: 0x${string}[]): IlDetails | undefined`

</details>

## 👷 Develop

### How to
Expand Down Expand Up @@ -293,5 +308,6 @@ yarn prettier . --write
| Sync state, etc | ♻️️ |
| Content generators | 🎇 |
| Bridge | 🌉 |
| Risk | 🚦 |
| Prettier | #️⃣ |
| Docs | 📙 |
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import {
getContestReward,
} from "./contests";
import { AssetOracle, assetOracles, vaultOracles } from "./oracles";
import { IlDetails, getIL } from "./risk";

export {
deployments,
Expand Down Expand Up @@ -120,4 +121,6 @@ export {
getTokenData,
TokenData,
sonicWhitelistedAssets,
getIL,
IlDetails,
};
189 changes: 189 additions & 0 deletions src/risk.ts
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;
};
111 changes: 111 additions & 0 deletions tests/risk.test.ts
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);
});
});

0 comments on commit c0bd329

Please sign in to comment.