MagpieSymbiosisBridge
The MagpieSymbiosisBridge contract is designed to facilitate cross-chain liquidity aggregation using the Symbiosis bridge, integrating multiple external libraries and interfaces. It inherits from Ownable2Step and Pausable contracts, providing ownership management and pausing capabilities. The contract manages various addresses and mappings to track internal callers, deposits, and configurations. Key features include functions for updating internal callers and addresses, initiating swap transactions with Magpie or user signatures, verifying signatures, and handling inbound and outbound bridging processes. It also includes functions for pausing and unpausing the contract, withdrawing ERC20 tokens, and handling Ether transfers. The contract ensures secure and efficient cross-chain operations with detailed logging and event emission for transparency and traceability.
updateInternalCaller
The updateInternalCaller function allows the owner to update the list of internal callers, emitting an event to log the changes. The updateWeth, updateNetworkIdAndRouterAddress, updatePortalAddress, updateGatewayAddress, and updateGasReceiverAddress functions enable the owner to update respective addresses and configurations, ensuring the contract can adapt to changes in the underlying infrastructure or requirements.
swapInWithMagpieSignature
The swapInWithMagpieSignature function allows users to initiate a swap transaction using a Magpie signature. This function can only be executed when the contract is not paused, ensuring that operations are halted during maintenance or emergencies. It retrieves swap data using the LibRouter.getData function and then calls the swapIn function with the retrieved data and a boolean flag set to true, indicating that a Magpie signature is being used. The function returns the amount of tokens received from the swap.
swapInWithUserSignature
The swapInWithUserSignature function, on the other hand, is restricted to internal callers through the onlyInternalCaller modifier. This function also retrieves swap data using LibRouter.getData. However, it includes an additional check to ensure that the fromAssetAddress is not a native asset, reverting the transaction with an InvalidAddress error if this condition is met. The function then calls swapIn with the retrieved data and a boolean flag set to false, indicating that a user signature is being used. It returns the amount of tokens received from the swap.
verifySignature
The verifySignature function is designed to verify the signature for a swap operation by constructing a message from the provided SwapData and checking it against the expected signature. The function begins by determining the length of the message based on whether the swap includes an affiliate. Using inline assembly, it constructs the message by loading various pieces of data from the calldata into memory, including addresses, amounts, and other relevant details. The function handles both the presence and absence of an affiliate by storing the appropriate keccak256 hash in memory. It then loads data such as toAddress, fromAssetAddress, toAssetAddress, amountOutMin, gasFee, recipientNetworkId, recipientAddress, synthesisAddress, symbiosisAddress, bridgeFee, chainId, and clientId into the message. Additionally, it processes the destinationAddress and destinationChain by copying their lengths and values into memory and computing their keccak256 hashes. Finally, the function calls LibRouter.verifySignature with the constructed message and other parameters to verify the signature. If the signature is valid, it returns the address of the signer, ensuring the integrity and authenticity of the swap operation.
swapIn
The swapIn function executes an inbound swap operation, handling the entire process from verifying the signature to transferring fees and performing the swap. It begins by incrementing the swapSequence to ensure each swap has a unique identifier. Using inline assembly, it retrieves the networkId and routerAddress from the stored networkIdAndRouterAddress variable. The function then verifies the signature of the swap data using the verifySignature function. If the swap data includes a permit, it calls LibRouter.permit to handle the permit process. It also transfers any associated fees using LibRouter.transferFees. Next, the function prepares the encoded deposit data and calculates its hash. It calls LibBridge.swapIn to perform the actual swap, passing the necessary parameters including the encoded deposit data, the verified address, the router address, and the WETH address. The bridgeIn function is then called to handle the bridging process, including transferring the fee and updating the deposit data hash. Finally, the function checks for reentrancy by comparing the current swapSequence with the incremented value. If they do not match, it reverts the transaction with a ReentrancyError. The function emits a BridgeIn event to log the details of the inbound swap operation.
bridgeIn
The bridgeIn function facilitates the bridging of an inbound asset transfer into the contract. It takes several parameters, including the transfer fee, refund address, asset address, amount, and a deposit data hash. The function begins by approving the portalAddress to spend the specified amount of the asset. Using inline assembly, it retrieves the bridge fee and other necessary data from the calldata. It constructs a call to the synthesize function, passing in the bridge fee, asset address, amount, receiver address, synthesis address, symbiosis address, refund address, chain ID, and client ID. If the execution of this call fails, the function reverts with a SynthesisFailed error. The function then calls dataIn to handle the transfer fee, deposit data hash, net amount (amount minus bridge fee), asset address, and refund address. Finally, it retrieves the crosschainId from the assembly block and emits a BridgeIn event to log the details of the inbound asset transfer. This ensures that the bridging process is securely executed and properly recorded.
dataIn
The dataIn function executes an inbound data transfer by taking parameters such as the transfer fee, deposit data hash, amount, asset address, and refund address. It begins by creating a payload and initializing strings for the destination address and chain. Using inline assembly, it retrieves the destination address and chain from the calldata, copies their lengths and values into memory, and constructs the payload with the deposit data hash, amount, and asset address. The function then calls IAxelarGasService to pay the native gas fee for the contract call and IAxelarGateway to execute the contract call to the destination chain and address. If the operation fails, tokens are transferred to the refund address. Finally, the function emits a Deposit event to log the details of the inbound data transfer.
execute
The execute function handles the execution of cross-chain commands by validating the contract call through the IAxelarGateway. It takes parameters such as the command ID, source chain, source address, and payload. If the validation fails, the function reverts with a NotApprovedByGateway error. Upon successful validation, it calls the addDeposit function to process the payload.
addDeposit
The addDeposit function extracts the deposit data hash, amount, and asset address from the payload using inline assembly and updates the deposit mapping accordingly. It then emits a Deposit event to log the details of the validated deposit, ensuring the integrity and traceability of the cross-chain transaction.
swapOut
The swapOut function facilitates the outbound swap of assets, restricted to internal callers. It retrieves the network ID and router address using inline assembly, then obtains swap data via LibRouter.getData. The function calculates the deposit data hash and checks the deposit amount. If no deposit is found, it reverts with a DepositIsNotFound error. Otherwise, it resets the deposit amount to zero and calls LibBridge.swapOut to execute the swap, returning the amount received from the swap.
multicall
The multicall function allows the contract owner to execute multiple delegate calls in a single transaction. It takes an array of calldata, iterates through each item, and performs a delegate call to the contract itself using Address.functionDelegateCall. The results of each call are stored in an array, which is then returned. This function enables batch processing of multiple operations, enhancing efficiency and reducing transaction costs.
Last updated