diff --git a/xmrstak/backend/amd/amd_gpu/gpu.cpp b/xmrstak/backend/amd/amd_gpu/gpu.cpp
index 9a4ba739d23e0fc9e06172d7232255361c69a9ff..b3d36e70446d2e0c74bd52c8562b90a7162eb87c 100644
--- a/xmrstak/backend/amd/amd_gpu/gpu.cpp
+++ b/xmrstak/backend/amd/amd_gpu/gpu.cpp
@@ -309,8 +309,8 @@ size_t InitOpenCLGpu(cl_context opencl_ctx, GpuContext* ctx, const char* source_
 	}
 
 	size_t scratchPadSize = std::max(
-		cn_select_memory(::jconf::inst()->GetMiningAlgo()),
-		cn_select_memory(::jconf::inst()->GetMiningAlgoRoot())
+		cn_select_memory(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo()),
+		cn_select_memory(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgoRoot())
 	);
 
 	size_t g_thd = ctx->rawIntensity;
@@ -376,8 +376,8 @@ size_t InitOpenCLGpu(cl_context opencl_ctx, GpuContext* ctx, const char* source_
 	}
 
 	xmrstak_algo miner_algo[2] = {
-		::jconf::inst()->GetMiningAlgo(),
-		::jconf::inst()->GetMiningAlgoRoot()
+		::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo(),
+		::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgoRoot()
 	};
 	int num_algos = miner_algo[0] == miner_algo[1] ? 1 : 2;
 
