# pxn合约的简单分析 **Published by:** [ Trembling bear](https://paragraph.com/@trembling-bear/) **Published on:** 2022-05-08 **URL:** https://paragraph.com/@trembling-bear/pxn ## Content 本人纯小白,第一次尝试分析合约代码,仅供学习参考! 合约地址: https://rinkeby.etherscan.io/address/0x3201fe090e70bd464bc93469545be5278595d1f5#code 合约类型: ERC721A 审计分析: Reentrancy: safemint 总是发生在最后一步 √ Ownership take over: 合约继承了Ownerable Timestamp dependency://Require DA started require( block.timestamp >= DA_STARTING_TIMESTAMP, "DA has not started!" ); require(block.timestamp <= WL_STARTING_TIMESTAMP, "DA is finished"); Contract interact: callerIsUser()这个函数要求调用者不能是其他合约 modifier callerIsUser() { require(tx.origin == msg.sender, "The caller is another contract"); _; } 业务逻辑分析: (1)白单Mintfunction mintWL(bytes calldata signature) public payable callerIsUser { require(DA_FINAL_PRICE > 0, "Dutch action must be over!"); require( !userToHasMintedPublicWL[msg.sender], "Can only mint once during public WL!" ); require( block.timestamp >= WL_STARTING_TIMESTAMP, "WL has not started yet!" ); require( block.timestamp <= WL_STARTING_TIMESTAMP + 86400, "WL has finished!" ); //Require max supply just in case. require( PUBLIC_WL_MINTED + 1 <= WL_QUANTITY, "Max supply of 6000!" ); require( wlSigner == keccak256( abi.encodePacked( "\x19Ethereum Signed Message:\n32", bytes32(uint256(uint160(msg.sender))) ) ).recover(signature), "Signer address mismatch." ); require(msg.value >= WLprice, "Must send enough eth for WL Mint"); userToHasMintedPublicWL[msg.sender] = true; PUBLIC_WL_MINTED++; //Mint them _safeMint(msg.sender, 1); 必须在荷兰拍以后进行; !userToHasMintedPublicWL[msg.sender] 是否已经mint; 到时间才能开启mint; block.timestamp <= WL_STARTING_TIMESTAMP + 86400 mint时间; 上限为6000个; 看起来没有问题。 (2)荷兰拍函数function mintDutchAuction(uint8 quantity) public payable callerIsUser { require( DA_ACTIVE == true, "DA isnt active" ); //Require DA started require( block.timestamp >= DA_STARTING_TIMESTAMP, "DA has not started!" ); require(block.timestamp <= WL_STARTING_TIMESTAMP, "DA is finished"); //Require max 2 per tx require(quantity > 0 && quantity < 3, "Can only mint max 2 NFTs!"); //Require max 2 per wallet require(balanceOf(msg.sender) + quantity < 3, "Can only mint max 2 NFTs!"); uint256 _currentPrice = currentPrice(); //Require enough ETH require( msg.value >= quantity * _currentPrice, "Did not send enough eth." ); //Max supply require( totalSupply() + quantity <= DA_QUANTITY, "Max supply for DA reached!" ); //This calculates the final price if (totalSupply() + quantity == DA_QUANTITY) { DA_FINAL_PRICE = _currentPrice; if (((DA_FINAL_PRICE / 100) * 50) < WLprice) { WLprice = ((DA_FINAL_PRICE / 100) * 50); } } userToTokenBatchPriceData[msg.sender].push( TokenBatchPriceData(uint128(msg.value), quantity) ); //Mint the quantity _safeMint(msg.sender, quantity); } 需要在规定时间mint,限制了最多两个钱包,每个两次mint。totalSupply() + quantity <= DA_QUANTITY 不超过最大的荷兰拍总数。当达到最大的荷兰拍总数时,计算此时的的价格,如果此时的价格小于白名单价格,此时价格+0.5是白名单的价格。 if (((DA_FINAL_PRICE / 100) * 50) < WLprice) { WLprice = ((DA_FINAL_PRICE / 100) * 50); } (3)项目方保留 function devMint() external onlyOwner { require( block.timestamp >= WL_STARTING_TIMESTAMP + 86400, "WL hasnt finished!" ); uint256 leftOver = 10000 - totalSupply(); _safeMint(DEV_FUND, leftOver); } (4)function teamMint(uint8 quantity) public payable { require( block.timestamp >= WL_STARTING_TIMESTAMP, "WL has finished!" ); require(_teamList[msg.sender] >= quantity, "already claimed"); require( msg.value >= quantity * WLprice, "Must send enough eth for WL Mint" ); require(totalSupply() + quantity <= 10000, "exceeds supply"); _teamList[msg.sender] = _teamList[msg.sender] - quantity; _safeMint(msg.sender, quantity); } 数量上限是10000个,需要eth余额足够。 ## Publication Information - [ Trembling bear](https://paragraph.com/@trembling-bear/): Publication homepage - [All Posts](https://paragraph.com/@trembling-bear/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@trembling-bear): Subscribe to updates