_mint
函数中的错误加法操作在 _mint
函数中,对于非质押账户的条件块中存在错误的加法操作。nonStakingSupply += nonStakingSupply;
应更改为 nonStakingSupply += _amount;
,因为它意图将非质押供应量增加以发行的数量,而不是以其自身的先前值。
// contracts/tokens/BaseToken.sol
function _mint(address _account, uint256 _amount) internal {
require(_account != address(0), "BaseToken: mint to the zero address");
_updateRewards(_account);
totalSupply += _amount;
balances[_account] += _amount;
if (nonStakingAccounts[_account]) {
nonStakingSupply += nonStakingSupply;//@audit
}
emit Transfer(address(0), _account, _amount);
}
Recommended
将加法操作更正为 nonStakingSupply += _amount;
。
withdraw
function index errorThe exploitable logical vulnerability in the provided Smart Contract code lies within the handling mechanisms in the withdraw
function, specifically how the refinanced status of each token ID is checked and modified. The issue arises from the premature removal of tokenRefinanceInfos
entries before checking all token IDs in the withdraw request. This approach allows a user to potentially manipulate and bypass the refinanced status check for subsequent token IDs in a batch withdrawal, leading to unauthorized actions like double withdrawal.
poc:
_user
has previously deposited two or more NFTs from the same contract _nft
into the smart contract, and these NFTs have distinct token IDs, say tokenId1
and tokenId2
.hasRefinanced = false
).tokenId1
and tokenId2
from the same NFT collection _nft
in the same transaction using the withdraw
function.tokenId1
is listed before tokenId2
.tokenId1
, the contract checks hasRefinanced
status, finds it false, and proceeds with withdrawal.tokenRefinanceInfo
of tokenId1
by replacing it with the last in the list and then popping the last element – reducing the array by one.tokenRefinanceInfos
. If tokenId2
was right next to tokenId1
in the list initially, its index is now decremented by one.tokenId2
.tokenId1
and tokenId2
), tokenId2
now occupies the index previously held by tokenId1
.tokenId2
could either reference an incorrect item or skip checks as it might wrongly assume the length constraint fails.tokenId2
(and potentially others) to bypass the crucial hasRefinanced
check, thereby allowing withdrawals even if they might have been refinanced or should not be eligible for withdrawal.Recommendations:
tokenRefinanceInfos
until after all validations and withdrawals are processed for an entire batch.