@@ -936,7 +936,7 @@ size_t InitOpenCL(GpuContext* ctx, size_t num_gpus, size_t platform_idx)
 size_t XMRSetJob(GpuContext* ctx, uint8_t* input, size_t input_len, uint64_t target, xmrstak_algo miner_algo)
 {
 	// switch to the kernel storage 
-	int kernel_storage = miner_algo == ::jconf::inst()->GetMiningAlgo() ? 0 : 1;
+	int kernel_storage = miner_algo == ::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo() ? 0 : 1;
 
 	cl_int ret;
 
@@ -1101,7 +1101,7 @@ size_t XMRSetJob(GpuContext* ctx, uint8_t* input, size_t input_len, uint64_t tar
 size_t XMRRunJob(GpuContext* ctx, cl_uint* HashOutput, xmrstak_algo miner_algo)
 {
 	// switch to the kernel storage
-	int kernel_storage = miner_algo == ::jconf::inst()->GetMiningAlgo() ? 0 : 1;
+	int kernel_storage = ::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo() ? 0 : 1;
 	
 	cl_int ret;
 	cl_uint zero = 0;
diff --git a/xmrstak/backend/amd/autoAdjust.hpp b/xmrstak/backend/amd/autoAdjust.hpp
index e7e98d4b264f45b604aba4e2a3358a48fec3aecc..685890bc27eafcb172fa941a1fc34575b6edbff5 100644
--- a/xmrstak/backend/amd/autoAdjust.hpp
+++ b/xmrstak/backend/amd/autoAdjust.hpp
@@ -84,8 +84,8 @@ private:
 		constexpr size_t byteToMiB = 1024u * 1024u;
 
 		size_t hashMemSize = std::max(
-			cn_select_memory(::jconf::inst()->GetMiningAlgo()),
-			cn_select_memory(::jconf::inst()->GetMiningAlgoRoot())
+			cn_select_memory(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo()),
+			cn_select_memory(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgoRoot())
 		);
 
 		std::string conf;
@@ -128,7 +128,7 @@ private:
 			}
 
 			// increase all intensity limits by two for aeon
-			if(::jconf::inst()->GetMiningAlgo() == cryptonight_lite)
+			if(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo() == cryptonight_lite)
 				maxThreads *= 2u;
 
 			// keep 128MiB memory free (value is randomly chosen)
diff --git a/xmrstak/backend/amd/minethd.cpp b/xmrstak/backend/amd/minethd.cpp
index a3acf9d0337b8d8df279b1bac48e52d1f6628859..4353e3d05d21aa01fb76be8139ff5ffe340432cd 100644
--- a/xmrstak/backend/amd/minethd.cpp
+++ b/xmrstak/backend/amd/minethd.cpp
@@ -195,7 +195,7 @@ void minethd::work_main()
 	cpu_ctx = cpu::minethd::minethd_alloc_ctx();
 	
 	// start with root algorithm and switch later if fork version is reached
-	auto miner_algo = ::jconf::inst()->GetMiningAlgoRoot();
+	auto miner_algo = ::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgoRoot();
 	cn_hash_fun hash_fun = cpu::minethd::func_selector(::jconf::inst()->HaveHardwareAes(), true /*bNoPrefetch*/, miner_algo);
 
 	globalStates::inst().iConsumeCnt++;
@@ -222,14 +222,15 @@ void minethd::work_main()
 		uint8_t new_version = oWork.getVersion();
 		if(new_version != version || oWork.iPoolId != lastPoolId)
 		{
-			if(new_version >= ::jconf::inst()->GetMiningForkVersion() || oWork.iPoolId == 0)
+			coinDescription coinDesc = ::jconf::inst()->GetCurrentCoinSelection().GetDescription(oWork.iPoolId);
+			if(new_version >= coinDesc.GetMiningForkVersion())
 			{
-				miner_algo = ::jconf::inst()->GetMiningAlgo();
+				miner_algo = coinDesc.GetMiningAlgo();
 				hash_fun = cpu::minethd::func_selector(::jconf::inst()->HaveHardwareAes(), true /*bNoPrefetch*/, miner_algo);
 			}
 			else
 			{
-				miner_algo = ::jconf::inst()->GetMiningAlgoRoot();
+				miner_algo = coinDesc.GetMiningAlgoRoot();
 				hash_fun = cpu::minethd::func_selector(::jconf::inst()->HaveHardwareAes(), true /*bNoPrefetch*/, miner_algo);
 			}
 			lastPoolId = oWork.iPoolId;
diff --git a/xmrstak/backend/cpu/autoAdjust.hpp b/xmrstak/backend/cpu/autoAdjust.hpp
index ed96d8b7b44b003045a6880e683798484b47eeb1..518721a2f6d423176a97fc726e2cac13b5285922 100644
--- a/xmrstak/backend/cpu/autoAdjust.hpp
+++ b/xmrstak/backend/cpu/autoAdjust.hpp
@@ -37,8 +37,8 @@ public:
 	{
 
 		const size_t hashMemSizeKB = std::max(
-			cn_select_memory(::jconf::inst()->GetMiningAlgo()),
-			cn_select_memory(::jconf::inst()->GetMiningAlgoRoot())
+			cn_select_memory(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo()),
+			cn_select_memory(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgoRoot())
 		) / 1024u;
 		const size_t halfHashMemSizeKB = hashMemSizeKB / 2u;
 
diff --git a/xmrstak/backend/cpu/autoAdjustHwloc.hpp b/xmrstak/backend/cpu/autoAdjustHwloc.hpp
index f110ee3efefbbb55d0f274e32492342960ef5218..b1f3914735092761bf18b7331359cae70df40193 100644
--- a/xmrstak/backend/cpu/autoAdjustHwloc.hpp
+++ b/xmrstak/backend/cpu/autoAdjustHwloc.hpp
@@ -29,8 +29,8 @@ public:
 	autoAdjust()
 	{
 		hashMemSize = std::max(
-			cn_select_memory(::jconf::inst()->GetMiningAlgo()),
-			cn_select_memory(::jconf::inst()->GetMiningAlgoRoot())
+			cn_select_memory(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo()),
+			cn_select_memory(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgoRoot())
 		);
 		halfHashMemSize = hashMemSize / 2u;
 	}
diff --git a/xmrstak/backend/cpu/crypto/cryptonight_common.cpp b/xmrstak/backend/cpu/crypto/cryptonight_common.cpp
index 3ff3cb9f573403349dd528c052d6a331e41e74b5..ee3b66301e0a0f09d75f0d0e0efe504f4f0d62c2 100644
--- a/xmrstak/backend/cpu/crypto/cryptonight_common.cpp
+++ b/xmrstak/backend/cpu/crypto/cryptonight_common.cpp
@@ -204,8 +204,8 @@ size_t cryptonight_init(size_t use_fast_mem, size_t use_mlock, alloc_msg* msg)
 cryptonight_ctx* cryptonight_alloc_ctx(size_t use_fast_mem, size_t use_mlock, alloc_msg* msg)
 {
 	size_t hashMemSize = std::max(
-		cn_select_memory(::jconf::inst()->GetMiningAlgo()),
-		cn_select_memory(::jconf::inst()->GetMiningAlgoRoot())
+		cn_select_memory(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo()),
+		cn_select_memory(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgoRoot())
 	);
 
 	cryptonight_ctx* ptr = (cryptonight_ctx*)_mm_malloc(sizeof(cryptonight_ctx), 4096);
@@ -283,8 +283,8 @@ cryptonight_ctx* cryptonight_alloc_ctx(size_t use_fast_mem, size_t use_mlock, al
 void cryptonight_free_ctx(cryptonight_ctx* ctx)
 {
 	size_t hashMemSize = std::max(
-		cn_select_memory(::jconf::inst()->GetMiningAlgo()),
-		cn_select_memory(::jconf::inst()->GetMiningAlgoRoot())
+		cn_select_memory(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo()),
+		cn_select_memory(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgoRoot())
 	);
 
 	if(ctx->ctx_info[0] != 0)
diff --git a/xmrstak/backend/cpu/minethd.cpp b/xmrstak/backend/cpu/minethd.cpp
index 9494a79404a87bb9a37997432b6eda479e7e7644..f8f70f9702b7b1e47d4418ad561ab1b1ef5bbd81 100644
--- a/xmrstak/backend/cpu/minethd.cpp
+++ b/xmrstak/backend/cpu/minethd.cpp
@@ -231,7 +231,7 @@ bool minethd::self_test()
 
 	bool bResult = true;
 
-	if(::jconf::inst()->GetMiningAlgo() == cryptonight)
+	if(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo() == cryptonight)
 	{
 		unsigned char out[32 * MAX_N];
 		cn_hash_fun hashf;
@@ -276,13 +276,13 @@ bool minethd::self_test()
 				"\xa0\x84\xf0\x1d\x14\x37\xa0\x9c\x69\x85\x40\x1b\x60\xd4\x35\x54\xae\x10\x58\x02\xc5\xf5\xd8\xa9\xb3\x25\x36\x49\xc0\xbe\x66\x05"
 				"\xa0\x84\xf0\x1d\x14\x37\xa0\x9c\x69\x85\x40\x1b\x60\xd4\x35\x54\xae\x10\x58\x02\xc5\xf5\xd8\xa9\xb3\x25\x36\x49\xc0\xbe\x66\x05", 160) == 0;
 	}
-	else if(::jconf::inst()->GetMiningAlgo() == cryptonight_lite)
+	else if(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo() == cryptonight_lite)
 	{
 	}
-	else if(::jconf::inst()->GetMiningAlgo() == cryptonight_monero)
+	else if(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo() == cryptonight_monero)
 	{
 	}
-	else if(::jconf::inst()->GetMiningAlgo() == cryptonight_aeon)
+	else if(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo() == cryptonight_aeon)
 	{
 	}
 
@@ -424,7 +424,7 @@ void minethd::work_main()
 	job_result result;
 
 	// start with root algorithm and switch later if fork version is reached
-	auto miner_algo = ::jconf::inst()->GetMiningAlgoRoot();
+	auto miner_algo = ::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgoRoot();
 	cn_hash_fun hash_fun = func_selector(::jconf::inst()->HaveHardwareAes(), bNoPrefetch, miner_algo);
 	ctx = minethd_alloc_ctx();
 
@@ -464,14 +464,15 @@ void minethd::work_main()
 		uint8_t new_version = oWork.getVersion();
 		if(new_version != version || oWork.iPoolId != lastPoolId)
 		{
-			if(new_version >= ::jconf::inst()->GetMiningForkVersion() || oWork.iPoolId == 0)
+			coinDescription coinDesc = ::jconf::inst()->GetCurrentCoinSelection().GetDescription(oWork.iPoolId);
+			if(new_version >= coinDesc.GetMiningForkVersion())
 			{
-				miner_algo = ::jconf::inst()->GetMiningAlgo();
+				miner_algo = coinDesc.GetMiningAlgo();
 				hash_fun = func_selector(::jconf::inst()->HaveHardwareAes(), bNoPrefetch, miner_algo);
 			}
 			else
 			{
-				miner_algo = ::jconf::inst()->GetMiningAlgoRoot();
+				miner_algo = coinDesc.GetMiningAlgoRoot();
 				hash_fun = func_selector(::jconf::inst()->HaveHardwareAes(), bNoPrefetch, miner_algo);
 			}
 			lastPoolId = oWork.iPoolId;
@@ -696,7 +697,7 @@ void minethd::multiway_work_main()
 	globalStates::inst().iConsumeCnt++;
 
 	// start with root algorithm and switch later if fork version is reached
-	auto miner_algo = ::jconf::inst()->GetMiningAlgoRoot();
+	auto miner_algo = ::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgoRoot();
 	cn_hash_fun_multi hash_fun_multi = func_multi_selector(N, ::jconf::inst()->HaveHardwareAes(), bNoPrefetch, miner_algo);
 	uint8_t version = 0;
 	size_t lastPoolId = 0;
@@ -728,14 +729,15 @@ void minethd::multiway_work_main()
 		uint8_t new_version = oWork.getVersion();
 		if(new_version != version || oWork.iPoolId != lastPoolId)
 		{
-			if(new_version >= ::jconf::inst()->GetMiningForkVersion() || oWork.iPoolId == 0)
+			coinDescription coinDesc = ::jconf::inst()->GetCurrentCoinSelection().GetDescription(oWork.iPoolId);
+			if(new_version >= coinDesc.GetMiningForkVersion())
 			{
-				miner_algo = ::jconf::inst()->GetMiningAlgo();
+				miner_algo = coinDesc.GetMiningAlgo();
 				hash_fun_multi = func_multi_selector(N, ::jconf::inst()->HaveHardwareAes(), bNoPrefetch, miner_algo);
 			}
 			else
 			{
-				miner_algo = ::jconf::inst()->GetMiningAlgoRoot();
+				miner_algo = coinDesc.GetMiningAlgoRoot();
 				hash_fun_multi = func_multi_selector(N, ::jconf::inst()->HaveHardwareAes(), bNoPrefetch, miner_algo);
 			}
 			lastPoolId = oWork.iPoolId;
diff --git a/xmrstak/backend/nvidia/minethd.cpp b/xmrstak/backend/nvidia/minethd.cpp
index 4593dab04850794a8ab953fe39318c6270323323..92f5f789b0c649f4aa2a1270a8612a535a3b47ad 100644
--- a/xmrstak/backend/nvidia/minethd.cpp
+++ b/xmrstak/backend/nvidia/minethd.cpp
@@ -239,7 +239,7 @@ void minethd::work_main()
 	cpu_ctx = cpu::minethd::minethd_alloc_ctx();
 	
 	// start with root algorithm and switch later if fork version is reached
-	auto miner_algo = ::jconf::inst()->GetMiningAlgoRoot();
+	auto miner_algo = ::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgoRoot();
 	cn_hash_fun hash_fun = cpu::minethd::func_selector(::jconf::inst()->HaveHardwareAes(), true /*bNoPrefetch*/, miner_algo);
 	
 	uint32_t iNonce;
@@ -267,14 +267,15 @@ void minethd::work_main()
 		uint8_t new_version = oWork.getVersion();
 		if(new_version != version || oWork.iPoolId != lastPoolId)
 		{
-			if(new_version >= ::jconf::inst()->GetMiningForkVersion() || oWork.iPoolId == 0)
+			coinDescription coinDesc = ::jconf::inst()->GetCurrentCoinSelection().GetDescription(oWork.iPoolId);
+			if(new_version >= coinDesc.GetMiningForkVersion())
 			{
-				miner_algo = ::jconf::inst()->GetMiningAlgo();
+				miner_algo = coinDesc.GetMiningAlgo();
 				hash_fun = cpu::minethd::func_selector(::jconf::inst()->HaveHardwareAes(), true /*bNoPrefetch*/, miner_algo);
 			}
 			else
 			{
-				miner_algo = ::jconf::inst()->GetMiningAlgoRoot();
+				miner_algo = coinDesc.GetMiningAlgoRoot();
 				hash_fun = cpu::minethd::func_selector(::jconf::inst()->HaveHardwareAes(), true /*bNoPrefetch*/, miner_algo);
 			}
 			lastPoolId = oWork.iPoolId;
diff --git a/xmrstak/backend/nvidia/nvcc_code/cuda_extra.cu b/xmrstak/backend/nvidia/nvcc_code/cuda_extra.cu
index f016ef40b36a12ebc2075a88b5992e45902dee48..f192f01ddc4e0ced551ff72e3fa93e7bdfebf941 100644
--- a/xmrstak/backend/nvidia/nvcc_code/cuda_extra.cu
+++ b/xmrstak/backend/nvidia/nvcc_code/cuda_extra.cu
@@ -280,14 +280,14 @@ extern "C" int cryptonight_extra_cpu_init(nvid_ctx* ctx)
 		CUDA_CHECK(ctx->device_id, cudaDeviceSetCacheConfig(cudaFuncCachePreferL1));
 
 	size_t hashMemSize = std::max(
-		cn_select_memory(::jconf::inst()->GetMiningAlgo()),
-		cn_select_memory(::jconf::inst()->GetMiningAlgoRoot())
+		cn_select_memory(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo()),
+		cn_select_memory(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgoRoot())
 	);
 
 	size_t wsize = ctx->device_blocks * ctx->device_threads;
 	CUDA_CHECK(ctx->device_id, cudaMalloc(&ctx->d_ctx_state, 50 * sizeof(uint32_t) * wsize));
 	size_t ctx_b_size = 4 * sizeof(uint32_t) * wsize;
-	if(cryptonight_heavy == ::jconf::inst()->GetMiningAlgo())
+	if(cryptonight_heavy == ::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo())
 	{
 		// extent ctx_b to hold the state of idx0
 		ctx_b_size += sizeof(uint32_t) * wsize;
@@ -580,8 +580,8 @@ extern "C" int cuda_get_deviceinfo(nvid_ctx* ctx)
 		ctx->free_device_memory = freeMemory;
 
 		size_t hashMemSize = std::max(
-			cn_select_memory(::jconf::inst()->GetMiningAlgo()),
-			cn_select_memory(::jconf::inst()->GetMiningAlgoRoot())
+			cn_select_memory(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo()),
+			cn_select_memory(::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgoRoot())
 		);
 
 #ifdef WIN32
@@ -612,7 +612,7 @@ extern "C" int cuda_get_deviceinfo(nvid_ctx* ctx)
 		// up to 16kibyte extra memory is used per thread for some kernel (lmem/local memory)
 		// 680bytes are extra meta data memory per hash
 		size_t perThread = hashMemSize + 16192u + 680u;
-		if(cryptonight_heavy == ::jconf::inst()->GetMiningAlgo())
+		if(cryptonight_heavy == ::jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo())
 			perThread += 50 * 4; // state double buffer
 		
 		size_t max_intensity = limitedMemory / perThread;
diff --git a/xmrstak/jconf.cpp b/xmrstak/jconf.cpp
index 6fad9b4bfd90de470eaec4e7266f9fa4244bf11d..3f55eba92ab33b0d3ae87bb414cdcfa11e5ecab3 100644
--- a/xmrstak/jconf.cpp
+++ b/xmrstak/jconf.cpp
@@ -86,35 +86,27 @@ configVal oConfigValues[] = {
 
 constexpr size_t iConfigCnt = (sizeof(oConfigValues)/sizeof(oConfigValues[0]));
 
-struct xmrstak_coin_algo
-{
-	const char* coin_name;
-	xmrstak_algo algo;
-	xmrstak_algo algo_root;
-	uint8_t fork_version;
-	const char* default_pool;
-};
-
-xmrstak_coin_algo coin_algos[] = { 
-	{ "aeon7", cryptonight_aeon, cryptonight_lite, 7u, "mine.aeon-pool.com:5555" },
-	{ "croat", cryptonight, cryptonight, 0u, nullptr },
-	{ "cryptonight", cryptonight, cryptonight, 0u, nullptr },
-	{ "cryptonight_lite", cryptonight_lite, cryptonight_lite, 0u, nullptr },
+xmrstak::coin_selection coins[] = {
+	// name, userpool, devpool, default_pool_suggestion
+	{ "aeon7",            {cryptonight_aeon, cryptonight_lite, 7u}, {cryptonight_aeon, cryptonight_lite, 7u}, "mine.aeon-pool.com:5555" },
+	{ "croat",            {cryptonight, cryptonight, 0u},           {cryptonight, cryptonight, 0u},            nullptr },
+	{ "cryptonight",      {cryptonight, cryptonight, 0u},           {cryptonight, cryptonight, 0u},            nullptr },
+	{ "cryptonight_lite", {cryptonight_lite, cryptonight_lite, 0u}, {cryptonight_lite, cryptonight_lite, 0u},  nullptr },
+	{ "edollar",          {cryptonight, cryptonight, 0u},           {cryptonight, cryptonight, 0u},            nullptr },
+	{ "electroneum",      {cryptonight, cryptonight, 0u},           {cryptonight, cryptonight, 0u},            nullptr },
+	{ "graft",            {cryptonight_monero, cryptonight, 8u},    {cryptonight_monero, cryptonight, 7u},     nullptr },
+	{ "haven",            {cryptonight_heavy, cryptonight, 2u},     {cryptonight_heavy, cryptonight, 3u},      nullptr },
+	{ "intense",          {cryptonight, cryptonight, 0u},           {cryptonight, cryptonight, 0u},            nullptr },
+	{ "karbo",            {cryptonight, cryptonight, 0u},           {cryptonight, cryptonight, 0u},            nullptr },
+	{ "monero7",          {cryptonight_monero, cryptonight, 7u},    {cryptonight_monero, cryptonight, 7u},     "pool.usxmrpool.com:3333" },
+	{ "stellite",         {cryptonight_monero, cryptonight, 3u},    {cryptonight_monero, cryptonight, 7u},     nullptr },
 	{ "cryptonight_heavy", cryptonight_heavy, cryptonight_heavy, 0u, nullptr },
+	{ "sumokoin",         {cryptonight_heavy, cryptonight, 3u},     {cryptonight_heavy, cryptonight, 3u},      nullptr }
 	{ "cryptonight_lite_v7", cryptonight_aeon, cryptonight_aeon, 0u, nullptr },
 	{ "cryptonight_v7", cryptonight_monero, cryptonight_monero, 0u, nullptr },
-	{ "edollar", cryptonight, cryptonight, 0u, nullptr },
-	{ "electroneum", cryptonight, cryptonight, 0u, nullptr },
-	{ "graft", cryptonight_monero, cryptonight, 8u, nullptr },
-	{ "haven", cryptonight_heavy, cryptonight, 2u, nullptr },
-	{ "intense", cryptonight, cryptonight, 0u, nullptr },
-	{ "karbo", cryptonight, cryptonight, 0u, nullptr },
-	{ "monero7", cryptonight_monero, cryptonight, 7u, "pool.usxmrpool.com:3333" },
-	{ "stellite", cryptonight_monero, cryptonight, 3u, nullptr },
-	{ "sumokoin", cryptonight_heavy, cryptonight, 3u, nullptr }
 };
 
-constexpr size_t coin_alogo_size = (sizeof(coin_algos)/sizeof(coin_algos[0]));
+constexpr size_t coin_alogo_size = (sizeof(coins)/sizeof(coins[0]));
 
 inline bool checkType(Type have, Type want)
 {
@@ -318,7 +310,7 @@ void jconf::GetAlgoList(std::string& list)
 	for(size_t i=0; i < coin_alogo_size; i++)
 	{
 		list += "\t- ";
-		list += coin_algos[i].coin_name;
+		list += coins[i].coin_name;
 		list += "\n";
 	}
 }
@@ -336,7 +328,7 @@ bool jconf::IsOnAlgoList(std::string& needle)
 
 	for(size_t i=0; i < coin_alogo_size; i++)
 	{
-		if(needle == coin_algos[i].coin_name)
+		if(needle == coins[i].coin_name)
 			return true;
 	}
 	return false;
@@ -348,10 +340,10 @@ const char* jconf::GetDefaultPool(const char* needle)
 	
 	for(size_t i=0; i < coin_alogo_size; i++)
 	{
-		if(strcmp(needle, coin_algos[i].coin_name) == 0)
+		if(strcmp(needle, coins[i].coin_name) == 0)
 		{
-			if(coin_algos[i].default_pool != nullptr)
-				return coin_algos[i].default_pool;
+			if(coins[i].default_pool != nullptr)
+				return coins[i].default_pool;
 			else
 				return default_example;
 		}
@@ -635,16 +627,14 @@ bool jconf::parse_config(const char* sFilename, const char* sFilenamePools)
 			return false;
 		}
 
-		if(ctmp == coin_algos[i].coin_name)
+		if(ctmp == coins[i].coin_name)
 		{
-			mining_algo = coin_algos[i].algo;
-			mining_algo_root = coin_algos[i].algo_root;
-			mining_fork_version = coin_algos[i].fork_version;
+			currentCoin = coins[i];
 			break;
 		}
 	}
 
-	if(mining_algo == invalid_algo)
+	if(currentCoin.GetDescription(1).GetMiningAlgo() == invalid_algo)
 	{
 		std::string cl;
 		GetAlgoList(cl);
diff --git a/xmrstak/jconf.hpp b/xmrstak/jconf.hpp
index 76b93ddaede4145dcac240708a95132310270670..102b70f54f761ca6f0add0c4b24b8430d69d53ef 100644
--- a/xmrstak/jconf.hpp
+++ b/xmrstak/jconf.hpp
@@ -1,7 +1,7 @@
 #pragma once
 
-#include "xmrstak/backend/cryptonight.hpp"
 #include "xmrstak/misc/environment.hpp"
+#include "xmrstak/misc/coinDescription.hpp"
 #include "params.hpp"
 
 #include <stdlib.h>
@@ -48,12 +48,8 @@ public:
 
 	bool TlsSecureAlgos();
 
-	inline xmrstak_algo GetMiningAlgo() const { return mining_algo; }
+	inline xmrstak::coin_selection GetCurrentCoinSelection() const { return currentCoin; }
 
-	inline xmrstak_algo GetMiningAlgoRoot() const { return mining_algo_root; }
-
-	inline uint8_t GetMiningForkVersion() const { return mining_fork_version; }
-	
 	std::string GetMiningCoin();
 
 	static void GetAlgoList(std::string& list);
@@ -94,7 +90,5 @@ private:
 	opaque_private* prv;
 
 	bool bHaveAes;
-	xmrstak_algo mining_algo;
-	xmrstak_algo mining_algo_root;
-	uint8_t mining_fork_version;
+	xmrstak::coin_selection currentCoin;
 };
diff --git a/xmrstak/misc/coinDescription.hpp b/xmrstak/misc/coinDescription.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..c8acf04e3712fcd63e4bcb2d92b78da0e03840b6
--- /dev/null
+++ b/xmrstak/misc/coinDescription.hpp
@@ -0,0 +1,60 @@
+#pragma once
+
+#include "xmrstak/backend/cryptonight.hpp"
+
+#include <stdlib.h>
+#include <string>
+
+
+namespace xmrstak
+{
+	struct coinDescription
+	{
+		xmrstak_algo algo;
+		xmrstak_algo algo_root;
+		uint8_t fork_version;
+
+		coinDescription() = default;
+
+		coinDescription(const xmrstak_algo in_algo, xmrstak_algo in_algo_root, const uint8_t in_fork_version) :
+			algo(in_algo), algo_root(in_algo_root), fork_version(in_fork_version)
+		{}
+
+		inline xmrstak_algo GetMiningAlgo() const { return algo; }
+		inline xmrstak_algo GetMiningAlgoRoot() const { return algo_root; }
+		inline uint8_t GetMiningForkVersion() const { return fork_version; }
+	};
+
+	struct coin_selection
+	{
+		const char* coin_name = nullptr;
+		/* [0] -> user pool
+		 * [1] -> dev pool
+		 */
+		coinDescription pool_coin[2];
+		const char* default_pool = nullptr;
+
+		coin_selection() = default;
+
+		coin_selection(
+			const char* in_coin_name,
+			const coinDescription user_coinDescription,
+			const coinDescription dev_coinDescription,
+			const char* in_default_pool
+		) :
+			coin_name(in_coin_name), default_pool(in_default_pool)
+		{
+			pool_coin[0] = user_coinDescription;
+			pool_coin[1] = dev_coinDescription;
+		}
+
+		/** get coin description for the pool
+		 *
+		 * @param poolId 0 select dev pool, else the user pool is selected
+		 */
+		inline coinDescription GetDescription(size_t poolId) const {
+			coinDescription tmp = (poolId == 0 ? pool_coin[1] : pool_coin[0]);
+			return tmp;
+		}
+	};
+} // namespace xmrstak
\ No newline at end of file
diff --git a/xmrstak/misc/executor.cpp b/xmrstak/misc/executor.cpp
index 0e1dd9f4e203f8fe60f79e699d4b2d48988dc2ef..8c454ebc141af58f450c31c860795e206727b599 100644
--- a/xmrstak/misc/executor.cpp
+++ b/xmrstak/misc/executor.cpp
@@ -421,7 +421,9 @@ void executor::on_miner_result(size_t pool_id, job_result& oResult)
 	{
 		//Ignore errors silently
 		if(pool->is_running() && pool->is_logged_in())
-			pool->cmd_submit(oResult.sJobID, oResult.iNonce, oResult.bResult, backend_name, backend_hashcount, total_hashcount, jconf::inst()->GetMiningAlgo());
+			pool->cmd_submit(oResult.sJobID, oResult.iNonce, oResult.bResult, backend_name, 
+			backend_hashcount, total_hashcount, jconf::inst()->GetCurrentCoinSelection().GetDescription(0).GetMiningAlgo()
+		);
 		return;
 	}
 
@@ -432,7 +434,9 @@ void executor::on_miner_result(size_t pool_id, job_result& oResult)
 	}
 
 	size_t t_start = get_timestamp_ms();
-	bool bResult = pool->cmd_submit(oResult.sJobID, oResult.iNonce, oResult.bResult, backend_name, backend_hashcount, total_hashcount, jconf::inst()->GetMiningAlgo());
+	bool bResult = pool->cmd_submit(oResult.sJobID, oResult.iNonce, oResult.bResult, 
+		backend_name, backend_hashcount, total_hashcount, jconf::inst()->GetCurrentCoinSelection().GetDescription(1).GetMiningAlgo()
+	);
 	size_t t_len = get_timestamp_ms() - t_start;
 
 	if(t_len > 0xFFFF)
@@ -548,7 +552,7 @@ void executor::ex_main()
 		pools.emplace_back(i+1, params.poolURL.c_str(), params.poolUsername.c_str(), params.poolRigid.c_str(), params.poolPasswd.c_str(), 9.9, false, params.poolUseTls, "", params.nicehashMode);
 	}
 
-	switch(jconf::inst()->GetMiningAlgo())
+	switch(jconf::inst()->GetCurrentCoinSelection().GetDescription(0).GetMiningAlgo())
 	{
 	case cryptonight_heavy:
 		if(dev_tls)