Investigating dapp smart contract transactions


#1

Background: About a week ago @preethi posted an interesting twitter thread that suggested some dapps were creating the illusion of ‘success’ by creating wallets and sending money back and forth to generate bogus numbers; if true, these practices could easily mislead investors to pour money into non-performing projects (Source)

As this would be a natural area for TruStory to investigate, Preethi put a call out to the community. Thanks to @masher and @Catherinesjkim for taking the lead, doing some quick analyses to brainstorming (slack storming?) an initial framework for how we might investigate such claims.

Last Thursday, Mattison, Catherine, @sijo0703, @dnivrav and I met over zoom to discuss how we might proceed. @masher explained an initial approach as follows:

  1. We would go to Dapprader, as they curate all the dapps across ETH, EOS, and TRX (also providing ranking for most popular ones); to facilitate our investigation, we would initially limit our exploration to Ethereum dapps as the tooling for examining transactions within a dapp smart contract is the most advanced (most abundance of data to examine)
  2. We discussed what it might mean to have ‘bogus transactions’. @masher and @Catherinesjkim had previously looked at a popular dapp - My Crypto Hero - and saw a bunch of different transactions for “0 Ether” and reasoned that that would be a good place to start looking for suspicious activity because why would an address send multiple transactions of 0 Ether, but still pay a transaction fee each time? The idea of non-fungible tokens (NFT) as a reason for 0 Ether transaction came up, so we decided that our initial explorations would be for Dapps that had no reason to send NFTs. So instead of Games or Collectibles where a user might trade NFTs, and thus potentially confounding our analysis, we decided to start our investigation on Gambling dapps (we reasoned there should be no reason to send NFTs)
  3. We would each pick a Gambling dapp, go to it’s profile on Dapprader, then click on the most recent Smart Contract to examine, in further depth, all transactions FROM other addresses to this particular smart contract address.
  4. We’d look for all transactions that had ‘0 Ether’, then all addresses that sent 0 Ether TO the smart contract in question, to see if there was any discernable pattern being sent to the smart contract and, if so, if those transactions were being sent at a specific time or any other regularities that would suggest that a script, or bot, had been written to generate these “bogus” transactions.

(NOTE: @masher @Catherinesjkim @sijo0703 @dnivrav , feel free to add / or correct whatever I got wrong here)

We each chose a particular Gambling dapp to do an initial exploratory investigation. My preliminary investigation for EtherDice is as follows:

To keep this preliminary exploration within scope and focused, I chose the most recent Smart Contract address:

Smart Contract #4

0xda548e0AD6c88652FD21c38F46eDb58bE3a7B1dA

Initial findings for EtherDice (as of Feb 16, 2019):

  • At the time of this analysis, there were 108 total transactions TO this particular smart contract address.

  • 77 out of 108 transactions were for 0 Ether

  • All the transactions for 0 Ether came FROM the following 16 different addresses

    • 0x051d7f77ca4b322451bb7937400e1d1aa216ddad (5 txs)
    • 0x097254e687e480b914ef83fa9d5089ed83fa3319 (4 txs)
    • 0x1431e45d9c8004e3c2f69ca0cea53fd9e2a46f87 (4 txs)
    • 0x16123aca433d112ffe251177a9833d9bb0d23977 (1 tx)
    • 0x3b0535c602078a22a9954209b3556549c4e5e987 (3 txs)
    • 0x40e58eb50de07a197e4ac178220a4d487a187e14 (3 txs)
    • 0x52ecc67bcaff974728160eacb70eed1945d1c94f (1 tx)
    • 0x6d4db4a6f7b0b6778800724f7bd6c80f61ba6423 (1 tx)
    • 0x9e4907070e114869f53b642f0942cd088526a021 (4 txs)
    • 0xa2e8bfa6a9be3b367618c0422d414d28490469bf ( 16 txs )
    • 0xb37e16a835acd6f480016f5a0e45f97a72d55b0a (3 txs)
    • 0xb477aceb6262b12a3c7b2445027a072f95c75bd3 ( 16 txs )
    • 0xb74d5f0a81ce99ac1857133e489bc2b4954935ff (2 txs)
    • 0xb9ace70ce234180f009aee04fc84fd755856fe86 (3 txs)
    • 0xc951d3463ebba4e9ec8ddfe1f42bc5895c46ec8f (1 tx)
    • 0xf8aba22dc7bbf6b7f5ac2c7eb868543e9d26aa8c ( 10 txs )

