header-langage
简体中文
繁體中文
English
Scan to Download the APP
Partnered With:

Solidity extremely brief introduction | ERC721 project about 4: BAYC contract serious vulnerabilities

Read this article in 21 Minutes
There are two serious bugs in the BAYC contract, one that can cause images to be swapped and the other that can cause BAYC to overshoot beyond the set limit of 10,000
原文标题:《 Solidity 极简入门 ERC721 专题:4. BAYC 合约严重漏洞 》
原文来源:0xAA  


I have been reworking solidity to consolidate the details and also writing a "Solidity Minimalism Primer" for nerds (find another tutorial for programmers) with weekly updates of 1-3 sessions.


The github:github.com/AmazingAng/WTFSolidity all open source code


Before I knew it I had already completed the first 13 sessions (basics) of the Solidity minimalism tutorial covering: HelloWorld.sol, variable types, storage locations, functions, control flow, Constructors, modifiers, events, inheritance, Abstract contracts, interfaces, libraries, exceptions. Before the further content, I decided to make a special topic of ERC721 to comprehensively apply the previous content, so as to help you better review the basic knowledge and have a deeper understanding of the ERC721 contract. Hopefully, after studying this topic, everyone will publish their own NFT.


TL; DR is too long to look at


- When I checked the BAYC contract I found two serious loopholes, one of which may cause BAYC to overissue, exceeding the set supply limit of 10,000 pieces.


- Overissue vulnerability refers to the fact that the reserveApes function used in the contract for the project party to reserve BAYC NFT does not check whether it is overissue. The owner address can be cast at any time and is not limited by the upper limit of supply.


- The vulnerability can be triggered in two situations: the project side does evil (almost impossible) and the hacker steals the owner's private key (possible).


- Affected by the vulnerability include BAYC and other NFT project parties that reuse their code.


- The simplest solution is for BAYC project party to give up ownership.


- These two bugs weren't hard to find, and I'm certainly not the first to find them (see this blog post from October), but they didn't get enough attention. Since BAYC's market value is now more than $4 billion, we hope to attract the attention of the project side.


Disclaiming: This article is a technical discussion, not FUD BAYC. I like BAYC a lot and hope that bugs never get triggered.


BAYC


This is WTF  In lecture 4 of the ERC721 series, we cover BAYC contracts and their vulnerabilities.


BAYC (Bored Ape Yacht Club) is the top NFT project, with a record price of 0.08&Nbsp at the end of April 2021; The price of ETH is on sale, 10,000 pieces in total. The floor is now valued at around 130 ETH, up more than 1,000 times and worth more than $4 billion.



BAYC contracts


BAYC's contract is inetherscanOpen source, everyone can view, today we will study it carefully.


BAYC's contract is open-source on EtherScan


BAYC's contract is flat, one file includes all parent contracts, a total of 2021 lines. But the first 1900 lines are all about the parent contract, and only the last 100 lines are about the master contract, which we'll focus on.


Inheritance & have spent



The Solidity version of the BAYC contract is 0.7.0, inheriting two contracts, ERC721 and Ownable. The most important thing about the ERC721 contract is that it implements the onlyOwner decorator so that specific functions can only be called from the owner address of the contract. See Solidity Minimalist tutorial Lecture 8: Constructors and Decorators.


State variable & NBSP;  



Since the solidity version of the contract is 0.7.0 and SafeMath is not yet built in, it declares using the SafeMath library for the Uint256 type with using-for to prevent overflow errors.


There are eight state variables in the contract:


BAYC_PROVENANCE: Merges the hashes of all NFT images together in a certain order. This is actually a very clever design, which can prove that the content and order of the picture is determined, and there is no need to expose the picture information before opening the picture, but also can solve the NFT project side to steal the rare high degree of change to their own. Bug 1. But the BAYC project side made the mistake of adding a setProvenanceHash function that allowed the owner to change BayC_ProvenanceHash countless times, contrary to its original intent and leaving open the possibility of wrongdoing, Like swapping pictures and altering Bayc Provenance. The correct modification to BAYC_PROVENANCE is set to immutable, which cannot be modified after initialization in constructor.  



StartingIndexBlock: The height of the block to start selling.

StartingIndex: Looks like a redundant variable?

ApePrice: BAYC Offer Price, 0.08 ETH.

MaxApePurchase: Maximum number of mints at a time, up to 20 at a time. Mint multiple NFT in one transaction, saving gas than mint only one NFT at a time.

MAX_APES: Maximum supply of NFT, 10,000 units.

Bug 2saleIsActive: Whether to start public sale.

REVEAL_TIMESTAMP: The block height of the open graph.


function


The BAYC main contract defines 10 functions:


Constuctor: constructor, initializing token name, code, MAX_APES, REVEAL_TIMESTAMP.    


Withdraw: Withdraw ETH obtained from selling BAYC.



  ReserveApes: ** is important! ** The project side reserves BAYC for itself and gives itself 30 mintfor each invocation. Only the owner of the contract can call. Bug 2



setRevealTimestamp:更改 REVEAL_TIMESTAMP。 



setProvenanceHash:更改 BAYC_PROVENANCE。Bug 1 



setBaseURI:设定 BAYC 的 BaseURI(ERC721 合约中的状态变量)。 



flipSaleState:打开/暂停公售。 



mintApe:**重要!**买家支付 ETH 并铸造 BAYC。调用 ERC721 的_safeMint 函数。条件:

