delegatecall is tricky to use and wrong usage or incorrect understanding can lead to devastating results.
You must keep 2 things in mind when using delegatecall
- delegatecall preserves context (storage, caller, etc...)
- storage layout must be the same for the contract calling delegatecall and the contract getting called
Use stateless Library