Hi there! First post here and very new Solidity dev (2 weeks now) so sorry if this is an obvious question.
I’m creating an ERC-721 contract and using a few OpenZeppelin contracts as parent contracts: Ownable, ERC721, and PullPayment.
Generally what I want to do is mint a token, then send a percentage of that payment to some other addresses.
I’ve been reading up on best practices and since I will be disbursing funds to addresses programmatically from my contract, I want to ensure it is as secure as possible.
Some pseudocode for context, followed by questions.
contract MyNFT is Ownable, ERC721, PullPayment {
Counters.Counter private nftId;
...
function mintAToken() external payable {
// CHECKS - are calls to parent contracts like ERC721 ok?
// ensure the max supply has not been reached
require(totalSupply() < maximumTokens, "No supply");
// maximum one piece per address
require(balanceOf(msg.sender) == 0, "One per address");
// EFFECTS + INTERACTIONS (unclear)
// mint the token
_mint(msg.sender, nftId);
nftId.increment();
// emit events - does this count as effect or interaction?
emit NewToken(some info about token);
// send money to charity or someone else
// depositToEscrow is wrapper around PullPayment's _asyncTransfer
// external payable because apparently you can't do internal payable
uint256 percentOfPayment = getPercentOfPayment(msg.value, somePercent);
depositToEscrow(beneficiary, percentOfPayment);
}
}
-
Is calling functions derived from parent contracts (i.e.
owner()fromOwnableortotalSupply()fromERC721) ever seen as an ‘external’ call that could be used for reentrancy/other vulnerabilities? -
Additionally in the example above, is calling
_mintfromERC721an interaction and therefore no state changing should be done after it? Is incrementing thenftIdcounter after minting a vulnerability? -
Is calling external functions in the
requirestatements (checks) at the beginning of a function a vulnerability? (including something liketotalSupply()from the parent contracts, though that may be answered in 1) -
Is calling something from
PullPaymentsseen as external since it ends up calling theEscrowcontract created by my contractMyNFT(and ditto for any other child contracts of my contract)? -
Lastly, a general question: what is emitting events seen as? Can I do it safely after interactions with external contracts?
Thanks in advance, and also thanks so much to the Open Zeppelin team for your amazing contracts, it’s made everything way easier.