Fast Khaki Raccoon
High
flashMint
upon minting to the user would mint an enormous amounts of fees to the admin, due to _mint
invoking _update
with the flash loan amount.
function flashMint(address _recipient, uint256 _amount, bytes calldata _data) external override lock {
_shortCircuitRewards = 1;
uint256 _fee = _amount / 1000;
_mint(_recipient, _amount); // @audit it would trigger update and mint the admins fees from transfers that are not of "real" tokens
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);
//@audit right here
} 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);
}
This is dangerous as these transfers are not from "real" tokens, but ones that are used for 1 time use during rush moments, like liquidations, leveraging and so on...
Note that the same happens in burn, which is also invoked inside this function. This would not only cause the fee to be higher, but also to be taken 2 times, as both mint and burn would charge it.
_mint(_recipient, _amount);
IFlashLoanRecipient(_recipient).callback(_data);
_burn(_recipient, _amount);
_mint
triggers _update
minting an enormous amounts of fees, reducing the FL amount that our user receives, leading to his inability to repay the loan and the TX reverting.
function flashMint(address _recipient, uint256 _amount, bytes calldata _data) external override lock {
_shortCircuitRewards = 1;
uint256 _fee = _amount / 1000;
_mint(_recipient, _amount); // @audit it would trigger update and mint the admins fees from transfers that are not of "real" tokens
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);
//@audit right here
} 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);
}
No response
No response
- User uses flashmint to perform some kind of arbitrage
- Needs 10m
- Fees are 0.1%, so 10k gets minted to the admin as a fee
- User is unable to repay the loan, so the TX reverts
Users unable to use flash-loans due to _mint
triggering _update
which would mint percentage fee to the system.
FL revert in most cases.
Fee is taken 2 times, as mint and burn would take a part each time they are invoked.
No response
Don't charge percentage based fees on FL.