You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The function mintVoucher() does not satisfy the "checks, effects, interactions" pattern and as such is vulnerable to re-entrancy / read-only re-entrancy attacks from the caller.
Vulnerability Detail
The mintVoucher() function calls _safeMint(msg.sender, _voucherID) before incrementing the voucher ID:
function mintVoucher(
SharedStructs.Voucher memoryvoucher
) public onlyOwner whenNotPaused {
require(voucher.value >0, "Value of voucher must be greater than 0");
vouchers[_voucherID] = voucher;
_safeMint(msg.sender, _voucherID);
emitmintVoucherEvent(_voucherID, voucher);
_incrementVoucherID();
}
_safeMint() will call onERC721Received() on the recipient of the token in case it is a contract:
function _safeMint(addressto, uint256tokenId) internalvirtual {
_safeMint(to, tokenId, "");
}
function _safeMint(
addressto,
uint256tokenId,
bytesmemorydata
) internalvirtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
function _checkOnERC721Received(
addressfrom,
addressto,
uint256tokenId,
bytesmemorydata
) privatereturns (bool) {
if (to.isContract()) {
tryIERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4retval) {
return retval ==IERC721Receiver.onERC721Received.selector;
} catch (bytesmemoryreason) {
if (reason.length==0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
/// @solidity memory-safe-assemblyassembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
returntrue;
}
}
This gives the caller of mintVoucher() time to execute arbitrary code in a state where the voucher has been created and the token minted but the voucher ID has not been increased yet.
Impact
In the current code iteration, only the owner of WiiQareVoucherV1() can call the mintVoucher() function. If the owner is trusted, the impact is low. However, if the code evolves into a more decentralized version this could bring unbound consequences.
Summary
The function
mintVoucher()
does not satisfy the "checks, effects, interactions" pattern and as such is vulnerable to re-entrancy / read-only re-entrancy attacks from the caller.Vulnerability Detail
The
mintVoucher()
function calls_safeMint(msg.sender, _voucherID)
before incrementing the voucher ID:_safeMint()
will callonERC721Received()
on the recipient of the token in case it is a contract:This gives the caller of
mintVoucher()
time to execute arbitrary code in a state where the voucher has been created and the token minted but the voucher ID has not been increased yet.Impact
In the current code iteration, only the owner of
WiiQareVoucherV1()
can call themintVoucher()
function. If the owner is trusted, the impact is low. However, if the code evolves into a more decentralized version this could bring unbound consequences.References
audit-wiiqare-1/contracts/WiiQareVoucherV1.sol
Lines 67 to 75 in 0243110
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/7de6fd4a2604764497990bcc0013f95763713190/contracts/token/ERC721/ERC721.sol#L304-L315
Recommendation
Move the
_safeMint()
call responsible for the external call at the end of the function:The text was updated successfully, but these errors were encountered: