We told you yesterday of an exploit users had found in Diablo III that let them “dupe” gold, a serious flaw in the game’s economy which forced Blizzard to shut down the game’s auction houses.
But just how did this exploit work? Redditor TyroPyro has a good explanation:
The gold “dupe” involved creating a RMAH auction for billions of gold while staying under the $US250 limit. The example I saw in a video was 6 billion gold (600 x 10,000,000 at $US0.39 per stack, for $US234). When they posted this auction only ~1.7 billion appeared to be for sale, with the rest “missing” until they sent it to their stash and ended up with more than they started with. The exact numbers from a duping video:
Create RMAH auction for: 6,000,000,000 gold
Auction shows up as: 1,705,032,704 gold
This much is missing! 4,294,967,296 gold
The missing amount, divided by 2: 2,147,483,648 gold
2,147,483,648 (or 231) is the maximum value you can store in an int32 in programming. I’m no programmer, but I took one class in high school and was taught about the limits of different variable types. See:http://stackoverflow.com/questions/9459…
Simply put, their RMAH gold selling code wasn’t written to handle numbers over 2,147,483,648 properly, and the result was duplicate gold being added to people’s stashes.
Slightly complicated, maybe, but there you go.
Some speculation on how the gold bug made it to live [Reddit, via Gamasutra]
Comments
15 responses to “How A Loophole And Giant Numbers Broke Diablo III’s Economy”
Aaaand now unless they can figure how much of that money has been laundered into different accounts via legit trading,
the pooch is screwed
correction, the dead pooch is screwed, I believe the live version of the aforementioned pooch was screwed at implementation of the RMAH
Indeed.
You’d be surprised how easy that is to do when everything is contained in a single system. They handle gold sellers in WoW with the same basic process.
I’m curious how you personally would approach tracking say, a single gold that is now 20-30 trades down the line, hell, or even more with the help of some buddies, let alone across every account.
Gold sellers are usually dealt with on a very harsh basis where they usually take your entire account from you, or give you a warning and take nothing from you. I personally once wrote a bot for a few MMO’s as an experiment (automation of systems that provide no direct method of doing so at the time was my business, though within the business realm heh), had 2 accounts banned and lost everything and on another 2 excuses were accepted and they let me keep everything i’d gained through it.
Since they’re not physical objects, you don’t need to trace the same unique ‘gold pieces’ that were originally duped; the goal is to remove the value of duplicated gold from the system as fairly and cleanly as possible. At the company I worked for years ago, the process was to build a full time-based transaction tree from the time of duplication forwards. Because the amount of duped gold at the root (ie. the person who did the duping) is known, then starting from the root a recursive logic was applied that went something like this:
– Let X be the value of duplicated gold known to be possessed by this node.
– If the current node has equal to or greater than X in his gold pool, deduct that gold immediately and terminate the recursion logic at this node.
– If the current node has less than X in his gold pool, deduct the amount it does have, then for the remainder, inspect all transactions involving outbound gold made from the current node after the time X was received by the current node, and determine the fewest number of transactions that need to be reversed to recover the value of the remainder of X, preferencing transfers (ie. sending gold from one player to another) ahead of purchases (ie. trading gold for items). If there is no way to reverse the exact amount required, the excess amount scheduled to be reversed is added to the current node’s gold pool.
– For each transaction determined by the step above, return any items transferred, then let Y be the value of the transaction being reversed and recurse this logic, passing Y into X, with the player at the other end of the transaction being the new node.
This is only a simple representation of the logic, but because it’s time-based and each node’s transactions are only examined from the time that node received duplicated gold onwards, it can handle any complexity of transaction tree, including branching, merging, hundreds or thousands of transactions down the line, etc. It’s fairly quick to process even in large games, but ideally it’s done during maintenance or emergency downtime.
Gold sellers are often dealt with much more harshly though, yes. With a gold seller account, all transactions from the root are cancelled, and depending on how hard the company wants to be, they may also cancel all transactions down the tree and confiscate items transferred.
You cover several assumptions (like that X is predefined, somehow they KNOW how much a number that is inherently bigger than their own game can contain is) under the guise of math.
The amount is known in any game system where changes to the gold variable are logged. Numeric overflows, once known, are predictable and in this case can be easily derived from logged auction values and cancellations. The overflow happens in the auction business logic, not directly in the player’s gold variable, so the discrepant values are known because they happen prior to being merged back into the player’s value. There is an assumption, but not the one you think – it’s assumed changes to the player gold variable are logged. It’s a fairly safe assumption though as it’s network game data integrity 101. (as an aside, this is why you always use accessors for properties, not direct writes)
What other assumptions do you see in what I said?
You make it SOUND like you know what you’re talking about – but purely by throwing assumptions out as though they are fact. You don’t even know how much logging they use, the sheer number of transactions involved, transacting gold between accounts maybe even 5000 times for all you or I know.
Let me put it this way. If PAYPAL cannot do this effectively (scammers have very thorough ways of preventing charge backs as i’m sure you’re aware), then i’m unsure how a game can, and simply it is impossible for me to KNOW how they would do it, as it is for you, not to mention as I say in my experience and the forums of most big MMO’s, it’s simply NOT something that’s done. It’s worth nobodys time when they have the complete right to just terminate your account, or get you to say you won’t do it again. Even the source link is “Some speculation on how…”…
So yes, to answer your question – nearly everything said is an assumption. Or as you would say, “Let X be an assumption that sounds like math used for evil”
I’m not going to argue with you because I can only access Kotaku on my phone (thanks work filter) and I hate typing long replies on touch screens. Suffice to say there are far fewer assumptions than you think. It absolutely is easy to predict and repair numeric overflow bugs in suitably logged systems and without trying to sound rude, solving problems like that in software from games to telco infrastructure management to battlefield awareness has been a large part of my work for most of my career, I’ve learned from very intelligent people and I am confident I understand enough about the problem domain to make the comments I have.
At this point we can agree to disagree, but I stand by what I said. This type of problem it’s not difficult to solve, just time consuming.
They should just fix the issue, refund or take money from whoever and then disable the RMAH forever and leave the GAH alive. Will bring many players back to the game 😀 but then diablo 3’s money making disappears too 🙁 hmmm
Damn it, tricked again. Clicked on a Luke Plunkett headline because I was actually interested in the subject, got no real information except a lazy repost of a Reddit thread. No commentary from Luke to suggest he even understands what he’s reposting. Sometimes Kotaku is the worst.
Integer overflow. Really, blizzard? Something that simple…
Yeah pretty dumb, especially with how long the freaking game was in production 😐
I haven’t seen the video itself, which I’m sure has vastly better information than either Reddit or Kotaku has gleaned, but it looks to be an unsigned integer overflow, yeah. It wasn’t detected before now because it wasn’t a problem before 1.0.8 – before that patch, there was an upper limit to the value of gold that could be sold in a single auction that didn’t exceed 4 billion. In 1.0.8 they increased the stack size you can sell gold at from 1 million to 10 million, and so the upper limit also went up.
Not to defend Blizzard here, but this is actually a really easy problem to have slip through the cracks. The people who implemented the recent stack size change likely had no idea that there was a size cap elsewhere in the transaction code, as (assuming they use unit testing) they’d expect the unit tests would cover cases like that, but the person who wrote the unit tests wouldn’t have necessarily covered a far boundary case when it was first written because due to other limits at the time, the value would never have been exceeded.
It’s poor communication between programmers (some of whom might not even still be on the team), but if you’ve done large team development before you’ll recognise it straight away as something that can happen anywhere, and all too easily. It’s a common pitfall of complex code and the doctrine of unintended consequences.