It can be pointed out that its relatively easy for dapp owners to spin up “multiple wallets”, and multiple addresses, as suggested in the original tweet above, so all these 16 different addresses could theoretically be owned by 1 individual.

I decided to focus on 3 addresses with double digit transactions (see bolded above).

0xa2e8bfa6a9be3b367618c0422d414d28490469bf ( 16 txs ) (Etherscan)

As of this writing, there are a total of 539 transactions, 16 of which were sent to our EtherDice Smart Contract, under analysis. Although transactions to EtherDice were for 0 Ether, other transactions to other addresses were for NON-zero amounts (0.1 - 24.617 Ether). Most of the transactions were to Dice2Win, presumably another gambling dapp.

When trying to find any pattern in terms of frequency of transaction, certain time periods or regularity of transaction, I was unable to find anything that would suggest artificiality. You can see the transactions sent to EtherDice, highlighted in the picture below, have various dates/times.

For my second analysis, i examined:

0xb477aceb6262b12a3c7b2445027a072f95c75bd3 ( 16 txs ) (Etherscan)

As of this writing, there are a total of 153 transactions, 16 of which were sent to our EtherDice Smart Contract, under analysis. Again, although transactions to EtherDice were for 0 Ether, other transactions to other addresses were for NON-zero amounts, some for as little as 0.006 - 8.43 Ether.

When trying to find any pattern in terms of frequency of transaction, certain time periods or regularity of transaction, I was unable to find anything that would suggest artificiality. You can see the transactions sent to EtherDice, highlighted in the picture below, have various dates/times.

For my third analysis, I examined:

0xf8aba22dc7bbf6b7f5ac2c7eb868543e9d26aa8c (10 txs) (Etherscan)

As of this writing, there are a total of 662 transactions, 10 of which were sent to our EtherDice Smart Contract, under analysis. Again, although transactions to EtherDice were for 0 Ether, other transactions to other addresses were for NON-zero amounts, some for as little as 0.02692307 - 2.3 Ether.

When trying to find any pattern in terms of frequency of transaction, certain time periods or regularity of transaction, I was unable to find anything that would suggest artificiality.

Conclusion (for EtherDice): My initial analysis for EtherDice has not found evidence to suggest artificial transactions or anything suspicious, aside from the fact that the transactions were for 0 Ether. This does not mean that such evidence won’t be found for other dapps. I will wait to see what my colleagues find: @masher @Catherinesjkim @sijo0703 @dnivrav and others.

DATA: For anyone interested, the data I used for my analysis above is contained in an excel sheet, since discourse doesn’t allow posting excel files, I’ll post this in slack.

Next Steps: My initial methodology involved writing a script to render the smart contract data from the Etherscan API. Although, the initial app is super clunky, it did allow me to transfer the data onto excel for further analysis. My hope is to further develop a simple frontend that would allow interested TruStory members to query Etherscan API and display relevant data for a particular analysis. My initial efforts are in React (will post the project on github soon).


#2

Thank you, @paulapivat for your analysis and listing to down the procedure.

Background: During the Slack call, @masher pointed out an interesting observation wrt to the activity graph on the dappradar ranking page. Some of the dapps such as FCK, tokenpark, win777 have a repetitive pattern that to seems to be artificially generated. Hence, I took up the task of studying and comparing between one dapp in the top 5 with a repetitive pattern and one with a varying pattern. FCK and FOMO3D were the two dapps I selected and the following 3 metrics were taken for preliminary analysis:
a. Users vs Volume
b. As @paulapivat mentioned in the procedure, finding regularity in patterns of 0 Ether transactions
c. Social Media activity - Github, discord, telegram, twitter

1. FCK

a. The User activity pattern is almost fixed(420-480 per day) between January 21st - Feb 16th except for the period of Feb 1-4. Yet the volume of transactions didn’t change much even when number of users dipped from 400 to 30. - Flag

Follow-up task: Need to selectively verify the data between Feb 1-4.

b. Of the 3000 transactions extracted from the smart contract 0x999999C60566e0a78DF17F71886333E1dACE0BAE, 1500 of them represented transactions with 0 Ether. Half as many as the total number of transactions.

But in every case analyzed, a transaction for 0 Ether meant the function was Settle bet


and whenever the value was greater than 0 Ether was placed, the function was Place bet

Hence, 0 Ether transactions do occur for Gambling apps. Yet there was no visible pattern seen in terms of time but all the 0 Ether transactions originated from the same address: 0x6666662ac054fed267a5818001104eb0b5e8bab3

