Skip to content

Instantly share code, notes, and snippets.

@turboza
Last active February 23, 2021 07:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save turboza/622cac1f1f9339a19d95baad9d630be7 to your computer and use it in GitHub Desktop.
Save turboza/622cac1f1f9339a19d95baad9d630be7 to your computer and use it in GitHub Desktop.
Investigating Superfarm IDO issues on Polkastarters

Problem

In the Superfarm IDO on Polkastarters from Feb 22, Out of ~1,000 attempts to purchase, 669 trxs failed. Many of those failures were still unclear why.

ref: https://etherscan.io/address/0x001602799ee561c9f9405176d33eba6f29ce3386 image

Commonly Failed Issue

As inspected, there are several issues, ex. not enough gas limit.

However, there is one common issue which is hard to understand what it is.

Fail with error 'User has to cover the cost of the swap in ETH, use the cost function to determine'

Potential Root Cause

The Polkadot website might not calculate the _amount of swap function correctly. So when execute the transaction it failed.

For example, this trx will never be passed because the _amount is not correctly calculated.

The sent _amount is 19230769230999997000000 instead of the correct one of 19230769231000000000000

Possibly the issue from rounding.

Detail on Finding Root Cause

As I tried to see where is the error from I found this line in the Superfarm contract.

/* Confirm the user has funds for the transfer, confirm the value is equal */
require(msg.value == cost(_amount), "User has to cover the cost of the swap in ETH, use the cost function to determine");

So I randomly picked the failed trx to replicate the calculator.

For example, this failed one https://etherscan.io/tx/0xdec2f70ab1377f843fe840f640a75025bd22e1acb2f6fcac87dad4384d4f9fcc.

Input Data

Function: swap(uint256 _tokenId) ***

MethodID: 0x94b918de
[0]:  0000000000000000000000000000000000000000000004128088e69cc2c22940

Parameter

msg.value: 0.250000000003 ETH
_amount: 19230769230999997000000 (decimal from hex value in the input data)
tradeValue: 13000000000000

And to execute the code in the error line,

cost(_amount) = 19230769230999997000000 * 13000000000000 / (10^18) 
              = 250000000002999940 wei
              = 0.25000000000299994 ETH

And we found that the cost(_amount) is not equal to msg.value (sent ETH).

cost(_amount) = 0.25000000000299994 ETH
msg.value     = 0.250000000003 ETH

⚠️ That's why the contract rejected this transaction.

And the weird number is _amount of 19230769230999997000000.

The number would pass perfectly if the _amount is 19230769231000000000000.


Note: This is all my quick observation and it could be wrong. Feel free to suggest if anything is not correct or missed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment