Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
163370 | 23 days ago | Contract Creation | 0 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
RelayFacet
Compiler Version
v0.8.26+commit.8a97fa7a
ZkSolc Version
v1.5.3
Optimization Enabled:
Yes with Mode 3
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import { ILiFi } from "../Interfaces/ILiFi.sol"; import { LibAsset } from "../Libraries/LibAsset.sol"; import { LibSwap } from "../Libraries/LibSwap.sol"; import { LibUtil } from "../Libraries/LibUtil.sol"; import { ReentrancyGuard } from "../Helpers/ReentrancyGuard.sol"; import { SwapperV2 } from "../Helpers/SwapperV2.sol"; import { Validatable } from "../Helpers/Validatable.sol"; import { ECDSA } from "solady/utils/ECDSA.sol"; /// @title Relay Facet /// @author LI.FI (https://li.fi) /// @notice Provides functionality for bridging through Relay Protocol /// @custom:version 1.0.0 contract RelayFacet is ILiFi, ReentrancyGuard, SwapperV2, Validatable { // Receiver for native transfers address public immutable relayReceiver; // Relayer wallet for ERC20 transfers address public immutable relaySolver; /// Storage /// mapping(bytes32 => bool) public consumedIds; /// Types /// /// @dev Relay specific parameters /// @param requestId Relay API request ID /// @param nonEVMReceiver set only if bridging to non-EVM chain /// @params receivingAssetId address of receiving asset /// @params signature attestation signature provided by the Relay solver struct RelayData { bytes32 requestId; bytes32 nonEVMReceiver; bytes32 receivingAssetId; bytes signature; } /// Events /// event BridgeToNonEVMChain( bytes32 indexed transactionId, uint256 indexed destinationChainId, bytes32 receiver ); /// Errors /// error InvalidQuote(); /// Modifiers /// /// @param _bridgeData The core information needed for bridging /// @param _relayData Data specific to Relay modifier onlyValidQuote( ILiFi.BridgeData memory _bridgeData, RelayData calldata _relayData ) { // Ensure that the id isn't already consumed if (consumedIds[_relayData.requestId]) { revert InvalidQuote(); } // Ensure nonEVMAddress is not empty if ( _bridgeData.receiver == LibAsset.NON_EVM_ADDRESS && _relayData.nonEVMReceiver == bytes32(0) ) { revert InvalidQuote(); } // Verify that the bridging quote has been signed by the Relay solver // as attested using the attestation API // API URL: https://api.relay.link/requests/{requestId}/signature/v2 bytes32 message = ECDSA.toEthSignedMessageHash( keccak256( abi.encodePacked( _relayData.requestId, block.chainid, bytes32(uint256(uint160(address(this)))), bytes32(uint256(uint160(_bridgeData.sendingAssetId))), _getMappedChainId(_bridgeData.destinationChainId), _bridgeData.receiver == LibAsset.NON_EVM_ADDRESS ? _relayData.nonEVMReceiver : bytes32(uint256(uint160(_bridgeData.receiver))), _relayData.receivingAssetId ) ) ); address signer = ECDSA.recover(message, _relayData.signature); if (signer != relaySolver) { revert InvalidQuote(); } _; } /// Constructor /// /// @param _relayReceiver The receiver for native transfers /// @param _relaySolver The relayer wallet for ERC20 transfers constructor(address _relayReceiver, address _relaySolver) { relayReceiver = _relayReceiver; relaySolver = _relaySolver; } /// External Methods /// /// @notice Bridges tokens via Relay /// @param _bridgeData The core information needed for bridging /// @param _relayData Data specific to Relay function startBridgeTokensViaRelay( ILiFi.BridgeData calldata _bridgeData, RelayData calldata _relayData ) external payable nonReentrant onlyValidQuote(_bridgeData, _relayData) refundExcessNative(payable(msg.sender)) validateBridgeData(_bridgeData) doesNotContainSourceSwaps(_bridgeData) doesNotContainDestinationCalls(_bridgeData) { LibAsset.depositAsset( _bridgeData.sendingAssetId, _bridgeData.minAmount ); _startBridge(_bridgeData, _relayData); } /// @notice Performs a swap before bridging via Relay /// @param _bridgeData The core information needed for bridging /// @param _swapData An array of swap related data for performing swaps before bridging /// @param _relayData Data specific to Relay function swapAndStartBridgeTokensViaRelay( ILiFi.BridgeData memory _bridgeData, LibSwap.SwapData[] calldata _swapData, RelayData calldata _relayData ) external payable nonReentrant onlyValidQuote(_bridgeData, _relayData) refundExcessNative(payable(msg.sender)) containsSourceSwaps(_bridgeData) doesNotContainDestinationCalls(_bridgeData) validateBridgeData(_bridgeData) { _bridgeData.minAmount = _depositAndSwap( _bridgeData.transactionId, _bridgeData.minAmount, _swapData, payable(msg.sender) ); _startBridge(_bridgeData, _relayData); } /// Internal Methods /// /// @dev Contains the business logic for the bridge via Relay /// @param _bridgeData The core information needed for bridging /// @param _relayData Data specific to Relay function _startBridge( ILiFi.BridgeData memory _bridgeData, RelayData calldata _relayData ) internal { // check if sendingAsset is native or ERC20 if (LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) { // Native // Send Native to relayReceiver along with requestId as extra data (bool success, bytes memory reason) = relayReceiver.call{ value: _bridgeData.minAmount }(abi.encode(_relayData.requestId)); if (!success) { revert(LibUtil.getRevertMsg(reason)); } } else { // ERC20 // We build the calldata from scratch to ensure that we can only // send to the solver address bytes memory transferCallData = bytes.concat( abi.encodeWithSignature( "transfer(address,uint256)", relaySolver, _bridgeData.minAmount ), abi.encode(_relayData.requestId) ); (bool success, bytes memory reason) = address( _bridgeData.sendingAssetId ).call(transferCallData); if (!success) { revert(LibUtil.getRevertMsg(reason)); } } consumedIds[_relayData.requestId] = true; // Emit special event if bridging to non-EVM chain if (_bridgeData.receiver == LibAsset.NON_EVM_ADDRESS) { emit BridgeToNonEVMChain( _bridgeData.transactionId, _getMappedChainId(_bridgeData.destinationChainId), _relayData.nonEVMReceiver ); } emit LiFiTransferStarted(_bridgeData); } /// @notice get Relay specific chain id for non-EVM chains /// IDs found here https://li.quest/v1/chains?chainTypes=UTXO,SVM /// @param chainId LIFI specific chain id function _getMappedChainId( uint256 chainId ) internal pure returns (uint256) { // Bitcoin if (chainId == 20000000000001) { return 8253038; } // Solana if (chainId == 1151111081099710) { return 792703809; } return chainId; } }
// SPDX-License-Identifier: MIT /// @custom:version 1.0.0 pragma solidity ^0.8.17; interface ILiFi { /// Structs /// struct BridgeData { bytes32 transactionId; string bridge; string integrator; address referrer; address sendingAssetId; address receiver; uint256 minAmount; uint256 destinationChainId; bool hasSourceSwaps; bool hasDestinationCall; } /// Events /// event LiFiTransferStarted(ILiFi.BridgeData bridgeData); event LiFiTransferCompleted( bytes32 indexed transactionId, address receivingAssetId, address receiver, uint256 amount, uint256 timestamp ); event LiFiTransferRecovered( bytes32 indexed transactionId, address receivingAssetId, address receiver, uint256 amount, uint256 timestamp ); event LiFiGenericSwapCompleted( bytes32 indexed transactionId, string integrator, string referrer, address receiver, address fromAssetId, address toAssetId, uint256 fromAmount, uint256 toAmount ); // Deprecated but kept here to include in ABI to parse historic events event LiFiSwappedGeneric( bytes32 indexed transactionId, string integrator, string referrer, address fromAssetId, address toAssetId, uint256 fromAmount, uint256 toAmount ); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.17; import { InsufficientBalance, NullAddrIsNotAnERC20Token, NullAddrIsNotAValidSpender, NoTransferToNullAddress, InvalidAmount, NativeAssetTransferFailed } from "../Errors/GenericErrors.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { LibSwap } from "./LibSwap.sol"; /// @title LibAsset /// @custom:version 1.0.2 /// @notice This library contains helpers for dealing with onchain transfers /// of assets, including accounting for the native asset `assetId` /// conventions and any noncompliant ERC20 transfers library LibAsset { uint256 private constant MAX_UINT = type(uint256).max; address internal constant NULL_ADDRESS = address(0); address internal constant NON_EVM_ADDRESS = 0x11f111f111f111F111f111f111F111f111f111F1; /// @dev All native assets use the empty address for their asset id /// by convention address internal constant NATIVE_ASSETID = NULL_ADDRESS; //address(0) /// @notice Gets the balance of the inheriting contract for the given asset /// @param assetId The asset identifier to get the balance of /// @return Balance held by contracts using this library function getOwnBalance(address assetId) internal view returns (uint256) { return isNativeAsset(assetId) ? address(this).balance : IERC20(assetId).balanceOf(address(this)); } /// @notice Transfers ether from the inheriting contract to a given /// recipient /// @param recipient Address to send ether to /// @param amount Amount to send to given recipient function transferNativeAsset( address payable recipient, uint256 amount ) private { if (recipient == NULL_ADDRESS) revert NoTransferToNullAddress(); if (amount > address(this).balance) revert InsufficientBalance(amount, address(this).balance); // solhint-disable-next-line avoid-low-level-calls (bool success, ) = recipient.call{ value: amount }(""); if (!success) revert NativeAssetTransferFailed(); } /// @notice If the current allowance is insufficient, the allowance for a given spender /// is set to MAX_UINT. /// @param assetId Token address to transfer /// @param spender Address to give spend approval to /// @param amount Amount to approve for spending function maxApproveERC20( IERC20 assetId, address spender, uint256 amount ) internal { if (isNativeAsset(address(assetId))) { return; } if (spender == NULL_ADDRESS) { revert NullAddrIsNotAValidSpender(); } if (assetId.allowance(address(this), spender) < amount) { SafeERC20.forceApprove(IERC20(assetId), spender, MAX_UINT); } } /// @notice Transfers tokens from the inheriting contract to a given /// recipient /// @param assetId Token address to transfer /// @param recipient Address to send token to /// @param amount Amount to send to given recipient function transferERC20( address assetId, address recipient, uint256 amount ) private { if (isNativeAsset(assetId)) { revert NullAddrIsNotAnERC20Token(); } if (recipient == NULL_ADDRESS) { revert NoTransferToNullAddress(); } uint256 assetBalance = IERC20(assetId).balanceOf(address(this)); if (amount > assetBalance) { revert InsufficientBalance(amount, assetBalance); } SafeERC20.safeTransfer(IERC20(assetId), recipient, amount); } /// @notice Transfers tokens from a sender to a given recipient /// @param assetId Token address to transfer /// @param from Address of sender/owner /// @param to Address of recipient/spender /// @param amount Amount to transfer from owner to spender function transferFromERC20( address assetId, address from, address to, uint256 amount ) internal { if (isNativeAsset(assetId)) { revert NullAddrIsNotAnERC20Token(); } if (to == NULL_ADDRESS) { revert NoTransferToNullAddress(); } IERC20 asset = IERC20(assetId); uint256 prevBalance = asset.balanceOf(to); SafeERC20.safeTransferFrom(asset, from, to, amount); if (asset.balanceOf(to) - prevBalance != amount) { revert InvalidAmount(); } } function depositAsset(address assetId, uint256 amount) internal { if (amount == 0) revert InvalidAmount(); if (isNativeAsset(assetId)) { if (msg.value < amount) revert InvalidAmount(); } else { uint256 balance = IERC20(assetId).balanceOf(msg.sender); if (balance < amount) revert InsufficientBalance(amount, balance); transferFromERC20(assetId, msg.sender, address(this), amount); } } function depositAssets(LibSwap.SwapData[] calldata swaps) internal { for (uint256 i = 0; i < swaps.length; ) { LibSwap.SwapData calldata swap = swaps[i]; if (swap.requiresDeposit) { depositAsset(swap.sendingAssetId, swap.fromAmount); } unchecked { i++; } } } /// @notice Determines whether the given assetId is the native asset /// @param assetId The asset identifier to evaluate /// @return Boolean indicating if the asset is the native asset function isNativeAsset(address assetId) internal pure returns (bool) { return assetId == NATIVE_ASSETID; } /// @notice Wrapper function to transfer a given asset (native or erc20) to /// some recipient. Should handle all non-compliant return value /// tokens as well by using the SafeERC20 contract by open zeppelin. /// @param assetId Asset id for transfer (address(0) for native asset, /// token address for erc20s) /// @param recipient Address to send asset to /// @param amount Amount to send to given recipient function transferAsset( address assetId, address payable recipient, uint256 amount ) internal { isNativeAsset(assetId) ? transferNativeAsset(recipient, amount) : transferERC20(assetId, recipient, amount); } /// @dev Checks whether the given address is a contract and contains code function isContract(address _contractAddr) internal view returns (bool) { uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(_contractAddr) } return size > 0; } }
// SPDX-License-Identifier: MIT /// @custom:version 1.0.0 pragma solidity ^0.8.17; import { LibAsset } from "./LibAsset.sol"; import { LibUtil } from "./LibUtil.sol"; import { InvalidContract, NoSwapFromZeroBalance, InsufficientBalance } from "../Errors/GenericErrors.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; library LibSwap { struct SwapData { address callTo; address approveTo; address sendingAssetId; address receivingAssetId; uint256 fromAmount; bytes callData; bool requiresDeposit; } event AssetSwapped( bytes32 transactionId, address dex, address fromAssetId, address toAssetId, uint256 fromAmount, uint256 toAmount, uint256 timestamp ); function swap(bytes32 transactionId, SwapData calldata _swap) internal { if (!LibAsset.isContract(_swap.callTo)) revert InvalidContract(); uint256 fromAmount = _swap.fromAmount; if (fromAmount == 0) revert NoSwapFromZeroBalance(); uint256 nativeValue = LibAsset.isNativeAsset(_swap.sendingAssetId) ? _swap.fromAmount : 0; uint256 initialSendingAssetBalance = LibAsset.getOwnBalance( _swap.sendingAssetId ); uint256 initialReceivingAssetBalance = LibAsset.getOwnBalance( _swap.receivingAssetId ); if (nativeValue == 0) { LibAsset.maxApproveERC20( IERC20(_swap.sendingAssetId), _swap.approveTo, _swap.fromAmount ); } if (initialSendingAssetBalance < _swap.fromAmount) { revert InsufficientBalance( _swap.fromAmount, initialSendingAssetBalance ); } // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory res) = _swap.callTo.call{ value: nativeValue }(_swap.callData); if (!success) { LibUtil.revertWith(res); } uint256 newBalance = LibAsset.getOwnBalance(_swap.receivingAssetId); emit AssetSwapped( transactionId, _swap.callTo, _swap.sendingAssetId, _swap.receivingAssetId, _swap.fromAmount, newBalance > initialReceivingAssetBalance ? newBalance - initialReceivingAssetBalance : newBalance, block.timestamp ); } }
// SPDX-License-Identifier: MIT /// @custom:version 1.0.0 pragma solidity ^0.8.17; import "./LibBytes.sol"; library LibUtil { using LibBytes for bytes; function getRevertMsg( bytes memory _res ) internal pure returns (string memory) { // If the _res length is less than 68, then the transaction failed silently (without a revert message) if (_res.length < 68) return "Transaction reverted silently"; bytes memory revertData = _res.slice(4, _res.length - 4); // Remove the selector which is the first 4 bytes return abi.decode(revertData, (string)); // All that remains is the revert string } /// @notice Determines whether the given address is the zero address /// @param addr The address to verify /// @return Boolean indicating if the address is the zero address function isZeroAddress(address addr) internal pure returns (bool) { return addr == address(0); } function revertWith(bytes memory data) internal pure { assembly { let dataSize := mload(data) // Load the size of the data let dataPtr := add(data, 0x20) // Advance data pointer to the next word revert(dataPtr, dataSize) // Revert with the given data } } }
// SPDX-License-Identifier: UNLICENSED /// @custom:version 1.0.0 pragma solidity ^0.8.17; /// @title Reentrancy Guard /// @author LI.FI (https://li.fi) /// @notice Abstract contract to provide protection against reentrancy abstract contract ReentrancyGuard { /// Storage /// bytes32 private constant NAMESPACE = keccak256("com.lifi.reentrancyguard"); /// Types /// struct ReentrancyStorage { uint256 status; } /// Errors /// error ReentrancyError(); /// Constants /// uint256 private constant _NOT_ENTERED = 0; uint256 private constant _ENTERED = 1; /// Modifiers /// modifier nonReentrant() { ReentrancyStorage storage s = reentrancyStorage(); if (s.status == _ENTERED) revert ReentrancyError(); s.status = _ENTERED; _; s.status = _NOT_ENTERED; } /// Private Methods /// /// @dev fetch local storage function reentrancyStorage() private pure returns (ReentrancyStorage storage data) { bytes32 position = NAMESPACE; // solhint-disable-next-line no-inline-assembly assembly { data.slot := position } } }
// SPDX-License-Identifier: MIT /// @custom:version 1.0.0 pragma solidity ^0.8.17; import { ILiFi } from "../Interfaces/ILiFi.sol"; import { LibSwap } from "../Libraries/LibSwap.sol"; import { LibAsset } from "../Libraries/LibAsset.sol"; import { LibAllowList } from "../Libraries/LibAllowList.sol"; import { ContractCallNotAllowed, NoSwapDataProvided, CumulativeSlippageTooHigh } from "../Errors/GenericErrors.sol"; /// @title Swapper /// @author LI.FI (https://li.fi) /// @notice Abstract contract to provide swap functionality contract SwapperV2 is ILiFi { /// Types /// /// @dev only used to get around "Stack Too Deep" errors struct ReserveData { bytes32 transactionId; address payable leftoverReceiver; uint256 nativeReserve; } /// Modifiers /// /// @dev Sends any leftover balances back to the user /// @notice Sends any leftover balances to the user /// @param _swaps Swap data array /// @param _leftoverReceiver Address to send leftover tokens to /// @param _initialBalances Array of initial token balances modifier noLeftovers( LibSwap.SwapData[] calldata _swaps, address payable _leftoverReceiver, uint256[] memory _initialBalances ) { uint256 numSwaps = _swaps.length; if (numSwaps != 1) { address finalAsset = _swaps[numSwaps - 1].receivingAssetId; uint256 curBalance; _; for (uint256 i = 0; i < numSwaps - 1; ) { address curAsset = _swaps[i].receivingAssetId; // Handle multi-to-one swaps if (curAsset != finalAsset) { curBalance = LibAsset.getOwnBalance(curAsset) - _initialBalances[i]; if (curBalance > 0) { LibAsset.transferAsset( curAsset, _leftoverReceiver, curBalance ); } } unchecked { ++i; } } } else { _; } } /// @dev Sends any leftover balances back to the user reserving native tokens /// @notice Sends any leftover balances to the user /// @param _swaps Swap data array /// @param _leftoverReceiver Address to send leftover tokens to /// @param _initialBalances Array of initial token balances modifier noLeftoversReserve( LibSwap.SwapData[] calldata _swaps, address payable _leftoverReceiver, uint256[] memory _initialBalances, uint256 _nativeReserve ) { uint256 numSwaps = _swaps.length; if (numSwaps != 1) { address finalAsset = _swaps[numSwaps - 1].receivingAssetId; uint256 curBalance; _; for (uint256 i = 0; i < numSwaps - 1; ) { address curAsset = _swaps[i].receivingAssetId; // Handle multi-to-one swaps if (curAsset != finalAsset) { curBalance = LibAsset.getOwnBalance(curAsset) - _initialBalances[i]; uint256 reserve = LibAsset.isNativeAsset(curAsset) ? _nativeReserve : 0; if (curBalance > 0) { LibAsset.transferAsset( curAsset, _leftoverReceiver, curBalance - reserve ); } } unchecked { ++i; } } } else { _; } } /// @dev Refunds any excess native asset sent to the contract after the main function /// @notice Refunds any excess native asset sent to the contract after the main function /// @param _refundReceiver Address to send refunds to modifier refundExcessNative(address payable _refundReceiver) { uint256 initialBalance = address(this).balance - msg.value; _; uint256 finalBalance = address(this).balance; if (finalBalance > initialBalance) { LibAsset.transferAsset( LibAsset.NATIVE_ASSETID, _refundReceiver, finalBalance - initialBalance ); } } /// Internal Methods /// /// @dev Deposits value, executes swaps, and performs minimum amount check /// @param _transactionId the transaction id associated with the operation /// @param _minAmount the minimum amount of the final asset to receive /// @param _swaps Array of data used to execute swaps /// @param _leftoverReceiver The address to send leftover funds to /// @return uint256 result of the swap function _depositAndSwap( bytes32 _transactionId, uint256 _minAmount, LibSwap.SwapData[] calldata _swaps, address payable _leftoverReceiver ) internal returns (uint256) { uint256 numSwaps = _swaps.length; if (numSwaps == 0) { revert NoSwapDataProvided(); } address finalTokenId = _swaps[numSwaps - 1].receivingAssetId; uint256 initialBalance = LibAsset.getOwnBalance(finalTokenId); if (LibAsset.isNativeAsset(finalTokenId)) { initialBalance -= msg.value; } uint256[] memory initialBalances = _fetchBalances(_swaps); LibAsset.depositAssets(_swaps); _executeSwaps( _transactionId, _swaps, _leftoverReceiver, initialBalances ); uint256 newBalance = LibAsset.getOwnBalance(finalTokenId) - initialBalance; if (newBalance < _minAmount) { revert CumulativeSlippageTooHigh(_minAmount, newBalance); } return newBalance; } /// @dev Deposits value, executes swaps, and performs minimum amount check and reserves native token for fees /// @param _transactionId the transaction id associated with the operation /// @param _minAmount the minimum amount of the final asset to receive /// @param _swaps Array of data used to execute swaps /// @param _leftoverReceiver The address to send leftover funds to /// @param _nativeReserve Amount of native token to prevent from being swept back to the caller function _depositAndSwap( bytes32 _transactionId, uint256 _minAmount, LibSwap.SwapData[] calldata _swaps, address payable _leftoverReceiver, uint256 _nativeReserve ) internal returns (uint256) { uint256 numSwaps = _swaps.length; if (numSwaps == 0) { revert NoSwapDataProvided(); } address finalTokenId = _swaps[numSwaps - 1].receivingAssetId; uint256 initialBalance = LibAsset.getOwnBalance(finalTokenId); if (LibAsset.isNativeAsset(finalTokenId)) { initialBalance -= msg.value; } uint256[] memory initialBalances = _fetchBalances(_swaps); LibAsset.depositAssets(_swaps); ReserveData memory rd = ReserveData( _transactionId, _leftoverReceiver, _nativeReserve ); _executeSwaps(rd, _swaps, initialBalances); uint256 newBalance = LibAsset.getOwnBalance(finalTokenId) - initialBalance; if (LibAsset.isNativeAsset(finalTokenId)) { newBalance -= _nativeReserve; } if (newBalance < _minAmount) { revert CumulativeSlippageTooHigh(_minAmount, newBalance); } return newBalance; } /// Private Methods /// /// @dev Executes swaps and checks that DEXs used are in the allowList /// @param _transactionId the transaction id associated with the operation /// @param _swaps Array of data used to execute swaps /// @param _leftoverReceiver Address to send leftover tokens to /// @param _initialBalances Array of initial balances function _executeSwaps( bytes32 _transactionId, LibSwap.SwapData[] calldata _swaps, address payable _leftoverReceiver, uint256[] memory _initialBalances ) internal noLeftovers(_swaps, _leftoverReceiver, _initialBalances) { uint256 numSwaps = _swaps.length; for (uint256 i = 0; i < numSwaps; ) { LibSwap.SwapData calldata currentSwap = _swaps[i]; if ( !((LibAsset.isNativeAsset(currentSwap.sendingAssetId) || LibAllowList.contractIsAllowed(currentSwap.approveTo)) && LibAllowList.contractIsAllowed(currentSwap.callTo) && LibAllowList.selectorIsAllowed( bytes4(currentSwap.callData[:4]) )) ) revert ContractCallNotAllowed(); LibSwap.swap(_transactionId, currentSwap); unchecked { ++i; } } } /// @dev Executes swaps and checks that DEXs used are in the allowList /// @param _reserveData Data passed used to reserve native tokens /// @param _swaps Array of data used to execute swaps function _executeSwaps( ReserveData memory _reserveData, LibSwap.SwapData[] calldata _swaps, uint256[] memory _initialBalances ) internal noLeftoversReserve( _swaps, _reserveData.leftoverReceiver, _initialBalances, _reserveData.nativeReserve ) { uint256 numSwaps = _swaps.length; for (uint256 i = 0; i < numSwaps; ) { LibSwap.SwapData calldata currentSwap = _swaps[i]; if ( !((LibAsset.isNativeAsset(currentSwap.sendingAssetId) || LibAllowList.contractIsAllowed(currentSwap.approveTo)) && LibAllowList.contractIsAllowed(currentSwap.callTo) && LibAllowList.selectorIsAllowed( bytes4(currentSwap.callData[:4]) )) ) revert ContractCallNotAllowed(); LibSwap.swap(_reserveData.transactionId, currentSwap); unchecked { ++i; } } } /// @dev Fetches balances of tokens to be swapped before swapping. /// @param _swaps Array of data used to execute swaps /// @return uint256[] Array of token balances. function _fetchBalances( LibSwap.SwapData[] calldata _swaps ) private view returns (uint256[] memory) { uint256 numSwaps = _swaps.length; uint256[] memory balances = new uint256[](numSwaps); address asset; for (uint256 i = 0; i < numSwaps; ) { asset = _swaps[i].receivingAssetId; balances[i] = LibAsset.getOwnBalance(asset); if (LibAsset.isNativeAsset(asset)) { balances[i] -= msg.value; } unchecked { ++i; } } return balances; } }
// SPDX-License-Identifier: UNLICENSED /// @custom:version 1.0.0 pragma solidity ^0.8.17; import { LibAsset } from "../Libraries/LibAsset.sol"; import { LibUtil } from "../Libraries/LibUtil.sol"; import { InvalidReceiver, InformationMismatch, InvalidSendingToken, InvalidAmount, NativeAssetNotSupported, InvalidDestinationChain, CannotBridgeToSameNetwork } from "../Errors/GenericErrors.sol"; import { ILiFi } from "../Interfaces/ILiFi.sol"; import { LibSwap } from "../Libraries/LibSwap.sol"; contract Validatable { modifier validateBridgeData(ILiFi.BridgeData memory _bridgeData) { if (LibUtil.isZeroAddress(_bridgeData.receiver)) { revert InvalidReceiver(); } if (_bridgeData.minAmount == 0) { revert InvalidAmount(); } if (_bridgeData.destinationChainId == block.chainid) { revert CannotBridgeToSameNetwork(); } _; } modifier noNativeAsset(ILiFi.BridgeData memory _bridgeData) { if (LibAsset.isNativeAsset(_bridgeData.sendingAssetId)) { revert NativeAssetNotSupported(); } _; } modifier onlyAllowSourceToken( ILiFi.BridgeData memory _bridgeData, address _token ) { if (_bridgeData.sendingAssetId != _token) { revert InvalidSendingToken(); } _; } modifier onlyAllowDestinationChain( ILiFi.BridgeData memory _bridgeData, uint256 _chainId ) { if (_bridgeData.destinationChainId != _chainId) { revert InvalidDestinationChain(); } _; } modifier containsSourceSwaps(ILiFi.BridgeData memory _bridgeData) { if (!_bridgeData.hasSourceSwaps) { revert InformationMismatch(); } _; } modifier doesNotContainSourceSwaps(ILiFi.BridgeData memory _bridgeData) { if (_bridgeData.hasSourceSwaps) { revert InformationMismatch(); } _; } modifier doesNotContainDestinationCalls( ILiFi.BridgeData memory _bridgeData ) { if (_bridgeData.hasDestinationCall) { revert InformationMismatch(); } _; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Gas optimized ECDSA wrapper. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ECDSA.sol) /// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ECDSA.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol) /// /// @dev Note: /// - The recovery functions use the ecrecover precompile (0x1). /// - As of Solady version 0.0.68, the `recover` variants will revert upon recovery failure. /// This is for more safety by default. /// Use the `tryRecover` variants if you need to get the zero address back /// upon recovery failure instead. /// - As of Solady version 0.0.134, all `bytes signature` variants accept both /// regular 65-byte `(r, s, v)` and EIP-2098 `(r, vs)` short form signatures. /// See: https://eips.ethereum.org/EIPS/eip-2098 /// This is for calldata efficiency on smart accounts prevalent on L2s. /// /// WARNING! Do NOT use signatures as unique identifiers: /// - Use a nonce in the digest to prevent replay attacks on the same contract. /// - Use EIP-712 for the digest to prevent replay attacks across different chains and contracts. /// EIP-712 also enables readable signing of typed data for better user safety. /// This implementation does NOT check if a signature is non-malleable. library ECDSA { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The signature is invalid. error InvalidSignature(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* RECOVERY OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`. function recover(bytes32 hash, bytes memory signature) internal view returns (address result) { /// @solidity memory-safe-assembly assembly { result := 1 let m := mload(0x40) // Cache the free memory pointer. for {} 1 {} { mstore(0x00, hash) mstore(0x40, mload(add(signature, 0x20))) // `r`. if eq(mload(signature), 64) { let vs := mload(add(signature, 0x40)) mstore(0x20, add(shr(255, vs), 27)) // `v`. mstore(0x60, shr(1, shl(1, vs))) // `s`. break } if eq(mload(signature), 65) { mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`. mstore(0x60, mload(add(signature, 0x40))) // `s`. break } result := 0 break } result := mload( staticcall( gas(), // Amount of gas left for the transaction. result, // Address of `ecrecover`. 0x00, // Start of input. 0x80, // Size of input. 0x01, // Start of output. 0x20 // Size of output. ) ) // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. if iszero(returndatasize()) { mstore(0x00, 0x8baa579f) // `InvalidSignature()`. revert(0x1c, 0x04) } mstore(0x60, 0) // Restore the zero slot. mstore(0x40, m) // Restore the free memory pointer. } } /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`. function recoverCalldata(bytes32 hash, bytes calldata signature) internal view returns (address result) { /// @solidity memory-safe-assembly assembly { result := 1 let m := mload(0x40) // Cache the free memory pointer. mstore(0x00, hash) for {} 1 {} { if eq(signature.length, 64) { let vs := calldataload(add(signature.offset, 0x20)) mstore(0x20, add(shr(255, vs), 27)) // `v`. mstore(0x40, calldataload(signature.offset)) // `r`. mstore(0x60, shr(1, shl(1, vs))) // `s`. break } if eq(signature.length, 65) { mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`. calldatacopy(0x40, signature.offset, 0x40) // Copy `r` and `s`. break } result := 0 break } result := mload( staticcall( gas(), // Amount of gas left for the transaction. result, // Address of `ecrecover`. 0x00, // Start of input. 0x80, // Size of input. 0x01, // Start of output. 0x20 // Size of output. ) ) // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. if iszero(returndatasize()) { mstore(0x00, 0x8baa579f) // `InvalidSignature()`. revert(0x1c, 0x04) } mstore(0x60, 0) // Restore the zero slot. mstore(0x40, m) // Restore the free memory pointer. } } /// @dev Recovers the signer's address from a message digest `hash`, /// and the EIP-2098 short form signature defined by `r` and `vs`. function recover(bytes32 hash, bytes32 r, bytes32 vs) internal view returns (address result) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x00, hash) mstore(0x20, add(shr(255, vs), 27)) // `v`. mstore(0x40, r) mstore(0x60, shr(1, shl(1, vs))) // `s`. result := mload( staticcall( gas(), // Amount of gas left for the transaction. 1, // Address of `ecrecover`. 0x00, // Start of input. 0x80, // Size of input. 0x01, // Start of output. 0x20 // Size of output. ) ) // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. if iszero(returndatasize()) { mstore(0x00, 0x8baa579f) // `InvalidSignature()`. revert(0x1c, 0x04) } mstore(0x60, 0) // Restore the zero slot. mstore(0x40, m) // Restore the free memory pointer. } } /// @dev Recovers the signer's address from a message digest `hash`, /// and the signature defined by `v`, `r`, `s`. function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal view returns (address result) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x00, hash) mstore(0x20, and(v, 0xff)) mstore(0x40, r) mstore(0x60, s) result := mload( staticcall( gas(), // Amount of gas left for the transaction. 1, // Address of `ecrecover`. 0x00, // Start of input. 0x80, // Size of input. 0x01, // Start of output. 0x20 // Size of output. ) ) // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. if iszero(returndatasize()) { mstore(0x00, 0x8baa579f) // `InvalidSignature()`. revert(0x1c, 0x04) } mstore(0x60, 0) // Restore the zero slot. mstore(0x40, m) // Restore the free memory pointer. } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* TRY-RECOVER OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ // WARNING! // These functions will NOT revert upon recovery failure. // Instead, they will return the zero address upon recovery failure. // It is critical that the returned address is NEVER compared against // a zero address (e.g. an uninitialized address variable). /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`. function tryRecover(bytes32 hash, bytes memory signature) internal view returns (address result) { /// @solidity memory-safe-assembly assembly { result := 1 let m := mload(0x40) // Cache the free memory pointer. for {} 1 {} { mstore(0x00, hash) mstore(0x40, mload(add(signature, 0x20))) // `r`. if eq(mload(signature), 64) { let vs := mload(add(signature, 0x40)) mstore(0x20, add(shr(255, vs), 27)) // `v`. mstore(0x60, shr(1, shl(1, vs))) // `s`. break } if eq(mload(signature), 65) { mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`. mstore(0x60, mload(add(signature, 0x40))) // `s`. break } result := 0 break } pop( staticcall( gas(), // Amount of gas left for the transaction. result, // Address of `ecrecover`. 0x00, // Start of input. 0x80, // Size of input. 0x40, // Start of output. 0x20 // Size of output. ) ) mstore(0x60, 0) // Restore the zero slot. // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. result := mload(xor(0x60, returndatasize())) mstore(0x40, m) // Restore the free memory pointer. } } /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`. function tryRecoverCalldata(bytes32 hash, bytes calldata signature) internal view returns (address result) { /// @solidity memory-safe-assembly assembly { result := 1 let m := mload(0x40) // Cache the free memory pointer. mstore(0x00, hash) for {} 1 {} { if eq(signature.length, 64) { let vs := calldataload(add(signature.offset, 0x20)) mstore(0x20, add(shr(255, vs), 27)) // `v`. mstore(0x40, calldataload(signature.offset)) // `r`. mstore(0x60, shr(1, shl(1, vs))) // `s`. break } if eq(signature.length, 65) { mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`. calldatacopy(0x40, signature.offset, 0x40) // Copy `r` and `s`. break } result := 0 break } pop( staticcall( gas(), // Amount of gas left for the transaction. result, // Address of `ecrecover`. 0x00, // Start of input. 0x80, // Size of input. 0x40, // Start of output. 0x20 // Size of output. ) ) mstore(0x60, 0) // Restore the zero slot. // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. result := mload(xor(0x60, returndatasize())) mstore(0x40, m) // Restore the free memory pointer. } } /// @dev Recovers the signer's address from a message digest `hash`, /// and the EIP-2098 short form signature defined by `r` and `vs`. function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal view returns (address result) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x00, hash) mstore(0x20, add(shr(255, vs), 27)) // `v`. mstore(0x40, r) mstore(0x60, shr(1, shl(1, vs))) // `s`. pop( staticcall( gas(), // Amount of gas left for the transaction. 1, // Address of `ecrecover`. 0x00, // Start of input. 0x80, // Size of input. 0x40, // Start of output. 0x20 // Size of output. ) ) mstore(0x60, 0) // Restore the zero slot. // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. result := mload(xor(0x60, returndatasize())) mstore(0x40, m) // Restore the free memory pointer. } } /// @dev Recovers the signer's address from a message digest `hash`, /// and the signature defined by `v`, `r`, `s`. function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal view returns (address result) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x00, hash) mstore(0x20, and(v, 0xff)) mstore(0x40, r) mstore(0x60, s) pop( staticcall( gas(), // Amount of gas left for the transaction. 1, // Address of `ecrecover`. 0x00, // Start of input. 0x80, // Size of input. 0x40, // Start of output. 0x20 // Size of output. ) ) mstore(0x60, 0) // Restore the zero slot. // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise. result := mload(xor(0x60, returndatasize())) mstore(0x40, m) // Restore the free memory pointer. } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* HASHING OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns an Ethereum Signed Message, created from a `hash`. /// This produces a hash corresponding to the one signed with the /// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign) /// JSON-RPC method as part of EIP-191. function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 result) { /// @solidity memory-safe-assembly assembly { mstore(0x20, hash) // Store into scratch space for keccak256. mstore(0x00, "\x00\x00\x00\x00\x19Ethereum Signed Message:\n32") // 28 bytes. result := keccak256(0x04, 0x3c) // `32 * 2 - (32 - 28) = 60 = 0x3c`. } } /// @dev Returns an Ethereum Signed Message, created from `s`. /// This produces a hash corresponding to the one signed with the /// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign) /// JSON-RPC method as part of EIP-191. /// Note: Supports lengths of `s` up to 999999 bytes. function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32 result) { /// @solidity memory-safe-assembly assembly { let sLength := mload(s) let o := 0x20 mstore(o, "\x19Ethereum Signed Message:\n") // 26 bytes, zero-right-padded. mstore(0x00, 0x00) // Convert the `s.length` to ASCII decimal representation: `base10(s.length)`. for { let temp := sLength } 1 {} { o := sub(o, 1) mstore8(o, add(48, mod(temp, 10))) temp := div(temp, 10) if iszero(temp) { break } } let n := sub(0x3a, o) // Header length: `26 + 32 - o`. // Throw an out-of-offset error (consumes all gas) if the header exceeds 32 bytes. returndatacopy(returndatasize(), returndatasize(), gt(n, 0x20)) mstore(s, or(mload(0x00), mload(n))) // Temporarily store the header. result := keccak256(add(s, sub(0x20, n)), add(n, sLength)) mstore(s, sLength) // Restore the length. } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* EMPTY CALLDATA HELPERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns an empty calldata bytes. function emptySignature() internal pure returns (bytes calldata signature) { /// @solidity memory-safe-assembly assembly { signature.length := 0 } } }
// SPDX-License-Identifier: MIT /// @custom:version 1.0.0 pragma solidity ^0.8.17; error AlreadyInitialized(); error CannotAuthoriseSelf(); error CannotBridgeToSameNetwork(); error ContractCallNotAllowed(); error CumulativeSlippageTooHigh(uint256 minAmount, uint256 receivedAmount); error DiamondIsPaused(); error ExternalCallFailed(); error FunctionDoesNotExist(); error InformationMismatch(); error InsufficientBalance(uint256 required, uint256 balance); error InvalidAmount(); error InvalidCallData(); error InvalidConfig(); error InvalidContract(); error InvalidDestinationChain(); error InvalidFallbackAddress(); error InvalidReceiver(); error InvalidSendingToken(); error NativeAssetNotSupported(); error NativeAssetTransferFailed(); error NoSwapDataProvided(); error NoSwapFromZeroBalance(); error NotAContract(); error NotInitialized(); error NoTransferToNullAddress(); error NullAddrIsNotAnERC20Token(); error NullAddrIsNotAValidSpender(); error OnlyContractOwner(); error RecoveryAddressCannotBeZero(); error ReentrancyError(); error TokenNotSupported(); error UnAuthorized(); error UnsupportedChainId(uint256 chainId); error WithdrawFailed(); error ZeroAmount();
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to * 0 before setting it to a non-zero value. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT /// @custom:version 1.0.0 pragma solidity ^0.8.17; library LibBytes { // solhint-disable no-inline-assembly // LibBytes specific errors error SliceOverflow(); error SliceOutOfBounds(); error AddressOutOfBounds(); bytes16 private constant _SYMBOLS = "0123456789abcdef"; // ------------------------- function slice( bytes memory _bytes, uint256 _start, uint256 _length ) internal pure returns (bytes memory) { if (_length + 31 < _length) revert SliceOverflow(); if (_bytes.length < _start + _length) revert SliceOutOfBounds(); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add( add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)) ) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add( add( add(_bytes, lengthmod), mul(0x20, iszero(lengthmod)) ), _start ) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress( bytes memory _bytes, uint256 _start ) internal pure returns (address) { if (_bytes.length < _start + 20) { revert AddressOutOfBounds(); } address tempAddress; assembly { tempAddress := div( mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000 ) } return tempAddress; } /// Copied from OpenZeppelin's `Strings.sol` utility library. /// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/8335676b0e99944eef6a742e16dcd9ff6e68e609/contracts/utils/Strings.sol function toHexString( uint256 value, uint256 length ) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
// SPDX-License-Identifier: MIT /// @custom:version 1.0.0 pragma solidity ^0.8.17; import { InvalidContract } from "../Errors/GenericErrors.sol"; /// @title Lib Allow List /// @author LI.FI (https://li.fi) /// @notice Library for managing and accessing the conract address allow list library LibAllowList { /// Storage /// bytes32 internal constant NAMESPACE = keccak256("com.lifi.library.allow.list"); struct AllowListStorage { mapping(address => bool) allowlist; mapping(bytes4 => bool) selectorAllowList; address[] contracts; } /// @dev Adds a contract address to the allow list /// @param _contract the contract address to add function addAllowedContract(address _contract) internal { _checkAddress(_contract); AllowListStorage storage als = _getStorage(); if (als.allowlist[_contract]) return; als.allowlist[_contract] = true; als.contracts.push(_contract); } /// @dev Checks whether a contract address has been added to the allow list /// @param _contract the contract address to check function contractIsAllowed( address _contract ) internal view returns (bool) { return _getStorage().allowlist[_contract]; } /// @dev Remove a contract address from the allow list /// @param _contract the contract address to remove function removeAllowedContract(address _contract) internal { AllowListStorage storage als = _getStorage(); if (!als.allowlist[_contract]) { return; } als.allowlist[_contract] = false; uint256 length = als.contracts.length; // Find the contract in the list for (uint256 i = 0; i < length; i++) { if (als.contracts[i] == _contract) { // Move the last element into the place to delete als.contracts[i] = als.contracts[length - 1]; // Remove the last element als.contracts.pop(); break; } } } /// @dev Fetch contract addresses from the allow list function getAllowedContracts() internal view returns (address[] memory) { return _getStorage().contracts; } /// @dev Add a selector to the allow list /// @param _selector the selector to add function addAllowedSelector(bytes4 _selector) internal { _getStorage().selectorAllowList[_selector] = true; } /// @dev Removes a selector from the allow list /// @param _selector the selector to remove function removeAllowedSelector(bytes4 _selector) internal { _getStorage().selectorAllowList[_selector] = false; } /// @dev Returns if selector has been added to the allow list /// @param _selector the selector to check function selectorIsAllowed(bytes4 _selector) internal view returns (bool) { return _getStorage().selectorAllowList[_selector]; } /// @dev Fetch local storage struct function _getStorage() internal pure returns (AllowListStorage storage als) { bytes32 position = NAMESPACE; // solhint-disable-next-line no-inline-assembly assembly { als.slot := position } } /// @dev Contains business logic for validating a contract address. /// @param _contract address of the dex to check function _checkAddress(address _contract) private view { if (_contract == address(0)) revert InvalidContract(); if (_contract.code.length == 0) revert InvalidContract(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
{ "viaIR": false, "remappings": [ "@eth-optimism/=node_modules/@hop-protocol/sdk/node_modules/@eth-optimism/", "@uniswap/=node_modules/@uniswap/", "eth-gas-reporter/=node_modules/eth-gas-reporter/", "hardhat/=node_modules/hardhat/", "hardhat-deploy/=node_modules/hardhat-deploy/", "@openzeppelin/=lib/openzeppelin-contracts/", "celer-network/=lib/sgn-v2-contracts/", "create3-factory/=lib/create3-factory/src/", "solmate/=lib/solmate/src/", "solady/=lib/solady/src/", "permit2/=lib/Permit2/src/", "ds-test/=lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "lifi/=src/", "test/=test/", "Permit2/=lib/Permit2/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-gas-snapshot/=lib/Permit2/lib/forge-gas-snapshot/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "openzeppelin/=lib/openzeppelin-contracts/contracts/", "sgn-v2-contracts/=lib/sgn-v2-contracts/contracts/" ], "evmVersion": "shanghai", "outputSelection": { "*": { "*": [ "abi" ] } }, "optimizer": { "enabled": true, "mode": "3", "fallback_to_optimizing_for_size": false, "disable_system_request_memoization": true }, "metadata": {}, "libraries": {}, "detectMissingLibraries": false, "enableEraVMExtensions": false, "forceEVMLA": false }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_relayReceiver","type":"address"},{"internalType":"address","name":"_relaySolver","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CannotBridgeToSameNetwork","type":"error"},{"inputs":[],"name":"ContractCallNotAllowed","type":"error"},{"inputs":[{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"uint256","name":"receivedAmount","type":"uint256"}],"name":"CumulativeSlippageTooHigh","type":"error"},{"inputs":[],"name":"InformationMismatch","type":"error"},{"inputs":[{"internalType":"uint256","name":"required","type":"uint256"},{"internalType":"uint256","name":"balance","type":"uint256"}],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidContract","type":"error"},{"inputs":[],"name":"InvalidQuote","type":"error"},{"inputs":[],"name":"InvalidReceiver","type":"error"},{"inputs":[],"name":"NativeAssetTransferFailed","type":"error"},{"inputs":[],"name":"NoSwapDataProvided","type":"error"},{"inputs":[],"name":"NoSwapFromZeroBalance","type":"error"},{"inputs":[],"name":"NoTransferToNullAddress","type":"error"},{"inputs":[],"name":"NullAddrIsNotAValidSpender","type":"error"},{"inputs":[],"name":"NullAddrIsNotAnERC20Token","type":"error"},{"inputs":[],"name":"ReentrancyError","type":"error"},{"inputs":[],"name":"SliceOutOfBounds","type":"error"},{"inputs":[],"name":"SliceOverflow","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"transactionId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"dex","type":"address"},{"indexed":false,"internalType":"address","name":"fromAssetId","type":"address"},{"indexed":false,"internalType":"address","name":"toAssetId","type":"address"},{"indexed":false,"internalType":"uint256","name":"fromAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"AssetSwapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"transactionId","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"receiver","type":"bytes32"}],"name":"BridgeToNonEVMChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"transactionId","type":"bytes32"},{"indexed":false,"internalType":"string","name":"integrator","type":"string"},{"indexed":false,"internalType":"string","name":"referrer","type":"string"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"address","name":"fromAssetId","type":"address"},{"indexed":false,"internalType":"address","name":"toAssetId","type":"address"},{"indexed":false,"internalType":"uint256","name":"fromAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toAmount","type":"uint256"}],"name":"LiFiGenericSwapCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"transactionId","type":"bytes32"},{"indexed":false,"internalType":"string","name":"integrator","type":"string"},{"indexed":false,"internalType":"string","name":"referrer","type":"string"},{"indexed":false,"internalType":"address","name":"fromAssetId","type":"address"},{"indexed":false,"internalType":"address","name":"toAssetId","type":"address"},{"indexed":false,"internalType":"uint256","name":"fromAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toAmount","type":"uint256"}],"name":"LiFiSwappedGeneric","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"transactionId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"receivingAssetId","type":"address"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"LiFiTransferCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"transactionId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"receivingAssetId","type":"address"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"LiFiTransferRecovered","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"bytes32","name":"transactionId","type":"bytes32"},{"internalType":"string","name":"bridge","type":"string"},{"internalType":"string","name":"integrator","type":"string"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"address","name":"sendingAssetId","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"bool","name":"hasSourceSwaps","type":"bool"},{"internalType":"bool","name":"hasDestinationCall","type":"bool"}],"indexed":false,"internalType":"struct ILiFi.BridgeData","name":"bridgeData","type":"tuple"}],"name":"LiFiTransferStarted","type":"event"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"consumedIds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"relayReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"relaySolver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"transactionId","type":"bytes32"},{"internalType":"string","name":"bridge","type":"string"},{"internalType":"string","name":"integrator","type":"string"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"address","name":"sendingAssetId","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"bool","name":"hasSourceSwaps","type":"bool"},{"internalType":"bool","name":"hasDestinationCall","type":"bool"}],"internalType":"struct ILiFi.BridgeData","name":"_bridgeData","type":"tuple"},{"components":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"bytes32","name":"nonEVMReceiver","type":"bytes32"},{"internalType":"bytes32","name":"receivingAssetId","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct RelayFacet.RelayData","name":"_relayData","type":"tuple"}],"name":"startBridgeTokensViaRelay","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"transactionId","type":"bytes32"},{"internalType":"string","name":"bridge","type":"string"},{"internalType":"string","name":"integrator","type":"string"},{"internalType":"address","name":"referrer","type":"address"},{"internalType":"address","name":"sendingAssetId","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"bool","name":"hasSourceSwaps","type":"bool"},{"internalType":"bool","name":"hasDestinationCall","type":"bool"}],"internalType":"struct ILiFi.BridgeData","name":"_bridgeData","type":"tuple"},{"components":[{"internalType":"address","name":"callTo","type":"address"},{"internalType":"address","name":"approveTo","type":"address"},{"internalType":"address","name":"sendingAssetId","type":"address"},{"internalType":"address","name":"receivingAssetId","type":"address"},{"internalType":"uint256","name":"fromAmount","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"bool","name":"requiresDeposit","type":"bool"}],"internalType":"struct LibSwap.SwapData[]","name":"_swapData","type":"tuple[]"},{"components":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"bytes32","name":"nonEVMReceiver","type":"bytes32"},{"internalType":"bytes32","name":"receivingAssetId","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct RelayFacet.RelayData","name":"_relayData","type":"tuple"}],"name":"swapAndStartBridgeTokensViaRelay","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
3cda3351f80238b9d7eca92938cbb888bd170919e845ac3cd617d567848b1ed9fae779d301000609a99802f1144244ec121f0343eb1c7d60ce5816916c4addba12b7769100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000040000000000000000000000000634e831ce6d460c2cd5067af98d6452eb280e374000000000000000000000000f70da97812cb96acdf810712aa562db8dfa3dbef
Deployed Bytecode
0x0004000000000002002300000000000200000000030100190000006004300270000005ab0340019700030000003103550002000000010355000005ab0040019d00000001002001900000002b0000c13d0000008002000039000000400020043f000000040030008c000000a20000413d000000000201043b000000e002200270000005b00020009c0000005d0000a13d000005b10020009c0000006c0000613d000005b20020009c0000007d0000613d000005b30020009c000000a20000c13d000000240030008c000000a20000413d0000000002000416000000000002004b000000a20000c13d0000000401100370000000000101043b000000000010043f000000200000043f0000004002000039000000000100001916a9166c0000040f000000000101041a000000ff001001900000000001000039000000010100c039000000800010043f000005b601000041000016aa0001042e0000000002000416000000000002004b000000a20000c13d0000001f02300039000005ac02200197000000c002200039000000400020043f0000001f0430018f000005ad05300198000000c0025000390000003c0000613d000000c006000039000000000701034f000000007807043c0000000006860436000000000026004b000000380000c13d000000000004004b000000490000613d000000000151034f0000000304400210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000120435000000400030008c000000a20000413d000000c00100043d000005ae0010009c000000a20000213d000000e00200043d000005ae0020009c000000a20000213d000000800010043f000000a00020043f0000014000000443000001600010044300000020010000390000018000100443000001a000200443000001000010044300000002010000390000012000100443000005af01000041000016aa0001042e000005b40020009c0000009c0000613d000005b50020009c000000a20000c13d0000000001000416000000000001004b000000a20000c13d0000000001000412001f00000001001d001e00200000003d0000800501000039000000440300003900000000040004150000001f0440008a000000760000013d0000000001000416000000000001004b000000a20000c13d0000000001000412001d00000001001d001c00000000003d0000800501000039000000440300003900000000040004150000001d0440008a0000000504400210000005c90200004116a916810000040f000005ae01100197000000800010043f000005b601000041000016aa0001042e000000440030008c000000a20000413d0000000402100370000000000202043b000005b70020009c000000a20000213d0000000004230049000005b80040009c000000a20000213d000001440040008c000000a20000413d0000002404100370000000000404043b001b00000004001d000005b70040009c000000a20000213d0000001b04000029001a00040040003d0000001a0430006a000005b80040009c000000a20000213d000000800040008c000000a20000413d000005b904000041000000000504041a000000010050008c000000c80000c13d000005e701000041000000000010043f000005dc01000041000016ab00010430000000640030008c000000a20000413d0000000402100370000000000202043b000005b70020009c000000a40000a13d0000000001000019000016ab0001043000000004022000390000000004230049000005b80040009c000000a20000213d000001400040008c000000a20000413d000001c004000039000000400040043f000000000521034f000000000505043b000000800050043f0000002005200039000000000651034f000000000606043b000005b70060009c000000a20000213d00000000072600190000001f06700039000000000036004b000000a20000813d000000000671034f000000000606043b000005b70060009c000000c20000213d0000001f08600039000005e8088001970000003f08800039000005e808800197000005ba0080009c000001a00000a13d000005d801000041000000000010043f0000004101000039000000040010043f000005cf01000041000016ab0001043000000004022000390000000105000039001800000005001d000000000054041b001900000002001d0000000002230049000005b80020009c000000a20000213d000001400020008c000000a20000413d000001c002000039000000400020043f0000001905000029000000000451034f000000000404043b000000800040043f001700200050003d0000001704100360000000000404043b000005b70040009c000000a20000213d00000019054000290000001f04500039000000000034004b000000a20000813d000000000451034f000000000404043b000005b70040009c000000c20000213d0000001f06400039000005e8066001970000003f06600039000005e806600197000005ba0060009c000000c20000213d0000002005500039000001c006600039000000400060043f000001c00040043f0000000006540019000000000036004b000000a20000213d000000000651034f000005e8074001980000001f0840018f000001e005700039000000fd0000613d000001e009000039000000000a06034f00000000ab0a043c0000000009b90436000000000059004b000000f90000c13d000000000008004b0000010a0000613d000000000676034f0000000307800210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000001e0044000390000000000040435000000a00020043f0000001702000029001600200020003d0000001602100360000000000202043b000005b70020009c000000a20000213d00000019052000290000001f02500039000000000032004b000000a20000813d000000000251034f000000000202043b000005b70020009c000000c20000213d0000001f04200039000005e8044001970000003f04400039000005e806400197000000400400043d0000000006640019000000000046004b00000000070000390000000107004039000005b70060009c000000c20000213d0000000100700190000000c20000c13d0000002007500039000000400060043f00000000052404360000000006720019000000000036004b000000a20000213d000000000671034f000005e8072001980000001f0820018f0000000003750019000001390000613d000000000906034f000000000a050019000000009b09043c000000000aba043600000000003a004b000001350000c13d000000000008004b000001460000613d000000000676034f0000000307800210000000000803043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f000000000063043500000000022500190000000000020435000000c00040043f0000001602000029001500200020003d0000001502100360000000000202043b000005ae0020009c000000a20000213d000000e00020043f0000001502000029001400200020003d0000001402100360000000000202043b000005ae0020009c000000a20000213d000001000020043f0000001402000029001300200020003d0000001302100360000000000202043b000005ae0020009c000000a20000213d000001200020043f0000001303000029001100200030003d0000001102100360000000000202043b000001400020043f001000400030003d0000001002100360000000000202043b000001600020043f001200600030003d0000001202100360000000000202043b000000000002004b0000000003000039000000010300c039000000000032004b000000a20000c13d000001800020043f0000001202000029000f00200020003d0000000f02100360000000000202043b000000000002004b0000000003000039000000010300c039000000000032004b000000a20000c13d000001a00020043f0000001a01100360000000000101043b000e00000001001d000000000010043f000000200000043f0000000001000414000005ab0010009c000005ab01008041000000c001100210000005bb011001c7000080100200003916a916a40000040f0000000100200190000000a20000613d000000000101043b000000000101041a000000ff00100190000002750000c13d000001200100043d000005ae01100197000d00000001001d000005bc0010009c000001970000c13d0000001a0100002900000020011000390000000201100367000000000101043b000000000001004b000002750000613d000001600100043d000c00000001001d000005be0010009c000002790000613d0000000c01000029000005bf0010009c0000027b0000c13d000005c0010000410000027a0000013d0000002007700039000001c008800039000000400080043f000001c00060043f0000000008760019000000000038004b000000a20000213d000000000871034f000005e8096001980000001f0a60018f000001e007900039000001b20000613d000001e00b000039000000000c08034f00000000cd0c043c000000000bdb043600000000007b004b000001ae0000c13d00000000000a004b000001bf0000613d000000000898034f0000000309a00210000000000a070433000000000a9a01cf000000000a9a022f000000000808043b0000010009900089000000000898022f00000000089801cf0000000008a8019f0000000000870435000001e0066000390000000000060435000000a00040043f0000002004500039000000000541034f000000000505043b000005b70050009c000000a20000213d00000000062500190000001f02600039000000000032004b000000a20000813d000000000261034f000000000202043b000005b70020009c000000c20000213d0000001f05200039000005e8055001970000003f05500039000005e807500197000000400500043d0000000007750019000000000057004b00000000080000390000000108004039000005b70070009c000000c20000213d0000000100800190000000c20000c13d0000002008600039000000400070043f00000000062504360000000007820019000000000037004b000000a20000213d000000000881034f000005e8092001980000001f0a20018f0000000007960019000001ed0000613d000000000b08034f000000000c06001900000000bd0b043c000000000cdc043600000000007c004b000001e90000c13d00000000000a004b000001fa0000613d000000000898034f0000000309a00210000000000a070433000000000a9a01cf000000000a9a022f000000000808043b0000010009900089000000000898022f00000000089801cf0000000008a8019f000000000087043500000000022600190000000000020435000000c00050043f0000002002400039000000000421034f000000000404043b000005ae0040009c000000a20000213d000000e00040043f0000002002200039000000000421034f000000000404043b000005ae0040009c000000a20000213d000001000040043f0000002002200039000000000421034f000000000404043b000005ae0040009c000000a20000213d000001200040043f0000002004200039000000000441034f000000000404043b000001400040043f0000004004200039000000000441034f000000000404043b000001600040043f0000006002200039000000000421034f000000000404043b000000000004004b0000000005000039000000010500c039000000000054004b000000a20000c13d000001800040043f0000002002200039000000000221034f000000000202043b000000000002004b0000000004000039000000010400c039000000000042004b000000a20000c13d000001a00020043f0000002402100370000000000202043b001a00000002001d000005b70020009c000000a20000213d0000001a020000290000002302200039000000000032004b000000a20000813d0000001a020000290000000402200039000000000221034f000000000202043b001900000002001d000005b70020009c000000a20000213d0000001a02000029000000240220003900000019040000290000000504400210001800000002001d001700000004001d0000000002240019000000000032004b000000a20000213d0000004401100370000000000101043b001600000001001d000005b70010009c000000a20000213d0000001601000029001500040010003d000000150130006a000005b80010009c000000a20000213d000000800010008c000000a20000413d0000000001000415001400000001001d000005b901000041000000000201041a000000010020008c000000980000613d0000000102000039001b00000002001d000000000021041b00000015010000290000000201100367000000000101043b001300000001001d000000000010043f000000200000043f0000000001000414000005ab0010009c000005ab01008041000000c001100210000005bb011001c7000080100200003916a916a40000040f0000000100200190000000a20000613d000000000101043b000000000101041a000000ff00100190000002750000c13d000001200100043d000005ae01100197001200000001001d000005bc0010009c0000033d0000c13d000000150100002900000020011000390000000201100367000000000101043b000000000001004b0000033d0000c13d000005e601000041000000000010043f000005dc01000041000016ab00010430000005bd01000041000c00000001001d000001000100043d000a00000001001d00000002010003670000000d02000029000005bc0020009c000002860000c13d0000001a020000290000002002200039000000000221034f000000000202043b000d00000002001d0000001a02000029000800400020003d0000000801100360000000000101043b000900000001001d000000400100043d000b00000001001d000005c10100004100000000001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005c2011001c70000800b0200003916a916a40000040f000000010020019000000ed00000613d0000000a02000029000005ae0320019700000000050004100000000b070000290000002002700039000000000101043b0000000e040000290000000000420435000000e00470003900000009060000290000000000640435000000c0047000390000000d060000290000000000640435000000a0047000390000000c060000290000000000640435000000800470003900000000003404350000006003700039000000000053043500000040037000390000000000130435000000e0010000390000000000170435000005c30070009c000000c20000213d0000000b030000290000010001300039000000400010043f000005ab0020009c000005ab0200804100000040012002100000000002030433000005ab0020009c000005ab020080410000006002200210000000000112019f0000000002000414000005ab0020009c000005ab02008041000000c002200210000000000112019f000005c4011001c7000080100200003916a916a40000040f0000000100200190000000a20000613d000000000101043b000000200010043f000005c501000041000000000010043f0000000001000414000005ab0010009c000005ab01008041000000c001100210000005c6011001c7000080100200003916a916a40000040f0000000100200190000000a20000613d000000080200002900000020022000390000000204000367000000000224034f000000000202043b00000000050000310000001b0350006a000000230330008a000005c706300197000005c707200197000000000867013f000000000067004b0000000006000019000005c706004041000000000032004b0000000003000019000005c703008041000005c70080009c000000000603c019000000000101043b000000000006004b000000a20000c13d0000001a03200029000000000234034f000000000202043b000005b70020009c000000a20000213d00000000062500490000002007300039000005c703600197000005c708700197000000000938013f000000000038004b0000000003000019000005c703004041000000000067004b0000000006000019000005c706002041000005c70090009c000000000306c019000000000003004b000000a20000c13d0000001f03200039000005e8033001970000003f03300039000005e806300197000000400300043d0000000006630019000000000036004b00000000080000390000000108004039000005b70060009c000000c20000213d0000000100800190000000c20000c13d000000400060043f00000000062304360000000008720019000000000058004b000000a20000213d000000000574034f000005e8072001980000001f0820018f00000000047600190000031c0000613d000000000905034f000000000a060019000000009b09043c000000000aba043600000000004a004b000003180000c13d000000000008004b000003290000613d000000000575034f0000000307800210000000000804043300000000087801cf000000000878022f000000000505043b0000010007700089000000000575022f00000000057501cf000000000585019f000000000054043500000000022600190000000000020435000000400200043d001b00000002001d000000000010043f0000000001060433000000400010043f0000000001030433000000400010008c0000040a0000613d000000410010008c0000000002000019000004120000c13d00000060013000390000000001010433000000f801100270000000200010043f00000040013000390000000001010433000004100000013d000001600100043d001100000001001d000005be0010009c000003460000613d0000001101000029000005bf0010009c000003480000c13d000005c001000041000003470000013d000005bd01000041001100000001001d000001000100043d000f00000001001d00000002010003670000001202000029000005bc0020009c000003530000c13d00000015020000290000002002200039000000000221034f000000000202043b001200000002001d0000001502000029000d00400020003d0000000d01100360000000000101043b000e00000001001d000000400100043d001000000001001d000005c10100004100000000001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005c2011001c70000800b0200003916a916a40000040f000000010020019000000ed00000613d0000000f02000029000005ae03200197000000000500041000000010070000290000002002700039000000000101043b00000013040000290000000000420435000000e0047000390000000e060000290000000000640435000000c00470003900000012060000290000000000640435000000a00470003900000011060000290000000000640435000000800470003900000000003404350000006003700039000000000053043500000040037000390000000000130435000000e0010000390000000000170435000005c30070009c000000c20000213d00000010030000290000010001300039000000400010043f000005ab0020009c000005ab0200804100000040012002100000000002030433000005ab0020009c000005ab020080410000006002200210000000000112019f0000000002000414000005ab0020009c000005ab02008041000000c002200210000000000112019f000005c4011001c7000080100200003916a916a40000040f0000000100200190000000a20000613d000000000101043b000000200010043f000005c501000041000000000010043f0000000001000414000005ab0010009c000005ab01008041000000c001100210000005c6011001c7000080100200003916a916a40000040f0000000100200190000000a20000613d0000000d0200002900000020022000390000000204000367000000000224034f000000000202043b0000000005000031000000160350006a000000230330008a000005c706300197000005c707200197000000000867013f000000000067004b0000000006000019000005c706004041000000000032004b0000000003000019000005c703008041000005c70080009c000000000603c019000000000101043b000000000006004b000000a20000c13d0000001503200029000000000234034f000000000202043b000005b70020009c000000a20000213d00000000062500490000002007300039000005c703600197000005c708700197000000000938013f000000000038004b0000000003000019000005c703004041000000000067004b0000000006000019000005c706002041000005c70090009c000000000306c019000000000003004b000000a20000c13d0000001f03200039000005e8033001970000003f03300039000005e806300197000000400300043d0000000006630019000000000036004b00000000080000390000000108004039000005b70060009c000000c20000213d0000000100800190000000c20000c13d000000400060043f00000000062304360000000008720019000000000058004b000000a20000213d000000000574034f000005e8072001980000001f0820018f0000000004760019000003e90000613d000000000905034f000000000a060019000000009b09043c000000000aba043600000000004a004b000003e50000c13d000000000008004b000003f60000613d000000000575034f0000000307800210000000000804043300000000087801cf000000000878022f000000000505043b0000010007700089000000000575022f00000000057501cf000000000585019f000000000054043500000000022600190000000000020435000000400200043d001600000002001d000000000010043f0000000001060433000000400010043f0000000001030433000000400010008c000006830000613d000000410010008c00000000020000190000068b0000c13d00000060013000390000000001010433000000f801100270000000200010043f00000040013000390000000001010433000006890000013d00000040013000390000000001010433000000ff021002700000001b02200039000000200020043f000005b801100197000000600010043f00000001020000390000000001000414000005ab0010009c000005ab01008041000000c001100210000005c8011001c716a916a40000040f00000000030100190000006003300270000005ab03300197000000200030008c000000200400003900000000040340190000001f0540018f000000200640019000000001046001bf000004290000613d000000000701034f000000007807043c00000018090000290000000009890436001800000009001d000000000049004b000004230000c13d000000000005004b000004360000613d000000000661034f0000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f00000000005404350003000000010355000100000003001f000000000003004b000006b30000613d000000010120018f0000000001010433001800000001001d000000600000043f0000001b01000029000000400010043f000005c901000041000000000010044300000000010004120000000400100443000000200100003900000024001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005ca011001c7000080050200003916a916a40000040f000000010020019000000ed00000613d000000000101043b000000180110014f000005ae00100198000002750000c13d000005cb010000410000000000100443000000000100041000000004001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005cc011001c70000800a0200003916a916a40000040f000000010020019000000ed00000613d000000000101043b0000000002000416001b00000021005300000e860000413d0000000003000031000000190130006a000005b80010009c000000a20000213d000001400010008c000000a20000413d000000400100043d000005cd0010009c000000c20000213d0000014002100039000000400020043f00000002020003670000001904200360000000000404043b00000000054104360000001704200360000000000404043b000005b70040009c000000a20000213d00000019084000290000001f04800039000000000034004b0000000006000019000005c706008041000005c707400197000005c704300197000000000947013f000000000047004b0000000007000019000005c707004041000005c70090009c000000000706c019000000000007004b000000a20000c13d000000000682034f000000000606043b000005b70060009c000000c20000213d0000001f07600039000005e8077001970000003f07700039000005e809700197000000400700043d0000000009970019000000000079004b000000000a000039000000010a004039000005b70090009c000000c20000213d0000000100a00190000000c20000c13d000000200a800039000000400090043f00000000086704360000000009a60019000000000039004b000000a20000213d000000000aa2034f000005e80b6001980000001f0c60018f0000000009b80019000004a80000613d000000000d0a034f000000000e08001900000000df0d043c000000000efe043600000000009e004b000004a40000c13d00000000000c004b000004b50000613d000000000aba034f000000030bc00210000000000c090433000000000cbc01cf000000000cbc022f000000000a0a043b000001000bb00089000000000aba022f000000000aba01cf000000000aca019f0000000000a904350000000006680019000000000006043500000000007504350000001605200360000000000505043b000005b70050009c000000a20000213d00000019065000290000001f05600039000000000035004b0000000007000019000005c707008041000005c705500197000000000845013f000000000045004b0000000004000019000005c704004041000005c70080009c000000000407c019000000000004004b000000a20000c13d000000000462034f000000000404043b000005b70040009c000000c20000213d0000001f05400039000005e8055001970000003f05500039000005e807500197000000400500043d0000000007750019000000000057004b00000000080000390000000108004039000005b70070009c000000c20000213d0000000100800190000000c20000c13d0000002008600039000000400070043f00000000064504360000000007840019000000000037004b000000a20000213d000000000782034f000005e8084001980000001f0940018f0000000003860019000004ec0000613d000000000a07034f000000000b06001900000000ac0a043c000000000bcb043600000000003b004b000004e80000c13d000000000009004b000004f90000613d000000000787034f0000000308900210000000000903043300000000098901cf000000000989022f000000000707043b0000010008800089000000000787022f00000000078701cf000000000797019f000000000073043500000000034600190000000000030435000000400310003900000000005304350000001503200360000000000303043b000005ae0030009c000000a20000213d000000600410003900000000003404350000001403200360000000000303043b000005ae0030009c000000a20000213d000000800410003900000000003404350000001303200360000000000303043b000005ae0030009c000000a20000213d000000a00410003900000000003404350000001104200360000000000404043b000000c00510003900000000004504350000001005200360000000000605043b000000e005100039001800000006001d00000000006504350000001205200360000000000505043b000000000005004b0000000006000039000000010600c039000000000065004b000000a20000c13d000001000610003900000000005604350000000f02200360000000000202043b000000000002004b0000000005000039000000010500c039000000000052004b000000a20000c13d00000120011000390000000000210435000000000003004b000006ea0000613d000000000004004b00000b870000613d000005c10100004100000000001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005c2011001c70000800b0200003916a916a40000040f000000010020019000000ed00000613d000000000101043b000000180010006b000007170000613d0000001901000029000e0000000000350000000001100079000005b80010009c000000a20000213d000001400010008c000000a20000413d000000400300043d000005cd0030009c000000c20000213d0000014001300039000000400010043f0000000f02000029000001200120008a0000000205000367000000000115034f000000000101043b000600000001001d0000000008130436000001000720008a000000000175034f000000000101043b000005b70010009c000000a20000213d00000019061000290000001f016000390000000e02000029000000000021004b0000000004000019000005c704008041000005c709100197000005c701200197000000000a19013f000000000019004b0000000009000019000005c709004041000005c700a0009c000000000904c019000000000009004b000000a20000c13d000000000465034f000000000404043b000005b70040009c000000c20000213d0000001f09400039000005e8099001970000003f09900039000505e80090019b000000400900043d000000050a90002900000000009a004b000000000b000039000000010b004039000005b700a0009c000000c20000213d0000000100b00190000000c20000c13d00000020066000390000004000a0043f000000000a490436000000000b6400190000000e00b0006c000000a20000213d000000000665034f000005e80b400198000c001f00400193000a0000000b001d000000000cba0019000005860000613d000000000d06034f00000000db0d043c000000000aba04360000000000ca004b000005820000c13d0000000c02000029000000000002004b000b000a00600364000000030a200210000005950000613d000000000b0c0433000000000bab01cf000000000bab022f0000000b0200035f000000000d02043b000001000ea00089000000000ded022f000000000ded01cf000000000bbd019f0000000000bc0435000400200040003d000000040b90002900000000000b043500000000009804350000002007700039000000000875034f000000000808043b000005b70080009c000000a20000213d00000019088000290000001f098000390000000e0090006c000000000b000019000005c70b008041000005c709900197000000000c19013f000000000019004b0000000001000019000005c701004041000005c700c0009c00000000010bc019000000000001004b000000a20000c13d000000000185034f000000000d01043b000005b700d0009c000000c20000213d0000001f01d00039000005e8011001970000003f01100039000305e80010019b000000400100043d0000000309100029000000000019004b000000000c000039000000010c004039000005b70090009c000000c20000213d0000000100c00190000000c20000c13d0000002008800039000000400090043f0000000009d10436000000000b8d00190000000e00b0006c000000a20000213d000000000e85034f000005e80cd001980009001f00d001930000000008c90019000005cd0000613d000000000f0e034f00000000fb0f043c0000000009b90436000000000089004b000005c90000c13d0000000902000029000000000002004b0008000000ce03530000000309200210000005dc0000613d000000000b080433000000000b9b01cf000000000b9b022f000000080200035f000000000f02043b0000010002900089000000000f2f022f00000000022f01cf0000000002b2019f00000000002804350002002000d0003d00000002021000290000000000020435000000400230003900000000001204350000002001700039000000000215034f000000000202043b000700000002001d000005ae0020009c000000a20000213d0000006002300039000000070700002900000000007204350000002001100039000000000215034f000000000202043b001800000002001d000005ae0020009c000000a20000213d0000008002300039000000180700002900000000007204350000002007100039000000000175034f000000000801043b000005ae0080009c000000a20000213d000000a00130003900000000008104350000002001700039000000000115034f000000000201043b000000c001300039000d00000002001d00000000002104350000004001700039000000000115034f000000000201043b000000e001300039000100000002001d00000000002104350000006001700039000000000215034f000000000702043b000000000007004b0000000002000039000000010200c039000000000027004b000000a20000c13d000001000230003900000000007204350000002001100039000000000115034f000000000501043b000000000005004b0000000001000039000000010100c039000000000015004b000000a20000c13d00000120013000390000000000510435000000000007004b000006ee0000c13d000000400300043d000005cd0030009c000000c20000213d0000014001300039000000400010043f0000000601000029000000000f130436000000400700043d0000000501700029000000000071004b000000000b000039000000010b004039000005b70010009c000000c20000213d0000000100b00190000000c20000c13d000000400010043f00000000014704360000000a041000290000000a0000006b000006350000613d000000006206043c0000000001210436000000000041004b000006310000c13d0000000c0000006b000006410000613d00000000010404330000000001a101cf0000000001a1022f0000000b0200035f000000000202043b0000010006a00089000000000262022f00000000026201cf000000000112019f00000000001404350000000401700029000000000001043500000000007f0435000000400400043d0000000301400029000000000041004b00000000060000390000000106004039000005b70010009c000000c20000213d0000000100600190000000c20000c13d000000400010043f0000000001d404360000000006c1001900000000000c004b000006560000613d00000000e20e043c0000000001210436000000000061004b000006520000c13d000000090000006b000006620000613d000000000106043300000000019101cf000000000191022f000000080200035f000000000202043b0000010007900089000000000272022f00000000027201cf000000000112019f000000000016043500000002014000290000000000010435000000e00130003900000001020000290000000000210435000000c0013000390000000d020000290000000000210435000000a0013000390000000000810435000000800130003900000018020000290000000000210435000000600130003900000007020000290000000000210435000000400130003900000000004104350000012001300039000000000051043500000100013000390000000000010435000000000005004b000006ee0000c13d0000000d0000006b00000b870000613d000000180000006b000006f20000c13d00000000010004160000000d0010006c00000b870000413d000000400100043d000008790000013d00000040013000390000000001010433000000ff021002700000001b02200039000000200020043f000005b801100197000000600010043f00000001020000390000000001000414000005ab0010009c000005ab01008041000000c001100210000005c8011001c716a916a40000040f00000000030100190000006003300270000005ab03300197000000200030008c000000200400003900000000040340190000001f0540018f000000200640019000000001046001bf000006a20000613d000000000701034f000000007807043c0000001b090000290000000009890436001b00000009001d000000000049004b0000069c0000c13d000000000005004b000006af0000613d000000000661034f0000000305500210000000000704043300000000075701cf000000000757022f000000000606043b0000010005500089000000000656022f00000000055601cf000000000575019f00000000005404350003000000010355000100000003001f000000000003004b000006b70000c13d000005e401000041000000000010043f000005e501000041000016ab00010430000000010120018f0000000001010433001b00000001001d000000600000043f0000001601000029000000400010043f000005c901000041000000000010044300000000010004120000000400100443000000200100003900000024001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005ca011001c7000080050200003916a916a40000040f000000010020019000000ed00000613d000000000101043b0000001b0110014f000005ae00100198000002750000c13d000005cb010000410000000000100443000000000100041000000004001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005cc011001c70000800a0200003916a916a40000040f000000010020019000000ed00000613d000000000101043b0000000002000416000c00000021005300000e860000413d000001800100043d000000000001004b000006ee0000613d000001a00100043d000000000001004b000006ee0000c13d000001200100043d000005ae00100198000007040000c13d000005e201000041000000000010043f000005dc01000041000016ab00010430000005e301000041000000000010043f000005dc01000041000016ab00010430000000400300043d000005ce0100004100000000001304350000000001000411000005ae02100197000c00000003001d0000000401300039000b00000002001d000000000021043500000000010004140000001802000029000000040020008c0000071b0000c13d0000000103000031000000200030008c00000020040000390000000004034019000007470000013d000001400100043d000000000001004b00000b870000613d000001600100043d001b00000001001d000005c10100004100000000001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005c2011001c70000800b0200003916a916a40000040f000000010020019000000ed00000613d000000000101043b0000001b0010006b0000075e0000c13d000005e001000041000000000010043f000005dc01000041000016ab000104300000000c02000029000005ab0020009c000005ab020080410000004002200210000005ab0010009c000005ab01008041000000c001100210000000000121019f000005cf011001c7000000180200002916a916a40000040f00000000030100190000006003300270000005ab03300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000c05700029000007360000613d000000000801034f0000000c09000029000000008a08043c0000000009a90436000000000059004b000007320000c13d000000000006004b000007430000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000007640000613d0000001f01400039000000600110018f0000000c04100029000000000014004b00000000020000390000000102004039000e00000004001d000005b70040009c000000c20000213d0000000100200190000000c20000c13d0000000e02000029000000400020043f000000200030008c000000a20000413d0000000c0200002900000000020204330000000d0020006c000007700000813d000005d201000041000000000010043f0000000d0100002900000c3c0000013d000000190000006b000007770000c13d000005df01000041000000000010043f000005dc01000041000016ab000104300000001f0530018f000005ad06300198000000400200043d000000000462001900000e970000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000076b0000c13d00000e970000013d0000000002000410000c05ae0020019c000007b10000c13d000005db01000041000000000010043f000005dc01000041000016ab00010430000001400100043d000a00000001001d000000800100043d000700000001001d0000001901000029000000010110008a000800000001001d0000000501100210000600180010002d00000002010003670000000602100360000000000202043b0000001a030000290000000003300079000001030330008a000005c704200197000005c705300197000000000654013f000000000054004b0000000004000019000005c704004041000000000032004b0000000003000019000005c703008041000005c70060009c000000000403c019000000000004004b000000a20000c13d0000001a03000029001200840030003d0000001202200029000000000121034f000000000101043b000b00000001001d000005ae0010009c000000a20000213d0000000b0000006b000008160000c13d000005cb010000410000000000100443000000000100041000000004001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005cc011001c70000800a0200003916a916a40000040f000000010020019000000ed00000613d000000000101043b0000000002000416000900000021005300000e860000413d000000400100043d001300000001001d0000098e0000013d000005ce020000410000000e04000029000000000024043500000004024000390000000c04000029000000000042043500000000020004140000001804000029000000040040008c000007e90000613d0000000e01000029000005ab0010009c000005ab010080410000004001100210000005ab0020009c000005ab02008041000000c002200210000000000112019f000005cf011001c7000000180200002916a916a40000040f00000000030100190000006003300270000005ab03300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000e05700029000007d60000613d000000000801034f0000000e09000029000000008a08043c0000000009a90436000000000059004b000007d20000c13d000000000006004b000007e30000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000008270000613d0000001f01400039000000600110018f0000000e02100029000005b70020009c000000c20000213d000000400020043f000000200030008c000000a20000413d0000000e010000290000000001010433000a00000001001d0000002001200039000005d003000041000000000031043500000064012000390000000d03000029000000000031043500000044012000390000000c03000029000000000031043500000024012000390000000b03000029000000000031043500000064010000390000000000120435000005d10020009c000000c20000213d000000a001200039000000400010043f000000180100002916a9155e0000040f000005ce01000041000000400200043d0000000000120435000e00000002001d00000004012000390000000c02000029000000000021043500000000010004140000001802000029000000040020008c000008330000c13d0000000103000031000000200030008c000000200400003900000000040340190000085f0000013d000000400200043d000005ce0100004100000000001204350000000001000410000005ae01100197001b00000002001d0000000402200039000000000012043500000000010004140000000b02000029000000040020008c000009500000c13d0000000103000031000000200030008c000000200400003900000000040340190000097c0000013d0000001f0530018f000005ad06300198000000400200043d000000000462001900000e970000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000082e0000c13d00000e970000013d0000000e02000029000005ab0020009c000005ab020080410000004002200210000005ab0010009c000005ab01008041000000c001100210000000000121019f000005cf011001c7000000180200002916a916a40000040f00000000030100190000006003300270000005ab03300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000000e057000290000084e0000613d000000000801034f0000000e09000029000000008a08043c0000000009a90436000000000059004b0000084a0000c13d000000000006004b0000085b0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f0003000000010355000000010020019000000a420000613d0000001f01400039000000600210018f0000000e01200029000000000021004b00000000020000390000000102004039000005b70010009c000000c20000213d0000000100200190000000c20000c13d000000400010043f000000200030008c000000a20000413d0000000e0200002900000000020204330000000a0220006c00000e860000413d0000000d0020006c00000b870000c13d0000001902000029000e0000000000350000000003200079000005b80030009c000000a20000213d000001400030008c000000a20000413d000005cd0010009c000000c20000213d0000014002100039000000400020043f00000002030003670000001902300360000000000202043b00000000052104360000001702300360000000000402043b000005b70040009c000000a20000213d00000019084000290000001f028000390000000e04000029000000000042004b0000000006000019000005c706008041000005c702200197000005c704400197000000000742013f000000000042004b0000000002000019000005c702004041000005c70070009c000000000206c019000000000002004b000000a20000c13d000000000283034f000000000602043b000005b70060009c000000c20000213d0000001f02600039000005e8022001970000003f02200039000005e802200197000000400700043d0000000009270019000000000079004b000000000a000039000000010a004039000005b70090009c000000c20000213d0000000100a00190000000c20000c13d000000200a800039000000400090043f00000000086704360000000002a600190000000e0020006c000000a20000213d000000000aa3034f000005e80b6001980000001f0c60018f0000000009b80019000008b70000613d000000000d0a034f000000000e08001900000000d20d043c000000000e2e043600000000009e004b000008b30000c13d00000000000c004b000008c40000613d0000000002ba034f000000030ac00210000000000b090433000000000bab01cf000000000bab022f000000000202043b000001000aa000890000000002a2022f0000000002a201cf0000000002b2019f00000000002904350000000002680019000000000002043500000000007504350000001602300360000000000502043b000005b70050009c000000a20000213d00000019065000290000001f026000390000000e0020006c0000000005000019000005c705008041000005c702200197000000000742013f000000000042004b0000000002000019000005c702004041000005c70070009c000000000205c019000000000002004b000000a20000c13d000000000263034f000000000402043b000005b70040009c000000c20000213d0000001f02400039000005e8022001970000003f02200039000005e802200197000000400500043d0000000007250019000000000057004b00000000080000390000000108004039000005b70070009c000000c20000213d0000000100800190000000c20000c13d0000002008600039000000400070043f000000000645043600000000028400190000000e0020006c000000a20000213d000000000783034f000005e8084001980000001f0940018f0000000002860019000008fb0000613d000000000a07034f000000000b06001900000000ac0a043c000000000bcb043600000000002b004b000008f70000c13d000000000009004b000009080000613d000000000787034f0000000308900210000000000902043300000000098901cf000000000989022f000000000707043b0000010008800089000000000787022f00000000078701cf000000000797019f000000000072043500000000024600190000000000020435000000400210003900000000005204350000001502300360000000000202043b000005ae0020009c000000a20000213d000000600410003900000000002404350000001402300360000000000202043b000005ae0020009c000000a20000213d000000800410003900000000002404350000001302300360000000000202043b000005ae0020009c000000a20000213d000000a00410003900000000002404350000001102300360000000000202043b000000c00410003900000000002404350000001002300360000000000202043b000000e00410003900000000002404350000001202300360000000000202043b000000000002004b0000000004000039000000010400c039000000000042004b000000a20000c13d000001000410003900000000002404350000000f02300360000000000202043b000000000002004b0000000003000039000000010300c039000000000032004b000000a20000c13d000001200310003900000000002304350000001a0200002916a90ee60000040f000005cb010000410000000000100443000000000100041000000004001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005cc011001c70000800a0200003916a916a40000040f000000010020019000000ed00000613d000000000101043b0000001b0210006c0000094c0000a13d000000000100041116a910c20000040f000005b901000041000000000001041b0000000001000019000016aa0001042e0000001b02000029000005ab0020009c000005ab020080410000004002200210000005ab0010009c000005ab01008041000000c001100210000000000121019f000005cf011001c70000000b0200002916a916a40000040f00000000030100190000006003300270000005ab03300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000001b057000290000096b0000613d000000000801034f0000001b09000029000000008a08043c0000000009a90436000000000059004b000009670000c13d000000000006004b000009780000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f0003000000010355000000010020019000000a4e0000613d0000001f01400039000000600110018f0000001b02100029000000000012004b00000000010000390000000101004039001300000002001d000005b70020009c000000c20000213d0000000100100190000000c20000c13d0000001301000029000000400010043f000000200030008c000000a20000413d0000001b010000290000000001010433000900000001001d00000017010000290000003f01100039000005d4011001970000001301100029000000130010006c00000000020000390000000102004039000005b70010009c000000c20000213d0000000100200190000000c20000c13d000000400010043f000000190100002900000013020000290000000001120436001100000001001d00000017020000290000001f0120018f000000000002004b000009aa0000613d0000001104000029000000170240002900000000030000310000000203300367000000003503043c0000000004540436000000000024004b000009a60000c13d000000000001004b0000000001000410001005ae0010019b001b00000000001d000009b80000013d00000017010000290000000001010433000000160200002900000000001204350000001b020000290000000102200039001b00000002001d000000190020006c00000a5a0000813d0000001b01000029000000050110021000000018031000290000000202000367000000000332034f000000000303043b0000001a040000290000000004400079000001030440008a000005c705300197000005c706400197000000000765013f000000000065004b0000000005000019000005c705004041000000000043004b0000000004000019000005c704008041000005c70070009c000000000504c019000000000005004b000000a20000c13d0000001203300029000000000232034f000000000202043b000005ae0020009c000000a20000213d000000000002004b001600110010002d000009e50000613d000000400300043d000005ce010000410000000000130435001700000003001d0000000401300039000000100300002900000000003104350000000001000414000000040020008c00000a010000c13d0000000103000031000000200030008c0000002004000039000000000403401900000a2b0000013d000005cb010000410000000000100443000000000100041000000004001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005cc011001c70000800a0200003916a916a40000040f000000010020019000000ed00000613d000000000101043b000000130200002900000000020204330000001b0020006c00000a3c0000a13d00000016020000290000000000120435000000130200002900000000020204330000001b0020006c00000a3c0000a13d0000000002000416000000000121004b000009b10000813d00000e860000013d0000001703000029000005ab0030009c000005ab030080410000004003300210000005ab0010009c000005ab01008041000000c001100210000000000131019f000005cf011001c716a916a40000040f00000000030100190000006003300270000005ab03300197000000200030008c000000200400003900000000040340190000002006400190000000170560002900000a1a0000613d000000000701034f0000001708000029000000007907043c0000000008980436000000000058004b00000a160000c13d0000001f0740019000000a270000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f0003000000010355000000010020019000000b8b0000613d0000001f01400039000000600210018f0000001701200029000000000021004b00000000020000390000000102004039000005b70010009c000000c20000213d0000000100200190000000c20000c13d000000400010043f000000200030008c000000a20000413d000000130100002900000000010104330000001b0010006c000009af0000213d000005d801000041000000000010043f0000003201000039000000040010043f000005cf01000041000016ab000104300000001f0530018f000005ad06300198000000400200043d000000000462001900000e970000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00000a490000c13d00000e970000013d0000001f0530018f000005ad06300198000000400200043d000000000462001900000e970000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00000a550000c13d00000e970000013d0000000001000411000d05ae0010019b001700000000001d00000a660000013d00000000010004160000000f0010006c00000b870000413d00000017020000290000000102200039001700000002001d000000190020006c00000b970000813d0000001701000029000000050110021000000018021000290000000201000367000000000221034f000000000202043b0000001a030000290000000003300079000001030330008a000005c704200197000005c705300197000000000654013f000000000054004b0000000004000019000005c704004041000000000032004b0000000003000019000005c703008041000005c70060009c000000000403c019000000000004004b000000a20000c13d0000001802200029000000c003200039000000000331034f000000000303043b000000000003004b0000000004000039000000010400c039000000000043004b000000a20000c13d000000000003004b00000a610000613d0000004002200039000000000321034f000000000303043b001b00000003001d000005ae0030009c000000a20000213d0000004002200039000000000121034f000000000101043b000f00000001001d000000000001004b00000b870000613d0000001b0000006b00000a5e0000613d000000400200043d000005ce010000410000000000120435000e00000002001d00000004012000390000000d02000029000000000021043500000000010004140000001b02000029000000040020008c00000aa50000c13d0000000103000031000000200030008c0000002004000039000000000403401900000ad00000013d0000000e02000029000005ab0020009c000005ab020080410000004002200210000005ab0010009c000005ab01008041000000c001100210000000000121019f000005cf011001c70000001b0200002916a916a40000040f00000000030100190000006003300270000005ab03300197000000200030008c0000002004000039000000000403401900000020064001900000000e0560002900000abf0000613d000000000701034f0000000e08000029000000007907043c0000000008980436000000000058004b00000abb0000c13d0000001f0740019000000acc0000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f0003000000010355000000010020019000000c2d0000613d0000001f01400039000000600110018f0000000e04100029000000000014004b00000000020000390000000102004039001600000004001d000005b70040009c000000c20000213d0000000100200190000000c20000c13d0000001602000029000000400020043f000000200030008c000000a20000413d0000000e0200002900000000020204330000000f0020006c00000c390000413d000000100000006b000007730000613d000005ce020000410000001604000029000000000024043500000004024000390000001004000029000000000042043500000000020004140000001b04000029000000040040008c00000b1c0000613d0000001601000029000005ab0010009c000005ab010080410000004001100210000005ab0020009c000005ab02008041000000c002200210000000000112019f000005cf011001c70000001b0200002916a916a40000040f00000000030100190000006003300270000005ab03300197000000200030008c000000200400003900000000040340190000002006400190000000160560002900000b090000613d000000000701034f0000001608000029000000007907043c0000000008980436000000000058004b00000b050000c13d0000001f0740019000000b160000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f0003000000010355000000010020019000000c400000613d0000001f01400039000000600110018f0000001602100029000005b70020009c000000c20000213d000000400020043f000000200030008c000000a20000413d00000016010000290000000001010433000e00000001001d0000002001200039000005d003000041000000000031043500000064012000390000000f03000029000000000031043500000044012000390000001003000029000000000031043500000024012000390000000d03000029000000000031043500000064010000390000000000120435000005d10020009c000000c20000213d000000a001200039000000400010043f0000001b0100002916a9155e0000040f000000400200043d000005ce010000410000000000120435001600000002001d00000004012000390000001002000029000000000021043500000000010004140000001b02000029000000040020008c00000b490000c13d0000000103000031000000200030008c0000002004000039000000000403401900000b740000013d0000001602000029000005ab0020009c000005ab020080410000004002200210000005ab0010009c000005ab01008041000000c001100210000000000121019f000005cf011001c70000001b0200002916a916a40000040f00000000030100190000006003300270000005ab03300197000000200030008c000000200400003900000000040340190000002006400190000000160560002900000b630000613d000000000701034f0000001608000029000000007907043c0000000008980436000000000058004b00000b5f0000c13d0000001f0740019000000b700000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f0003000000010355000000010020019000000c4c0000613d0000001f01400039000000600210018f0000001601200029000000000021004b00000000020000390000000102004039000005b70010009c000000c20000213d0000000100200190000000c20000c13d000000400010043f000000200030008c000000a20000413d000000160100002900000000010104330000000e0110006c00000e860000413d0000000f0010006c00000a610000613d000005e101000041000000000010043f000005dc01000041000016ab000104300000001f0530018f000005ad06300198000000400200043d000000000462001900000e970000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00000b920000c13d00000e970000013d0000000001000415000e00000001001d000000020100036700000018020000290000000002200079000000df0220008a0000001903000029000000010030008c00000c580000c13d0000001803100360000000000303043b000005c704300197000005c705200197000000000654013f000000000054004b0000000004000019000005c704004041000000000023004b0000000002000019000005c702008041000005c70060009c000000000402c019000000000004004b000000a20000c13d0000001802300029001b00000002001d0000004002200039000000000321034f000000000303043b000005ae0030009c000000a20000213d0000000004000415000000230440008a001a000500400218000000000003004b00000bd40000613d000000200220008a000000000121034f000000000101043b000005ae0010009c000000a20000213d000000000010043f000005d501000041000000200010043f0000000001000414000005ab0010009c000005ab01008041000000c001100210000005bb011001c7000080100200003916a916a40000040f0000000100200190000000a20000613d000000000101043b000000000101041a000000ff0010019000000c290000613d0000000001000415000000220110008a001a00050010021800000002010003670000001b01100360000000000101043b000005ae0010009c000000a20000213d000000000010043f000005d501000041000000200010043f0000000001000414000005ab0010009c000005ab01008041000000c001100210000005bb011001c7000080100200003916a916a40000040f0000000100200190000000a20000613d000000000101043b000000000101041a0000001a020000290000000502200270000000ff02100195000000ff0010019000000c290000613d0000001b04000029000000a0024000390000000201000367000000000221034f000000000302043b000000000200003100000000044200490000001f0440008a000005c705400197000005c706300197000000000756013f000000000056004b0000000005000019000005c705004041000000000043004b0000000004000019000005c704008041000005c70070009c000000000504c019000000000005004b000000a20000c13d0000001b03300029000000000431034f000000000404043b000005b70040009c000000a20000213d000000040040008c000000a20000413d00000000044200490000002002300039000000000042004b0000000003000019000005c703002041000005c704400197000005c705200197000000000645013f000000000045004b0000000004000019000005c704004041000005c70060009c000000000403c019000000000004004b000000a20000c13d000000000121034f000000000101043b000005d601100197000000000010043f000005d701000041000000200010043f0000000001000414000005ab0010009c000005ab01008041000000c001100210000005bb011001c7000080100200003916a916a40000040f0000000100200190000000a20000613d000000000101043b000000000101041a000000ff0010019000000e070000c13d000005de01000041000000000010043f000005dc01000041000016ab000104300000001f0530018f000005ad06300198000000400200043d000000000462001900000e970000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00000c340000c13d00000e970000013d000005d201000041000000000010043f0000000f01000029000000040010043f000000240020043f000005d301000041000016ab000104300000001f0530018f000005ad06300198000000400200043d000000000462001900000e970000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00000c470000c13d00000e970000013d0000001f0530018f000005ad06300198000000400200043d000000000462001900000e970000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00000c530000c13d00000e970000013d0000000603100360000000000303043b000005c704300197000005c705200197000000000654013f000000000054004b0000000004000019000005c704004041000000000023004b0000000002000019000005c702008041000005c70060009c000000000402c019000000000004004b000000a20000c13d0000001202300029000000000121034f000000000101043b000f00000001001d000005ae0010009c000000a20000213d0000000001000415000600000001001d001700000000001d0000001701000029000000050110021000000018021000290000000201000367000000000221034f000000000202043b0000001a030000290000000003300079000001030330008a000005c704200197000005c705300197000000000654013f000000000054004b0000000004000019000005c704004041000000000032004b0000000003000019000005c703008041000005c70060009c000000000403c019000000000004004b000000a20000c13d0000001802200029001b00000002001d0000004002200039000000000221034f000000000202043b000005ae0020009c000000a20000213d000000000002004b00000cab0000613d0000001b020000290000002002200039000000000121034f000000000101043b000005ae0010009c000000a20000213d000000000010043f000005d501000041000000200010043f0000000001000414000005ab0010009c000005ab01008041000000c001100210000005bb011001c7000080100200003916a916a40000040f0000000100200190000000a20000613d000000000101043b000000000101041a002000ff00100193000000ff0010019000000c290000613d0000000001000415000000200110008a0016000500100218000000020100036700000caf0000013d0000000002000415000000210220008a0016000500200218002100010000003d0000001b01100360000000000101043b000005ae0010009c000000a20000213d000000000010043f000005d501000041000000200010043f0000000001000414000005ab0010009c000005ab01008041000000c001100210000005bb011001c7000080100200003916a916a40000040f0000000100200190000000a20000613d000000000101043b000000000101041a00000016020000290000000502200270000000ff02100195000000ff0010019000000c290000613d0000001b04000029000000a0024000390000000201000367000000000221034f000000000302043b000000000200003100000000044200490000001f0440008a000005c705400197000005c706300197000000000756013f000000000056004b0000000005000019000005c705004041000000000043004b0000000004000019000005c704008041000005c70070009c000000000504c019000000000005004b000000a20000c13d0000001b03300029000000000431034f000000000404043b000005b70040009c000000a20000213d000000040040008c000000a20000413d00000000044200490000002002300039000000000042004b0000000003000019000005c703002041000005c704400197000005c705200197000000000645013f000000000045004b0000000004000019000005c704004041000005c70060009c000000000403c019000000000004004b000000a20000c13d000000000121034f000000000101043b000005d601100197000000000010043f000005d701000041000000200010043f0000000001000414000005ab0010009c000005ab01008041000000c001100210000005bb011001c7000080100200003916a916a40000040f0000000100200190000000a20000613d000000000101043b000000000101041a000000ff0010019000000c290000613d00000007010000290000001b0200002916a911a70000040f00000017020000290000000102200039001700000002001d000000190020006c00000c700000413d000000000100041500000006011000690000000001000002000000080000006b00000e0a0000613d0000000f01000029000705ae0010019b001700000000001d0000001702000029000000190020006c00000a3c0000813d00000017010000290000000502100210000f00000002001d00000018022000290000000201000367000000000221034f000000000202043b0000001a030000290000000003300079000001030330008a000005c704200197000005c705300197000000000654013f000000000054004b0000000004000019000005c704004041000000000032004b0000000003000019000005c703008041000005c70060009c000000000403c019000000000004004b000000a20000c13d0000001202200029000000000121034f000000000101043b001b00000001001d000005ae0010009c000000a20000213d0000001b02000029000000070020006c00000e010000613d0000001b0000006b00000d490000613d000000400200043d000005ce010000410000000000120435001600000002001d00000004012000390000001002000029000000000021043500000000010004140000001b02000029000000040020008c00000d580000c13d0000000103000031000000200030008c0000002004000039000000000403401900000d830000013d000005cb010000410000000000100443000000000100041000000004001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005cc011001c70000800a0200003916a916a40000040f000000010020019000000ed00000613d000000000101043b00000d920000013d0000001602000029000005ab0020009c000005ab020080410000004002200210000005ab0010009c000005ab01008041000000c001100210000000000121019f000005cf011001c70000001b0200002916a916a40000040f00000000030100190000006003300270000005ab03300197000000200030008c000000200400003900000000040340190000002006400190000000160560002900000d720000613d000000000701034f0000001608000029000000007907043c0000000008980436000000000058004b00000d6e0000c13d0000001f0740019000000d7f0000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f0003000000010355000000010020019000000e1f0000613d0000001f01400039000000600210018f0000001601200029000000000021004b00000000020000390000000102004039000005b70010009c000000c20000213d0000000100200190000000c20000c13d000000400010043f000000200030008c000000a20000413d0000001601000029000000000101043300000013020000290000000002020433000000170020006c00000a3c0000a13d0000000f0300002900000011023000290000000002020433000f00000021005300000e860000413d00000e010000613d0000001b0000006b00000db00000613d0000000d0000006b000007730000613d000000400200043d000005ce010000410000000000120435001600000002001d00000004012000390000001002000029000000000021043500000000010004140000001b02000029000000040020008c00000db40000c13d0000000103000031000000200030008c0000002004000039000000000403401900000ddf0000013d00000000010004110000000f0200002916a910c20000040f00000e010000013d0000001602000029000005ab0020009c000005ab020080410000004002200210000005ab0010009c000005ab01008041000000c001100210000000000121019f000005cf011001c70000001b0200002916a916a40000040f00000000030100190000006003300270000005ab03300197000000200030008c000000200400003900000000040340190000002006400190000000160560002900000dce0000613d000000000701034f0000001608000029000000007907043c0000000008980436000000000058004b00000dca0000c13d0000001f0740019000000ddb0000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000100000003001f0003000000010355000000010020019000000e2b0000613d0000001f01400039000000600110018f0000001602100029000000000012004b00000000010000390000000101004039000005b70020009c000000c20000213d0000000100100190000000c20000c13d000000400020043f000000200030008c000000a20000413d000000160100002900000000010104330000000f0010006c00000e370000413d0000002001200039000005d903000041000000000031043500000044012000390000000f03000029000000000031043500000024012000390000000d03000029000000000031043500000044010000390000000000120435000005da0020009c000000c20000213d0000008001200039000000400010043f0000001b0100002916a9155e0000040f00000017020000290000000102200039001700000002001d000000080020006c00000d140000413d00000e0a0000013d00000007010000290000001b0200002916a911a70000040f00000000010004150000000e0110006900000000010000020000000b01000029000005ae0210019800000e3b0000c13d000005cb010000410000000000100443000000000100041000000004001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005cc011001c70000800a0200003916a916a40000040f000000010020019000000ed00000613d000000000101043b00000e840000013d0000001f0530018f000005ad06300198000000400200043d000000000462001900000e970000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00000e260000c13d00000e970000013d0000001f0530018f000005ad06300198000000400200043d000000000462001900000e970000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00000e320000c13d00000e970000013d000005d202000041000000000020043f0000000f0200002900000eaf0000013d000000400300043d000005ce010000410000000000130435001b00000003001d0000000401300039000000100300002900000000003104350000000001000414000000040020008c00000e4a0000c13d0000000103000031000000200030008c0000002004000039000000000403401900000e750000013d0000001b03000029000005ab0030009c000005ab030080410000004003300210000005ab0010009c000005ab01008041000000c001100210000000000131019f000005cf011001c716a916a40000040f00000000030100190000006003300270000005ab03300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000001b0570002900000e640000613d000000000801034f0000001b09000029000000008a08043c0000000009a90436000000000059004b00000e600000c13d000000000006004b00000e710000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f0003000000010355000000010020019000000e8c0000613d0000001f01400039000000600210018f0000001b01200029000000000021004b00000000020000390000000102004039000005b70010009c000000c20000213d0000000100200190000000c20000c13d000000400010043f000000200030008c000000a20000413d0000001b010000290000000001010433000000090110006c00000eaa0000813d000005d801000041000000000010043f0000001101000039000000040010043f000005cf01000041000016ab000104300000001f0530018f000005ad06300198000000400200043d000000000462001900000e970000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b00000e930000c13d000000000005004b00000ea40000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f00000000001404350000006001300210000005ab0020009c000005ab020080410000004002200210000000000112019f000016ab000104300000000a0010006c00000eb30000813d000005dd02000041000000000020043f0000000a02000029000000040020043f000000240010043f000005d301000041000016ab00010430000001400010043f0000008001000039000000150200002916a90ee60000040f000005cb010000410000000000100443000000000100041000000004001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005cc011001c70000800a0200003916a916a40000040f000000010020019000000ed00000613d000000000101043b0000000c0210006c00000ec90000a13d000000000100041116a910c20000040f000005b901000041000000000001041b0000000001000415000000140110006900000000010000020000000001000019000016aa0001042e000000000001042f00000020030000390000000004310436000000003202043400000000002404350000004001100039000000000002004b00000ee00000613d000000000400001900000000051400190000000006430019000000000606043300000000006504350000002004400039000000000024004b00000ed90000413d000000000312001900000000000304350000001f02200039000005e8022001970000000001120019000000000001042d0007000000000002000000400500043d0000002004500039000000c003100039000400000003001d0000000003030433000300000003001d0000008003100039000600000003001d0000000003030433000005ae003001980000002003000039000700000002001d000500000001001d000200000004001d00000f7e0000613d000100000005001d000005d9010000410000000000140435000005c90100004100000000001004430000000001000412000000040010044300000024003004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005ca011001c7000080050200003916a916a40000040f0000000100200190000010c10000613d000000000101043b0000000104000029000000440240003900000003030000290000000000320435000005ae011001970000002402400039000000000012043500000044010000390000000000140435000005e90040009c000000200a00008a000000070b000029000010b90000813d0000008005400039000000400050043f0000000201b00367000000000101043b00000020020000390000000000250435000000a0034000390000000000130435000005ea0040009c000010b90000213d000000c002400039000000400020043f000000e0014000390000000004040433000000000004004b000000020900002900000f2e0000613d000000000600001900000000071600190000000008960019000000000808043300000000008704350000002006600039000000000046004b00000f270000413d000000000614001900000000000604350000000005050433000000000005004b00000f3b0000613d000000000700001900000000086700190000000009370019000000000909043300000000009804350000002007700039000000000057004b00000f340000413d00000000036500190000000000030435000000000345001900000000003204350000003f033000390000000004a3016f0000000003240019000000000043004b00000000040000390000000104004039000005b70030009c000010b90000213d0000000100400190000010b90000c13d000000400030043f0000000004020433000000060200002900000000020204330000000003000414000005ae02200197000000040020008c00000f9d0000c13d00000001030000310000000002000019000000000003004b00000fb20000613d000005b70030009c000010b90000213d0000001f013000390000000001a1016f0000003f011000390000000004a1016f000000400100043d0000000004410019000000000014004b00000000050000390000000105004039000005b70040009c000010b90000213d0000000100500190000010b90000c13d000000400040043f00000000073104360000000004a301700000001f0530018f0000000003470019000000030600036700000f700000613d000000000806034f000000008908043c0000000007970436000000000037004b00000f6c0000c13d000000000005004b00000fb30000613d000000000446034f0000000305500210000000000603043300000000065601cf000000000656022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000464019f000000000043043500000fb30000013d0000000201200367000000000101043b00000000001404350000000000350435000005ec0050009c000010b90000213d0000004001500039000000400010043f0000000001050433000100000001001d000005c90100004100000000001004430000000001000412000000040010044300000024000004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005ca011001c7000080050200003916a916a40000040f0000000100200190000010c10000613d000000000401043b0000000001000414000000040040008c00000fd80000c13d00000001020000390000000103000031000010760000013d000005ab0010009c000005ab010080410000004001100210000005ab0040009c000005ab040080410000006004400210000000000114019f000005ab0030009c000005ab03008041000000c003300210000000000131019f16a9169f0000040f000000070b000029000000200a00008a000000010220015f00030000000103550000006001100270000105ab0010019d000005ab03100197000000000003004b00000f550000c13d00000060010000390000000100200190000010a30000c13d0000000201b00367000000000101043b000000000010043f000000200000043f0000000001000414000005ab0010009c000005ab01008041000000c001100210000005bb011001c7000080100200003916a916a40000040f00000001002001900000000508000029000010bf0000613d000000000101043b000000000201041a000005f00220019700000001022001bf000000000021041b000000a00b80003900000000010b0433000005ae01100197000005bc0010009c000000e00a800039000010050000c13d000000000508043300000000060a0433000005be0060009c00030000000a001d00020000000b001d00000fec0000613d000005bf0060009c0000000701000029000005c00600604100000fee0000013d0000000202000029000005ab0020009c000005ab0200804100000040022002100000000103000029000005ab0030009c000005ab030080410000006003300210000000000223019f000005ab0010009c000005ab01008041000000c001100210000000000121019f0000000303000029000000000003004b000010700000613d000005c4011001c700008009020000390000000005000019000010710000013d000005bd06000041000000070100002900000020011000390000000201100367000000000101043b000000400200043d0000000000120435000005ab0020009c000005ab0200804100000040012002100000000002000414000005ab0020009c000005ab02008041000000c002200210000000000112019f000005ed011001c70000800d020000390000000303000039000005ee0400004116a9169f0000040f00000001002001900000000508000029000000030a000029000000020b000029000010bf0000613d000000400100043d000000200200003900000000022104360000000043080434000000000032043500000000020404330000004003100039000001400400003900000000004304350000016005100039000000004302043400000000003504350000018002100039000000000003004b000000200900008a0000101d0000613d000000000500001900000000062500190000000007540019000000000707043300000000007604350000002005500039000000000035004b000010160000413d000000000423001900000000000404350000001f03300039000000000393016f00000040048000390000000004040433000000600510003900000160063000390000000000650435000000000223001900000000430404340000000002320436000000000003004b000010330000613d000000000500001900000000062500190000000007540019000000000707043300000000007604350000002005500039000000000035004b0000102c0000413d0000000004230019000000000004043500000060048000390000000004040433000005ae044001970000008005100039000000000045043500000006040000290000000004040433000005ae04400197000000a005100039000000000045043500000000040b0433000005ae04400197000000c005100039000000000045043500000004040000290000000004040433000000e005100039000000000045043500000000040a04330000010005100039000000000045043500000100048000390000000004040433000000000004004b0000000004000039000000010400c0390000012005100039000000000045043500000120048000390000000004040433000000000004004b0000000004000039000000010400c039000001400510003900000000004504350000001f03300039000000000393016f00000000021200490000000002320019000005ab0020009c000005ab020080410000006002200210000005ab0010009c000005ab010080410000004001100210000000000112019f0000000002000414000005ab0020009c000005ab02008041000000c002200210000000000112019f000005c4011001c70000800d020000390000000103000039000005ef0400004116a9169f0000040f0000000100200190000010bf0000613d000000000001042d000000000204001916a9169f0000040f00030000000103550000006001100270000105ab0010019d000005ab03100197000000000003004b000000070b000029000010b50000613d000005b70030009c000010b90000213d0000001f01300039000005e8011001970000003f01100039000005e804100197000000400100043d0000000004410019000000000014004b00000000050000390000000105004039000005b70040009c000010b90000213d0000000100500190000010b90000c13d000000400040043f0000000007310436000005e8043001980000001f0530018f00000000034700190000000306000367000010940000613d000000000806034f000000008908043c0000000007970436000000000037004b000010900000c13d000000000005004b000010a10000613d000000000446034f0000000305500210000000000603043300000000065601cf000000000656022f000000000404043b0000010005500089000000000454022f00000000045401cf000000000464019f0000000000430435000000010020019000000fb50000c13d16a9113b0000040f000005eb02000041000000400300043d000700000003001d00000000002304350000000002010019000000040130003916a90ed10000040f00000007020000290000000001210049000005ab0010009c000005ab010080410000006001100210000005ab0020009c000005ab020080410000004002200210000000000121019f000016ab000104300000006001000039000000010020019000000fb50000c13d000010a30000013d000005d801000041000000000010043f0000004101000039000000040010043f000005cf01000041000016ab000104300000000001000019000016ab00010430000000000001042f0003000000000002000200000002001d000105ae0010019c000011220000613d000005cb010000410000000000100443000000000100041000000004001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005cc011001c70000800a0200003916a916a40000040f0000000100200190000011260000613d000000000101043b0000000203000029000000000031004b0000000104000029000011270000413d0000000001000414000000040040008c000010e00000c13d00000001020000390000000101000031000000000001004b000010f10000c13d000011190000013d000005ab0010009c000005ab01008041000000c001100210000000000003004b000010e90000613d000005c4011001c700008009020000390000000005000019000010ea0000013d000000000204001916a9169f0000040f00030000000103550000006001100270000105ab0010019d000005ab01100197000000000001004b000011190000613d000005f10010009c0000111c0000813d0000001f04100039000005e8044001970000003f04400039000005e805400197000000400400043d0000000005540019000000000045004b00000000060000390000000106004039000005b70050009c0000111c0000213d00000001006001900000111c0000c13d000000400050043f0000000006140436000005e8031001980000001f0410018f000000000136001900000003050003670000110c0000613d000000000705034f000000007807043c0000000006860436000000000016004b000011080000c13d000000000004004b000011190000613d000000000335034f0000000304400210000000000501043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f00000000003104350000000100200190000011370000613d000000000001042d000005d801000041000000000010043f0000004101000039000000040010043f000005cf01000041000016ab00010430000005db01000041000000000010043f000005dc01000041000016ab00010430000000000001042f0000000001000410000300000001001d0000800a0100003900000024030000390000000004000415000000030440008a0000000504400210000005cb0200004116a916810000040f000005d202000041000000000020043f0000000202000029000000040020043f000000240010043f000005d301000041000016ab00010430000005f201000041000000000010043f000005dc01000041000016ab000104300000000002010433000000440020008c000011480000813d000000400100043d000005f30010009c0000119b0000813d0000004002100039000000400020043f0000001d020000390000000002210436000005f4030000410000000000320435000000000001042d000000040220008a000005f50020009c000011a10000813d0000001f0620019000000000070000390000002007006039000000000467019f000000400300043d00000000043400190000000005420019000000000054004b0000115b0000813d00000000016100190000000001710019000000040110003900000000160104340000000004640436000000000054004b000011570000413d00000000022304360000001f01400039000005e801100197000000400010043f0000000003030433000005b80030009c000011990000213d0000001f0030008c000011990000a13d0000000006020433000005b70060009c000011990000213d000000000532001900000000022600190000001f03200039000000000053004b0000000006000019000005c706008041000005c703300197000005c707500197000000000873013f000000000073004b0000000003000019000005c703004041000005c70080009c000000000306c019000000000003004b000011990000c13d0000000032020434000005b70020009c0000119b0000213d0000001f06200039000005e8066001970000003f06600039000005e8066001970000000004160019000000000064004b00000000060000390000000106004039000005b70040009c0000119b0000213d00000001006001900000119b0000c13d000000400040043f00000000042104360000000006320019000000000056004b000011990000213d000000000002004b000011950000613d000000000500001900000000064500190000000007350019000000000707043300000000007604350000002005500039000000000025004b0000118e0000413d000000000242001900000000030000190000000000320435000000000001042d0000000001000019000016ab00010430000005d801000041000000000010043f0000004101000039000000040010043f000005cf01000041000016ab00010430000005d801000041000000000010043f0000001101000039000000040010043f000005cf01000041000016ab00010430000f000000000002000900000001001d000d00000002001d0000000201200367000000000101043b000005f60010009c000014f60000813d000005f702000041000000000020044300000004001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005cc011001c7000080020200003916a916a40000040f0000000100200190000014fe0000613d000000000101043b000000000001004b000014ff0000613d0000000d0100002900000080021000390000000201000367000000000321034f000000000303043b000c00000003001d000000000003004b000015030000613d000000400620008a000000000161034f000000000501043b000005ae0050009c000014f60000213d0000000002000410000000000005004b00000000010000190000000c01006029000b00000005001d000700000001001d000011df0000613d000000400b00043d000005ce0100004100000000001b0435000005ae012001970000000402b0003900000000001204350000000001000414000000040050008c000011f10000c13d0000000103000031000000200030008c00000020040000390000000004034019000012220000013d000800000006001d000005cb01000041000000000010044300000004002004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005cc011001c70000800a0200003916a916a40000040f0000000100200190000014fe0000613d000000000101043b000a00000001001d0000000b050000290000000806000029000012310000013d000800000006001d000005ab00b0009c000005ab0200004100000000020b40190000004002200210000005ab0010009c000005ab01008041000000c001100210000000000121019f000005cf011001c70000000002050019000a0000000b001d16a916a40000040f0000000a0b00002900000000030100190000006003300270000005ab03300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b00190000120f0000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b0000120b0000c13d000000000006004b0000121c0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f000300000001035500000001002001900000151c0000613d0000000b0500002900000008060000290000001f01400039000000600210018f0000000001b20019000000000021004b00000000020000390000000102004039000005b70010009c000014f80000213d0000000100200190000014f80000c13d000000400010043f000000200030008c000014f60000413d00000000010b0433000a00000001001d00000020016000390000000201100367000000000201043b000005ae0020009c000014f60000213d000000000002004b000012470000613d000000400b00043d000005ce0100004100000000001b04350000000001000410000005ae011001970000000403b0003900000000001304350000000001000414000000040020008c000012580000c13d0000000103000031000000200030008c00000020040000390000000004034019000012860000013d000005cb010000410000000000100443000000000100041000000004001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005cc011001c70000800a0200003916a916a40000040f0000000100200190000014fe0000613d000000000101043b000800000001001d0000000b05000029000012950000013d000005ab00b0009c000005ab0300004100000000030b40190000004003300210000005ab0010009c000005ab01008041000000c001100210000000000131019f000005cf011001c700080000000b001d16a916a40000040f000000080b00002900000000030100190000006003300270000005ab03300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b0019000012740000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b000012700000c13d000000000006004b000012810000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f00030000000103550000000100200190000015280000613d0000000b050000290000001f01400039000000600210018f0000000001b20019000000000021004b00000000020000390000000102004039000005b70010009c000014f80000213d0000000100200190000014f80000c13d000000400010043f000000200030008c000014f60000413d00000000010b0433000800000001001d0000000d01000029000000400c100039000000000005004b000000200b00008a000b0000000c001d000013ad0000613d00000002010003670000000002c1034f000000000d02043b000005ae00d0009c000014f60000213d0000002002c0008a000000000121034f000000000e01043b000005ae00e0009c000014f60000213d000000000500041500000000000d004b000013aa0000613d00000000000e004b000015180000613d000000400f00043d0000002401f000390000000000e10435000005f80100004100000000001f04350000000001000410000005ae011001970000000402f00039000000000012043500000000010004140000000400d0008c000500000005001d00060000000d001d00040000000e001d000012be0000c13d0000000103000031000000200030008c00000020040000390000000004034019000012f10000013d000005ab00f0009c000005ab0200004100000000020f40190000004002200210000005ab0010009c000005ab01008041000000c001100210000000000121019f000005d3011001c700000000020d001900030000000f001d16a916a40000040f000000030f00002900000000030100190000006003300270000005ab03300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057f0019000012db0000613d000000000801034f00000000090f0019000000008a08043c0000000009a90436000000000059004b000012d70000c13d000000000006004b000012e80000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f000300000001035500000001002001900000000b0c000029000000200b00008a000000060d0000290000000505000029000000040e000029000015400000613d0000001f01400039000000600210018f0000000001f20019000000000021004b00000000020000390000000102004039000005b70010009c000014f80000213d0000000100200190000014f80000c13d000000400010043f000000200030008c000014f60000413d00000000010f04330000000c0010006c000013aa0000813d0000000001000415000200000001001d000000400300043d0000004401300039000000010200008a00000000002104350000002001300039000005f902000041000000000021043500000024023000390000000000e2043500000044020000390000000000230435000300000003001d000005da0030009c000014f80000213d00000003030000290000008002300039000000400020043f000000000303043300000000020004140000000400d0008c000013480000c13d00000001020000390000000104000031000000000004004b0000135f0000613d000005b70040009c000014f80000213d0000001f014000390000000001b1016f0000003f011000390000000001b1016f000000400300043d0000000001130019000000000031004b00000000050000390000000105004039000005b70010009c000014f80000213d0000000100500190000014f80000c13d000000400010043f00000000014304360000000005b401700000001f0640018f00000000045100190000000307000367000013380000613d000000000807034f0000000009010019000000008a08043c0000000009a90436000000000049004b000013340000c13d000000000006004b000013450000613d000000000557034f0000000306600210000000000704043300000000076701cf000000000767022f000000000505043b0000010006600089000000000565022f00000000056501cf000000000575019f0000000000540435000000000002004b000013630000c13d000013910000013d000005ab0010009c000005ab010080410000004001100210000005ab0030009c000005ab030080410000006003300210000000000113019f000005ab0020009c000005ab02008041000000c002200210000000000121019f00000000020d001916a9169f0000040f000000040e000029000000060d000029000000200b00008a000000010220018f00030000000103550000006001100270000105ab0010019d000005ab04100197000000000004004b0000131c0000c13d00000060030000390000008001000039000000000002004b000013910000613d00000000040004150000000f0440008a00000005044002100000000002030433000000000002004b000013780000613d000005b80020009c000014f60000213d000000200020008c000014f60000413d0000000001010433000000000001004b0000000002000039000000010200c039000000000021004b000014f60000c13d00000000040004150000000e0440008a0000000504400210000000000001004b000013910000613d000100000004001d000005f70100004100000000001004430000000400d004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005cc011001c7000080020200003916a916a40000040f0000000100200190000014fe0000613d000000000101043b000000000001004b00000001010000290000000501100270000000000100003f000000010100c03f0000000b0c000029000000200b00008a000000060d0000290000000505000029000000040e000029000013a70000c13d000000400200043d0000002001200039000005f903000041000000000031043500000024012000390000000000e104350000004401000039000000000012043500000044012000390000000000010435000005da0020009c000014f80000213d0000008001200039000000400010043f00000000010d001916a9155e0000040f0000000601000029000000030200002916a9155e0000040f0000000505000029000000200b00008a0000000b0c0000290000000001000415000000020110006900000000010000020000000001000415000000000115004900000000010000020000000a020000290000000c0020006c0000000001020019000015070000413d00000002020003670000000d01200360000000000401043b000005ae0040009c000014f60000213d0000000d05000029000000a00d5000390000000001d2034f000000000101043b000000000300003100000000055300490000001f0550008a000005c706500197000005c707100197000000000867013f000000000067004b0000000006000019000005c706004041000000000051004b0000000005000019000005c705008041000005c70080009c000000000605c019000000000006004b000014f60000c13d0000000d05100029000000000152034f000000000101043b000005b70010009c000014f60000213d00000000061300490000002003500039000005c705600197000005c707300197000000000857013f000000000057004b0000000005000019000005c705004041000000000063004b0000000006000019000005c706002041000005c70080009c000000000506c019000000000005004b000014f60000c13d000000000532034f0000000006b101700000001f0710018f000000400200043d0000000003620019000013ea0000613d000000000805034f0000000009020019000000008a08043c0000000009a90436000000000039004b000013e60000c13d000000000007004b000013f70000613d000000000565034f0000000306700210000000000703043300000000076701cf000000000767022f000000000505043b0000010006600089000000000565022f00000000056501cf000000000575019f0000000000530435000000000312001900000000000304350000000003000414000000040040008c0000142a0000c13d00000001020000390000000103000031000000000003004b000014480000613d000005b70030009c000014f80000213d0000001f013000390000000001b1016f0000003f011000390000000004b1016f000000400100043d0000000004410019000000000014004b00000000050000390000000105004039000005b70040009c000014f80000213d0000000100500190000014f80000c13d000000400040043f00000000043104360000000006b301700000001f0730018f000000000564001900000003080003670000141c0000613d000000000908034f000000000a040019000000009b09043c000000000aba043600000000005a004b000014180000c13d000000000007004b0000144a0000613d000000000668034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f00000000006504350000144a0000013d000a0000000d001d000005ab0010009c000005ab010080410000006001100210000005ab0020009c000005ab020080410000004002200210000000000112019f000005ab0030009c000005ab03008041000000c002300210000000000112019f0000000703000029000000000003004b0000143d0000613d000005c4011001c7000080090200003900000000050000190000143e0000013d000000000204001916a9169f0000040f00030000000103550000006001100270000105ab0010019d000005ab031001970000000b0c000029000000200b00008a0000000a0d000029000000000003004b000014000000c13d0000006001000039000000800400003900000001002001900000150f0000613d0000004001d0008a0000000201100367000000000201043b000005ae0020009c000014f60000213d000000000002004b000014610000613d000000400b00043d000005ce0100004100000000001b04350000000001000410000005ae011001970000000404b0003900000000001404350000000001000414000000040020008c000014720000c13d000000200030008c00000020040000390000000004034019000014a00000013d000005cb010000410000000000100443000000000100041000000004001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005cc011001c70000800a0200003916a916a40000040f0000000100200190000014fe0000613d000000000101043b000a00000001001d0000000b0c000029000014af0000013d000005ab00b0009c000005ab0300004100000000030b40190000004003300210000005ab0010009c000005ab01008041000000c001100210000000000131019f000005cf011001c7000a0000000b001d16a916a40000040f0000000a0b00002900000000030100190000006003300270000005ab03300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000000057b00190000148e0000613d000000000801034f00000000090b0019000000008a08043c0000000009a90436000000000059004b0000148a0000c13d000000000006004b0000149b0000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000100000003001f000300000001035500000001002001900000000b0c000029000015340000613d0000001f01400039000000600210018f0000000001b20019000000000021004b00000000020000390000000102004039000005b70010009c000014f80000213d0000000100200190000014f80000c13d000000400010043f000000200030008c000014f60000413d00000000010b0433000a00000001001d00000002010003670000000d02100360000000000202043b000d00000002001d000005ae0020009c000014f60000213d0000000002c1034f000000000202043b000b00000002001d000005ae0020009c000014f60000213d0000002002c00039000000000121034f000000000101043b000700000001001d000005ae0010009c000014f60000213d000000400100043d000600000001001d000005fb0100004100000000001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005c2011001c70000800b0200003916a916a40000040f0000000100200190000014fe0000613d000000000101043b0000000603000029000000c002300039000000000012043500000080013000390000000c02000029000000000021043500000060013000390000000702000029000000000021043500000040013000390000000b02000029000000000021043500000020013000390000000d0200002900000000002104350000000a02000029000000080020006c000000000100001900000008010020290000000001120049000000a002300039000000000012043500000009010000290000000000130435000005ab0030009c000005ab0300804100000040013002100000000002000414000005ab0020009c000005ab02008041000000c002200210000000000112019f000005fc011001c70000800d020000390000000103000039000005fd0400004116a9169f0000040f0000000100200190000014f60000613d000000000001042d0000000001000019000016ab00010430000005d801000041000000000010043f0000004101000039000000040010043f000005cf01000041000016ab00010430000000000001042f000005ff01000041000000000010043f000005dc01000041000016ab00010430000005fe01000041000000000010043f000005dc01000041000016ab000104300000000002010019000005d201000041000000000010043f0000000c01000029000000040010043f000000240020043f000005d301000041000016ab00010430000005ab0040009c000005ab0400804100000040024002100000000001010433000005ab0010009c000005ab010080410000006001100210000000000121019f000016ab00010430000005fa01000041000000000010043f000005dc01000041000016ab000104300000001f0530018f000005ad06300198000000400200043d00000000046200190000154b0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000015230000c13d0000154b0000013d0000001f0530018f000005ad06300198000000400200043d00000000046200190000154b0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000152f0000c13d0000154b0000013d0000001f0530018f000005ad06300198000000400200043d00000000046200190000154b0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b0000153b0000c13d0000154b0000013d0000001f0530018f000005ad06300198000000400200043d00000000046200190000154b0000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000015470000c13d000000000005004b000015580000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f00000000001404350000006001300210000005ab0020009c000005ab020080410000004002200210000000000112019f000016ab000104300004000000000002000000400400043d000005f30040009c000016220000813d000005ae051001970000004001400039000000400010043f0000002001400039000006000300004100000000003104350000002001000039000000000014043500000000230204340000000001000414000000040050008c000015990000c13d0000000101000032000015d50000613d000005b70010009c000016220000213d0000001f03100039000005e8033001970000003f03300039000005e803300197000000400a00043d00000000033a00190000000000a3004b00000000040000390000000104004039000005b70030009c000016220000213d0000000100400190000016220000c13d000000400030043f00000000051a0436000005e8021001980000001f0310018f000000000125001900000003040003670000158b0000613d000000000604034f000000006706043c0000000005750436000000000015004b000015870000c13d000000000003004b000015d60000613d000000000224034f0000000303300210000000000401043300000000043401cf000000000434022f000000000202043b0000010003300089000000000232022f00000000023201cf000000000242019f0000000000210435000015d60000013d000200000004001d000005ab0030009c000005ab030080410000006003300210000005ab0020009c000005ab020080410000004002200210000000000223019f000005ab0010009c000005ab01008041000000c001100210000000000112019f000100000005001d000000000205001916a9169f0000040f000300000001035500000000030100190000006003300270000105ab0030019d000005ab04300198000015ed0000613d0000001f03400039000005ac033001970000003f033000390000060103300197000000400a00043d00000000033a00190000000000a3004b00000000050000390000000105004039000005b70030009c000016220000213d0000000100500190000016220000c13d000000400030043f0000001f0540018f00000000034a0436000005ad064001980000000004630019000015c70000613d000000000701034f0000000008030019000000007907043c0000000008980436000000000048004b000015c30000c13d000000000005004b000015ef0000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000015ef0000013d000000600a0000390000000002000415000000040220008a000000050220021000000000010a0433000000000001004b000015f70000c13d00020000000a001d000005f7010000410000000000100443000000040100003900000004001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005cc011001c7000080020200003916a916a40000040f0000000100200190000016510000613d0000000002000415000000040220008a0000160a0000013d000000600a000039000000800300003900000000010a043300000001002001900000163e0000613d0000000002000415000000030220008a0000000502200210000000000001004b000015fa0000613d000000050220027000000000020a001f000016140000013d00020000000a001d000005f7010000410000000000100443000000010100002900000004001004430000000001000414000005ab0010009c000005ab01008041000000c001100210000005cc011001c7000080020200003916a916a40000040f0000000100200190000016510000613d0000000002000415000000030220008a0000000502200210000000000101043b000000000001004b000000020a000029000016520000613d00000000010a0433000000050220027000000000020a001f000000000001004b000016210000613d000005b80010009c000016280000213d0000001f0010008c000016280000a13d0000002001a000390000000001010433000000000001004b0000000002000039000000010200c039000000000021004b000016280000c13d000000000001004b0000162a0000613d000000000001042d000005d801000041000000000010043f0000004101000039000000040010043f000005cf01000041000016ab000104300000000001000019000016ab00010430000000400100043d00000064021000390000060203000041000000000032043500000044021000390000060303000041000000000032043500000024021000390000002a030000390000000000320435000005eb020000410000000000210435000000040210003900000020030000390000000000320435000005ab0010009c000005ab01008041000000400110021000000604011001c7000016ab00010430000000000001004b000016630000c13d000000400200043d000100000002001d000005eb0100004100000000001204350000000401200039000000020200002916a90ed10000040f00000001020000290000000001210049000005ab0010009c000005ab010080410000006001100210000005ab0020009c000005ab020080410000004002200210000000000121019f000016ab00010430000000000001042f000000400100043d00000044021000390000060503000041000000000032043500000024021000390000001d030000390000000000320435000005eb020000410000000000210435000000040210003900000020030000390000000000320435000005ab0010009c000005ab01008041000000400110021000000606011001c7000016ab00010430000005ab0030009c000005ab030080410000004002300210000005ab0010009c000005ab010080410000006001100210000000000121019f000016ab00010430000000000001042f000005ab0010009c000005ab010080410000004001100210000005ab0020009c000005ab020080410000006002200210000000000112019f0000000002000414000005ab0020009c000005ab02008041000000c002200210000000000112019f000005c4011001c7000080100200003916a916a40000040f00000001002001900000167f0000613d000000000101043b000000000001042d0000000001000019000016ab0001043000000000050100190000000000200443000000050030008c0000168f0000413d000000040100003900000000020000190000000506200210000000000664001900000005066002700000000006060031000000000161043a0000000102200039000000000031004b000016870000413d000005ab0030009c000005ab0300804100000060013002100000000002000414000005ab0020009c000005ab02008041000000c002200210000000000112019f00000607011001c7000000000205001916a916a40000040f00000001002001900000169e0000613d000000000101043b000000000001042d000000000001042f000016a2002104210000000102000039000000000001042d0000000002000019000000000001042d000016a7002104230000000102000039000000000001042d0000000002000019000000000001042d000016a900000432000016aa0001042e000016ab0001043000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000001ffffffe000000000000000000000000000000000000000000000000000000000ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000002000000000000000000000000000000c000000100000000000000000000000000000000000000000000000000000000000000000000000000981886a600000000000000000000000000000000000000000000000000000000981886a700000000000000000000000000000000000000000000000000000000ae32859000000000000000000000000000000000000000000000000000000000f21a21160000000000000000000000000000000000000000000000000000000025d374e80000000000000000000000000000000000000000000000000000000081d82dd80000000000000000000000000000000000000020000000800000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa65bb2f450488ab0858c00edc14abc5297769bf42adb48cfb77752890e8b697b000000000000000000000000000000000000000000000000fffffffffffffe3f020000000000000000000000000000000000004000000000000000000000000000000000000000000000000011f111f111f111f111f111f111f111f111f111f100000000000000000000000000000000000000000000000000000000007dee6e000000000000000000000000000000000000000000000000000012309ce54001000000000000000000000000000000000000000000000000000416edef1601be000000000000000000000000000000000000000000000000000000002f3fb3419a8a0592ac89c5ad3bc6df8224c17b485976f597df104ee20d0df415241f670b0200000200000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffffeff02000000000000000000000000000000000000000000000000000000000000000000000019457468657265756d205369676e6564204d6573736167653a0a3332020000000000000000000000000000000000003c00000004000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000310ab089e4439a4c15d089f94afb7896ff553aecb10793d0ab882de59d99a32e02000002000000000000000000000000000000440000000000000000000000009cc7f708afc65944829bd487b90b72536b1951864fbfc14e125fc972a6507f390200000200000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffffebf70a0823100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000023b872dd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff5fcf4791810000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000440000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe07a8ac5d3b7183f220a0602439da45ea337311d699902d1ed11a3725a714e7f1effffffff000000000000000000000000000000000000000000000000000000007a8ac5d3b7183f220a0602439da45ea337311d699902d1ed11a3725a714e7f1f4e487b7100000000000000000000000000000000000000000000000000000000a9059cbb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff7f21f74345000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000275c273c0000000000000000000000000000000000000000000000000000000094539804000000000000000000000000000000000000000000000000000000000503c3ed000000000000000000000000000000000000000000000000000000004ac09ad3000000000000000000000000000000000000000000000000000000002c5211c6000000000000000000000000000000000000000000000000000000001e4ec46b0000000000000000000000000000000000000000000000000000000050dc905c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008baa579f00000000000000000000000000000000000000040000001c0000000000000000f86180300000000000000000000000000000000000000000000000000000000029f745a700000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000000000000000000000000000000000000000000ffffffffffffff80000000000000000000000000000000000000000000000000ffffffffffffff3f08c379a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffbf02000000000000000000000000000000000000200000000000000000000000007be3e48a8a8b4d32138937e1809ac83481fffe48e49bb60e43ed1d3d50349e4ccba69f43792f9f399347222505213b55af8e0b0b54b893085c2e27ecbe1644f1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000100000000000000005a04673700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffc05472616e73616374696f6e2072657665727465642073696c656e746c79000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe100000000000000000000000100000000000000000000000000000000000000001806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b83dd62ed3e00000000000000000000000000000000000000000000000000000000095ea7b30000000000000000000000000000000000000000000000000000000063ba9bff00000000000000000000000000000000000000000000000000000000796b89b91644bc98cd93958e4c9038275d622183e25ac5af08cc6b5d9553913202000000000000000000000000000000000000e00000000000000000000000007bfdfdb5e3a3776976e53cb0607060f54c5312701c8cba1155cc4d5394440b38e46e079c000000000000000000000000000000000000000000000000000000006eefed20000000000000000000000000000000000000000000000000000000005361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656400000000000000000000000000000000000000000000000000000003ffffffe06f742073756363656564000000000000000000000000000000000000000000005361666545524332303a204552433230206f7065726174696f6e20646964206e0000000000000000000000000000000000000084000000000000000000000000416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000000000000000000000000000000000000000006400000000000000000000000002000002000000000000000000000000000000000000000000000000000000008dca57fb3102b98f18a7520dc0df2ee5bb2ba78b8107df03e79b1a9c5d3cc095
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000634e831ce6d460c2cd5067af98d6452eb280e374000000000000000000000000f70da97812cb96acdf810712aa562db8dfa3dbef
-----Decoded View---------------
Arg [0] : _relayReceiver (address): 0x634E831cE6D460c2CD5067Af98D6452Eb280E374
Arg [1] : _relaySolver (address): 0xf70da97812CB96acDF810712Aa562db8dfA3dbEF
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000634e831ce6d460c2cd5067af98d6452eb280e374
Arg [1] : 000000000000000000000000f70da97812cb96acdf810712aa562db8dfa3dbef
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.