Hi @Joel welcome to Open Zeppelin
To my understanding reentrancy guard is for functions re-calling one that has already been entered. It's not intended to stop 2 users from calling a function in the same block (near the same time). Each user would call it separately and they would function properly.
Your function right now works "fine" as intended.
_safeMint
would finish before calling itself again in your loop in a synchronous manner.
how can I stop a malicious contract calling my mint function again and triggering 20 more _safeMints before the total supply has finished updating from the initial call?
First create a new boolean variable bool public inMinting
that should be global in scope.
Then create a modifier function
modifier lockTheMinting {
inMinting = true;
_;
inMinting = false;
}
Add this modifier to your mint function, or perhaps in a separate function.
You will need to add a
require(!inMinting, "Contract is minting, This function cannot be called while Minting.")
Somewhere in your contract to make sure they can't call the function while the minting is going on.
This way when someone mints, they are the only person that can mint at that time.
HOWEVER this introduces another problem.
What if a Malicious contract calls your Mint function before someone else can? Malicious contracts with bots could lock up the minting function and make sure no one else could mint.
My solution to that would be to create a whitelist.
Or you could create a blacklist only allowing one contract to mint one time.
It's really up to you and what you are requiring for your project.
I hope this helps, please let me know if you have more questions.