-
Notifications
You must be signed in to change notification settings - Fork 189
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to resolve incorrect lock? #123
Comments
This initial version of peggy is designed with the assumption that a transaction, if valid, will always succeed. This assumption should hold if a high enough threshold of validators/relayers are all operating correctly at all times. (ie, a lock will always result in a minted coin on the opposite chain, a burn will always result in an unlock on the opposite chain) The whitelist was added as a temporary fix, until more information/features could be gathered around having Cosmos's Coin and Bank systems support multiple tokens with the same denomination. (#69) So for example: in your scenario, it seems like COIN has been whitelisted, then COIN was locked on eth to create CosmosCOIN. You're trying to lock CosmosCOIN, which is not whitelisted, so it fails, preventing you from mistakenly succeeding at the incorrect lock. The way to resolve the above would to get CosmosCOIN whitelisted so that the transfer succeeds onto the Ethereum side and creates ETHCosmosCOIN, then to burn the ETHCosmosCOIN and get your CosmosCOIN back on the Cosmos side. Another of the reasons for the whitelisting feature was done to avoid the scenario like yours above, ie, prevent a user from mistakenly locking a token when they ought to burn it, though this is still not fully prevented, as the Cosmos transaction still goes through. It may be good to implement the same whitelist on the Cosmos side so that the incorrect transfer couldn't happen in the first place. This would result in challenges with having to synchronise the whitelist on both ETH/Cosmos though. Another option would be to have the whitelist checked at the UX layer, as the user is making the incorrect transfer and prevents it on the frontend (ie, the CLI checks the Ethereum whitelists, or if it was a webapp, the webapp queries ethereum for the whitelist) Again, ideally default support for all tokens including tokens with the same denomination seems most natural, and so aiming to get that feature supported on Cosmos may be the cleanest, in which case no whitelist should be needed. We considered implementing our own Coin/Bank that supported such, but it seemed like overkill and seemed like a feature that perhaps should be supported by core SDK stuff? |
I like the prefix solution better as it is able to prevent a mishap at the level of the state machine. Plus there might be other situations where it's good to be able to tell what category of asset a denom is within the SDK. Being able to check if it was an wrapped asset or not could be useful. There's also been some talk about using something like a metadata module to store information about a coin, like vesting. |
I'm not sure if the prefix method is perfect. With the prefix method, i suppose we would use something like a naming convention of: This could still result in a weird conflict, say, for example, someone named their coin on cosmos, originating on cosmos as: single_collateral_stable_coin When they tried to relay this, they would get weird unexpected issues, as we wouldn't be able to disambiguate a coin that originated on cosmos or on ethereum. I mean we could implement logic that checks the types of the first 3 prefixes and decides to assume the coin is ethereum-sourced if they match the above types and cosmos-sourced if not, but again it seems like a hacky fix based on assumptions as opposed to being super foolproof with real metadata. Ideally there was this real token metadata system included either as part of our bridge modules or built into cosmos itself - that would then allow us to unambiguously check where a token is from, whether it's wrapped or not, and more as described in those linked issues. Some of the above thinking, including waiting on a stable/defacto metadata system to emerge from the cosmos sdk team themself too is why we opted for a whitelisting based solution. The current system does still have a process for resolving an incorrect lock: The above process is cumbersome, but should work. Another addition that may be helpful is if, before step 1, in ebcli, we query ethereum (through infura or own eth node) to check the whitelist and block your transaction at the cli-level, before it even gets to the state machine. This means that the above 8 steps would still be possible by someone not using the cli or using a modified cli, but would not be possible for someone using the normal tooling. The only concern here is we'd be adding an external dependency of Infura/Eth Node on the CLI for the lock command, though that may be fine. Any thoughts? |
It's true having the fully featured metadata would be a more complete solution. I don't think there's that much wrong with just settling on a naming convention and enforcing it at the bridge level though. For example if underscore was the decided demarcation, the bridge could restrict usage to only denoms that did not contain any underscores. Probably it would be good to do something a little less common, maybe Checking the whitelist from the CLI is another option but I agree it would be good not to bog down the CLI with that kind of action. Maybe adding the relayer as an endpoint that the CLI could query for that information is an option. Your outlined solution makes sense beyond the fact that the relayer isn't capable of trying a failed transaction again. There's also the general problem of whitelisting a new token which can only be done by the operator. It seems like maybe any token coming from an SDK chain should be automatically whitelisted upon generation? For the sake of concrete actions that can be made on the current codebase that would prevent an invalid lock, I'd suggest using a single namespace to denote a token coming from on chain or off chain. The complexities of tracking chain id and bridge address are to allow multiple chains and multiple instance of a bridge on the same chain from interacting with a single sdk chain. I think that is out of scope for this version of peggy and realistically we're talking about only one sdk chain talking to one eth chain via one bridge contract. adding a prefix like Alternatively an improvement to the UX of the relayer that is able to check the status of relayed events and detect when one failed and try again would be a method of supporting the userflow you outlined as well. |
I'm in favor of removing the whitelist and updating namespacing. In my opinion the value of Also, we'll still need some sort of listed assets mapping on the contracts as we'd want to deploy a new token contract for the first lock of a cosmos-based asset but utilize the same contract for subsequent locks of the same asset. |
@okwme Cool, single namespace with a more uncommon prefix sounds fine. Agree about tracking chain id and bridge address not that important - in fact, chain id and bridge address needs to be implicitly tracked by the relayers, and all relayers need to follow them the same, otherwise this will result in clashing oracle claims and so we effectively have implicit tracking of chain id and bridge address anyway. @denalimarsh Agree, we do need to track contract addresses for tokens on both sides of the bridge though - are there any major implications for doing this on the Solidity side after removing whitelisting? I think the suggested namespacing conventions and idea to check/sync with IBC are nice, but shouldn't block us from moving forward and are easy to change as long as we aren't running with real users/$$ and don't need to maintain backwards compatibility with changes. I'm sure we'll want to implement full IBC integration in a future phase of the peggy project, still before we have real users/$$, so conventions/changes can also be made then. |
If we remove the whitelist we’ll need to add a map of (cosmos-based asset denom => token contract address). Function Some thoughts on removing param
I agree about namespacing conventions. For now, let's just use the proposed |
@denalimarsh |
Update: Cosmos SDK only supports denoms with [a-z][0-9] characters and max 16. I'm using "peggy" instead of "peg::" as the prefix. This also means there is no easy way to distinguish between two different Ethereum Tokens with the same symbol/name. Ideally I planned to include the Ethereum Token Contract address in the denom (eg: like, "peg::0x1203403450345::dai", or in denom metadata, but Cosmos SDK supports neither. The bridge will be vulnerable to an attacker that duplicates an ERC20 with the same name, mints duplicate coins for themselves, then transfers them across the bridge to the Cosmos side. This vulnerability will need to be fixed in a future version. I'll add this to the README to make it clear. |
Another solution would be to keep a registry of Eth based token denoms stored with their contract address and to create cosmos based assets with an incrementing name for collisions. So for instance the first time a contract with "Dai" is as a denom is moved over the contract address is stored and the second time a claim is relayed as "Dai" but with a different address the SDK can distinguish and will mint as "Dai-2" or something? |
@okwme Yep, this would basically effectively mean implementing a custom bridge-specific token metadata module. Ideally Cosmos SDK provides that and I think there is already talk of that? Anyway, could either build a custom metadata module into the bridge or into Cosmos itself as part of the next version, depending on feedback from the SDK team. |
rightiright i remember that discussion now. Sounds good, I think this solution works til then |
…yte-ordering Fix byte ordering in SendToCosmos
I locked an ERC-20 on Eth which was minted on SDK as Coin. Then I locked that Coin on SDK in order to return it to Eth. Of course when doing this you should not lock but instead burn the Coin. I did the incorrect lock instead of burn. After adding error logging to the Eth side it throws an error that says:
What are the methods available for undoing an incorrectly made relay?
In a similar vein: what are the methods for relaying a transactions which was originally missed?
The text was updated successfully, but these errors were encountered: