Skip to content

Commit 50e0dc7

Browse files
authored
Merge branch 'main' into main
2 parents 44244f5 + a6cefad commit 50e0dc7

File tree

1,398 files changed

+39333
-15928
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,398 files changed

+39333
-15928
lines changed

liquidations/smardex/index.ts

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { Liq } from "../utils/types";
2+
import axios from "axios";
3+
interface PositionHistory {
4+
transactionHash: string;
5+
}
6+
7+
interface PositionMainOwner {
8+
address: string;
9+
}
10+
11+
interface PositionMain {
12+
lastOwner: PositionMainOwner;
13+
}
14+
15+
interface Position {
16+
tick: number;
17+
tickVersion: string;
18+
index: string;
19+
validator: string;
20+
recipient: string;
21+
amount: string;
22+
startPrice: string;
23+
liquidationPenalty: number;
24+
totalExpo: string;
25+
amountReceived: string;
26+
amountRemaining: string;
27+
profit: string;
28+
liquidationPrice: string | null;
29+
effectiveTickPrice: string | null;
30+
type: string;
31+
status: string;
32+
history: PositionHistory[];
33+
mainPosition: PositionMain;
34+
}
35+
36+
interface ApiResponse {
37+
serverTimestamp: number;
38+
positions: Position[];
39+
}
40+
41+
const WSTETH_KEY = "ethereum:0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0";
42+
const API_URL = "https://usdn-public.api.smardex.io/usdn/positions/open";
43+
const API_KEY = process.env.SMARDEX_SUBGRAPH_API_KEY
44+
const EXPLORER_BASE_URL = "https://smardex.io/usdn/explorer?search=";
45+
46+
const fetchOpenPositions = async (): Promise<Position[]> => {
47+
const response = await axios.get<ApiResponse>(API_URL, {
48+
headers: { "x-api-key": API_KEY },
49+
});
50+
51+
if (response.data && response.data.positions && Array.isArray(response.data.positions)) {
52+
return response.data.positions;
53+
} else {
54+
return [];
55+
}
56+
};
57+
58+
const calculateLiquidationPrice = (position: Position): number => {
59+
if (!position.startPrice || !position.totalExpo || !position.amountRemaining) {
60+
return 0;
61+
}
62+
const startPrice = parseFloat(position.startPrice) / 1e18;
63+
const totalExpo = parseFloat(position.totalExpo) / 1e18;
64+
const collateral = parseFloat(position.amountRemaining) / 1e18;
65+
const leverage = totalExpo / collateral;
66+
return startPrice - (startPrice / leverage);
67+
};
68+
69+
const formatPosition = (position: Position): Liq => {
70+
const owner =
71+
position.recipient || '0x0000000000000000000000000000000000000000';
72+
73+
const searchParam = position.history && position.history.length > 0 ?
74+
position.history[position.history.length - 1].transactionHash : position.index;
75+
76+
const liquidationPrice = calculateLiquidationPrice(position);
77+
78+
return {
79+
owner,
80+
liqPrice: liquidationPrice,
81+
collateral: WSTETH_KEY,
82+
collateralAmount: position.amountRemaining,
83+
extra: {
84+
url: `${EXPLORER_BASE_URL}${searchParam}`,
85+
},
86+
};
87+
};
88+
89+
const positions = async (): Promise<Liq[]> => {
90+
if(!process.env.SMARDEX_SUBGRAPH_API_KEY) {
91+
throw new Error("Missing SMARDEX_SUBGRAPH_API_KEY environment variable");
92+
}
93+
94+
const positionsData = await fetchOpenPositions();
95+
96+
if (!positionsData || positionsData.length === 0) {
97+
return [];
98+
}
99+
100+
return positionsData.map(formatPosition);
101+
};
102+
103+
module.exports = {
104+
ethereum: {
105+
liquidations: positions,
106+
},
107+
};

0 commit comments

Comments
 (0)