@@ -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' ;
1615import {
1716 InstructionWithSigners ,
1817 LendingInstruction ,
@@ -32,6 +31,19 @@ import useWalletOnePointOh from '@hooks/useWalletOnePointOh';
3231import { sendTransactionsV3 , SequenceType } from '@utils/sendTransactions' ;
3332import 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+
3547export const PROTOCOL_SLUG = 'Save' ;
3648
3749const 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