Follow-up task: Need to understand if this is bot generated because of the function(settling bet) of the gambling dapp

c. Social Media Activity:

Github: Last activity on Dec 20,2018. No commits thereafter. And only 3 activities in total.
Discord: No access. Although the pinned post (Feb 14))on twitter invites people to join, as of today(Feb 16), the link seems to be dead or expired.
Telegram: Has limited activity with 1454 members
Twitter: Limited Activity.

2. FOMO3D

a. The number of users vs volume of transactions seem to be inter-dependent with no. of users more than the volume of transactions on most occasions. No sign of abnormality or artificiality than can be observed here.

b. Similar to FSK, 0 Ether transactions meant withdraw and greater than 0 Ether meant buyXaddr

Out of the 485 transactions extracted from smart contract 0x4e8ecF79AdE5e2C49B9e30D795517A81e0Bf00B8, 169 of them had 0 Ether transactions with no regular pattern. Unlike FSK, the origin of the 0 Ether transactions were from different set of addresses with a few repetition.

c. Social Media Activity:
Discord: The team Just behind FOMO3D runs the discord app with 23k users.
Twitter: With much less user activity, the twitter handle of Team JUST/FOMO3D is much more active then FSK.

Conclusion: Based on my limited understanding and time dedicated, the only substantial differences between the two dapps are:
I. In terms of the number of users vs volume study which seems a bit dodgy for FSK.
II. The origin of 0 ether transactions and the purpose behind it.

Need to analyze more on that front while finding other metrics for comparison.


#3

I chose to investigate dice2.win which has pretty normal looking activity graph compared to some artificial looking ones (i.e. FCK, TokenPark, Win777, etc). Source.

