-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcheck_fees.ts
More file actions
73 lines (62 loc) · 3.5 KB
/
Copy pathcheck_fees.ts
File metadata and controls
73 lines (62 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import * as anchor from "@coral-xyz/anchor";
import { Connection, PublicKey } from "@solana/web3.js";
import fs from "fs";
const PROGRAM_ID = new PublicKey("DgD37Vjs8ozzBwZnfsNEDQNw1SEsgBTr2TXfBdsrgXpe");
const PRECISION = BigInt("1000000000000"); // 1e12
const statePda = PublicKey.findProgramAddressSync([Buffer.from("state")], PROGRAM_ID)[0];
function positionPda(u: PublicKey) {
return PublicKey.findProgramAddressSync([Buffer.from("position"), u.toBuffer()], PROGRAM_ID)[0];
}
async function main() {
const connection = new Connection("https://api.devnet.solana.com", "confirmed");
const idl = JSON.parse(fs.readFileSync("./app/lib/soladrome.json", "utf8"));
const prov = new anchor.AnchorProvider(connection, {} as any, {});
const prog = new anchor.Program(idl, prov);
// ── Read ProtocolState raw to get fees_per_hi_sola (u128 at known offset) ──
// ProtocolState layout (after 8-byte discriminator):
// authority: Pubkey(32) | paused: bool(1) | pad(3?) | sola_mint: Pubkey(32) ...
// Easier: use the IDL-typed fetch then cast
const stateInfo = await connection.getAccountInfo(statePda);
if (!stateInfo) { console.log("state not found"); return; }
// fees_per_hi_sola is u128. Use program.account to deserialize
const stateAccts: any[] = await (prog.account as any).protocolState.all();
const state = stateAccts[0].account;
const globalAcc = BigInt(state.feesPerHiSola.toString());
const hiSolaMint = state.hiSolaMint as PublicKey;
console.log("\n=== ProtocolState ===");
console.log(` fees_per_hi_sola: ${globalAcc}`);
console.log(` total_hi_sola : ${(Number(state.totalHiSola)/1e6).toFixed(6)} hiSOLA`);
// ── Wallets ────────────────────────────────────────────────────────────────
const wallets: Record<string, string> = {
"JAfXUr5": "JAfXUr5WNpj4wTeWAQ9KXmj9zRjBESTdgviAo1LLNrFn",
"BVaJbgw": "BVaJbgw3NF7Ng28sHorBnzJrHgvu7S3L5wpdB6923LjA",
"FOUNDER": "46AqfBuHfgae9s5FK9RSHFExK5mJGiaPJhA9TFXc2Nw4",
};
console.log("\n=== UserPosition per wallet ===");
for (const [label, addr] of Object.entries(wallets)) {
const user = new PublicKey(addr);
const pda = positionPda(user);
const posInfo = await connection.getAccountInfo(pda);
if (!posInfo) { console.log(` [${label}]: no position`); continue; }
const pos: any = await (prog.account as any).userPosition.fetch(pda);
const debt = BigInt(pos.feesDebt.toString());
const borrowed = Number(pos.usdcBorrowed) / 1e6;
// hiSOLA balance
const ata = anchor.utils.token.associatedAddress({ mint: hiSolaMint, owner: user });
let hiSola = BigInt(0);
try { hiSola = BigInt((await connection.getTokenAccountBalance(ata)).value.amount); }
catch { /* no ATA */ }
const diff = globalAcc - debt;
const pending = diff > BigInt(0) ? (diff * hiSola) / PRECISION : BigInt(0);
console.log(`\n [${label}]`);
console.log(` hiSOLA balance : ${(Number(hiSola)/1e6).toFixed(4)}`);
console.log(` fees_debt : ${debt}`);
console.log(` fees_per_hi - debt: ${diff} ${diff < BigInt(0) ? "⚠️ DEBT > ACC" : ""}`);
console.log(` usdc_borrowed : ${borrowed.toFixed(6)} USDC`);
console.log(` pending USDC : ${(Number(pending)/1e6).toFixed(6)}`);
console.log(` account bytes : ${posInfo.data.length}`);
}
}
describe("fees", () => {
it("check", async function() { this.timeout(30000); await main(); });
});