void Update()
{
if(EnemyHealthScript.totalslashdamage > 0)
{
StartCoroutine(Slash());
}
if(EnemyHealthScript.totalslashdamage <= 0)
{
EnemyHealthScript.totalslashdamage = 0;
}
}

IEnumerator Slash()
{
    float duration = 20f;
    float damageAmount = 0;
    float damagePerLoop = EnemyHealthScript.totalslashdamage / duration;

    while(EnemyHealthScript.totalslashdamage > 0)
    {
        EnemyHealthScript.enemyHealth -= damagePerLoop;
        Debug.Log(damagePerLoop);
        damageAmount += damagePerLoop;
        EnemyHealthScript.totalslashdamage -= damagePerLoop;
        yield return new WaitForSeconds(2.5f);
    }
}

Dot ticks way to fast and I can’t get it to work based on actual seconds not sure why. I have a varible for duration and tick rate but it just does what it wants. Like it ticks super fast. 2-3 seconds when it should be over 20 seconds.

You keep adding new Coroutines. The ... is where your code goes.

void Update()
 {
     if(EnemyHealthScript.totalslashdamage > 0)
     {
		if (doSlash)
			StartCoroutine(Slash());
     }
     if(EnemyHealthScript.totalslashdamage <= 0)
     {
         EnemyHealthScript.totalslashdamage = 0;
     }
 }

IEnumerator Slash()
 {
	doSlash = false;
 
     ...
	 
     while(EnemyHealthScript.totalslashdamage > 0)
     {
         ...
         yield return new WaitForSeconds(2.5f);
     }
	 
	 doSlash = true;
 }