# MagpieStargateBridgeV3

The MagpieStargateBridgeV3 contract is designed for cross-chain communication and asset bridging using the Stargate bridge. It inherits from Ownable2Step and Pausable contracts, providing ownership management and pausing capabilities. The contract uses several libraries and interfaces to manage assets and facilitate swaps and deposits. Key features include state variables for tracking internal callers, asset mappings, and deposits, as well as functions for updating these mappings and addresses. It has functions for performing swaps with Magpie or user signatures, verifying signatures, and handling inbound and outbound asset transfers. The contract also includes functions for executing multiple calls in a single transaction, receiving Ether, and composing LayerZero messages. Overall, it provides a comprehensive framework for secure and efficient cross-chain asset management.

<table><thead><tr><th width="241">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 owner to update the internal caller list, emitting an <mark style="color:red;"><strong>UpdateInternalCaller</strong></mark> event upon changes. The <mark style="color:red;"><strong>updateWeth</strong></mark> function allows the owner to update the WETH address. The <mark style="color:red;"><strong>updateNetworkIdAndRouterAddress</strong></mark> function allows the owner to update the network ID and router address. The <mark style="color:red;"><strong>updateAssetToStargate</strong></mark> and <mark style="color:red;"><strong>updateStargateToAsset</strong></mark> functions allow the owner to update the mappings between assets and Stargate addresses, emitting corresponding events. The <mark style="color:red;"><strong>updateLzAddress</strong></mark> function allows the owner to update the LayerZero address.</td></tr><tr><td><mark style="color:red;"><strong>swapInWithMagpieSignature</strong></mark> </td><td>The <mark style="color:red;"><strong>swapInWithMagpieSignature</strong></mark> function allows users to perform a swap operation using a Magpie signature. This function can be called externally and requires a calldata parameter. It is payable and can only be executed when the contract is not paused. The function retrieves swap data using the <mark style="color:red;"><strong>LibRouter.getData</strong></mark> method and then calls the <mark style="color:red;"><strong>swapIn</strong></mark> function with the retrieved data and a boolean flag set to true, indicating that the swap is performed with a Magpie signature. The function returns the amount of output tokens received from the swap.</td></tr><tr><td><mark style="color:red;"><strong>swapInWithUserSignature</strong></mark> </td><td>The <mark style="color:red;"><strong>swapInWithUserSignature</strong></mark> function is similar but is restricted to internal callers only, as enforced by the <mark style="color:red;"><strong>onlyInternalCaller</strong></mark> modifier. This function also retrieves swap data using the <mark style="color:red;"><strong>LibRouter.getData</strong></mark> method. However, it includes an additional check to ensure that the <mark style="color:red;"><strong>fromAssetAddress</strong></mark> in the swap data is not a native asset, reverting with an <mark style="color:red;"><strong>InvalidAddress</strong></mark> error if this condition is met. The function then calls the <mark style="color:red;"><strong>swapIn</strong></mark> function with the retrieved data and a boolean flag set to false, indicating that the swap is performed with a user signature. The function returns the amount of output tokens received from the swap.</td></tr><tr><td><mark style="color:red;"><strong>verifySignature</strong></mark> </td><td>The <mark style="color:red;"><strong>verifySignature</strong></mark> function is a private view function that verifies the signature for a swap operation. It takes two parameters: <mark style="color:red;"><strong>swapData</strong></mark>, which is a struct containing the details of the swap, and <mark style="color:red;"><strong>useCaller</strong></mark>, a boolean flag indicating whether to use the caller’s address for verification. The function returns the address of the signer if the signature is valid. The function begins by determining the length of the message based on whether the swap data includes an affiliate. It then uses inline assembly to construct the message that will be hashed and verified. Depending on the presence of an affiliate, it stores the appropriate keccak256 hash of the swap message structure in memory. The function then loads various fields from the calldata into memory, including addresses and amounts related to the swap. Finally, the function calls <mark style="color:red;"><strong>LibRouter.verifySignature</strong></mark> with the constructed message and other relevant parameters to verify the signature. If the signature is valid, the function returns the address of the signer.</td></tr><tr><td><mark style="color:red;"><strong>swapIn</strong></mark> </td><td>The <mark style="color:red;"><strong>swapIn</strong></mark> function executes an inbound swap operation. It increments the <mark style="color:red;"><strong>swapSequence</strong></mark> and stores the current sequence. Using inline assembly, it retrieves the network ID and router address from the <mark style="color:red;"><strong>networkIdAndRouterAddress</strong></mark> state variable. The function then verifies the signature of the swap data using the <mark style="color:red;"><strong>verifySignature</strong></mark> function. If the swap data includes a permit, it calls LibRouter.permit to handle the permit. It also transfers any applicable fees using <mark style="color:red;"><strong>LibRouter.transferFees</strong></mark>. The function constructs the encoded deposit data and calculates its hash. It then calls <mark style="color:red;"><strong>LibBridge.swapIn</strong></mark> to perform the swap and subsequently calls <mark style="color:red;"><strong>bridgeIn</strong></mark> to handle the bridging process. If the <mark style="color:red;"><strong>swapSequence</strong></mark> has changed during execution, it reverts with a <mark style="color:red;"><strong>ReentrancyError</strong></mark>.</td></tr><tr><td><mark style="color:red;"><strong>getExtraOptions</strong></mark> </td><td>The <mark style="color:red;"><strong>getExtraOptions</strong></mark> function retrieves extra options for the <mark style="color:red;"><strong>SendParam</strong></mark> struct, encoding them as bytes. It constructs the options with a gas limit and returns the encoded bytes.</td></tr><tr><td><mark style="color:red;"><strong>getSendParam</strong></mark> </td><td>The <mark style="color:red;"><strong>getSendParam</strong></mark> function constructs a <mark style="color:red;"><strong>SendParam</strong></mark> struct with the specified amount and encoded deposit data hash. It uses inline assembly to retrieve the receiver address, destination endpoint ID, and gas limit from the calldata. It then returns the constructed <mark style="color:red;"><strong>SendParam</strong></mark> struct, including the extra options and encoded deposit data hash.</td></tr><tr><td><mark style="color:red;"><strong>bridgeIn</strong></mark> </td><td>The <mark style="color:red;"><strong>bridgeIn</strong></mark> function facilitates the inbound transfer of assets into the contract. It takes several parameters, including the bridge fee, refund address, target asset address, amount, and a deposit data hash. The function first retrieves the corresponding Stargate address for the asset. If the address is invalid, it reverts with an <mark style="color:red;"><strong>InvalidStargateAddress</strong></mark> error. It calculates the total value to send, including the bridge fee and, if the asset is native, the amount. For non-native assets, it approves the transfer to the Stargate address. The function constructs a <mark style="color:red;"><strong>SendParam</strong></mark> struct using the <mark style="color:red;"><strong>getSendParam</strong></mark> function and then interacts with the Stargate contract to quote the amount received and send the token, including the bridge fee and refund address.</td></tr><tr><td><mark style="color:red;"><strong>swapOut</strong></mark> </td><td>The <mark style="color:red;"><strong>swapOut</strong></mark> function allows internal callers to execute an outbound swap operation. It retrieves the network ID and router address using inline assembly. The function then obtains swap data and calculates the deposit data hash. It checks if the deposit amount is available; if not, it reverts with a <mark style="color:red;"><strong>DepositIsNotFound</strong></mark> error. The function resets the deposit amount to zero and calls <mark style="color:red;"><strong>LibBridge.swapOut</strong></mark> to perform the swap, returning the amount of output tokens received.</td></tr><tr><td><mark style="color:red;"><strong>getDepositAmount</strong></mark> </td><td>The <mark style="color:red;"><strong>getDepositAmount</strong></mark> function is a private pure function that extracts and returns the deposit amount from an encoded bytes array. It uses inline assembly to load the amount from the specified position in the bytes array.</td></tr><tr><td><mark style="color:red;"><strong>lzCompose</strong></mark> </td><td>The <mark style="color:red;"><strong>lzCompose</strong></mark> function handles the composition of LayerZero messages. It verifies the sender and the asset address, ensuring they match the expected values. If the checks pass, it decodes the deposit data hash from the message and updates the deposit amount for the corresponding asset. The function emits a <mark style="color:red;"><strong>Deposit</strong></mark> event with the deposit data hash and the updated deposit amount.</td></tr><tr><td><mark style="color:red;"><strong>multicall</strong></mark> </td><td>The <mark style="color:red;"><strong>multicall</strong></mark> function allows the contract owner to execute multiple function calls in a single transaction. It takes an array of calldata and iterates through each element, performing a delegate call to the contract itself. The results of each call are stored in an array, which is returned at the end.</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>
