Deep Dive into High-Profile Crypto Exploits — Part II: NBA’s The Association

Solidgroup
3 min readApr 27, 2022

This is the 2nd part in our series about high profile crypto exploits.
You can read the previous part about the Beanstalk attack
here.

TLDR; On April 20th, 2022 the National Basketball Association (NBA) released an NFT collection called the Association [ https://finance.yahoo.com/news/nba-playoffs-nft-drop-gets-003624130.html].
Due to missing checks in the code, an attacker managed to mint thousands of pieces. In response the NBA decided to increase the number of pieces in the collection from 18,000 to 30,000

Background

In order to understand this exploit, we will try to provide a quick explanation of the relevant terms:

  • ecrecover() — a Solidity function that allows smart contracts to validate that a message is properly signed by a specific address. The signature is computed off-chain and can be shared by the user as a “proof” for the smart contract that it was signed by an expected party.
    It is mainly used to log in to websites (like Opensea) or whitelist addresses in a presale without triggering a blockchain transaction.
    You can read more about it here.

ecrecover is widely used on multiple NFT projects as it gives the owner the ability to whitelist users without the need to actually run any transaction and spend gas fee.

The Attack — A High-level overview

The Association NFT Sale Contract — https://etherscan.io/address/0xdd5a649fc076886dfd4b9ad6acfc9b5eb882e83c#code

💡 It’s important to mention that the signature can be publicly viewed by anyone, and this is why all data must be verified on-chain.

In the NBA case, Here’s the code that verified the signature:

function verify(vData memory info) public view returns (bool) {
require(info.from != address(0), "INVALID_SIGNER");
bytes memory cat =
abi.encode(
info.from,
info.start,
info.end,
info.eth_price,
info.dust_price,
info.max_mint,
info.mint_free
);
// console.log("data-->");
// console.logBytes(cat);
bytes32 hash = keccak256(cat);
// console.log("hash ->");
// console.logBytes32(hash);
require(info.signature.length == 65, "Invalid signature length");
bytes32 sigR;
bytes32 sigS;
uint8 sigV;
bytes memory signature = info.signature;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
assembly {
sigR := mload(add(signature, 0x20))
sigS := mload(add(signature, 0x40))
sigV := byte(0, mload(add(signature, 0x60)))
}
bytes32 data =
keccak256(
abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)
);
address recovered = ecrecover(data, sigV, sigR, sigS);
return signer == recovered;
}

The critical flaw lies in the fact that the signature contained the whitelisted address (The info.from field), but the verify function did not verify that the msg.sender is the one that was specified in the signature. This means anyone with a valid signature could send it to the contract and the signature would be accepted. All the attacker had to do was get one of those signatures and simply send them to the mint function in the NBA’s contract. Since the contract did not verify the sender is actually whitelisted, it allowed the attacker to mint the NFTs.

In addition, the smart contract missed another crucial component — every signature could be used multiple times, thereby allowing the attacker to easily mint thousands of pieces.

Possible Fix

require(msg.sender == info.from, "The sender is not in the whitelist");

Prevention

This attacker is a rather simple one and could be exploited by nearly anyone with a basic understanding of Solidity.

It looks like the developers of the NBA’s smart contract missed key elements that are crucial when using the ecrecover() function.

This attack could have easily been avoided if the smart contract verified msg.sender is the same as the from in the signed data, and only allowed every signature to be used once.

Summary

The main lesson here is to understand how signatures in solidity work and that they are publicly available to everyone, any user can send the signature to the smart contract. Therefore, the verification of the signature should be done in the smart contract.

Links

The Association collection on opensea: https://opensea.io/collection/the-association-nft

The Association NFT smart contract: https://etherscan.io/address/0xd7bea2b69c7a1015aadaa134e564eee6d34149c0#code

The Association Sale contract (the contract that contained the crucial bug in the mint_approved function):

https://etherscan.io/address/0xdd5a649fc076886dfd4b9ad6acfc9b5eb882e83c#code

About Solid Group

Solid Group is a blockchain consulting and auditing service provider founded by cybersecurity experts with a great passion for the cryptocurrency world. We are known for our exceptional out of the box thinking, experience, and our credibility among the community. Throughout our work, our team was able to discover many high severity issues & vulnerabilities. We work with leading companies in the field, helping them increase their resilience through tailored services and solutions.

‌Solid Group provides ALL IN ONE ICO SOLUTION -

  • audited token generator ( Generate your own token with NO CODING KNOWLEDGE)
  • sniper bot protection tool
  • Smart contract auditing service

🌍 solidgrp.io | 🐦 Twitter | 📣 Telegram Group | ✉️ info@solidgrp.io

--

--

Solidgroup

We are a group 3 software developers with combined experience of over 15years in various fields such as Software design, Operating systems, and solidity.