Dx Protocol Vulnerability Disclosure: Mitigation of a $5,200,000 Smart Contract Exploit

Lockigod
Decurity
Published in
5 min readJul 6, 2023

--

TL;DR This is a curious story about how our researcher looked up a seemingly random smart contract and ended up saving $5,200,000 USD a few hours later.

The report details the discovery and the mitigation of a critical vulnerability in an unverified smart contract of DX.app — a popular token launchpad.

The bug’s potential impact could have led up to $5,200,000 USD losses, but our report prevented a disastrous outcome.

Identifying the vulnerability

As part of our Defimon product research efforts we analyze various suspicious contracts and transactions to create the detection rules for the exploits, hacks, scams and other on-chain threats.

During a routine inspection, we stumbled upon an unverified smart contract on BSC with the address 0xeb3a9c56d963b971d320f889be2fb8b59853e449. Despite the absence of a verified source code, the contract held a substantial balance of LP tokens in PancakeSwap.

79 pages of LP tokens on Bscscan

This was curious and we decided to dig deeper. After decompiling the bytecode with the Dedaub’s tool, we unveiled the following unlockToken function:

A function that unlocks tokens from the vulnerable smart contract

There are the following important variables:

  • varg0 — an ID of a user’s locker
  • _unlockToken[msg.sender][varg0].field0 — a boolean variable which means that user has some locked tokens
  • _unlockToken[msg.sender][varg0].field2 — an amount of locked tokens
  • _unlockToken[msg.sender][varg0].field3 — a token locktime
  • _unlockToken[msg.sender][varg0].field5 — an address of the token that a user has locked

Through decompilation and further investigation we concluded that this was a contract that allowed locking liquidity in certain pools via the https://dx.app/dxlock interface. The intended use of the contract was for the token creators to lock their liquidity during IDOs. When certain conditions were met, the owners could unlock their tokens.

The function unlockToken in the decompiled source code was particularly interesting because it seemed to miss some important sanity checks. Namely, the contract allowed to unlock the tokens multiple times because it lacked a check that block.timestamp is larger than locktime. It seemed that after the lock period elapsed, the tokens could be unlocked only once, but before that they could be unlocked infinite number of times, because lock amount was set to zero only if block.timestamp was larger than locktime.

This opened the door to an exploit allowing the draining of all LP tokens from the lock contract. The method was as follows:

  1. Acquire tokens to get LP tokens of a known pool.
  2. Create a locker.
  3. Unlock tokens from that locker as many times as possible to drain LP tokens.
  4. Withdraw these LP tokens, thereby draining the initial pool.

Here’s the PoC exploit code:

In this code the tokens are bought and added as liquidity to the BARMY-WBNB pool in order to get LP tokens. After that a locker is created with these LP tokens on a vulnerable contract which are then unlocked 100 times without any issues. As a result an attacker is able to get 100x more LP tokens than they initially deposited. POC operates with small amounts just to show the impact, however amounts can be increased.

Assessing Potential Impact

When we realized this is a critical bug, we tried to estimate the possible losses. At first, it seemed that this is an old contract, and there is no actual liquidity in the pools where the tokens have been locked. However, upon further investigation, we scraped the list of tokens and their respective balances and counted total WBNB value available in the pools.

After careful calculations it turned out that the total value of WBNB that could be drained was 21,600 or about $5,200,000 USD at the moment of writing.

Note that this figure reflects the losses that could be inflicted by an exploit that targets a single instance of the locking contract. However, Dx has more locking contracts on BSC and other chains.

Mitigation and Response

As soon as we realized that there is actual money involved, we contacted the DX.app administrators in the Telegram group. At first, they were unresponsive and then told us that they do not believe we are auditors.

After a little persuasion, a war room chat was created with the project’s founders and the developers where we reported all the details including the PoC code.

After a while, the developers came up with an idea how to fix the vulnerability: set the locking fees so high that the attack won’t be feasible. We concluded that this most probably would indeed mitigate the attack within the threat model of the external adversaries.

Although effective against external threats, this would not prevent project owners from potentially draining the funds in a hypothetical rug pull scenario. The developers stated that the rug pull possibility was well-known before and decided to leave it as is.

The DX.app team offered various responses to the vulnerability report, including claims that the issue was already known and the contract was inactive, therefore having no impact. They also cited protection through CertiK Skynet and multiple auditing partners and claimed that fund draining was impossible due to locked transfers. However, these statements were debunked by presenting a working exploit code.

Meanwhile, they rushed to implement the same fix (setting the huge fees) in all other instances of the locking contract.

Finally, as a reward for our efforts, the project offered us a 500 USD bounty.

Although we’re happy that we were able to protect a significant amount of user funds from being stolen, the process of reporting the bug was higher friction than we expected and raises questions about the Dx Protocol’s approach to security. We would urge users to take caution when interacting with their projects in the future.

Timeline (GMT)

  • Jun 28, 16:30 — Vulnerability discovered
  • Jun 28, 18:00 — Exploit finished
  • Jun 29, 11:00 — Impact confirmed
  • Jun 29, 11:20 — War room created
  • Jun 29, 15:00 — Vulnerability mitigated by setting large fees

If you need a professional security audit for your blockchain software, smart contracts or a dApp, do not hesitate to submit the contact form. Check out our previous audits at GitHub.

--

--