Skip to content

Commit a6888d0

Browse files
authored
save fix (#176)
1 parent ac35578 commit a6888d0

File tree

1 file changed

+78
-13
lines changed

1 file changed

+78
-13
lines changed

hub/providers/Defi/plans/save.tsx

Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ import {
1010
createAssociatedTokenAccountIdempotentInstruction,
1111
getAssociatedTokenAddressSync,
1212
} from '@solana/spl-token-new';
13-
import { useConnection } from '@solana/wallet-adapter-react';
14-
import { Connection, Keypair, PublicKey } from '@solana/web3.js';
15-
import { SolendActionCore } from '@solendprotocol/solend-sdk';
13+
import { Connection, Keypair, PublicKey, AccountInfo, TransactionMessage, VersionedTransaction } from '@solana/web3.js';
14+
import { parseReserve, SolendActionCore } from '@solendprotocol/solend-sdk';
1615
import {
1716
InstructionWithSigners,
1817
LendingInstruction,
@@ -32,6 +31,19 @@ import useWalletOnePointOh from '@hooks/useWalletOnePointOh';
3231
import { sendTransactionsV3, SequenceType } from '@utils/sendTransactions';
3332
import tokenPriceService from '@utils/services/tokenPrice';
3433

34+
// simulatedAccount is one element from simulated.value.accounts
35+
function simulatedToAccountInfo(simulatedAccount: any): AccountInfo<Buffer> {
36+
const [base64Data, _encoding] = simulatedAccount.data;
37+
return {
38+
data: Buffer.from(base64Data, 'base64'),
39+
executable: simulatedAccount.executable,
40+
lamports: simulatedAccount.lamports,
41+
owner: new PublicKey(simulatedAccount.owner),
42+
rentEpoch: simulatedAccount.rentEpoch,
43+
};
44+
}
45+
46+
3547
export const PROTOCOL_SLUG = 'Save';
3648

3749
const SAVE_TRANSACTIONS_ENDPOINT = 'https://api.save.finance/transactions';
@@ -358,7 +370,66 @@ export const useSavePlans = (
358370
},
359371
);
360372

361-
const solendIxs = await solendAction.getInstructions();
373+
const solendIxs = await solendAction.getInstructions();
374+
375+
376+
const ixs = [
377+
...solendIxs.oracleIxs,
378+
...solendIxs.preLendingIxs,
379+
...solendIxs.lendingIxs,
380+
...solendIxs.postLendingIxs,
381+
] as InstructionWithSigners[];
382+
383+
// Get Transaction Message
384+
const message = new TransactionMessage({
385+
payerKey: wallet.publicKey,
386+
recentBlockhash: (await connection.current.getLatestBlockhash()).blockhash,
387+
instructions: ixs.map((ix) => ix.instruction),
388+
}).compileToV0Message();
389+
390+
// Get Versioned Transaction
391+
const vtx = new VersionedTransaction(message);
392+
393+
const res = await connection.current.simulateTransaction(
394+
vtx,
395+
{
396+
commitment: 'processed',
397+
sigVerify: false,
398+
accounts: {
399+
encoding: 'base64',
400+
addresses: [reserveAddress],
401+
}
402+
}
403+
);
404+
405+
const accountInfo = res?.value.accounts?.map(simulatedToAccountInfo);
406+
let cTokenExchangeRate = new BigNumber(reserve.cTokenExchangeRate);
407+
let buffer = 0.02;
408+
if (accountInfo?.[0]) {
409+
const simulatedReserve = parseReserve(new PublicKey(reserveAddress), accountInfo?.[0], 'base64');
410+
411+
412+
const decimals = simulatedReserve.info.liquidity.mintDecimals;
413+
const availableAmount = new BigNumber(
414+
simulatedReserve.info.liquidity.availableAmount.toString()
415+
).shiftedBy(-decimals);
416+
const totalBorrow = new BigNumber(
417+
simulatedReserve.info.liquidity.borrowedAmountWads.toString()
418+
).shiftedBy(-18 - decimals);
419+
const accumulatedProtocolFees = new BigNumber(
420+
simulatedReserve.info.liquidity.accumulatedProtocolFeesWads.toString()
421+
).shiftedBy(-18 - decimals);
422+
const totalSupply = totalBorrow
423+
.plus(availableAmount)
424+
.minus(accumulatedProtocolFees);
425+
426+
cTokenExchangeRate = new BigNumber(totalSupply).dividedBy(
427+
new BigNumber(simulatedReserve.info.collateral.mintTotalSupply.toString()).shiftedBy(
428+
-decimals
429+
)
430+
);
431+
buffer = 0;
432+
}
362433

363434
const userAta = await SplToken.getAssociatedTokenAddress(
364435
ASSOCIATED_TOKEN_PROGRAM_ID,
@@ -375,16 +446,10 @@ export const useSavePlans = (
375446
true,
376447
);
377448

378-
const ixs = [
379-
...solendIxs.oracleIxs,
380-
...solendIxs.preLendingIxs,
381-
...solendIxs.lendingIxs,
382-
...solendIxs.postLendingIxs,
383-
] as InstructionWithSigners[];
384-
385449
const transferAmountBase = new BigNumber(amount)
386-
.shiftedBy(reserve?.mintDecimals ?? 0)
387-
.div(reserve.cTokenExchangeRate)
450+
.shiftedBy(reserve.mintDecimals)
451+
.times(1-buffer)
452+
.div(cTokenExchangeRate)
388453
.dp(0, BigNumber.ROUND_DOWN)
389454
.toNumber();
390455

0 commit comments

Comments
 (0)