diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php
index f461b525152530cb15a8a2ea8964c6170390aa09..df98969c262cea0b631504f57abd1353c4ab26d3 100644
--- a/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php
+++ b/app/code/Magento/Catalog/Block/Product/ProductList/Toolbar.php
@@ -192,7 +192,14 @@ class Toolbar extends \Magento\Framework\View\Element\Template
             $this->_collection->setPageSize($limit);
         }
         if ($this->getCurrentOrder()) {
-            $this->_collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection());
+            if ($this->getCurrentOrder() == 'position') {
+                $this->_collection->addAttributeToSort(
+                    $this->getCurrentOrder(),
+                    $this->getCurrentDirection()
+                )->addAttributeToSort('entity_id', $this->getCurrentDirection());
+            } else {
+                $this->_collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection());
+            }
         }
         return $this;
     }
diff --git a/app/code/Magento/Directory/Model/Currency.php b/app/code/Magento/Directory/Model/Currency.php
index a8df4936b8fae8ba0ece3f90a1efb3e01519fb0c..0b5b836b4ac93933b65c44f9d4447722dabc1c3a 100644
--- a/app/code/Magento/Directory/Model/Currency.php
+++ b/app/code/Magento/Directory/Model/Currency.php
@@ -6,6 +6,7 @@
 
 namespace Magento\Directory\Model;
 
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\Exception\InputException;
 use Magento\Directory\Model\Currency\Filter;
 
@@ -65,6 +66,11 @@ class Currency extends \Magento\Framework\Model\AbstractModel
      */
     protected $_localeCurrency;
 
+    /**
+     * @var CurrencyConfig
+     */
+    private $currencyConfig;
+
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
@@ -76,6 +82,7 @@ class Currency extends \Magento\Framework\Model\AbstractModel
      * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
      * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
      * @param array $data
+     * @param CurrencyConfig $currencyConfig
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
@@ -88,7 +95,8 @@ class Currency extends \Magento\Framework\Model\AbstractModel
         \Magento\Framework\Locale\CurrencyInterface $localeCurrency,
         \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
         \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
