contract EthAdapter is AssetAdapterWithFees {

    uint16 internal constant ETH_TYPE_ID = 1;
    uint16 internal constant ETH_ASSET_DATA_LENGTH = 34;
    uint256 internal accumulatedFees = 0;

    constructor() internal AssetAdapter(ETH_TYPE_ID) {}

    /**
    * @dev eth assetData bytes contents:
    * offset length type     contents
    * +00    32     uint256  data length (== 0x22 == 34 bytes)
    * +32     2     uint16   asset type  (== ETH_TYPE_ID == 1)
    * +34    32     uint256  ether amount in wei
    */
    function getAmount(bytes memory assetData) internal pure returns (uint256 amount) {
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            amount := mload(add(assetData, 34))
        }
    }

    function rawSendAsset(
        bytes memory /*assetData*/,
        uint256 _amount,
        address payable _to
    ) internal returns (bool success) {
        // To enable more complex purchase receiver contracts, we're using `call.value(...)` instead
        // of plain `transfer(...)`, which allows only 2300 gas to be used by the fallback function.
        // This works for transfers to plain accounts too, no need to check if it's a contract.
        // solium-disable-next-line security/no-call-value
        (bool transferSuccessful,) = _to.call.value(_amount)("");
        require(transferSuccessful, "eth transfer failed");
        return true;
    }

    function rawAccumulateFee(bytes memory /*assetData*/, uint256 _amount) internal {
        accumulatedFees += _amount;
    }

    function withdrawFees(
        bytes calldata /*assetData*/,
        address payable _to
    ) external onlyOwner returns (bool success) {
        uint256 fees = accumulatedFees;
        accumulatedFees = 0;
        _to.transfer(fees);
        return true;
    }

    /**
     * This adapter can receive eth payments, but no other use of the fallback function is allowed.
     */
    function () external payable {
        require(msg.data.length == 0, "invalid method called");
    }

    function checkAssetData(bytes memory assetData, address /*_pool*/) internal view {
        require(assetData.length == ETH_ASSET_DATA_LENGTH, "invalid asset data length");
    }

}
function getAmount(bytes memory assetData) internal pure returns (uint256 amount) {
    // solium-disable-next-line security/no-inline-assembly
    assembly {
        amount := mload(add(assetData, 34))
    }
}

/**
 * @dev eth assetData bytes contents:
 * offset length type     contents
 * +00    32     uint256  data length (== 0x22 == 34 bytes)
 * +32     2     uint16   asset type  (== ETH_TYPE_ID == 1)
 * +34    32     uint256  ether amount in wei
 */