abstract contract AssetAdapter {

    uint16 public immutable ASSET_TYPE;  // solhint-disable-line var-name-mixedcase

    constructor(
        uint16 assetType
    ) {
        ASSET_TYPE = assetType;
    }

    /**
     * Ensure the described asset is sent to the given address.
     * Should revert if the transfer failed, but callers must also handle `false` being returned,
     * much like ERC-20's `transfer`.
     */
    function rawSendAsset(
        bytes memory assetData,
        uint256 _amount,
        address payable _to
    ) internal virtual returns (bool success);

    /**
     * Ensure the described asset is sent to this contract.
     * Should revert if the transfer failed, but callers must also handle `false` being returned,
     * much like ERC-20's `transfer`.
     */
    function rawLockAsset(
        uint256 amount,
        address payable _from
    ) internal returns (bool success) {
        return RampInstantPoolInterface(_from).sendFundsToSwap(amount);
    }

    function getAmount(bytes memory assetData) internal virtual pure returns (uint256);

    /**
     * Verify that the passed asset data can be handled by this adapter and given pool.
     *
     * @dev it's sufficient to use this only when creating a new swap -- all the other swap
     * functions first check if the swap hash is valid, while a swap hash with invalid
     * asset type wouldn't be created at all.
     *
     * @dev asset type is 2 bytes long, and it's at offset 32 in `assetData`'s memory (the first 32
     * bytes are the data length). We load the word at offset 2 (it ends with the asset type bytes),
     * and retrieve its last 2 bytes into a `uint16` variable.
     */
    modifier checkAssetTypeAndData(bytes memory assetData, address _pool) {
        uint16 assetType;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            assetType := and(
                mload(add(assetData, 2)),
                0xffff
            )
        }
        require(assetType == ASSET_TYPE, "iat");  // "invalid asset type"
        checkAssetData(assetData, _pool);
        _;
    }

    function checkAssetData(bytes memory assetData, address _pool) internal virtual view;

}
/**
 * Abstract class for an asset adapter -- a class handling a binary asset description,
 * encapsulating the asset-specific transfer logic, to maintain a single interface for the main
 * escrows contract, regardless of asset type.
 * The `assetData` bytes represent a tightly packed struct, consisting of a 2-byte (uint16) asset
 * type, followed by asset-specific data. For now there are 2 asset types, ETH and ERC-20 tokens.
 * The asset type bytes must be equal to the `ASSET_TYPE` constant in each subclass.
 *
 * @dev Subclasses of this class are used as mixins to their respective main escrows contract.
 *
 * @author Ramp Network sp. z o.o.
 */
function rawSendAsset(
    bytes memory assetData,
    uint256 _amount,
    address payable _to
) internal virtual returns (bool success);

/**
 * Ensure the described asset is sent to the given address.
 * Should revert if the transfer failed, but callers must also handle `false` being returned,
 * much like ERC-20's `transfer`.
 */