AthanorLabs / atomic-swap

💫 ETH-XMR atomic swap implementation
GNU Lesser General Public License v3.0
345 stars 44 forks source link

additonal erc20 and taker decimal checks #478

Closed dimalinux closed 1 year ago

dimalinux commented 1 year ago

When making an offer between XMR and ETH, it is impossible for the maker to propose min/max values in XMR that can not be represented in whole WEI units. This is because XMR is limited to 12 decimal places and the exchange rate is capped at 6 decimal places. This doesn't prevent all problems though. The taker can chose a value between the maker's min/max values that, when converted to ETH, result in fractional piconeros when divided by the exchange rate. We could allow rounding in this case (not done in this PR), as long as our code never expects provided = ToETH(ToXMR(provided)). This inverse-equal expectation could happen if, for example, the taker looks at the maker-locked XMR balance, converts it back to ETH and then compares the converted amount. If the piconero amount was rounded down for the locked amount, when converting back to ETH the value will be less than what the taker provided. In this PR, we just restrict taker values that could result in fractional piconero calculations to avoid these subtle rounding issues.

When making an offer between XMR and an ER20 token, even the existing maker limitations were insufficient. Some tokens, mainly stablecoins, only have 6 decimal places. That means that a maker could provide min/max values that, when converted into the token, would be more precise than the token supports. If rounding is used (not done in this PR), we'd need to be careful that min values are rounded up and max values are rounded down in the token units. Otherwise, the reverse calculation from the rounded token units leads to out-of-offer-range values when converting back to XMR.

In this PR we restrict all min/max amounts to values that are fully reversible: x = ToXMR(ToEth(x)). We also restrict all taker provided amounts to values that are fully reversible: y = ToETH(ToXMR(y)).

If the taker tries to provide an amount that is not fully reversible, we include the closest possible alternative value that is reversible in the error message, as computing this value would be non-trivial for end users to do on their own.

codecov[bot] commented 1 year ago

Codecov Report

Patch coverage: 85.24% and project coverage change: +0.01 :tada:

Comparison is base (65f75c2) 58.74% compared to head (29849e8) 58.75%.

Additional details and impacted files ```diff @@ Coverage Diff @@ ## master #478 +/- ## ========================================== + Coverage 58.74% 58.75% +0.01% ========================================== Files 128 128 Lines 12437 12608 +171 ========================================== + Hits 7306 7408 +102 - Misses 4360 4446 +86 + Partials 771 754 -17 ``` | [Impacted Files](https://app.codecov.io/gh/AthanorLabs/atomic-swap/pull/478?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | | |---|---|---| | [common/rpctypes/jsonrpc.go](https://app.codecov.io/gh/AthanorLabs/atomic-swap/pull/478?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-Y29tbW9uL3JwY3R5cGVzL2pzb25ycGMuZ28=) | `0.00% <0.00%> (ø)` | | | [protocol/txsender/external\_sender.go](https://app.codecov.io/gh/AthanorLabs/atomic-swap/pull/478?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cHJvdG9jb2wvdHhzZW5kZXIvZXh0ZXJuYWxfc2VuZGVyLmdv) | `0.00% <0.00%> (ø)` | | | [protocol/xmrmaker/ethereum\_asset\_amount.go](https://app.codecov.io/gh/AthanorLabs/atomic-swap/pull/478?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cHJvdG9jb2wveG1ybWFrZXIvZXRoZXJldW1fYXNzZXRfYW1vdW50Lmdv) | `35.71% <37.50%> (ø)` | | | [protocol/xmrmaker/backend\_offers.go](https://app.codecov.io/gh/AthanorLabs/atomic-swap/pull/478?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cHJvdG9jb2wveG1ybWFrZXIvYmFja2VuZF9vZmZlcnMuZ28=) | `51.21% <43.75%> (+1.21%)` | :arrow_up: | | [coins/round.go](https://app.codecov.io/gh/AthanorLabs/atomic-swap/pull/478?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-Y29pbnMvcm91bmQuZ28=) | `76.92% <77.27%> (+1.92%)` | :arrow_up: | | [protocol/xmrmaker/net.go](https://app.codecov.io/gh/AthanorLabs/atomic-swap/pull/478?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cHJvdG9jb2wveG1ybWFrZXIvbmV0Lmdv) | `52.54% <77.27%> (+2.09%)` | :arrow_up: | | [coins/exchange\_rate.go](https://app.codecov.io/gh/AthanorLabs/atomic-swap/pull/478?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-Y29pbnMvZXhjaGFuZ2VfcmF0ZS5nbw==) | `79.41% <85.18%> (+8.82%)` | :arrow_up: | | [protocol/xmrtaker/net.go](https://app.codecov.io/gh/AthanorLabs/atomic-swap/pull/478?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cHJvdG9jb2wveG1ydGFrZXIvbmV0Lmdv) | `81.48% <89.28%> (+10.24%)` | :arrow_up: | | [coins/coins.go](https://app.codecov.io/gh/AthanorLabs/atomic-swap/pull/478?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-Y29pbnMvY29pbnMuZ28=) | `91.20% <90.00%> (+1.55%)` | :arrow_up: | | [ethereum/test\_support.go](https://app.codecov.io/gh/AthanorLabs/atomic-swap/pull/478?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-ZXRoZXJldW0vdGVzdF9zdXBwb3J0Lmdv) | `96.74% <96.00%> (-3.26%)` | :arrow_down: | | ... and [13 more](https://app.codecov.io/gh/AthanorLabs/atomic-swap/pull/478?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | | ... and [17 files with indirect coverage changes](https://app.codecov.io/gh/AthanorLabs/atomic-swap/pull/478/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Do you have feedback about the report comment? Let us know in this issue.