Fast Khaki Raccoon
Medium
DecentralizedIndex::_update()
runs in an infinite loop in some cases
DecentralizedIndex::_update()
handles the ERC20 update to handle fees. The issue is that in some cases, it will run an infinite recursion. Let's imagine the simplest scenario:
function _update(address _from, address _to, uint256 _amount) internal override {
require(!_blacklist[_to], "BK");
bool _buy = _from == V2_POOL && _to != V2_ROUTER;
bool _sell = _to == V2_POOL;
uint256 _fee;
if (_swapping == 0 && _swapAndFeeOn == 1) {
if (_from != V2_POOL) {
_processPreSwapFeesAndSwap();
}
if (_buy && _fees.buy > 0) {
_fee = (_amount * _fees.buy) / DEN;
super._update(_from, address(this), _fee);
} else if (_sell && _fees.sell > 0) {
_fee = (_amount * _fees.sell) / DEN;
super._update(_from, address(this), _fee);
} else if (!_buy && !_sell && _config.hasTransferTax) {
_fee = _amount / 10000; // 0.01%
_fee = _fee == 0 && _amount > 0 ? 1 : _fee;
super._update(_from, address(this), _fee);
}
}
_processBurnFee(_fee);
super._update(_from, _to, _amount - _fee);
}
Tokens are sent from address(bob)
to address(alice)
. _buy
and _sell
will both be false, we are not swapping and swap and fee are on, we will go in the third block (assuming transfer tax is on). We will get 0.01% of the amount, give it to address(this)
, then we go out of the block and process the burn fee:
function _processBurnFee(uint256 _amtToProcess) internal {
if (_amtToProcess == 0 || _fees.burn == 0) {
return;
}
uint256 _burnAmt = (_amtToProcess * _fees.burn) / DEN;
_totalSupply -= _burnAmt;
_burn(address(this), _burnAmt);
}
There, we call _burn()
again which calls _update()
once again where _from
and _to
are address(this)
and address(0)
respectively which will bring us in the same third block, process a fee again and process the burn fees again. As seen, this will keep running in an infinite loop, eventually running out of gas.
No response
No response
- User flash mints when the transfer tax is on
- We have the following line there:
_burn(_msgSender(), _fee == 0 ? 1 : _fee);
- This will run infinitely
Some functionalities don't work properly, especially when the transfer tax is on
No response
Refactor the _update()
function