-        array $data = []
+        array $data = [],
+        CurrencyConfig $currencyConfig = null
     ) {
         parent::__construct(
             $context,
@@ -102,6 +110,7 @@ class Currency extends \Magento\Framework\Model\AbstractModel
         $this->_directoryHelper = $directoryHelper;
         $this->_currencyFilterFactory = $currencyFilterFactory;
         $this->_localeCurrency = $localeCurrency;
+        $this->currencyConfig = $currencyConfig ?: ObjectManager::getInstance()->get(CurrencyConfig::class);
     }
 
     /**
@@ -347,7 +356,7 @@ class Currency extends \Magento\Framework\Model\AbstractModel
      */
     public function getConfigAllowCurrencies()
     {
-        $allowedCurrencies = $this->_getResource()->getConfigCurrencies($this, self::XML_PATH_CURRENCY_ALLOW);
+        $allowedCurrencies = $this->currencyConfig->getConfigCurrencies(self::XML_PATH_CURRENCY_ALLOW);
         $appBaseCurrencyCode = $this->_directoryHelper->getBaseCurrencyCode();
         if (!in_array($appBaseCurrencyCode, $allowedCurrencies)) {
             $allowedCurrencies[] = $appBaseCurrencyCode;
@@ -369,8 +378,7 @@ class Currency extends \Magento\Framework\Model\AbstractModel
      */
     public function getConfigDefaultCurrencies()
     {
-        $defaultCurrencies = $this->_getResource()->getConfigCurrencies($this, self::XML_PATH_CURRENCY_DEFAULT);
-        return $defaultCurrencies;
+        return $this->currencyConfig->getConfigCurrencies(self::XML_PATH_CURRENCY_DEFAULT);
     }
 
     /**
@@ -378,8 +386,7 @@ class Currency extends \Magento\Framework\Model\AbstractModel
      */
     public function getConfigBaseCurrencies()
     {
-        $defaultCurrencies = $this->_getResource()->getConfigCurrencies($this, self::XML_PATH_CURRENCY_BASE);
-        return $defaultCurrencies;
+        return $this->currencyConfig->getConfigCurrencies(self::XML_PATH_CURRENCY_BASE);
     }
 
     /**
diff --git a/app/code/Magento/Directory/Model/CurrencyConfig.php b/app/code/Magento/Directory/Model/CurrencyConfig.php
new file mode 100644
index 0000000000000000000000000000000000000000..fdb561c2241706c83daf0b389319c59847ddfe93
--- /dev/null
+++ b/app/code/Magento/Directory/Model/CurrencyConfig.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Directory\Model;
+
+use Magento\Framework\App\Area;
+use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\App\State;
+use Magento\Store\Model\ScopeInterface;
+use Magento\Store\Model\StoreManagerInterface;
+
+/**
+ * Provide config values for allowed, base and default currencies.
+ */
+class CurrencyConfig
+{
+    /**
+     * @var State
+     */
+    private $appState;
+
+    /**
+     * @var ScopeConfigInterface
+     */
+    private $config;
+
+    /**
+     * @var StoreManagerInterface
+     */
+    private $storeManager;
+
+    /**
+     * CurrencyConfig constructor.
+     *
+     * @param State $appState
+     * @param ScopeConfigInterface $config
+     * @param StoreManagerInterface $storeManager
+     */
+    public function __construct(
+        State $appState,
+        ScopeConfigInterface $config,
+        StoreManagerInterface $storeManager
+    ) {
+        $this->appState = $appState;
+        $this->config = $config;
+        $this->storeManager = $storeManager;
+    }
+
+    /**
+     * Retrieve config currency data by config path.
+     *
+     * @param string $path
+     * @return array
+     */
+    public function getConfigCurrencies(string $path)
+    {
+        $result = $this->appState->getAreaCode() === Area::AREA_ADMINHTML
+            ? $this->getConfigForAllStores($path)
+            : $this->getConfigForCurrentStore($path);
+        sort($result);
+
+        return array_unique($result);
+    }
+
+    /**
+     * Get allowed, base and default currency codes for all stores.
+     *
+     * @param string $path
+     * @return array
+     */
+    private function getConfigForAllStores(string $path)
+    {
+        $storesResult = [[]];
+        foreach ($this->storeManager->getStores() as $store) {
+            $storesResult[] = explode(
+                ',',
+                $this->config->getValue($path, ScopeInterface::SCOPE_STORE, $store->getCode())
+            );
+        }
+
+        return array_merge(...$storesResult);
+    }
+
+    /**
+     * Get allowed, base and default currency codes for current store.
+     *
+     * @param string $path
+     * @return mixed
+     */
+    private function getConfigForCurrentStore(string $path)
+    {
+        $store = $this->storeManager->getStore();
+
+        return explode(',', $this->config->getValue($path, ScopeInterface::SCOPE_STORE, $store->getCode()));
+    }
+}
diff --git a/app/code/Magento/Directory/Model/ResourceModel/Currency.php b/app/code/Magento/Directory/Model/ResourceModel/Currency.php
index ac0716fc4e67e0bc5dc07900fd95104e8a8d56f9..ffbcce11cb4f62a17196d92d240879db52edb626 100644
--- a/app/code/Magento/Directory/Model/ResourceModel/Currency.php
+++ b/app/code/Magento/Directory/Model/ResourceModel/Currency.php
@@ -165,6 +165,8 @@ class Currency extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
      * @param string $path
      * @return array
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @deprecated because doesn't take into consideration scopes and system config values.
+     * @see \Magento\Directory\Model\CurrencyConfig::getConfigCurrencies()
      */
     public function getConfigCurrencies($model, $path)
     {
diff --git a/app/code/Magento/Directory/Test/Unit/Model/CurrencyConfigTest.php b/app/code/Magento/Directory/Test/Unit/Model/CurrencyConfigTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9b52bae26f90fd65298a0cbf6df97dd483eb77b2
--- /dev/null
+++ b/app/code/Magento/Directory/Test/Unit/Model/CurrencyConfigTest.php
@@ -0,0 +1,127 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Directory\Test\Unit\Model;
+
+use Magento\Config\App\Config\Type\System;
+use Magento\Directory\Model\CurrencyConfig;
+use Magento\Framework\App\Area;
+use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\App\State;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Store\Api\Data\StoreInterface;
+use Magento\Store\Model\StoreManagerInterface;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * Provide tests for CurrencyConfig model.
+ */
+class CurrencyConfigTest extends TestCase
+{
+    /**
+     * @var CurrencyConfig
+     */
+    private $testSubject;
+
+    /**
+     * @var System|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $config;
+
+    /**
+     * @var StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $storeManager;
+
+    /**
+     * @var State|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $appState;
+
+    /**
+     * @inheritdoc
+     */
+    protected function setUp()
+    {
+        $this->config = $this->getMockBuilder(ScopeConfigInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->storeManager = $this->getMockBuilder(StoreManagerInterface::class)
+            ->setMethods(['getStores', 'getWebsites'])
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $this->appState = $this->getMockBuilder(State::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $objectManager = new ObjectManager($this);
+        $this->testSubject = $objectManager->getObject(
+            CurrencyConfig::class,
+            [
+                'storeManager' => $this->storeManager,
+                'appState' => $this->appState,
+                'config' => $this->config,
+            ]
+        );
+    }
+
+    /**
+     * Test get currency config for admin and storefront areas.
+     *
+     * @dataProvider getConfigCurrenciesDataProvider
+     * @return void
+     */
+    public function testGetConfigCurrencies(string $areCode)
+    {
+        $path = 'test/path';
+        $expected = ['ARS', 'AUD', 'BZD'];
+
+        $this->appState->expects(self::once())
+            ->method('getAreaCode')
+            ->willReturn($areCode);
+
+        /** @var StoreInterface|\PHPUnit_Framework_MockObject_MockObject $store */
+        $store = $this->getMockBuilder(StoreInterface::class)
+            ->setMethods(['getCode'])
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $store->expects(self::once())
+            ->method('getCode')
+            ->willReturn('testCode');
+
+        if ($areCode === Area::AREA_ADMINHTML) {
+            $this->storeManager->expects(self::once())
+                ->method('getStores')
+                ->willReturn([$store]);
+        } else {
+            $this->storeManager->expects(self::once())
+                ->method('getStore')
+                ->willReturn($store);
+        }
+
+        $this->config->expects(self::once())
+            ->method('getValue')
+            ->with(
+                self::identicalTo($path)
+            )->willReturn('ARS,AUD,BZD');
+
+        $result = $this->testSubject->getConfigCurrencies($path);
+
+        self::assertEquals($expected, $result);
+    }
+
+    /**
+     * Provide test data for getConfigCurrencies test.
+     *
+     * @return array
+     */
+    public function getConfigCurrenciesDataProvider()
+    {
+        return [
+            ['areaCode' => Area::AREA_ADMINHTML],
+            ['areaCode' => Area::AREA_FRONTEND],
+        ];
+    }
+}
diff --git a/app/code/Magento/Sales/Model/Service/CreditmemoService.php b/app/code/Magento/Sales/Model/Service/CreditmemoService.php
index 2f08c26de905878219b1c738d10c51be696367df..24f56c0dbd595215956cd9134f4e8ca23ecf194c 100644
--- a/app/code/Magento/Sales/Model/Service/CreditmemoService.php
+++ b/app/code/Magento/Sales/Model/Service/CreditmemoService.php
@@ -195,7 +195,7 @@ class CreditmemoService implements \Magento\Sales\Api\CreditmemoManagementInterf
      */
     protected function validateForRefund(\Magento\Sales\Api\Data\CreditmemoInterface $creditmemo)
     {
-        if ($creditmemo->getId()) {
+        if ($creditmemo->getId() && $creditmemo->getState() != \Magento\Sales\Model\Order\Creditmemo::STATE_OPEN) {
             throw new \Magento\Framework\Exception\LocalizedException(
                 __('We cannot register an existing credit memo.')
             );
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Service/CreditmemoServiceTest.php b/app/code/Magento/Sales/Test/Unit/Model/Service/CreditmemoServiceTest.php
index 9ecab6cf9ab52d76b80d4c195c7e00608db187ec..2e668f0b0d6f114ce3adb6efc14d2292c16b4cd2 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Service/CreditmemoServiceTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Service/CreditmemoServiceTest.php
@@ -243,6 +243,78 @@ class CreditmemoServiceTest extends \PHPUnit\Framework\TestCase
         $this->assertSame($creditMemoMock, $this->creditmemoService->refund($creditMemoMock, true));
     }
 
+    public function testRefundPendingCreditMemo()
+    {
+        $creditMemoMock = $this->getMockBuilder(\Magento\Sales\Api\Data\CreditmemoInterface::class)
+            ->setMethods(['getId', 'getOrder', 'getState', 'getInvoice'])
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $creditMemoMock->expects($this->once())->method('getId')->willReturn(444);
+        $creditMemoMock->expects($this->once())->method('getState')
+            ->willReturn(\Magento\Sales\Model\Order\Creditmemo::STATE_OPEN);
+        $orderMock = $this->getMockBuilder(Order::class)->disableOriginalConstructor()->getMock();
+
+        $creditMemoMock->expects($this->atLeastOnce())->method('getOrder')->willReturn($orderMock);
+        $orderMock->expects($this->once())->method('getBaseTotalRefunded')->willReturn(0);
+        $orderMock->expects($this->once())->method('getBaseTotalPaid')->willReturn(10);
+        $creditMemoMock->expects($this->once())->method('getBaseGrandTotal')->willReturn(10);
+
+        $this->priceCurrencyMock->expects($this->any())
+            ->method('round')
+            ->willReturnArgument(0);
+
+        // Set payment adapter dependency
+        $refundAdapterMock = $this->getMockBuilder(\Magento\Sales\Model\Order\RefundAdapterInterface::class)
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $this->objectManagerHelper->setBackwardCompatibleProperty(
+            $this->creditmemoService,
+            'refundAdapter',
+            $refundAdapterMock
+        );
+
+        // Set resource dependency
+        $resourceMock = $this->getMockBuilder(\Magento\Framework\App\ResourceConnection::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->objectManagerHelper->setBackwardCompatibleProperty(
+            $this->creditmemoService,
+            'resource',
+            $resourceMock
+        );
+
+        // Set order repository dependency
+        $orderRepositoryMock = $this->getMockBuilder(\Magento\Sales\Api\OrderRepositoryInterface::class)
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $this->objectManagerHelper->setBackwardCompatibleProperty(
+            $this->creditmemoService,
+            'orderRepository',
+            $orderRepositoryMock
+        );
+
+        $adapterMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class)
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $resourceMock->expects($this->once())->method('getConnection')->with('sales')->willReturn($adapterMock);
+        $adapterMock->expects($this->once())->method('beginTransaction');
+        $refundAdapterMock->expects($this->once())
+            ->method('refund')
+            ->with($creditMemoMock, $orderMock, false)
+            ->willReturn($orderMock);
+        $orderRepositoryMock->expects($this->once())
+            ->method('save')
+            ->with($orderMock);
+        $creditMemoMock->expects($this->once())
+            ->method('getInvoice')
+            ->willReturn(null);
+        $adapterMock->expects($this->once())->method('commit');
+        $this->creditmemoRepositoryMock->expects($this->once())
+            ->method('save');
+
+        $this->assertSame($creditMemoMock, $this->creditmemoService->refund($creditMemoMock, true));
+    }
+
     /**
      * @expectedExceptionMessage The most money available to refund is 1.
      * @expectedException \Magento\Framework\Exception\LocalizedException
diff --git a/app/code/Magento/Sitemap/Model/Observer.php b/app/code/Magento/Sitemap/Model/Observer.php
index 3ae3061310a0b24a76b7bc2c410cc64c156c7ecf..840a6a1858fae5974db7f2e908b13213780dd2c2 100644
--- a/app/code/Magento/Sitemap/Model/Observer.php
+++ b/app/code/Magento/Sitemap/Model/Observer.php
@@ -113,7 +113,6 @@ class Observer
                 $sitemap->generateXml();
             } catch (\Exception $e) {
                 $errors[] = $e->getMessage();
-                throw $e;
             }
         }
 
@@ -122,8 +121,7 @@ class Observer
             \Magento\Store\Model\ScopeInterface::SCOPE_STORE
         )
         ) {
-            $translate = $this->_translateModel->getTranslateInline();
-            $this->_translateModel->setTranslateInline(false);
+            $this->inlineTranslation->suspend();
 
             $this->_transportBuilder->setTemplateIdentifier(
                 $this->_scopeConfig->getValue(
diff --git a/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php b/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php
index 92e6f4e2e2293d2b6b3e31058732df7d70810cd5..ac88f23ff9d6977f086df62cb84927f027c1eada 100644
--- a/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php
+++ b/app/code/Magento/Sitemap/Test/Unit/Model/ObserverTest.php
@@ -7,6 +7,10 @@ namespace Magento\Sitemap\Test\Unit\Model;
 
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 
+/**
+ * Class ObserverTest
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class ObserverTest extends \PHPUnit\Framework\TestCase
 {
     /**
@@ -96,11 +100,11 @@ class ObserverTest extends \PHPUnit\Framework\TestCase
         );
     }
 
-    /**
-     * @expectedException \Exception
-     */
-    public function testScheduledGenerateSitemapsThrowsException()
+    public function testScheduledGenerateSitemapsSendsExceptionEmail()
     {
+        $exception = 'Sitemap Exception';
+        $transport = $this->createMock(\Magento\Framework\Mail\TransportInterface::class);
+
         $this->scopeConfigMock->expects($this->once())->method('isSetFlag')->willReturn(true);
 
         $this->collectionFactoryMock->expects($this->once())
@@ -111,7 +115,55 @@ class ObserverTest extends \PHPUnit\Framework\TestCase
             ->method('getIterator')
             ->willReturn(new \ArrayIterator([$this->sitemapMock]));
 
-        $this->sitemapMock->expects($this->once())->method('generateXml')->willThrowException(new \Exception());
+        $this->sitemapMock->expects($this->once())
+            ->method('generateXml')
+            ->willThrowException(new \Exception($exception));
+
+        $this->scopeConfigMock->expects($this->at(1))
+            ->method('getValue')
+            ->with(
+                \Magento\Sitemap\Model\Observer::XML_PATH_ERROR_RECIPIENT,
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+            )
+            ->willReturn('error-recipient@example.com');
+
+        $this->inlineTranslationMock->expects($this->once())
+            ->method('suspend');
+
+        $this->transportBuilderMock->expects($this->once())
+            ->method('setTemplateIdentifier')
+            ->will($this->returnSelf());
+
+        $this->transportBuilderMock->expects($this->once())
+            ->method('setTemplateOptions')
+            ->with([
+                'area' => \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE,
+                'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID,
+            ])
+            ->will($this->returnSelf());
+
+        $this->transportBuilderMock->expects($this->once())
+            ->method('setTemplateVars')
+            ->with(['warnings' => $exception])
+            ->will($this->returnSelf());
+
+        $this->transportBuilderMock->expects($this->once())
+            ->method('setFrom')
+            ->will($this->returnSelf());
+
+        $this->transportBuilderMock->expects($this->once())
+            ->method('addTo')
+            ->will($this->returnSelf());
+
+        $this->transportBuilderMock->expects($this->once())
+            ->method('getTransport')
+            ->willReturn($transport);
+
+        $transport->expects($this->once())
+            ->method('sendMessage');
+
+        $this->inlineTranslationMock->expects($this->once())
+            ->method('resume');
 
         $this->observer->scheduledGenerateSitemaps();
     }
diff --git a/dev/tests/integration/testsuite/Magento/Directory/Model/CurrencyConfigTest.php b/dev/tests/integration/testsuite/Magento/Directory/Model/CurrencyConfigTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b620d9097b4befcc634d1ad4235129f632c66c5d
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Directory/Model/CurrencyConfigTest.php
@@ -0,0 +1,202 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Directory\Model;
+
+use Magento\Directory\Model\Currency as CurrencyModel;
+use Magento\Framework\App\Area;
+use Magento\Framework\App\Config\ConfigResource\ConfigInterface;
+use Magento\Framework\App\Config\ReinitableConfigInterface;
+use Magento\Store\Model\Store;
+use Magento\Store\Model\StoreManagerInterface;
+use Magento\TestFramework\App\State;
+use Magento\TestFramework\Helper\Bootstrap;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * Provide tests for CurrencyConfig model.
+ */
+class CurrencyConfigTest extends TestCase
+{
+    /**
+     * @var string
+     */
+    private $baseCurrencyPath = 'currency/options/base';
+
+    /**
+     * @var string
+     */
+    private $defaultCurrencyPath = 'currency/options/default';
+
+    /**
+     * @var string
+     */
+    private $allowedCurrenciesPath = 'currency/options/allow';
+
+    /**
+     * @var ConfigInterface
+     */
+    private $config;
+
+    /**
+     * @var CurrencyModel
+     */
+    private $currency;
+
+    /**
+     * @inheritdoc
+     */
+    protected function setUp()
+    {
+        $this->currency = Bootstrap::getObjectManager()->get(CurrencyModel::class);
+        $this->config = Bootstrap::getObjectManager()->get(ConfigInterface::class);
+    }
+
+    /**
+     * Test get currency config for admin and storefront areas.
+     *
+     * @dataProvider getConfigCurrenciesDataProvider
+     * @magentoDataFixture Magento/Store/_files/store.php
+     * @magentoDbIsolation disabled
+     * @param string $areaCode
+     * @param array $expected
+     * @return void
+     */
+    public function testGetConfigCurrencies(string $areaCode, array $expected)
+    {
+        /** @var State $appState */
+        $appState = Bootstrap::getObjectManager()->get(State::class);
+        $appState->setAreaCode($areaCode);
+        $store = Bootstrap::getObjectManager()->get(Store::class);
+        $store->load('test', 'code');
+        $this->clearCurrencyConfig();
+        $this->setStoreConfig($store->getId());
+        $storeManager = Bootstrap::getObjectManager()->get(StoreManagerInterface::class);
+        $storeManager->setCurrentStore($store->getId());
+
+        if ($areaCode === Area::AREA_ADMINHTML) {
+            self::assertEquals($expected['allowed'], $this->currency->getConfigAllowCurrencies());
+            self::assertEquals($expected['base'], $this->currency->getConfigBaseCurrencies());
+            self::assertEquals($expected['default'], $this->currency->getConfigDefaultCurrencies());
+        } else {
+            /** @var StoreManagerInterface $storeManager */
+            $storeManager = Bootstrap::getObjectManager()->get(StoreManagerInterface::class);
+            foreach ($storeManager->getStores() as $store) {
+                $storeManager->setCurrentStore($store->getId());
+                self::assertEquals(
+                    $expected[$store->getCode()]['allowed'],
+                    $this->currency->getConfigAllowCurrencies()
+                );
+                self::assertEquals(
+                    $expected[$store->getCode()]['base'],
+                    $this->currency->getConfigBaseCurrencies()
+                );
+                self::assertEquals(
+                    $expected[$store->getCode()]['default'],
+                    $this->currency->getConfigDefaultCurrencies()
+                );
+            }
+        }
+    }
+
+    /**
+     * Provide test data for getConfigCurrencies test.
+     *
+     * @return array
+     */
+    public function getConfigCurrenciesDataProvider()
+    {
+        return [
+            [
+                'areaCode' => Area::AREA_ADMINHTML,
+                'expected' => [
+                    'allowed' => ['BDT', 'BNS', 'BTD', 'EUR', 'USD'],
+                    'base' => ['BDT', 'USD'],
+                    'default' => ['BDT', 'USD'],
+                ],
+            ],
+            [
+                'areaCode' => Area::AREA_FRONTEND,
+                'expected' => [
+                    'default' => [
+                        'allowed' => ['EUR', 'USD'],
+                        'base' => ['USD'],
+                        'default' => ['USD'],
+                    ],
+                    'test' => [
+                        'allowed' => ['BDT', 'BNS', 'BTD', 'USD'],
+                        'base' => ['BDT'],
+                        'default' => ['BDT'],
+                    ],
+                ],
+            ],
+        ];
+    }
+
+    /**
+     * Remove currency config form Db.
+     *
+     * @return void
+     */
+    private function clearCurrencyConfig()
+    {
+        $storeManager = Bootstrap::getObjectManager()->get(StoreManagerInterface::class);
+        foreach ($storeManager->getStores() as $store) {
+            $this->config->deleteConfig(
+                $this->allowedCurrenciesPath,
+                'stores',
+                $store->getId()
+            );
+            $this->config->deleteConfig(
+                $this->baseCurrencyPath,
+                'stores',
+                $store->getId()
+            );
+            $this->config->deleteConfig(
+                $this->defaultCurrencyPath,
+                'stores',
+                $store->getId()
+            );
+        }
+    }
+
+    /**
+     * Set allowed, base and default currency config values for given store.
+     *
+     * @param string $storeId
+     * @return void
+     */
+    private function setStoreConfig(string $storeId)
+    {
+        $allowedCurrencies = 'BDT,BNS,BTD';
+        $baseCurrency = 'BDT';
+        $this->config->saveConfig(
+            $this->baseCurrencyPath,
+            $baseCurrency,
+            'stores',
+            $storeId
+        );
+        $this->config->saveConfig(
+            $this->defaultCurrencyPath,
+            $baseCurrency,
+            'stores',
+            $storeId
+        );
+        $this->config->saveConfig(
+            $this->allowedCurrenciesPath,
+            $allowedCurrencies,
+            'stores',
+            $storeId
+        );
+        Bootstrap::getObjectManager()->get(ReinitableConfigInterface::class)->reinit();
+        Bootstrap::getObjectManager()->create(StoreManagerInterface::class)->reinitStores();
+    }
+
+    protected function tearDown()
+    {
+        $this->clearCurrencyConfig();
+    }
+}