
A Single Word Triggers a "Tragedy": $200 Million Locked Forever in Akutar NFT
TechFlow Selected TechFlow Selected

A Single Word Triggers a "Tragedy": $200 Million Locked Forever in Akutar NFT
This article guided everyone through learning a new minting method—the Dutch auction—and its underlying principles, while also introducing the term "totalBids," a word associated with a $200 million valuation.
The article is written by Jason Chen, from the WeChat public account "Have You Understood This World a Bit More Today?" Readers are welcome to follow the official account to read past articles and communicate more deeply with the author, or follow the author's Twitter: jason_chen998 for the latest updates.
After writing the previous article on NBA, I was completely drained and wanted to take a break before writing again. However, the Web3 world is just too exciting—so many major news events happen every day that I ended up working over the weekend once again.

Today, an NFT project called Akutar lost access to 11,539 ETH—worth $34 million or about 200 million RMB—due to a smart contract bug. The funds are now permanently locked. $34 million—gone!
Let’s open the contract address and take a look at this massive sum—just imagine how the Akutar team must be crying their eyes out staring at that number.

First, let’s introduce Akutar. Based on its official website and Twitter presence, this isn’t some scam “dog” project. On the contrary, it’s a well-thought-out, high-quality project, evident from both the detailed artwork and the quality of its roadmap.

It was initiated by renowned baseball player Micha Johnson. The idea originated when he overheard a conversation between a young Black boy and his mother. The boy asked if a Black person could become an astronaut. Inspired by this, Micha Johnson decided to launch a series of NFTs depicting Black boys wearing helmets dreaming of becoming astronauts—a rather heartwarming story.

So why did this seemingly heartwarming NFT project fail? In part, it’s because the team prioritized profit over genuine social impact, ultimately shooting themselves in the foot. They adopted a unique Dutch auction mechanism.
Traditional auctions set a low starting price and allow bidders to increase their offers—the highest bidder wins. This is known as an English auction. A Dutch auction works in reverse: it starts at a high price and gradually decreases until someone buys at the current price. Dutch auctions test human psychology—everyone wants to wait for the lowest price but fears someone else will buy first.
Azuki used a Dutch auction, but Akutar modified the model. Azuki’s price dynamically decreased—buying later meant a lower price, while early buyers risked overpaying. Akutar added a “refund” rule, which seemed more user-friendly but, in my opinion, was actually designed to extract more money.
As shown in the image below, the auction started at 3.5 ETH, dropping by 1 ETH every six minutes. The final lowest purchase price became the benchmark. Anyone who paid above that price would receive a refund for the difference. For example, if the lowest purchase price was 1.5 ETH, everyone who paid more than that would get the difference refunded. This design encouraged users to buy early without fear—overpayment would be corrected later.

Therefore, Akutar had a large fund pool holding all user payments—both the team’s revenue and amounts due for refunds. Let me briefly explain: as mentioned in previous articles, smart contracts function like personal wallet addresses—they are blockchain addresses capable of receiving and sending cryptocurrency. When you mint an NFT, you send funds to the project’s contract address first, and then the contract sends you the NFT. In other words, all primary market sales go through the contract address first, and the team later withdraws funds from the contract to their own wallets.
This time, the $34 million got locked during the withdrawal step due to a bug. Because blockchain smart contracts are immutable, bugs cannot be fixed. In traditional internet applications, a bug preventing withdrawals could be patched and updated. But in Web3, it means you’re forever separated from that $34 million.
Let’s examine some key code snippets to understand how it works and pinpoint exactly where things went wrong.
First, let’s understand the Dutch auction logic. The current price is calculated by taking the current block timestamp, subtracting the start time (startAt), dividing by 6 (since the price drops every 6 minutes), yielding the number of price reductions (timeElapsed). Multiply that by the reduction amount to get total discount, then subtract from the starting price to get the current price. Importantly, these monetary parameters aren’t hardcoded—they’re modifiable variables, meaning the team left themselves backdoors to adjust prices dynamically and maximize profits.

Now that we understand price calculation, let’s see what happens during bidding. I won’t paste all the code—it’s too long—so I’ll highlight the critical parts.
First, the current price is fetched, multiplied by the purchase quantity (amount) to get the total price (totalPrice). Then it checks whether the user’s payment (value) meets or exceeds the total. If yes, execution continues.

Here, a bid structure is defined, including: bidder (the buyer’s address), price (their bid), bidsPlaced (total quantity purchased), and finalProcess (refund status: 0 = not refunded, 1 = refunded, 2 = refund canceled).

Now we reach the first pitfall: totalBids represents the total number of NFTs sold, initially 0. Each time a user places a bid, the amount they purchase is added to totalBids. Remember this—we’ll come back to it.

Then comes the second pitfall: a parameter called bidIndex tracks the number of users who placed bids. Remember these two: totalBids counts total NFTs sold, bidIndex counts the number of bidders.

Now, let’s discuss the refund process. The team triggers refunds by clicking a button called processRefunds. The underlying logic loops through all bidders—the number of iterations equals bidIndex (number of bidders). For each user, it checks if their finalProcess status is 0 (not yet refunded). If so, it calculates the refund amount: (user’s original bid – lowest successful bid) × quantity purchased.
Then, it sets that user’s finalProcess status from 0 to 1, marking them as refunded and preventing double claims.
The parameter refundProgress tracks how many users have been refunded. It increases by one after each refund. Since the loop runs bidIndex times, refundProgress should eventually equal bidIndex. This seems correct—refunded users should match bidders. But! Keep reading!

How does the withdrawal mechanism work, and what flaw prevents the team from withdrawing?
Below is the function allowing the team to withdraw funds—triggered by clicking the claimProjectFunds button. It includes three layers of validation. The first checks whether the auction has ended. If yes, it proceeds to the second layer: checking whether refundProgress (number of refunded users) is greater than totalBids (total NFTs sold). This condition was intended as a safeguard—to ensure all refunds are completed before withdrawal. But here lies the problem. Do you remember what totalBids means? It’s the number of NFTs sold—not the number of bidders!

You might ask—what’s wrong with that? Well, each bidder can buy multiple NFTs. So the number of bidders (refundProgress) is naturally smaller than the total number of NFTs sold (totalBids)—especially since one person buying two NFTs makes it mathematically impossible for refundProgress to ever exceed totalBids. For instance, if 10 people bought 11 NFTs, how can 10 ever be greater than 11?
Let’s check Etherscan: refundProgress shows 3,699—meaning 3,699 bidders. But totalBids is 5,495—over 5,000 NFTs sold. refundProgress will never surpass totalBids. That $34 million is now permanently trapped in the contract—forever on display for future generations.


The team made a typo. They meant to write bidIndex (number of bidders) but wrote totalBids (number of NFTs sold). One word cost $34 million. This might be the most expensive typo in history. Remember this word: totalBids—it’s worth $34 million!
Through this article, we’ve learned about a new minting method—the Dutch auction—and its mechanics. We’ve also met the most expensive word in crypto history: totalBids.
Join TechFlow official community to stay tuned
Telegram:https://t.me/TechFlowDaily
X (Twitter):https://x.com/TechFlowPost
X (Twitter) EN:https://x.com/BlockFlow_News














