# MagpieRouterV3

The MagpieRouterV3 contract is designed to facilitate token swaps. It inherits from Ownable2Step and Pausable contracts, ensuring controlled access and the ability to pause operations. The contract utilizes various libraries like Address, LibAsset, and LibRouter to handle different asset types and provide utility functions. It includes custom errors and an enums for different command actions, such as calls, approvals, transfers, and balance checks. Key features include functions for updating internal callers and bridge addresses, executing multiple delegate calls in a single transaction, and handling UniswapV3 swap callbacks. The contract also supports various swap operations, including those requiring signatures from Magpie and user, and provides functions for estimating gas, handling permits, and transferring affiliate fees. Additionally, it includes comprehensive command execution functions for calls, approvals, transfers, wrapping and unwrapping tokens, balance checks, mathematical operations, and comparisons, ensuring efficient and secure swap processes. The contract can also accept Ether payments directly.

<table data-full-width="false"><thead><tr><th width="226">Function Name</th><th>Description (Business Logic)</th></tr></thead><tbody><tr><td><mark style="color:red;"><strong>updateInternalCaller</strong></mark> </td><td>The <mark style="color:red;"><strong>updateInternalCaller</strong></mark> function allows the contract owner to update the list of authorized internal callers, emitting an <mark style="color:red;"><strong>UpdateInternalCaller</strong></mark> event upon execution. Similarly, the <mark style="color:red;"><strong>updateBridge</strong></mark> function updates the list of authorized bridge addresses and emits an <mark style="color:red;"><strong>UpdateBridge</strong></mark> event.</td></tr><tr><td><mark style="color:red;"><strong>multical</strong></mark>l </td><td>The <mark style="color:red;"><strong>multicall</strong></mark> function enables the contract owner to execute multiple delegate calls in a single transaction. It iterates over an array of calldata, performing each delegate call and storing the results in an array, which is then returned. This function enhances the contract’s efficiency by allowing batch processing of multiple operations.</td></tr><tr><td><mark style="color:red;"><strong>fallback</strong></mark> </td><td>It includes a <mark style="color:red;"><strong>fallback</strong></mark> function designed to handle <mark style="color:red;"><strong>uniswapV3SwapCallback</strong></mark> requests from any protocol based on UniswapV3. This function does not check for the factory since the contract is not intended to store tokens. Instead, it protects the user by ensuring the <mark style="color:red;"><strong>amountOutMin</strong></mark> check is performed at the end of execution by comparing the starting and final balances at the destination address. The function uses inline assembly to extract parameters from the calldata, such as <mark style="color:red;"><strong>amount0Delta</strong></mark>, <mark style="color:red;"><strong>amount1Delta</strong></mark>, and <mark style="color:red;"><strong>assetIn</strong></mark>. If the calldata size is not 164 bytes or if both <mark style="color:red;"><strong>amount0Delta</strong></mark> and <mark style="color:red;"><strong>amount1Delta</strong></mark> are non-positive, the function reverts with appropriate errors. The function then transfers the calculated amount of <mark style="color:red;"><strong>assetIn</strong></mark> to the caller.</td></tr><tr><td><mark style="color:red;"><strong>getFromAddress</strong></mark> </td><td>The <mark style="color:red;"><strong>getFromAddress</strong></mark> function retrieves the address to be used for a swap operation. It takes <mark style="color:red;"><strong>swapData</strong></mark>, a boolean <mark style="color:red;"><strong>useCaller</strong></mark>, and a boolean <mark style="color:red;"><strong>checkSignature</strong></mark> as parameters. If <mark style="color:red;"><strong>checkSignature</strong></mark> is true, the function constructs a message based on whether the swap data includes an affiliate and verifies the signature using the <mark style="color:red;"><strong>LibRouter.verifySignature</strong></mark> function. If the signature is valid, it returns the address from the swap data. If <mark style="color:red;"><strong>checkSignature</strong></mark> is false and <mark style="color:red;"><strong>useCaller</strong></mark> is true, it returns the caller’s address. Otherwise, it reverts with an <mark style="color:red;"><strong>InvalidCall</strong></mark> error. This function ensures that the correct address is used for the swap operation, providing flexibility and security in handling swap requests.</td></tr><tr><td><mark style="color:red;"><strong>swap</strong></mark> </td><td>The <mark style="color:red;"><strong>swap</strong></mark> function facilitates token swaps based on the provided <mark style="color:red;"><strong>swapData</strong></mark>. It takes the address initiating the swap (<mark style="color:red;"><strong>fromAddress</strong></mark>) and the full amount used for the operation (<mark style="color:red;"><strong>fullAmountIn</strong></mark>). The function calculates the initial balance of the destination address (<mark style="color:red;"><strong>toAddress</strong></mark>) for the output asset (<mark style="color:red;"><strong>toAssetAddress</strong></mark>). It then executes the swap by calling the execute function, which returns the amount transferred and the gas used. The function calculates the final balance of the destination address and determines the amount of tokens received (<mark style="color:red;"><strong>amountOut</strong></mark>). If the received amount is less than the minimum required (<mark style="color:red;"><strong>amountOutMin</strong></mark>), it reverts with an <mark style="color:red;"><strong>InsufficientAmountOut</strong></mark> error. Additionally, it checks if the input amount matches the transferred amount for non-native assets, reverting with an <mark style="color:red;"><strong>InvalidAmountIn</strong></mark> error if they do not match. If <mark style="color:red;"><strong>fullAmountIn</strong></mark> is greater than zero, it emits a <mark style="color:red;"><strong>Swap</strong></mark> event with the relevant details.</td></tr><tr><td><mark style="color:red;"><strong>estimateSwapGas</strong></mark> </td><td>The <mark style="color:red;"><strong>estimateSwapGas</strong></mark> function estimates the gas required for a swap operation. It retrieves the swap data using <mark style="color:red;"><strong>LibRouter.getData()</strong></mark> and determines the address initiating the swap. If the swap data includes a permit, it calls <mark style="color:red;"><strong>LibRouter.permit</strong></mark> to handle the permit. It then transfers any applicable fees using <mark style="color:red;"><strong>LibRouter.transferFees</strong></mark>. Finally, it calls the <mark style="color:red;"><strong>swap</strong></mark> function and returns the amount of tokens received and the gas used.</td></tr><tr><td><mark style="color:red;"><strong>swapWithMagpieSignature</strong></mark> </td><td>The <mark style="color:red;"><strong>swapWithMagpieSignature</strong></mark> function performs a swap operation using Magpie signature. It retrieves the swap data and the address initiating the swap, handles any permits, transfers fees, and calls the <mark style="color:red;"><strong>swap</strong></mark> function. It returns the amount of tokens received.</td></tr><tr><td><mark style="color:red;"><strong>swapWithUserSignature</strong></mark> </td><td>The <mark style="color:red;"><strong>swapWithUserSignature</strong></mark> function allows internal callers to perform a swap operation using a user-provided signature. It retrieves the swap data and the address initiating the swap, ensuring no native tokens are sent with the transaction. It handles any permits, transfers fees, and calls the <mark style="color:red;"><strong>swap</strong></mark> function, returning the amount of tokens received.</td></tr><tr><td><mark style="color:red;"><strong>swapWithoutSignature</strong></mark> </td><td>The <mark style="color:red;"><strong>swapWithoutSignature</strong></mark> function enables bridge addresses to perform a swap operation without requiring a signature. It retrieves the swap data and the address initiating the swap, then calls the <mark style="color:red;"><strong>swap</strong></mark> function, returning the amount of tokens received. This function is restricted to authorized bridge addresses using the <mark style="color:red;"><strong>onlyBridge</strong></mark> modifier.</td></tr><tr><td><mark style="color:red;"><strong>getCommandData</strong></mark> </td><td>The <mark style="color:red;"><strong>getCommandData</strong></mark> function prepares the necessary command data for iterating through a sequence of commands. It uses inline assembly to calculate the offsets and lengths required for processing the commands. Specifically, it calculates the <mark style="color:red;"><strong>commandsOffset</strong></mark> by adding 70 to the shifted value of the calldata at position 68, the <mark style="color:red;"><strong>commandsOffsetEnd</strong></mark> by adding 68 to the calldata at position 36, and the <mark style="color:red;"><strong>outputsLength</strong></mark> by shifting the calldata at position 70. These values are essential for correctly iterating through the commands during the swap operation.</td></tr><tr><td><mark style="color:red;"><strong>execute</strong></mark> </td><td>The <mark style="color:red;"><strong>execute</strong></mark> function handles the execution of a sequence of commands for the swap operation. It takes the address from which the assets will be swapped (<mark style="color:red;"><strong>fromAddress</strong></mark>) and the address of the asset to be swapped (<mark style="color:red;"><strong>fromAssetAddress</strong></mark>). The function retrieves the command data using <mark style="color:red;"><strong>getCommandData</strong></mark> and initializes a pointer for the output data. It then iterates through the commands using a loop, calling the <mark style="color:red;"><strong>executeCommand</strong></mark> function for each command. The <mark style="color:red;"><strong>executeCommand</strong></mark> function returns the amount transferred, the gas used, and updates the output pointer. If the final output pointer exceeds the allocated output length, the function reverts with an <mark style="color:red;"><strong>InvalidOutput</strong></mark> error. This function ensures that the swap operation is executed correctly and efficiently, handling multiple commands in a single transaction.</td></tr><tr><td><mark style="color:red;"><strong>getInput</strong></mark> </td><td><p>The <mark style="color:red;"><strong>getInput</strong></mark> function constructs the input data for a specific command based on its position (<mark style="color:red;"><strong>i</strong></mark>) and the memory pointer of the currently available output (<mark style="color:red;"><strong>outputPtr</strong></mark>). Using inline assembly, the function calculates the end position of the sequences and initializes the input data and native token amount. It iterates through the sequences, processing each one based on its type, such as <mark style="color:red;"><strong>NativeAmount</strong></mark>, <mark style="color:red;"><strong>Selector</strong></mark>, <mark style="color:red;"><strong>Address</strong></mark>, <mark style="color:red;"><strong>Amount</strong></mark>, <mark style="color:red;"><strong>Data</strong></mark>, <mark style="color:red;"><strong>CommandOutput</strong></mark>, <mark style="color:red;"><strong>RouterAddress</strong></mark>, and <mark style="color:red;"><strong>SenderAddress</strong></mark>. For each sequence type, the function performs specific operations: </p><p>• For NativeAmount, it determines the native token amount either from the output pointer or directly from the calldata. </p><p>• For <mark style="color:red;">Selector</mark>, it loads the function selector from the calldata. </p><p>• For <mark style="color:red;"><strong>Address</strong></mark>, it extracts the address from the calldata. </p><p>• For <mark style="color:red;"><strong>Amount</strong></mark>, it calculates the amount from the calldata. </p><p>• For <mark style="color:red;"><strong>Data</strong></mark>, it copies the data from the calldata to the input. </p><p>• For <mark style="color:red;"><strong>CommandOutput</strong></mark>, it loads the output data from the output pointer. </p><p>• For <mark style="color:red;"><strong>RouterAddress</strong></mark>, it stores the contract’s address. </p><p>• For <mark style="color:red;"><strong>SenderAddress</strong></mark>, it stores the caller’s address.</p><p>If an invalid sequence type is encountered, the function reverts with an <mark style="color:red;"><strong>InvalidSequenceType</strong></mark> error. After processing all sequences, it updates the input data length and the free memory pointer. This function ensures that the input data for each command is correctly constructed, enabling the execution of complex operations within the contract.</p></td></tr><tr><td><mark style="color:red;"><strong>executeCommandCall</strong></mark> </td><td>The <mark style="color:red;"><strong>executeCommandCall</strong></mark> function executes a command call with the given parameters. It retrieves the input data and native token amount using the <mark style="color:red;"><strong>getInput</strong></mark> function. The function then calculates the output length from the calldata and uses a switch statement to handle different selectors. If the selector is invalid or corresponds to a blacklisted <mark style="color:red;"><strong>transferFrom</strong></mark> call, the function reverts with appropriate errors. For valid selectors, it retrieves the target address from the calldata and ensures it is not the contract’s address. It then performs a call to the target address with the provided input data and native amount. If the call fails, it reverts with the returned data. The function updates the output offset pointer and returns the new position.</td></tr><tr><td><mark style="color:red;"><strong>executeCommandApproval</strong></mark> </td><td>The <mark style="color:red;"><strong>executeCommandApproval</strong></mark> function handles the execution of a command approval. It retrieves the input data using the <mark style="color:red;"><strong>getInput</strong></mark> function and extracts the <mark style="color:red;"><strong>self</strong></mark> address, <mark style="color:red;"><strong>spender</strong></mark> address, and the <mark style="color:red;"><strong>amount</strong></mark> to be approved from the input data. The function then calls the <mark style="color:red;"><strong>approve</strong></mark> method on the <mark style="color:red;"><strong>self</strong></mark> address, allowing the <mark style="color:red;"><strong>spender</strong></mark> to spend the specified <mark style="color:red;"><strong>amount</strong></mark>. This function ensures that the approval operation is executed correctly, enabling subsequent transactions to utilize the approved amount.</td></tr><tr><td><mark style="color:red;"><strong>executeCommandTransferFrom</strong></mark> </td><td>The <mark style="color:red;"><strong>executeCommandTransferFrom</strong></mark> function facilitates the execution of a transfer command from a specific address and asset. It retrieves the input data using the <mark style="color:red;"><strong>getInput</strong></mark> function and extracts the amount to be transferred from the input data. If the amount is greater than zero, it also extracts the recipient address and performs the transfer from the specified <mark style="color:red;"><strong>fromAddress</strong></mark> to the recipient using the <mark style="color:red;"><strong>transferFrom</strong></mark> method of the <mark style="color:red;"><strong>fromAssetAddress</strong></mark>. The function then updates the accumulated transfer amount and returns it. This ensures that the specified amount of the asset is correctly transferred from the source address to the destination address.</td></tr><tr><td><mark style="color:red;"><strong>executeCommandTransfer</strong></mark> </td><td>The <mark style="color:red;"><strong>executeCommandTransfer</strong></mark> function handles the execution of a direct transfer command. It retrieves the input data using the <mark style="color:red;"><strong>getInput</strong></mark> function and extracts the amount to be transferred. If the amount is greater than zero, it also extracts the sender (<mark style="color:red;"><strong>self</strong></mark>) and recipient addresses from the input data. The function then performs the <mark style="color:red;"><strong>transfer</strong></mark> from the sender to the recipient using the transfer method. This function ensures that the specified amount is correctly transferred from the sender to the recipient, facilitating the movement of assets within the contract.</td></tr><tr><td><mark style="color:red;"><strong>executeCommandWrap</strong></mark> </td><td>The executeCommandWrap function handles the execution of a wrap command, which is used to wrap native tokens. It retrieves the input data using the getInput function and extracts the self address and the amount to be wrapped from the input data. The function then calls the wrap method on the self address with the specified amount, ensuring that the native tokens are correctly wrapped.</td></tr><tr><td><mark style="color:red;"><strong>executeCommandUnwrap</strong></mark> </td><td>The <mark style="color:red;"><strong>executeCommandUnwrap</strong></mark> function is responsible for executing an unwrap command, which is used to unwrap native tokens. Similar to the wrap function, it retrieves the input data and extracts the <mark style="color:red;"><strong>self</strong></mark> address and the <mark style="color:red;"><strong>amount</strong></mark> to be unwrapped. The function then calls the <mark style="color:red;"><strong>unwrap</strong></mark> method on the <mark style="color:red;"><strong>self</strong></mark> address with the specified amount, ensuring that the native tokens are correctly unwrapped.</td></tr><tr><td><mark style="color:red;"><strong>executeCommandBalance</strong></mark> </td><td>The <mark style="color:red;"><strong>executeCommandBalance</strong></mark> function executes a balance command and returns the resulting balance. It retrieves the input data using the <mark style="color:red;"><strong>getInput</strong></mark> function and extracts the <mark style="color:red;"><strong>self</strong></mark> address. The function then calls the <mark style="color:red;"><strong>getBalance</strong></mark> method on the <mark style="color:red;"><strong>self</strong></mark> address to retrieve the balance. The balance is stored at the output offset pointer in memory, and the function updates the output offset pointer before returning it. This function ensures that the balance of the specified address is correctly retrieved and stored for further use in the contract.</td></tr><tr><td><mark style="color:red;"><strong>executeCommandMath</strong></mark> </td><td>The <mark style="color:red;"><strong>executeCommandMath</strong></mark> function executes a mathematical command based on the provided parameters. It retrieves the input data using the <mark style="color:red;"><strong>getInput</strong></mark> function and defines a nested assembly function, <mark style="color:red;"><strong>math</strong></mark>, to perform various mathematical operations. The function iterates through a set of commands, processing each one based on its operator type, such as addition, subtraction, multiplication, division, power, absolute value (both 128-bit and 256-bit), bitwise shift right, and bitwise shift left. For each operator, the function retrieves the operands from either the current output pointer or the input data, performs the specified operation, and stores the result in the current output pointer. If an invalid operator is encountered, the function reverts with an <mark style="color:red;"><strong>InvalidSequenceType</strong></mark> error. After processing all commands, the function updates the output offset pointer and returns it. This function ensures that complex mathematical operations can be executed efficiently within the contract, supporting a wide range of arithmetic and bitwise operations.</td></tr><tr><td><mark style="color:red;"><strong>executeCommandComparison</strong></mark> </td><td>The <mark style="color:red;"><strong>executeCommandComparison</strong></mark> function executes a comparison command based on the provided parameters. It retrieves the input data using the <mark style="color:red;"><strong>getInput</strong></mark> function and defines a nested assembly function, <mark style="color:red;"><strong>comparison</strong></mark>, to perform various comparison operations. The function iterates through a set of commands, processing each one based on its operator type, such as less than (<mark style="color:red;"><strong>Lt</strong></mark>), less than or equal to (<mark style="color:red;"><strong>Lte</strong></mark>), greater than (<mark style="color:red;"><strong>Gt</strong></mark>), greater than or equal to (<mark style="color:red;"><strong>Gte</strong></mark>), equal to (<mark style="color:red;"><strong>Eq</strong></mark>), and not equal to (<mark style="color:red;"><strong>Ne</strong></mark>). For each operator, the function retrieves the operands from either the current output pointer or the input data, performs the specified comparison, and stores the result in the current output pointer. If an invalid operator is encountered, the function reverts with an <mark style="color:red;"><strong>InvalidSequenceType</strong></mark> error. After processing all commands, the function updates the output offset pointer and returns it. This function ensures that complex comparison operations can be executed efficiently within the contract, supporting a wide range of relational operations to facilitate decision-making processes in the contract’s logic.</td></tr><tr><td><mark style="color:red;"><strong>executeCommand</strong></mark> </td><td><p>The <mark style="color:red;"><strong>executeCommand</strong></mark> function is a comprehensive handler for executing various commands within the swap operation. It takes several parameters, including the command data position (<mark style="color:red;"><strong>i</strong></mark>), the address from which assets will be transferred (<mark style="color:red;"><strong>fromAddress</strong></mark>), the asset address (<mark style="color:red;"><strong>fromAssetAddress</strong></mark>), and pointers for output memory (<mark style="color:red;"><strong>outputPtr</strong></mark> and <mark style="color:red;"><strong>outputOffsetPtr</strong></mark>). It also tracks the accumulated transferred amount (<mark style="color:red;"><strong>transferFromAmount</strong></mark>) and the gas used (<mark style="color:red;"><strong>gasUsed</strong></mark>). The function begins by determining the type of command to execute using the <mark style="color:red;"><strong>CommandAction</strong></mark> enumeration. Depending on the command type, it calls the appropriate function to handle the command: • Call: Executes a generic function call using <mark style="color:red;">executeCommandCall</mark>. </p><p>• Approval: Handles token approval operations with <mark style="color:red;"><strong>executeCommandApproval</strong></mark>. </p><p>• TransferFrom: Executes a transfer from a specific address using <mark style="color:red;"><strong>executeCommandTransferFrom</strong></mark>.</p><p>• Transfer: Executes a direct transfer with <mark style="color:red;">executeCommandTransfer</mark>. </p><p>• Wrap: Wraps native tokens using <mark style="color:red;"><strong>executeCommandWrap</strong></mark>. </p><p>• Unwrap: Unwraps native tokens with <mark style="color:red;"><strong>executeCommandUnwrap</strong></mark>. </p><p>• Balance: Retrieves the balance of an address using <mark style="color:red;"><strong>executeCommandBalance</strong></mark>. </p><p>• Math: Performs mathematical operations with <mark style="color:red;"><strong>executeCommandMath</strong></mark>. </p><p>• Comparison: Executes comparison operations using <mark style="color:red;"><strong>executeCommandComparison</strong></mark>. </p><p>• EstimateGasStart: Records the starting gas for estimation. </p><p>• EstimateGasEnd: Calculates the gas used by subtracting the remaining gas from the starting gas.</p><p>If an invalid command is encountered, the function reverts with an <mark style="color:red;"><strong>InvalidCommand</strong></mark> error. The function returns the updated values for <mark style="color:red;"><strong>transferFromAmount</strong></mark>, <mark style="color:red;"><strong>gasUsed</strong></mark>, and <mark style="color:red;"><strong>outputOffsetPtr</strong></mark>, ensuring that the swap operation is executed correctly and efficiently.</p></td></tr><tr><td><mark style="color:red;"><strong>receive</strong></mark> </td><td><mark style="color:red;"><strong>receive</strong></mark> function handles incoming Ether transfers.</td></tr></tbody></table>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.fly.trade/flycn/developers/fly.trade-contracts/magpierouterv3.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
