Skip to content

Commit 600d536

Browse files
authored
feat: add Sanctum Reserve fees adapter for Solana (#2738)
1 parent ade3c92 commit 600d536

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

fees/sanctum/index.ts

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Documentation for Sanctum Reserve
2+
//
3+
// Fees: There is a dynamic fee charged for utilisation of the Reserve Pool - based on the percentage of SOL left in the Reserve pool. This allows for low fees most of the time, and ensures efficient usage of SOL in times of great liquidity demand.
4+
// Source: https://learn.sanctum.so/docs/protocol/the-reserve/fees
5+
//
6+
// Are deposits open for The Reserve?: Public deposits are not open for The Reserve. Depositors will need to deposit SOL for a long time frame, and cannot remove their SOL at any given time. Returns rely on periods of demand for SOL, which fluctuate and cannot be predicted.
7+
// Source: https://learn.sanctum.so/docs/protocol/the-reserve/are-deposits-open-for-the-reserve
8+
//
9+
// What does the Reserve do?: Sanctum Reserve Pool provides deep liquidity for all liquid staking tokens on Solana. It accepts staked SOL and gives SOL in return, unstaking the staked SOL at the end of the epoch to replenish its reserves.
10+
// Source: https://learn.sanctum.so/docs/protocol/the-reserve/what-does-the-reserve-do
11+
//
12+
// When do I use the Reserve Pool?: You can unstake a stake account instantly to receive SOL. If the validator your stake account is staked to does not have its own LST, you can still unstake to receive SOL instantly.
13+
// Source: https://learn.sanctum.so/docs/protocol/the-reserve/when-do-i-use-the-reserve-pool
14+
15+
16+
import { FetchOptions, SimpleAdapter } from "../../adapters/types";
17+
import { CHAIN } from "../../helpers/chains";
18+
import { queryDuneSql } from "../../helpers/dune";
19+
20+
const fetch: any = async (options: FetchOptions) => {
21+
const fees = await queryDuneSql(options, `
22+
WITH unstake_transactions AS (
23+
SELECT
24+
aa.block_time,
25+
aa.tx_id,
26+
aa.balance_change / 1e9 AS fees
27+
FROM
28+
solana.account_activity aa
29+
INNER JOIN sanctum_unstake_solana.unstake_call_unstake u ON aa.tx_id = u.call_tx_id
30+
WHERE
31+
aa.address = 'EeQmNqm1RcQnee8LTyx6ccVG9FnR8TezQuw2JXq2LC1T'
32+
AND aa.balance_change > 0
33+
AND aa.tx_success = true
34+
AND aa.block_time >= from_unixtime(${options.startTimestamp})
35+
AND aa.block_time <= from_unixtime(${options.endTimestamp})
36+
UNION ALL
37+
SELECT
38+
aa.block_time,
39+
aa.tx_id,
40+
aa.balance_change / 1e9 AS unstake_fees
41+
FROM
42+
solana.account_activity aa
43+
INNER JOIN sanctum_unstake_solana.unstake_call_unstakewsol u ON aa.tx_id = u.call_tx_id
44+
WHERE
45+
aa.address = 'EeQmNqm1RcQnee8LTyx6ccVG9FnR8TezQuw2JXq2LC1T'
46+
AND aa.balance_change > 0
47+
AND aa.tx_success = true
48+
AND aa.block_time >= from_unixtime(${options.startTimestamp})
49+
AND aa.block_time <= from_unixtime(${options.endTimestamp})
50+
AND u.call_tx_id not in (
51+
select
52+
call_tx_id
53+
from
54+
sanctum_unstake_solana.unstake_call_unstake
55+
where
56+
call_block_time >= from_unixtime(${options.startTimestamp})
57+
AND call_block_time <= from_unixtime(${options.endTimestamp})
58+
)
59+
)
60+
SELECT
61+
SUM(fees) AS daily_fees
62+
FROM
63+
unstake_transactions
64+
`)
65+
const dailyFees = options.createBalances()
66+
dailyFees.addCGToken('solana', fees[0].daily_fees);
67+
return { dailyFees, dailyRevenue: dailyFees }
68+
}
69+
70+
const adapter: SimpleAdapter = {
71+
version: 2,
72+
adapter: {
73+
[CHAIN.SOLANA]: {
74+
fetch: fetch,
75+
start: '2022-07-22' // First unstake transaction
76+
},
77+
},
78+
isExpensiveAdapter: true
79+
};
80+
81+
export default adapter;

0 commit comments

Comments
 (0)