Skip to content

Commit da53846

Browse files
authored
Resolve: Add nonReentrant modifier to relevant base contract functions #601 (#611)
Add nonReentrant to possible reentrant fn calls
1 parent ed8b329 commit da53846

15 files changed

+50
-31
lines changed

contracts/base/ERC1155SignatureMint.sol

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import "./ERC1155Base.sol";
77

88
import "../extension/PrimarySale.sol";
99
import "../extension/SignatureMintERC1155.sol";
10-
10+
import { ReentrancyGuard } from "../extension/upgradeable/ReentrancyGuard.sol";
1111
import { CurrencyTransferLib } from "../lib/CurrencyTransferLib.sol";
1212

1313
/**
@@ -23,7 +23,7 @@ import { CurrencyTransferLib } from "../lib/CurrencyTransferLib.sol";
2323
*
2424
*/
2525

26-
contract ERC1155SignatureMint is ERC1155Base, PrimarySale, SignatureMintERC1155 {
26+
contract ERC1155SignatureMint is ERC1155Base, PrimarySale, SignatureMintERC1155, ReentrancyGuard {
2727
/*//////////////////////////////////////////////////////////////
2828
Constructor
2929
//////////////////////////////////////////////////////////////*/
@@ -52,7 +52,7 @@ contract ERC1155SignatureMint is ERC1155Base, PrimarySale, SignatureMintERC1155
5252
function mintWithSignature(
5353
MintRequest calldata _req,
5454
bytes calldata _signature
55-
) external payable virtual override returns (address signer) {
55+
) external payable virtual override nonReentrant returns (address signer) {
5656
require(_req.quantity > 0, "Minting zero tokens.");
5757

5858
uint256 tokenIdToMint;

contracts/base/ERC20SignatureMint.sol

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import "./ERC20Base.sol";
77

88
import "../extension/PrimarySale.sol";
99
import { SignatureMintERC20 } from "../extension/SignatureMintERC20.sol";
10-
10+
import { ReentrancyGuard } from "../extension/upgradeable/ReentrancyGuard.sol";
1111
import { CurrencyTransferLib } from "../lib/CurrencyTransferLib.sol";
1212

1313
/**
@@ -23,7 +23,7 @@ import { CurrencyTransferLib } from "../lib/CurrencyTransferLib.sol";
2323
*
2424
*/
2525

26-
contract ERC20SignatureMint is ERC20Base, PrimarySale, SignatureMintERC20 {
26+
contract ERC20SignatureMint is ERC20Base, PrimarySale, SignatureMintERC20, ReentrancyGuard {
2727
/*//////////////////////////////////////////////////////////////
2828
Constructor
2929
//////////////////////////////////////////////////////////////*/
@@ -50,7 +50,7 @@ contract ERC20SignatureMint is ERC20Base, PrimarySale, SignatureMintERC20 {
5050
function mintWithSignature(
5151
MintRequest calldata _req,
5252
bytes calldata _signature
53-
) external payable virtual returns (address signer) {
53+
) external payable virtual nonReentrant returns (address signer) {
5454
require(_req.quantity > 0, "Minting zero tokens.");
5555

5656
// Verify and process payload.

contracts/base/ERC20SignatureMintVote.sol

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import "./ERC20Vote.sol";
77

88
import "../extension/PrimarySale.sol";
99
import { SignatureMintERC20 } from "../extension/SignatureMintERC20.sol";
10-
10+
import { ReentrancyGuard } from "../extension/upgradeable/ReentrancyGuard.sol";
1111
import { CurrencyTransferLib } from "../lib/CurrencyTransferLib.sol";
1212

1313
/**
@@ -23,7 +23,7 @@ import { CurrencyTransferLib } from "../lib/CurrencyTransferLib.sol";
2323
*
2424
*/
2525

26-
contract ERC20SignatureMintVote is ERC20Vote, PrimarySale, SignatureMintERC20 {
26+
contract ERC20SignatureMintVote is ERC20Vote, PrimarySale, SignatureMintERC20, ReentrancyGuard {
2727
/*//////////////////////////////////////////////////////////////
2828
Constructor
2929
//////////////////////////////////////////////////////////////*/
@@ -50,7 +50,7 @@ contract ERC20SignatureMintVote is ERC20Vote, PrimarySale, SignatureMintERC20 {
5050
function mintWithSignature(
5151
MintRequest calldata _req,
5252
bytes calldata _signature
53-
) external payable virtual returns (address signer) {
53+
) external payable virtual nonReentrant returns (address signer) {
5454
require(_req.quantity > 0, "Minting zero tokens.");
5555

5656
// Verify and process payload.

contracts/base/ERC721Multiwrap.sol

+13-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import "../extension/Royalty.sol";
1111
import "../extension/SoulboundERC721A.sol";
1212
import "../extension/TokenStore.sol";
1313
import "../extension/Multicall.sol";
14+
import { ReentrancyGuard } from "../extension/upgradeable/ReentrancyGuard.sol";
1415

1516
/**
1617
* BASE: ERC721Base
@@ -26,7 +27,16 @@ import "../extension/Multicall.sol";
2627
*
2728
*/
2829

29-
contract ERC721Multiwrap is Multicall, TokenStore, SoulboundERC721A, ERC721A, ContractMetadata, Ownable, Royalty {
30+
contract ERC721Multiwrap is
31+
Multicall,
32+
TokenStore,
33+
SoulboundERC721A,
34+
ERC721A,
35+
ContractMetadata,
36+
Ownable,
37+
Royalty,
38+
ReentrancyGuard
39+
{
3040
/*//////////////////////////////////////////////////////////////
3141
Permission control roles
3242
//////////////////////////////////////////////////////////////*/
@@ -148,7 +158,7 @@ contract ERC721Multiwrap is Multicall, TokenStore, SoulboundERC721A, ERC721A, Co
148158
Token[] calldata _tokensToWrap,
149159
string calldata _uriForWrappedToken,
150160
address _recipient
151-
) public payable virtual onlyRoleWithSwitch(MINTER_ROLE) returns (uint256 tokenId) {
161+
) public payable virtual onlyRoleWithSwitch(MINTER_ROLE) nonReentrant returns (uint256 tokenId) {
152162
if (!hasRole(ASSET_ROLE, address(0))) {
153163
for (uint256 i = 0; i < _tokensToWrap.length; i += 1) {
154164
_checkRole(ASSET_ROLE, _tokensToWrap[i].assetContract);
@@ -170,7 +180,7 @@ contract ERC721Multiwrap is Multicall, TokenStore, SoulboundERC721A, ERC721A, Co
170180
* @param _tokenId The token Id of the wrapped NFT to unwrap.
171181
* @param _recipient The recipient of the underlying ERC1155, ERC721, ERC20 tokens of the wrapped NFT.
172182
*/
173-
function unwrap(uint256 _tokenId, address _recipient) public virtual onlyRoleWithSwitch(UNWRAP_ROLE) {
183+
function unwrap(uint256 _tokenId, address _recipient) public virtual onlyRoleWithSwitch(UNWRAP_ROLE) nonReentrant {
174184
require(_tokenId < nextTokenIdToMint(), "wrapped NFT DNE.");
175185
require(isApprovedOrOwner(msg.sender, _tokenId), "caller not approved for unwrapping.");
176186

contracts/base/ERC721SignatureMint.sol

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import "./ERC721Base.sol";
88
import "../extension/PrimarySale.sol";
99
import "../extension/PermissionsEnumerable.sol";
1010
import "../extension/SignatureMintERC721.sol";
11-
11+
import { ReentrancyGuard } from "../extension/upgradeable/ReentrancyGuard.sol";
1212
import { CurrencyTransferLib } from "../lib/CurrencyTransferLib.sol";
1313

1414
/**
@@ -24,7 +24,7 @@ import { CurrencyTransferLib } from "../lib/CurrencyTransferLib.sol";
2424
*
2525
*/
2626

27-
contract ERC721SignatureMint is ERC721Base, PrimarySale, SignatureMintERC721 {
27+
contract ERC721SignatureMint is ERC721Base, PrimarySale, SignatureMintERC721, ReentrancyGuard {
2828
/*//////////////////////////////////////////////////////////////
2929
Constructor
3030
//////////////////////////////////////////////////////////////*/
@@ -53,7 +53,7 @@ contract ERC721SignatureMint is ERC721Base, PrimarySale, SignatureMintERC721 {
5353
function mintWithSignature(
5454
MintRequest calldata _req,
5555
bytes calldata _signature
56-
) external payable virtual override returns (address signer) {
56+
) external payable virtual override nonReentrant returns (address signer) {
5757
require(_req.quantity == 1, "quantiy must be 1");
5858

5959
uint256 tokenIdToMint = nextTokenIdToMint();

contracts/prebuilts/loyalty/LoyaltyCard.sol

+4-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,10 @@ contract LoyaltyCard is
158158
}
159159

160160
/// @dev Lets an account with MINTER_ROLE mint an NFT. Always mints 1 NFT.
161-
function mintTo(address _to, string calldata _uri) external onlyRole(MINTER_ROLE) returns (uint256 tokenIdMinted) {
161+
function mintTo(
162+
address _to,
163+
string calldata _uri
164+
) external onlyRole(MINTER_ROLE) nonReentrant returns (uint256 tokenIdMinted) {
162165
tokenIdMinted = _mintTo(_to, _uri);
163166
emit TokensMinted(_to, tokenIdMinted, _uri);
164167
}

contracts/prebuilts/marketplace/english-auctions/EnglishAuctionsLogic.sol

+4-2
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ contract EnglishAuctionsLogic is IEnglishAuctions, ReentrancyGuard, ERC2771Conte
8888
/// @notice Auction ERC721 or ERC1155 NFTs.
8989
function createAuction(
9090
AuctionParameters calldata _params
91-
) external onlyListerRole onlyAssetRole(_params.assetContract) returns (uint256 auctionId) {
91+
) external onlyListerRole onlyAssetRole(_params.assetContract) nonReentrant returns (uint256 auctionId) {
9292
auctionId = _getNextAuctionId();
9393
address auctionCreator = _msgSender();
9494
TokenType tokenType = _getTokenType(_params.assetContract);
@@ -181,7 +181,9 @@ contract EnglishAuctionsLogic is IEnglishAuctions, ReentrancyGuard, ERC2771Conte
181181
}
182182

183183
/// @dev Cancels an auction.
184-
function cancelAuction(uint256 _auctionId) external onlyExistingAuction(_auctionId) onlyAuctionCreator(_auctionId) {
184+
function cancelAuction(
185+
uint256 _auctionId
186+
) external onlyExistingAuction(_auctionId) onlyAuctionCreator(_auctionId) nonReentrant {
185187
Auction memory _targetAuction = _englishAuctionsStorage().auctions[_auctionId];
186188
Bid memory _winningBid = _englishAuctionsStorage().winningBid[_auctionId];
187189

contracts/prebuilts/pack/Pack.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ contract Pack is
270270
}
271271

272272
/// @notice Lets a pack owner open packs and receive the packs' reward units.
273-
function openPack(uint256 _packId, uint256 _amountToOpen) external returns (Token[] memory) {
273+
function openPack(uint256 _packId, uint256 _amountToOpen) external nonReentrant returns (Token[] memory) {
274274
address opener = _msgSender();
275275

276276
require(isTrustedForwarder(msg.sender) || opener == tx.origin, "!EOA");

contracts/prebuilts/split/Split.sol

+7-5
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,16 @@ import "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgrad
2525
// Utils
2626
import "../../extension/Multicall.sol";
2727
import "../../lib/FeeType.sol";
28+
import "../../extension/upgradeable/ReentrancyGuard.sol";
2829

2930
contract Split is
3031
IThirdwebContract,
3132
Initializable,
3233
Multicall,
3334
ERC2771ContextUpgradeable,
3435
AccessControlEnumerableUpgradeable,
35-
PaymentSplitterUpgradeable
36+
PaymentSplitterUpgradeable,
37+
ReentrancyGuard
3638
{
3739
bytes32 private constant MODULE_TYPE = bytes32("Split");
3840
uint128 private constant VERSION = 1;
@@ -76,7 +78,7 @@ contract Split is
7678
* @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the
7779
* total shares and their previous withdrawals.
7880
*/
79-
function release(address payable account) public virtual override {
81+
function release(address payable account) public virtual override nonReentrant {
8082
uint256 payment = _release(account);
8183
require(payment != 0, "PaymentSplitter: account is not due payment");
8284
}
@@ -86,7 +88,7 @@ contract Split is
8688
* percentage of the total shares and their previous withdrawals. `token` must be the address of an IERC20
8789
* contract.
8890
*/
89-
function release(IERC20Upgradeable token, address account) public virtual override {
91+
function release(IERC20Upgradeable token, address account) public virtual override nonReentrant {
9092
uint256 payment = _release(token, account);
9193
require(payment != 0, "PaymentSplitter: account is not due payment");
9294
}
@@ -134,7 +136,7 @@ contract Split is
134136
/**
135137
* @dev Release the owed amount of token to all of the payees.
136138
*/
137-
function distribute() public virtual {
139+
function distribute() public virtual nonReentrant {
138140
uint256 count = payeeCount();
139141
for (uint256 i = 0; i < count; i++) {
140142
_release(payable(payee(i)));
@@ -144,7 +146,7 @@ contract Split is
144146
/**
145147
* @dev Release owed amount of the `token` to all of the payees.
146148
*/
147-
function distribute(IERC20Upgradeable token) public virtual {
149+
function distribute(IERC20Upgradeable token) public virtual nonReentrant {
148150
uint256 count = payeeCount();
149151
for (uint256 i = 0; i < count; i++) {
150152
_release(token, payee(i));

contracts/prebuilts/staking/EditionStake.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ contract EditionStake is
115115
}
116116

117117
/// @dev Admin can withdraw excess reward tokens.
118-
function withdrawRewardTokens(uint256 _amount) external {
118+
function withdrawRewardTokens(uint256 _amount) external nonReentrant {
119119
require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Not authorized");
120120

121121
// to prevent locking of direct-transferred tokens

contracts/prebuilts/staking/NFTStake.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ contract NFTStake is
115115
}
116116

117117
/// @dev Admin can withdraw excess reward tokens.
118-
function withdrawRewardTokens(uint256 _amount) external {
118+
function withdrawRewardTokens(uint256 _amount) external nonReentrant {
119119
require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "Not authorized");
120120

121121
// to prevent locking of direct-transferred tokens

contracts/prebuilts/token/TokenERC1155.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ contract TokenERC1155 is
215215
uint256 _tokenId,
216216
string calldata _uri,
217217
uint256 _amount
218-
) external onlyRole(MINTER_ROLE) {
218+
) external nonReentrant onlyRole(MINTER_ROLE) {
219219
uint256 tokenIdToMint;
220220
if (_tokenId == type(uint256).max) {
221221
tokenIdToMint = nextTokenIdToMint;

contracts/prebuilts/token/TokenERC20.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ contract TokenERC20 is
161161
*
162162
* - the caller must have the `MINTER_ROLE`.
163163
*/
164-
function mintTo(address to, uint256 amount) public virtual {
164+
function mintTo(address to, uint256 amount) public virtual nonReentrant {
165165
require(hasRole(MINTER_ROLE, _msgSender()), "not minter.");
166166
_mintTo(to, amount);
167167
}

contracts/prebuilts/token/TokenERC721.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ contract TokenERC721 is
191191
}
192192

193193
/// @dev Lets an account with MINTER_ROLE mint an NFT.
194-
function mintTo(address _to, string calldata _uri) external onlyRole(MINTER_ROLE) returns (uint256) {
194+
function mintTo(address _to, string calldata _uri) external nonReentrant onlyRole(MINTER_ROLE) returns (uint256) {
195195
// `_mintTo` is re-used. `mintTo` just adds a minter role check.
196196
return _mintTo(_to, _uri);
197197
}

contracts/prebuilts/unaudited/burn-to-claim-drop/extension/BurnToClaimDrop721Logic.sol

+4-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { ContractMetadata } from "../../../../extension/upgradeable/ContractMeta
3333
import { Ownable } from "../../../../extension/upgradeable/Ownable.sol";
3434
import { PermissionsStorage } from "../../../../extension/upgradeable/Permissions.sol";
3535
import { BurnToClaim, BurnToClaimStorage } from "../../../../extension/upgradeable/BurnToClaim.sol";
36+
import { ReentrancyGuard } from "../../../../extension/upgradeable/ReentrancyGuard.sol";
3637

3738
contract BurnToClaimDrop721Logic is
3839
ContractMetadata,
@@ -45,7 +46,8 @@ contract BurnToClaimDrop721Logic is
4546
LazyMint,
4647
Drop,
4748
ERC2771ContextUpgradeable,
48-
ERC721AUpgradeable
49+
ERC721AUpgradeable,
50+
ReentrancyGuard
4951
{
5052
using Strings for uint256;
5153

@@ -137,7 +139,7 @@ contract BurnToClaimDrop721Logic is
137139
//////////////////////////////////////////////////////////////*/
138140

139141
/// @notice Claim lazy minted tokens after burning required tokens from origin contract.
140-
function burnAndClaim(uint256 _burnTokenId, uint256 _quantity) external payable {
142+
function burnAndClaim(uint256 _burnTokenId, uint256 _quantity) external payable nonReentrant {
141143
_checkTokenSupply(_quantity);
142144

143145
// Verify and burn tokens on origin contract

0 commit comments

Comments
 (0)