This article introduces a triangular arbitrage opportunity from a few months ago.
Step 1
First, you can swap $SOL to $INF using @JupiterExchange via Meteora DLMM or Orca, that is a DEX aggregator on Solana.
Step 2
Then, you can swap $INF to $jitoSOL using @sanctumso via its infinite LST liquidity pool.
Step 3
Finnally, you can delayed unstake $jitoSOL to retain $SOL in the next epoch using @jito_sol, that is a solana liquid staking pool. Remember, manually deactivate your stake account by clicking on the "Deactivate" button on jito's Manage Stake Accounts page or in your wallet. Once your stake has finished deactivating click on the "Withdraw" button to withdraw SOL.
Some code
async function step1_On_Jup(solAmount) {
// Swapping SOL to INF
const quoteResponse = await (
await fetch('https://quote-api.jup.ag/v6/quote?' + new URLSearchParams({
inputMint: solMint,
outputMint: infMint,
amount: solAmount,
slippageBps: slippageBps,
})
)
).json();
console.log(`Swapping ${solAmount/oneAmount} SOL to ${quoteResponse.outAmount/oneAmount} INF`);
// https://station.jup.ag/docs/apis/swap-api
const { swapTransaction } = await (
await fetch('https://quote-api.jup.ag/v6/swap', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
quoteResponse,
userPublicKey: wallet.publicKey.toString(),
dynamicComputeUnitLimit: true,
prioritizationFeeLamports: 'auto'
})
})
).json();
const swapTransactionBuf = Buffer.from(swapTransaction, 'base64');
var transaction = VersionedTransaction.deserialize(swapTransactionBuf);
transaction.sign([wallet.payer]);
const rawTransaction = transaction.serialize()
const txid = await connection.sendRawTransaction(rawTransaction, {
skipPreflight: true,
maxRetries: 2
});
await connection.confirmTransaction(txid);
console.log(`https://solscan.io/tx/${txid}`);
step2_On_Sanctum( quoteResponse.outAmount );
}
async function step2_On_Sanctum(infAmount) {
// Swapping INF to jitoSOL
const quoteResponse = await (
await fetch('https://sanctum-s-api.fly.dev/v1/swap/quote?' + new URLSearchParams({
input: infMint,
outputLstMint: jitosolMint,
amount: infAmount,
mode: 'ExactIn'
})
)
).json();
console.log(`Swapping ${infAmount/oneAmount} INF to ${quoteResponse.outAmount/oneAmount} jitoSOL`);
// https://sanctum-s-api.fly.dev/#/LST%20Swaps/handle_swap
const swapTransaction = await (
await fetch('https://sanctum-s-api.fly.dev/v1/swap', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
input: infMint,
outputLstMint: jitosolMint,
amount: quoteResponse.inAmount,
quotedAmount: quoteResponse.outAmount,
swapSrc: quoteResponse.swapSrc,
mode: 'ExactIn',
signer: wallet.publicKey.toString(),
})
})
).json();
const swapTransactionBuf = Buffer.from(swapTransaction.tx, 'base64');
var transaction = VersionedTransaction.deserialize(swapTransactionBuf);
transaction.sign([wallet.payer]);
const rawTransaction = transaction.serialize()
const txid = await connection.sendRawTransaction(rawTransaction, {
skipPreflight: true,
maxRetries: 2
});
await connection.confirmTransaction(txid);
console.log(`https://solscan.io/tx/${txid}`);
}