4

I have the following python code to perform a swap on RAYDIUM:

def make_swap_instruction(
        self,
        amount_in: int,
        token_account_in: PublicKey,
        token_account_out: PublicKey,
        accounts: dict,
        serum_program_id=SERUM_PROGRAM_ID,
    ) -> TransactionInstruction:
        print("Making a swap instruction...")
        keys = [
            AccountMeta(pubkey=TOKEN_PROGRAM_ID, is_signer=False, is_writable=False),
            AccountMeta(pubkey=accounts["amm_id"], is_signer=False, is_writable=True),
            AccountMeta(
                pubkey=accounts["authority"], is_signer=False, is_writable=False
            ),
            AccountMeta(
                pubkey=accounts["open_orders"], is_signer=False, is_writable=True
            ),
            AccountMeta(
                pubkey=accounts["target_orders"], is_signer=False, is_writable=True
            ),
            AccountMeta(
                pubkey=accounts["base_vault"], is_signer=False, is_writable=True
            ),
            AccountMeta(
                pubkey=accounts["quote_vault"], is_signer=False, is_writable=True
            ),
            AccountMeta(pubkey=serum_program_id, is_signer=False, is_writable=False),
            AccountMeta(
                pubkey=accounts["market_id"], is_signer=False, is_writable=True
            ),
            AccountMeta(pubkey=accounts["bids"], is_signer=False, is_writable=True),
            AccountMeta(pubkey=accounts["asks"], is_signer=False, is_writable=True),
            AccountMeta(
                pubkey=accounts["event_queue"], is_signer=False, is_writable=True
            ),
            AccountMeta(
                pubkey=accounts["market_base_vault"], is_signer=False, is_writable=True
            ),
            AccountMeta(
                pubkey=accounts["market_quote_vault"], is_signer=False, is_writable=True
            ),
            AccountMeta(
                pubkey=accounts["market_authority"], is_signer=False, is_writable=False
            ),
            AccountMeta(pubkey=token_account_in, is_signer=False, is_writable=True),
            AccountMeta(pubkey=token_account_out, is_signer=False, is_writable=True),
            AccountMeta(pubkey=self.owner.pubkey(), is_signer=True, is_writable=False),
        ]
        print("Finished making, building SWAP LAYOUT...")
        data = SWAP_LAYOUT.build(
            dict(instruction=9, amount_in=int(amount_in), min_amount_out=0)
        )
        return TransactionInstruction(
            accounts=keys, program_id=AMM_PROGRAM_ID, data=data
        )

It is my understanding that the min_amount_out parameter in my SWAP_LAYOUT can be changed to set slippage. Since I have it at 0, I think my slippage is effectively 100%.

I am wondering if anyone has any ideas on what some efficient ways to set slippage might be. At the moment, all I can think to do is fetch the current price, and calculate how many tokens I should get back after adjusting for slippage. If anyone has any ideas, it would be greatly appreciated and I believe a value-add to the community since there doesn't seem to be much on this forum in Python or on slippage.

1
  • 2
    I know you're probably using Openbook even though you wrote SERUM_PROGRAM_ID in your code, but for anyone reading this, do not use that program. Its upgrade key may have been compromised in the FTX hack. Please migrate to the community fork. Commented Dec 29, 2023 at 2:03

1 Answer 1

1

To set slippage effectively in your swap operation on Raydium or any other decentralized exchange (DEX) platform, you indeed need to calculate min_amount_out based on the current market price of the tokens you are swapping and your desired slippage percentage. The min_amount_out parameter acts as a safety net, ensuring that your swap does not proceed if the amount of tokens you would receive falls below a certain threshold, which is determined by your slippage tolerance.

Here's a simple and efficient approach to calculating min_amount_out:

  • Fetch Current Price: Obtain the current price of the input and output tokens. This might involve querying the DEX or using an oracle.

  • Calculate Expected Output: Based on the amount of input tokens and their current price, calculate the expected amount of output tokens without slippage.

  • Apply Slippage Tolerance: Adjust the expected output by your desired slippage percentage to calculate min_amount_out.

Here's a Python function to illustrate the process:

def calculate_min_amount_out(amount_in: int, input_price: float, output_price: float, slippage: float) -> int:
    """
    Calculates the minimum amount out based on the input amount, prices of input/output tokens, and slippage tolerance.
    
    :param amount_in: Amount of input tokens being swapped.
    :param input_price: Price of the input token.
    :param output_price: Price of the output token.
    :param slippage: Desired slippage tolerance (e.g., 0.01 for 1% slippage).
    :return: The minimum amount of output tokens expected, adjusted for slippage tolerance.
    """
    # Calculate the expected output without slippage
    expected_output = (amount_in * input_price) / output_price
    
    # Apply slippage tolerance
    min_amount_out = expected_output * (1 - slippage)
    
    return int(min_amount_out)

You would then use this function to set the min_amount_out parameter in your swap instruction, based on the current prices and your desired slippage tolerance:

# Example usage
amount_in = 1000  # Amount of input tokens
input_price = 0.5  # Current price of input token in terms of output token
output_price = 1  # Just for example, usually differs
slippage = 0.01  # 1% slippage tolerance

min_amount_out = calculate_min_amount_out(amount_in, input_price, output_price, slippage)

# Now use this min_amount_out in your SWAP_LAYOUT
data = SWAP_LAYOUT.build(
    dict(instruction=9, amount_in=int(amount_in), min_amount_out=min_amount_out)
)

This method allows you to dynamically adjust min_amount_out based on real-time market conditions and your acceptable level of slippage, ensuring that your swaps do not execute at an undesirable rate.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.