Hypothetically, say that I create an ASA called $CD. I want every single account that has a $CD balance to be sent 10% more $CD at the end of every year (compounding interest kind of like a certificate of deposit). I also want this to be done through a smart contract.
Solutions that include pools inside smart contracts are not allowed. The $CD ASA can be stored in any account, not just a smart contract account.
Have you looked at the long discussion about bonds?
This may give you some ideas.
If every account with $CD should receive 10% whether or not they kept the $CD tokens for a long period of time or just receive it, a simple solution is the following:
Have two tokens $CD-held, $CD-real
Normal accounts only hold $CD-held.
It is possible at any point in time to each 1 $CD-held for x $CD-real and vice-versa. At the beginning x = 1. After one year, x=1.1, after two years , x = 1.1*1.1 = 1.21 and so on.
This simulates your 10% increase of the holdings of $CD-real every year, without any complicated logic.
For some other solutions discussed above, if you want to rely on normal ASA, you most likely will need to freeze the ASA and use a smart contract to transfer the ASA like Securities and Permissioned Tokens | Algorand Developer Portal and references.
Finally, another solution is to use a manual out-of-chain system.