Submitted by 0xAlix2
MiniEVM is an optimistic rollup consumer chain powered by EVM, it allows users to interact with EVM/solidity contracts through Cosmos. Part of those contracts is ERC20, which allows users to interact with ERC20Factory to create their ERC20s through Cosmos call messages.
When doing so, a new ERC20 is created, and of course, an address is generated say ADDRESS, on the Cosmos end this denom/token is saved as evm/ADDRESS (without the 0x prefix), and the corresponding EVM address is saved, this type of denoms are referred to as ERC20Denom.
Another type of denoms created is through CreateERC20, these also interact with the factory, but these are saved as just denoms, in other words, if a uinit denom is created it is just saved and referred to as uinit, the Cosmos part handles the part of minting and burning of these.
When MintCoins is called in the ERC20 keeper, it checks if the denom is ERC20Denom, if so, nothing is done, this is because minting should be done by the ERC20 creator/owner. If not, then sudoMint is called, here:
Similarly, in BurnCoins (here):
If the denom is ERC20Denom, it is supposed to be sent to the community pool. However, theres a huge flaw here, as it is sending the whole amount instead of coin.
If one of the coins returns true for types.IsERC20Denom(coin.Denom), then all the coins are sent to FundCommunityPool, not just the matching one. Then, the next iteration will send the coins again to 0x1 to be
burned. If 2 EVM coins are provided, then double of each will be sent to the fund.
Add the following test in minievm/x/evm/keeper/erc20_test.go:
minievm/x/evm/keeper/erc20.go:
leojin (Initia) confirmed and commented:
Initia mitigated:
Status: Mitigation confirmed. Full details in reports from berndartmueller, Franfran and 0xAlix2.