I still found some artificial looking transactions in dice2.win. For example, from this address (0x00000000c0293c8ca34dac9bcc0f953532d34e4d) to dice.2win’s smart contract address (0xd1ceeeeee83f8bcf3bedad437202b6154e9f5405) (there is 0 Eth as of yesterday, another strange fact Source), there were 1504 tx just from yesterday (KHScmb0gYtRC3WNupUhqd2ODuW5KXF428Pw/edit#gid=788224392) and there was no input or output of Eth value and each tx was happening every minute, sometimes 3x in a minute. I agree with @dnivrav that they are settling bet tx. Other addresses seem normal since they send at least 0.1 value of Eth.

Follow-up task: I don’t know exactly how dice2.win works since I never played it but contacted dice2.win and asked why some tx don’t have any Eth value in it and if they are bot generated SettleBet tx.

Maybe we can use Neutrino to finish this project if they are not expensive:https://www.neutrino.nu/index.html#SolutionsForLawEnforcement


#4

I also did some analysis on FCK. For the sake of consistency, I looked at batches of 6000 transactions between 1/1/2019 and 1/3/2019.

Interestingly enough, the first 3000 transactions, which covered 1/1/2019 to the very beginning of 1/2/2018, all came from two addresses, 0x6666662ac054fed267a5818001104eb0b5e8bab3 (2999 transactions) and 0x08a6268b1362b02f6473ec22fac93795353f5173 (1 transaction). Every transaction during the first day of the year contained zero ETH. Since all of the transactions examined in this section contained 0 ETH, the rationale for them all being settle functions is questionable.

I downloaded these transactions into a CSV. I am unable to find them now through EtherScan since EtherScan only allows the user to view transactions going back 30 days and 19 hours. I do not understand why EtherScan only allows for a user to browse through their UI back 30 days while they allow a user to download a CSV file for 3000 transactions from dates such as January 1st.

Transactions starting on 01/03/2019 began exhibiting a more normal pattern, similar to the one discussed by @dnivrav. Transactions came from 33 addresses on that date. Half of the transactions contained ETH, which would make sense from the standpoint that half of the transactions should be “bet” functions while the other half should be “settle” functions.


#5

this is fascinating. Is there something special about this date that would make it advantageous for them to have (maybe) juiced the numbers? (e.g. launch date)


#6

thank you for doing this @paulapivat.


#7

this lack of social media activity for FSK is quiet suspicious. especially when considering the data you present above on users vs. volume not being consistent for FSK.


#8

I don’t think it was launch date, as the first transactions associated with the DApp are from roughly 194 days ago.

Your comment did inspire me to go back and look at the initial transactions on the DApp. As you alluded to, more than 99% of the transactions that occurred in the roughly first 50 days this DApp was live contained 0 ETH. Furthermore, none of the transactions I eyeball analyzed contained the “settle function”.

It seems your thesis for FCK may be correct.


#9

Wow. Well, that’s not suspicious at all.


#10

I did some analysis on the two dapps I picked up from the Gambling category. I see 0 ETH transactions on both from specific addresses.

1. Good Luck Casino

I used the Etherscan API with a small Python program and got the following results: I will tweak the program a bit and share it in Github.
Note: The Etherscan API has a limit of 10000 transactions. This Dapp has a little over 10000 total transactions. There is only one smart contract address for this dapp which I have used for analysis

Smart contract #1 address: "0x05e7039c7afd77157845d9a4f1750b8ca93ec378"

Total number of transactions is : 10000
Total Zero Ethereum Value transactions: 105
The number of zero ETH transactions from address: 0x427e4b7de03ca8f730262f0e7d82c34b6b0ef9b0 is: 64
The number of zero ETH transactions from address: 0x7275feb7ad1063c07ee6b66f88bd0f3df129e035 is: 41

2. CryptoDice2

CryptoDice2 has three smart contracts listed in dappradar and I have checked the transactions to each of these addresses. The 0 ETH transactions I have found for each of the smart contract address are from four specific addresses listed here.

Smart contract #1 address: "0x8d4d8f0dbaF52BD46e566eb2ee38d834C3CE6ccf"

Total number of transactions is : 171
Total Zero Ethereum Value transactions: 98
The number of zero ETH transactions from address: 0x000042425e06b0b1e8e20a811c91d6864608324b is: 28
The number of zero ETH transactions from address: 0x00004242ca3469e30ae4a62775fee6584ed3fdca is: 24
The number of zero ETH transactions from address: 0x00004242f4449d49ec9c64ad6f9385a56b2a6297 is: 21
The number of zero ETH transactions from address: 0xe2cf529d780bda21d880e1d1a2035e7f4f503e60 is: 25

**Smart contract #2 address: **
"0x673A7132751569453914D31087409C28604c1c87"

Total number of transactions is : 28
Total Zero Ethereum Value transactions: 20
The number of zero ETH transactions from address: 0x000042425e06b0b1e8e20a811c91d6864608324b is: 1
The number of zero ETH transactions from address: 0x00004242ca3469e30ae4a62775fee6584ed3fdca is: 3
The number of zero ETH transactions from address: 0x00004242f4449d49ec9c64ad6f9385a56b2a6297 is: 4
The number of zero ETH transactions from address: 0xe2cf529d780bda21d880e1d1a2035e7f4f503e60 is: 12

**Smart contract #3 address: **
"0x3114b3312417b27A83bFD934764eeE363d1e9325"

Total number of transactions is : 1158
Total Zero Ethereum Value transactions: 50
The number of zero ETH transactions from address: 0x000042425e06b0b1e8e20a811c91d6864608324b is: 12
The number of zero ETH transactions from address: 0x00004242ca3469e30ae4a62775fee6584ed3fdca is: 14
The number of zero ETH transactions from address: 0x00004242f4449d49ec9c64ad6f9385a56b2a6297 is: 22
The number of zero ETH transactions from address: 0xcdad2d448583c1d9084f54c0d207b3ebe0398490 is: 2


#11

thanks @sijo0703! any insight into whether these zero value transactions are suspicious or not?


#12

@sijo0703 Interesting. The zero ether functions are sometimes necessary, like I had pointed out in my analysis. But the ratio of zero ether transactions to non-zero, like you’ve pointed out, is a huge concern.

Smart contract #1 address: " 0x673A7132751569453914D31087409C28604c1c87"
Total number of transactions is : 28
Total Zero Ethereum Value transactions: 20

The function for the addresses under this smart contract for the 20 transactions with 0 ETH states: PayRoyalty

The remaining have exactly 0.01 ETH and the corresponding function states: RollDice

Does this mean that entire smart contract(s) contain only Paying Royalty and Rolling Dice? Without any other function involved, let alone users.

I’m uncertain what paying royalty means. Do we have any Gamblers in the house or anyone who has tried a gambling dapp?


#13

@dnivrav @preethi Thanks! I have not looked into the smart contracts! But I think as you mentioned 0 ETH transactions are not unusual and can be fun calls on smart contracts which do not involve value transfer and may only involve data transfer. That actually makes 0 ETH criteria to identify suspicious transactions a tough one! Agree?


#14

One way to figure this out is to look at the smart contracts and see what these function calls actually do. Are the smart contracts open source on GitHub? If you can find the code for them, I’m happy to help investigate the methods to see if they legitimate function calls or not.

Sometimes etherscan also has the source code for the contracts.


#15

@preethi This is the core smart contract code for CryptoDice2 which I could find from Etherscan. The full source code is here. Check for contract Dice at the bottom.

This is the rollDice function which is I guess the core function of the dapp. I think it queries an external Oracle to generate the rollDice value.

 function rollDice(uint[] memory betNumbers) 
        public 
        payable
        returns (bool success)
    {
        
        bytes32 oraclizeQueryId;
        
        address payable player = msg.sender;
        
        uint betAmount = msg.value;
        
        require(betAmount >= minimumBet);
        require(betNumbers.length >= 1);

        emit PlayerBetAccepted(address(this), player, betNumbers, betAmount);

        emit RollDice(address(this), player, "Query to random.org was sent, standing by for the answer.");


        if(betNumbers.length < 6) {

            // Making oraclized query to random.org.

            oraclizeQueryId = oraclize_query("URL", "https://www.random.org/integers/?num=1&min=1&max=6&col=1&base=8&format=plain");

            // Recording the bet info for future reference.
            
            oraclizeStructs[oraclizeQueryId].status = false;
            oraclizeStructs[oraclizeQueryId].queryId = oraclizeQueryId;
            oraclizeStructs[oraclizeQueryId].player = player;
            oraclizeStructs[oraclizeQueryId].betNumbers = betNumbers;
            oraclizeStructs[oraclizeQueryId].betAmount = betAmount;

            // Recording oraclize indices.
            
            oraclizedIndices.push(oraclizeQueryId) -1;
  
            emit NumberGeneratorQuery(address(this), player, oraclizeQueryId);
 
 
        } else {
            
            // Player bets on every number, that's an invalid bet, money are returned back to the player.

            msg.sender.transfer(msg.value);

        }
    
    
        emit AwaitingRandomOrgCallback(address(this), oraclizeQueryId);

        return true;

    }

This is the payRoyalty fun which I guess it pays some royalty fees for the oraclized service they use

function payRoyalty()
        public
        payable
        returns (bool success)
    {

        // There is a cost associated to provide this service, as an example, it costs 0.004 ether to make a single call to oraclize and we need to somehow cover for the it.
        uint royalty = address(this).balance/2;

        address payable trustedParty1 = 0xE2cf529D780bda21D880E1d1A2035E7f4f503e60;
        address payable trustedParty2 = 0xE2cf529D780bda21D880E1d1A2035E7f4f503e60;
        trustedParty1.transfer(royalty/2);
        trustedParty2.transfer(royalty/2);

        return (true);
    }

I think it is a less feasible and time-consuming solution to look at each dapp code to find fradulant activity. I personally do not like to do that.
I found another site https://dappvolume.com/api where I think I can get more stats of dapp using api. I will explore that


#16

thanks for digging in! Well, I guess it’s useful to know whether the 0 value transactions are legit or not right? It seems like based on the above methods, these seems like valid function calls that are a core part of the dapp, so doesn’t seem too suspicious to me.

isn’t this just the same as looking at the volume metrics on the dapp sights? I thought the purpose of this experiment was to get raw data which would help us understand if there are dapps which are creating wallets and sending money back and forth to generate bogus numbers.


#17

Great job @sijo0703 going down one level further.

I think it is a less feasible and time-consuming solution to look at each dapp code to find fradulant activity. I personally do not like to do that.
Agreed but we can come up with new metrics once we completely prove that at least 1 dapp is fake including the possibility of the code with fraudulent activity.

I didn’t know the code was provided on Etherscan until you mentioned,@preethi. Thanks.

thanks for digging in! Well, I guess it’s useful to know whether the 0 value transactions are legit or not right? It seems like based on the above methods, these seems like valid function calls that are a core part of the dapp, so doesn’t seem too suspicious to me.

Yes,those functions are valid. But it is also certainly possible that dapp involves just these 2 functions to be continuously looped in a random manner. This will show an increase in the number of transactions without actual users. Will dig into the code further over the weekend to prove or disprove my hypothesis.


#18

Yes! I totally agree! Using dapp metrics API from other sites is same as using these sites to analyze metric data. The best option will be TruStory to develop an API which can be used for dapp metrics.:blush:


#19

I don’t think TruStory should do it. It’s not our core product. The infrastructure ecosystem should do it.


#20

Hoping this provides some clarity to the function of “0 Ether” transactions