HolographERC20βs onERC20Received() is presumably a callback that is called when the Holographer receives tokens. Its implementation is:
if (_isEventRegistered(HolographERC20Event.beforeOnERC20Received)) {
require(SourceERC20().beforeOnERC20Received(account, sender, address(this), amount, data));
}
try ERC20(account).balanceOf(address(this)) returns (uint256 balance) {
require(balance >= amount, "ERC20: balance check failed");
} catch {
revert("ERC20: failed getting balance");
}
if (_isEventRegistered(HolographERC20Event.afterOnERC20Received)) {
require(SourceERC20().afterOnERC20Received(account, sender, address(this), amount, data));
}
The issue is that the balance check is insufficient to verify that βamountβ has been sent to the contract. It could already have this amount in the balance, or it can be called any number of times after a single transfer of the tokens.
This leads to very severe risks in implementations which receive beforeOnERC20Received / afterOnERC20Received calls. They will assume funds were sent and may well reward user for the transfer, although they have not actually sent the tokens.
ERC20 implementations that trust enforcerβs checks in onERC20Received() to do fund related activity are subject to loss of funds.
Manual audit
Implement some caching of current balance, which will be compared to new balance in onERC20Received.
The text was updated successfully, but these errors were encountered:
All reactions