The safeMint
function updates the _setTokenData
internal state after calling _safeMint
, which may be at risk of a reentrancy attack. For example, due to the callback function in _safeMint
, an attacker could execute the safeMint
function again within the callback function, setting the same value for different tokenids.
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
totalSupply += _amount;
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(msg.sender, tokenId);
_setTokenData(tokenId, value);
Recommendation
_setTokenData(tokenId, value);
_safeMint(msg.sender, tokenId);
stakingToken
cannot be removedIf someone inadvertently sends ERC20 tokens directly to the contract (rather than through the contract's staking function), these tokens will not be recorded in the contract's totalSupply
. The withdrawAll
function only determines the amount of tokens that can be withdrawn based on totalSupply
. This means that if additional tokens are sent to the contract but are not recorded through the safeMint
or stakingMore
function, these tokens will not be included in totalSupply
.
function withdrawAll(address to) external onlyOwner {
require(finishAt<block.timestamp,"staking not finish yet");
require(totalSupply > 0, "totalSupply = 0");
stakingToken.transfer(to , totalSupply);
totalSupply =0;
}
Recommendation
Add a function to report the current ERC20 token balance of the contract, and compare it with totalSupply
to help identify and manage inconsistencies.
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external;
function allowance(address owner, address spender)
external
view
Due to the lack of return value, non-standard ERC20 interfaces may stop interacting with contracts compiled with Solidity > 0.4.22.
The correct transfer
interface is as follows:
function transfer(address to, uint256 amount) external returns (bool);
Recommendation
Set appropriate return values and types for the defined ERC20
functions.
stakingToken
with fee-on-transfer is not supportedThe staking token may transfer less token to the contract if it takes fee on transfer, causing bad balance sheet.