I’m Eloïs, a member of the PureStake development team working on Moonbeam and Moonriver. I’m excited to introduce a new proposal that will make it easier to transfer ERC20 tokens across the broader blockchain ecosystem.
Summary
This is a proposal to enable transfer of ERC20 tokens through XCM directly in Moonriver and Moonbeam.
The main idea is that all ERC20 tokens become sendables to others parachains through xtokens pallet/precompile (and receivable as well).
Abstract
Moonbeam is focused on bringing the best of both the Polkadot ecosystem and the EVM worlds to its users.
One of the main added value of the Polkadot ecosystem is of course XCM and the decentralized cross-chain interactions it provides.
In the EVM world, ERC20 tokens are a fundamental building block of the decentralized finance (DeFi) ecosystem, and enabling the transfer of ERC20 tokens across different blockchains is crucial to ensure the continued growth of the DeFi ecosystem that relies on them.
So allowing transfer of ERC20 tokens via XCM seems evident, but it raises many technical challenges that have taken time to mature and required some compromises.
Where are we now?
Currently it is not possible to transfer “real ERC20” assets through XCM. You have to create an XC20-asset (technically called “local asset”) through governance. This is restrictive but was easier to implement, and allows more security and lower costs because the asset is managed directly by the protocol.
These kind of assets expose an ERC20 API through precompiles, but they are not real evm contracts, the ERC20 api is “simulated” by the protocol.
Besides the fact that it needs to go through governance to be created, these XC20-assets are limited in functionality, they propose to define an owner who can mint/burn/freeze, but it is much more limited than what an EVM contract allows.
Why didn’t you allow transfers of ERC20 tokens through XCM from the beginning?
Relying on the implementation of a contract is risky and requires a lot of investigation time to ensure that the protocol remains secure, It was much easier to use assets managed by the protocol, so we started there first.
This is also due to the way XCM is designed. The XCM design poses two problems in particular:
- XCM is designed in such a way that assets should be burned/mint to be transferred, which is not covered by the ERC20 standards. Depending on the contract, mint/burn may not be possible, or may be allowed only by an owner/team, or may be managed by a DAO or anything else. It took time and ideas to work around/mitigate this problem.
- Each XCM instruction costs a certain weight which has to be determined before the execution of the XCM message, and if all the pre-calculated weight is not actually used there is no mechanism to refund the surplus. This is incompatible with the dynamic gas-cost paradigm of EVM.
Overall picture after this change
With the proposed implementation, any ERC20 token will be able to be sent or received through XCM without requiring any registration on the Moonriver/Moonbeam side (a registration will still be necessary on each destination parachain).
The sending will take place through the pallet/precompile xtokens, with a new variant Erc20 { contract_address }
on CurrencyId
enum. If you use the precompile, it will be enough to provide directly the address of the ERC20 contract as a “currency id”. If you want to fill in the multilocation directly, it will be of the form PalletId(Erc20Xcm)/AccountKey20(contractAddress, Network::Any)
.
For each asset that can be transferred via XCM, a unique ‘reserve chain’ is required, and in this case it must be Moonriver/Moonbeam. This is necessary in order to avoid the need to burn/mint the tokens, but it does come at a cost.
If we want to support in the future the transfer of ERC20 tokens through XCM with a reserve chain other than Moonriver/Moonbeam we will have to add constraints to the contracts (ask them to expose mint/burn methods callable by a protocol hardcoded address), which will then imply a registration/whitelist process managed by the governance.
As the reserve chain is Moonriver/Moonbeam, when a user sends ERC20 tokens to another chain, from the point of view of the ERC20 contract the tokens will be transferred to the sovereign account of the destination chain on Moonriver/Moonbeam. So we can follow how many tokens have been transferred on each chain.
When a user sends back ERC20 tokens from another chain to Moonriver/Moonbeam, this corresponds from the point of view of the ERC20 contract to a transfer from the sovereign account of the concerned chain to the user account.
There is a limitation on the amount of gas that can be used to perform the ERC20 transfer, since XCM does not support dynamic cost, we have to encode a gas limit in the protocol, and charge the full amount of this gas limit whatever the contract actually consumes. For the moment we propose to set the gas limit to 80’000 gas, which seems to be enough to support most ERC20 token transfers without being “too” expensive. In parallel we are discussing with Parity on making the design of XCM evolve, in order to better manage this point, but it’s a long work.
Security considerations
Security considerations for ERC20 contract developers
If the implementation of the transfer function returns true when the transfer has not really been done, it allows to duplicate tokens.
Indeed, in the case of sending tokens to another chain, they must be transferred to the sovereign account of the destination chain.
If the contract returns true, the XCM protocol will consider that the tokens have been transferred to the sovereign account of the destination chain and will then send the tokens on the destination chain.
We consider it to be the responsibility of each ERC20 contract to handle error cases correctly, and to return true only if the transfer really went well.
Next steps
After a few days of collecting feedback from the Community and if there are arguments against/or new suggestions, a 7 days voting session will take place. Otherwise this idea will be implemented and proposed to be included in one of the following Runtime Upgrades.
If you have any questions or comments, feel free to reply in the comment section below.