If saleIsActive is true, the public sale begins.

numberOfTokens  < =  MaxApePurchase, can only mint20 at a time.

The circulation after Mint is less than the total supply (10,000).

支付的 ETH 要大于 0.08 * mint 数量。       



SetStartingIndex: Looks like a redundant function?



emergencySetStartingIndexBlock:在紧急情况下,开始公售。将 startingIndexBlock 设为当前区块高度。 



Serious hole in BAYC contract


There are two serious bugs in the BAYC contract. One can cause images to be swapped, and the other, more serious, can cause BAYC to overshoot beyond the set limit of 10,000.


Bug 1: Risk of image being replaced


The BayC provenance variable used to prove that the image has not been tampered with or swapped can be changed by the contract owner at will. An attacker (either the project party or the hacker who stole the private key) could swap the image, use the setBaseURI function to set up a new metadata to store the url, and then compute BAYC_PROVENANCE for the new image and update it. That way, bayC Provenance can't be tested for tampering.


Correct rewriting: Set the BAYC_PROVENANCE variable to IMMUTABLE, initialize it in the constructor, and then it cannot be changed.


Bug 2: Secondary issue risk


The reserveApes function used to reserve BAYC for the project party does not check supply as the public mintApe function does, so even if the maximum supply MAX_APES is set to 10,000, The contract owner (project owner or hacker who stole the private key) can still call reserveApes to mint a new BAYC, making BAYC#10000, BAYC#10001, etc., with no upper limit.


Correct rewrite: Add a maximum supply check to the reserveApes function.


Under what circumstances will you be attacked


The two serious loopholes in the BAYC contract mentioned above need to be executed by the contract owner. In one case, the project side does evil and attacks the vulnerability. But it is clear that BAYC is so successful that it is much more profitable for the project side not to be evil, and there is absolutely no incentive to be evil, so this rarely happens. The second case is that the owner wallet private key is stolen by hackers, hackers do bad call reserveApes super issued BAYC for sale. Given that BAYC's official Instagram was stolen just a few days ago, this is not impossible. Currently BAYC owner address is: 0 xaba7161a7fb69c88e16ed9f455ce62b791ee4d03


Let us pray in silence.


How to solve it?


In fact, the method of these two vulnerabilities is very simple, that is, the BAYC project party calls renounceOwnership to abandon the contract owner. Because the related functions of the two vulnerabilities need to be called by the owner, no one can attack the vulnerability after giving up the owner permission.


Other solutions can also be discussed.


Easter egg: Who is the BAYC reserved by the project side?


The BAYC project called the reserveApes function only once, reserving a total of 30 baycs, #0 to #29, and giving them to 30 addresses.


1, emperortomatoketchup. Eth

2, 20 x46efbaedc92067e6d60e84ed6395099723252496

3, 0 xc5c7b46843014b1591e9af24de797156cde67f08

4, garga. Eth

5, 0 xwave. Eth

6, 0 xed7c0117d7d35850d71e2a3f390972406f8d5d46

7, 0 x898c4607809945b49d65ea51580101798931b241

8, rdlwriter. Eth

9, bmouse. Eth

10., cryptorobo eth

11, puzzle. Eth

12, 0 xddb338bc464fde06b382d28f37e57cb3727c2e1b

13, chrishol. Eth

14, keltron. Eth

15, yourstruly. Eth

16, 0 x7225fd5032038bcf49c36deba23a16262521ede9

17, dmnets. Eth

18, nabito. Eth

19, tropofarmer. Eth

20, 0 xc3fbc3f485f0d9b0bd21b13a4aaa8340160156cb

21, nftfox. Eth

22, d34thst4lker. Eth

23, thephotographer. Eth

24, 0 xed2d1254e79835bf5911aa8946e23bf508477da4

25, 0 xf9cb2a5944654b0c9b07d2311715728e30d3ee82

26, billymcsmithers. Eth

27, web3ireland. Eth

28, yourstruly. Eth

29, 0 x822a16309a9ee40f15e196898f11a010ecb1c963

30, brulik. Eth


conclusion


- This is lecture 4 of the Solidity Minimalism Tutorial ERC721 where we cover BAYC contracts and their vulnerabilities.


- When I checked the BAYC contract I found two serious loopholes, one of which may cause BAYC to overissue, exceeding the set supply limit of 10,000 pieces.


- Overissue vulnerability refers to the fact that the reserveApes function used in the contract for the project party to reserve BAYC NFT does not check whether it is overissue. The owner address can be cast at any time and is not limited by the upper limit of supply.


- The vulnerability can be triggered in two situations: the project side does evil (almost impossible) and the hacker steals the owner's private key (possible).


- Affected by the vulnerability include BAYC and other NFT project parties that reuse their code.


- The simplest solution is for BAYC project party to give up ownership.


- NFT project side needs more stringent audit contract!


Disclaiming: This article is a technical discussion, not FUD BAYC. I like BAYC a lot and hope that bugs never get triggered.


The original link


Welcome to join the official BlockBeats community:

Telegram Subscription Group: https://t.me/theblockbeats

Telegram Discussion Group: https://t.me/BlockBeats_App

Official Twitter Account: https://twitter.com/BlockBeatsAsia

举报 Correction/Report
Choose Library
Add Library
Cancel
Finish
Add Library
Visible to myself only
Public
Save
Correction/Report
Submit