How did this happen?

Technically, there is a bug in the ERC 20 smart contract that issues and manages the crypto token. Let’s use BEC as an example. (SMT is very similar.) The developer added a method called batchTransfer() to the contract. The method is intended to facilitate token transfer to multiple parties at once (i.e. a batch).

Image credit from the CVE-2018–10299 security alert

However, the developer made a crucial mistake in the following line of code:

uint256 amount = uint256(cnt) * _value

The cnt here is the number of recipients to transfer the tokens to, the _value is the number of BECs each recipient should receive, and the amount is the computed amount the contract should withdraw from the sender's account for the transfer.

Now, what if someone calls this batchTransfer function with a cnt * _value so large that the product exceeds the capability of the computer to keep track of 256 bit integer ( uint256 )? It will cause an infamous “buffer overflow,” and cause the amount to compute to zero. Notice that both cnt and _value are legitimate unit256 numbers, but the amount is now zero. Hence you can transfer _value number of BECs to anyone without withdrawing anything from the sender's account. So a sender with 1 BEC can now send trillions (in fact, vigintillions) of BECs to other recipients. [Thanks to the Alex O’s explanation in the comments section!]

How to prevent it?

The way to prevent this is to use the SafeMath library function when doing integer math. SafeMath detects and addresses the “integer overflow” problem. Interestingly, the BEC/SMT contract developers did use SafeMath, except in that one instance!

Why? One might guess that in the gold rush of ICOs, the developer might just copied and pasted some ERC 20 contract code from the Internet without fully understanding their implications.