PAID Network contract hack — deep dive
On March 5th 2021, PAID Network’s smart contract was hacked. The attacker gained control over it and new tokens were minted. This was followed by the hacker dumping the tokens in the market.
I will deep dive into the sequence of events which took place. More details will be updated here as and when I discover them during my research.
Goal: The main goal of my research is to not only identify the root cause of the hack but also to ensure that such attacks do not happen in future and we strengthen DeFi security. Also to help the PAID network team and the DeFi community.
If you want to collaborate with me on this research, contact me through Twitter (@CryptoShine)
So let’s start.
Note: I have shared exact timestamps, transaction ids and all the relevant information which you can use to look up on etherscan.
PAID network uses upgradeable smart contracts. This was disclosed by them in their audit and transparency report as well on Jan 26th 2021.
Creation of Proxy contract
On Jan-25–2021 09:26:31 AM UTC, PAID Deployer created the ProxyAdmin contract which was deployed at address: 0x7bb7580edb70170daf8a24afc6aaef93db720c24
Transaction: https://etherscan.io/tx/0xa78f7447a763d2952184cb1c2f643d2d858db14a6f6245001d0aff21141bf2d3
Transfer of Ownership
On Mar-05–2021 05:37:11 PM UTC, PAID network’s Deployer transferred ownership to attacker’s Ethereum address: 0x18738290af1aaf96f0acfa945c9c31ab21cd65be
Transaction: https://etherscan.io/tx/0x733dd279b3d24f3415f3850b8eceafc651c1998163dcd0352b9e83c46e2b33d9
The ProxyAdmin contract at address: 0x7bb7580edb70170daf8a24afc6aaef93db720c24 uses the transferOwnership() function to transfer the ownership.
This function uses a modifier, onlyOwner. In solidity smart contracts, you can use modifiers to ensure that it can only be called if a specific condition matches. In this case, the condition is that it can only be called by the owner as shown below.
Interaction with Proxy contract by attacker
First implementation upgrade
On Mar-05–2021 05:40:30 PM UTC, the first interaction with this Proxy contract was done by the attacker from address:
0x18738290af1aaf96f0acfa945c9c31ab21cd65be
Transaction: https://etherscan.io/tx/0x44a1c8649660a46382895d20b19b9a20cb8b0fd2406b655677459e489866c2f8
In the screenshot below, you can see the attacker calling the Upgraded() method in Proxy contract to upgrade the implementation to 0xdd08213d28a453c92454868c4daed51b3387e114
Second implementation upgrade
Soon after the first implementation upgrade, the attacker deployed a new implementation contract.
On Mar-05–2021 05:56:20 PM UTC, attacker deployed a new contract at address: 0xb828e66eb5b41b9ada9aa42420a6542cd095b9c7
On Mar-05–2021 05:59:43 PM UTC, upgraded the implementation contract as shown below.
Transaction: https://etherscan.io/tx/0xe4678ca53b308bb35f6fd393ca369e853f936788cd6c318cd38b0a25bec88b70
Malicious contract analysis
Now let us look at what the malicious smart contract deployed by the attacker actually does. Firstly, the contract is deployed as a bytecode on the blockchain and the source code is not available. However, it is possible for us to decompile the bytecode and reverse engineer it.
The bytecode looks like shown below.
Here is the decompiled bytecode
I have put the complete decompiled bytecode here: https://pastebin.com/9LbxbP7a
This is only for research purposes !!
Let us look at the mint() function inside this new implementation contract.
I have highlighted the relevant code section. As can be seen in the code, the mint function specifically checks that the caller address == 0x18738290af1aaf96f0acfa945c9c31ab21cd65be
This is done to ensure that no one else can invoke the mint() function in this contract other than the attacker.
Analysis of attacker’s address and Tornado.cash usage
This address was exclusively used by the attacker to deploy the malicious contract, to mint the tokens and to sell the PAID tokens.
For all these operations, the attacker would require some ETH.
On Feb-24–2021 08:28:32 AM UTC, the attacker transferred some ETH to his address for the purpose of gas expenditure.
The attacker was careful enough to use a transaction privacy service at tornado.cash which removes the on-chain link between the source and the destination address.
I’ll add more details here when I can.
Appendix
Attacker’s ETH address: 0x18738290af1aaf96f0acfa945c9c31ab21cd65be
Malicious implementation contract addresses:
0xdd08213d28a453c92454868c4daed51b3387e114
0xb828e66eb5b41b9ada9aa42420a6542cd095b9c7
PAID Network Deployer address: 0x6ba10437fd18899a4d920b60a9663b9a1d7a1120
ProxyAdmin contract
0x7bb7580edb70170daf8a24afc6aaef93db720c24
CryptoShine