本人纯小白,第一次尝试分析合约代码,仅供学习参考!
合约地址:
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)白单Mint
function 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余额足够。
