文件 1 的 10:Address.sol
pragma solidity ^0.8.0;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 10:BondlyLaunchpad.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
contract BondlyLaunchPad is Ownable {
using SafeERC20 for IERC20;
using MerkleProof for bytes32[];
uint256 public _currentCardId = 0;
address payable public _salesperson;
bool public _saleStarted = false;
struct Card {
uint256 cardId;
uint256 tokenId;
uint256 totalAmount;
uint256 currentAmount;
uint256 basePrice;
uint256 saleNumber;
address contractAddress;
address paymentToken;
bool isFinished;
}
struct History {
mapping(uint256 => mapping(address => uint256)) purchasedHistories;
}
event CreateCard(
address indexed _from,
uint256 _cardId,
address indexed _contractAddress,
uint256 _tokenId,
uint256 _totalAmount,
uint256 _basePrice,
uint256 _saleNumber,
address paymentToken
);
event PurchaseCard(address indexed _from, uint256 _cardId, uint256 _amount);
event CardChanged(uint256 _cardId);
mapping(uint256 => Card) public _cards;
mapping(uint256 => mapping(uint256 => uint256)) public _cardLimitsPerWallet;
mapping(uint256 => mapping(uint256 => uint256)) public _saleLimitsPerWallet;
mapping(uint256 => mapping(uint256 => uint256)) public _saleTierTimes;
mapping(uint256 => uint256) public _saleTierQuantity;
mapping(address => bool) public _blacklist;
mapping(uint256 => bytes32) public _whitelistRoot;
mapping(uint256 => bool) public _salePublicCheck;
History private _cardHistory;
History private _saleHistory;
constructor() {
_salesperson = payable(msg.sender);
}
function setSalesPerson(address payable newSalesPerson) external onlyOwner {
_salesperson = newSalesPerson;
}
function startSale() external onlyOwner {
_saleStarted = true;
}
function stopSale() external onlyOwner {
_saleStarted = false;
}
function createCard(
address _contractAddress,
uint256 _tokenId,
uint256 _totalAmount,
uint256 _saleNumber,
address _paymentTokenAddress,
uint256 _basePrice,
uint256[] calldata _limitsPerWallet
) external onlyOwner {
IERC1155 _contract = IERC1155(_contractAddress);
require(
_contract.balanceOf(_salesperson, _tokenId) >= _totalAmount,
"Initial supply cannot be more than available supply"
);
require(
_contract.isApprovedForAll(_salesperson, address(this)) == true,
"Contract must be whitelisted by owner"
);
uint256 _id = _getNextCardID();
_incrementCardId();
Card memory _newCard;
_newCard.cardId = _id;
_newCard.contractAddress = _contractAddress;
_newCard.tokenId = _tokenId;
_newCard.totalAmount = _totalAmount;
_newCard.currentAmount = _totalAmount;
_newCard.basePrice = _basePrice;
_newCard.paymentToken = _paymentTokenAddress;
_newCard.saleNumber = _saleNumber;
_newCard.isFinished = false;
_cards[_id] = _newCard;
_setCardLimitsPerWallet(_id, _limitsPerWallet);
emit CreateCard(
msg.sender,
_id,
_contractAddress,
_tokenId,
_totalAmount,
_basePrice,
_saleNumber,
_paymentTokenAddress
);
}
function isEligbleToBuy(
uint256 _cardId,
uint256 tier,
bytes32[] calldata whitelistProof
) public view returns (uint256) {
if (_blacklist[msg.sender] == true) return 0;
if (_saleStarted == false) return 0;
Card memory _currentCard = _cards[_cardId];
if (_salePublicCheck[_currentCard.saleNumber]) {
if (
!verifyWhitelist(
msg.sender,
_currentCard.saleNumber,
tier,
whitelistProof
)
) {
return 0;
}
} else {
if (
tier != 0 &&
!verifyWhitelist(
msg.sender,
_currentCard.saleNumber,
tier,
whitelistProof
)
) {
return 0;
}
}
uint256 startTime = _saleTierTimes[_currentCard.saleNumber][tier];
if (startTime != 0 && block.timestamp >= startTime) {
uint256 _currentCardBoughtAmount = _cardHistory.purchasedHistories[
_cardId
][msg.sender];
uint256 _cardLimitPerWallet = _cardLimitsPerWallet[_cardId][tier];
if (_currentCardBoughtAmount >= _cardLimitPerWallet) return 0;
uint256 _currentSaleBoughtAmount = _saleHistory.purchasedHistories[
_currentCard.saleNumber
][msg.sender];
uint256 _saleLimitPerWallet = _saleLimitsPerWallet[
_currentCard.saleNumber
][tier];
if (_currentSaleBoughtAmount >= _saleLimitPerWallet) return 0;
uint256 _cardAvailableForPurchase = _cardLimitPerWallet -
_currentCardBoughtAmount;
uint256 _saleAvailableForPurchase = _saleLimitPerWallet -
_currentSaleBoughtAmount;
uint256 _availableForPurchase = _cardAvailableForPurchase >
_saleAvailableForPurchase
? _saleAvailableForPurchase
: _cardAvailableForPurchase;
if (_currentCard.currentAmount <= _availableForPurchase)
return _currentCard.currentAmount;
return _availableForPurchase;
}
return 0;
}
function purchaseNFT(
uint256 _cardId,
uint256 _amount,
uint256 tier,
bytes32[] calldata whitelistProof
) external payable {
require(_blacklist[msg.sender] == false, "you are blocked");
require(_saleStarted == true, "Sale stopped");
Card memory _currentCard = _cards[_cardId];
require(_currentCard.isFinished == false, "Card is finished");
if (_salePublicCheck[_currentCard.saleNumber]) {
require(
verifyWhitelist(
msg.sender,
_currentCard.saleNumber,
tier,
whitelistProof
),
"Invalid proof for whitelist"
);
} else {
if (tier != 0) {
require(
verifyWhitelist(
msg.sender,
_currentCard.saleNumber,
tier,
whitelistProof
),
"Invalid proof for whitelist"
);
}
}
{
uint256 startTime = _saleTierTimes[_currentCard.saleNumber][tier];
require(
startTime != 0 && startTime <= block.timestamp,
"wait for sale start"
);
}
require(
_amount != 0 && _currentCard.currentAmount >= _amount,
"Order exceeds the max number of available NFTs"
);
uint256 _availableForPurchase;
{
uint256 _currentCardBoughtAmount = _cardHistory.purchasedHistories[
_cardId
][msg.sender];
uint256 _cardLimitPerWallet = _cardLimitsPerWallet[_cardId][tier];
uint256 _currentSaleBoughtAmount = _saleHistory.purchasedHistories[
_currentCard.saleNumber
][msg.sender];
uint256 _saleLimitPerWallet = _saleLimitsPerWallet[
_currentCard.saleNumber
][tier];
require(
_currentCardBoughtAmount < _cardLimitPerWallet &&
_currentSaleBoughtAmount < _saleLimitPerWallet,
"Order exceeds the max limit of NFTs per wallet"
);
uint256 _cardAvailableForPurchase = _cardLimitPerWallet -
_currentCardBoughtAmount;
uint256 _saleAvailableForPurchase = _saleLimitPerWallet -
_currentSaleBoughtAmount;
_availableForPurchase = _cardAvailableForPurchase >
_saleAvailableForPurchase
? _saleAvailableForPurchase
: _cardAvailableForPurchase;
if (_availableForPurchase > _amount) {
_availableForPurchase = _amount;
}
_cards[_cardId].currentAmount =
_cards[_cardId].currentAmount -
_availableForPurchase;
_cardHistory.purchasedHistories[_cardId][msg.sender] =
_currentCardBoughtAmount +
_availableForPurchase;
_saleHistory.purchasedHistories[_currentCard.saleNumber][
msg.sender
] = _currentSaleBoughtAmount + _availableForPurchase;
}
uint256 _price = _currentCard.basePrice * _availableForPurchase;
require(
_currentCard.paymentToken == address(0) ||
IERC20(_currentCard.paymentToken).allowance(
msg.sender,
address(this)
) >=
_price,
"Need to Approve payment"
);
if (_currentCard.paymentToken == address(0)) {
require(msg.value >= _price, "Not enough funds to purchase");
uint256 overPrice = msg.value - _price;
_salesperson.transfer(_price);
if (overPrice > 0) payable(msg.sender).transfer(overPrice);
} else {
IERC20(_currentCard.paymentToken).transferFrom(
msg.sender,
_salesperson,
_price
);
}
IERC1155(_currentCard.contractAddress).safeTransferFrom(
_salesperson,
msg.sender,
_currentCard.tokenId,
_availableForPurchase,
""
);
emit PurchaseCard(msg.sender, _cardId, _availableForPurchase);
}
function _getNextCardID() private view returns (uint256) {
return _currentCardId + 1;
}
function _incrementCardId() private {
_currentCardId++;
}
function cancelCard(uint256 _cardId) external onlyOwner {
_cards[_cardId].isFinished = true;
emit CardChanged(_cardId);
}
function setTier(
uint256 _saleNumber,
uint256 _tier,
uint256 _startTime
) external onlyOwner {
if (_tier + 1 > _saleTierQuantity[_saleNumber]) {
_saleTierQuantity[_saleNumber] = _tier + 1;
}
_saleTierTimes[_saleNumber][_tier] = _startTime;
}
function setTiers(uint256 _saleNumber, uint256[] calldata _startTimes)
external
onlyOwner
{
if (_startTimes.length > _saleTierQuantity[_saleNumber]) {
_saleTierQuantity[_saleNumber] = _startTimes.length;
}
for (uint256 i = 0; i < _startTimes.length; i++) {
_saleTierTimes[_saleNumber][i] = _startTimes[i];
}
}
function setSaleLimitPerWallet(
uint256 _saleNumber,
uint256 _tier,
uint256 _limitPerWallet
) external onlyOwner {
if (_tier + 1 > _saleTierQuantity[_saleNumber]) {
_saleTierQuantity[_saleNumber] = _tier + 1;
}
_saleLimitsPerWallet[_saleNumber][_tier] = _limitPerWallet;
}
function setSaleLimitsPerWallet(
uint256 _saleNumber,
uint256[] calldata _limitsPerWallet
) external onlyOwner {
if (_limitsPerWallet.length > _saleTierQuantity[_saleNumber]) {
_saleTierQuantity[_saleNumber] = _limitsPerWallet.length;
}
for (uint256 i = 0; i < _limitsPerWallet.length; i++) {
_saleLimitsPerWallet[_saleNumber][i] = _limitsPerWallet[i];
}
}
function setCardLimitPerWallet(
uint256 _cardNumber,
uint256 _tier,
uint256 _limitPerWallet
) external onlyOwner {
uint256 saleNumber = _cards[_cardNumber].saleNumber;
if (_tier + 1 > _saleTierQuantity[saleNumber]) {
_saleTierQuantity[saleNumber] = _tier + 1;
}
_cardLimitsPerWallet[_cardNumber][_tier] = _limitPerWallet;
}
function _setCardLimitsPerWallet(
uint256 _cardNumber,
uint256[] calldata _limitsPerWallet
) private {
uint256 saleNumber = _cards[_cardNumber].saleNumber;
if (_limitsPerWallet.length > _saleTierQuantity[saleNumber]) {
_saleTierQuantity[saleNumber] = _limitsPerWallet.length;
}
for (uint256 i = 0; i < _limitsPerWallet.length; i++) {
_cardLimitsPerWallet[_cardNumber][i] = _limitsPerWallet[i];
}
}
function setCardLimitsPerWallet(
uint256 _cardNumber,
uint256[] calldata _limitsPerWallet
) external onlyOwner {
_setCardLimitsPerWallet(_cardNumber, _limitsPerWallet);
}
function setCardsLimitsPerWallet(
uint256[] calldata _cardNumbers,
uint256[][] calldata _limitsPerWallet
) external onlyOwner {
require(
_cardNumbers.length == _limitsPerWallet.length,
"Array input size mismatch"
);
for (uint256 i = 0; i < _cardNumbers.length; i++) {
_setCardLimitsPerWallet(_cardNumbers[i], _limitsPerWallet[i]);
}
}
function resumeCard(uint256 _cardId) external onlyOwner {
_cards[_cardId].isFinished = false;
emit CardChanged(_cardId);
}
function setCardPrice(uint256 _cardId, uint256 _newPrice)
external
onlyOwner
{
_cards[_cardId].basePrice = _newPrice;
emit CardChanged(_cardId);
}
function setCardPaymentToken(uint256 _cardId, address _newAddr)
external
onlyOwner
{
_cards[_cardId].paymentToken = _newAddr;
emit CardChanged(_cardId);
}
function setCardSaleNumber(uint256 _cardId, uint256 _saleNumber)
external
onlyOwner
{
_cards[_cardId].saleNumber = _saleNumber;
emit CardChanged(_cardId);
}
function addBlackListAddress(address addr) external onlyOwner {
_blacklist[addr] = true;
}
function batchAddBlackListAddress(address[] calldata addr)
external
onlyOwner
{
for (uint256 i = 0; i < addr.length; i++) {
_blacklist[addr[i]] = true;
}
}
function removeBlackListAddress(address addr) external onlyOwner {
_blacklist[addr] = false;
}
function batchRemoveBlackListAddress(address[] calldata addr)
external
onlyOwner
{
for (uint256 i = 0; i < addr.length; i++) {
_blacklist[addr[i]] = false;
}
}
function setWhitelistRoot(uint256 saleNumber, bytes32 merkleRoot)
external
onlyOwner
{
_whitelistRoot[saleNumber] = merkleRoot;
}
function setWhitelistRoots(
uint256[] calldata saleNumbers,
bytes32[] calldata merkleRoots
) external onlyOwner {
require(
saleNumbers.length == merkleRoots.length,
"Array input size mismatch"
);
for (uint256 i = 0; i < saleNumbers.length; i++) {
_whitelistRoot[saleNumbers[i]] = merkleRoots[i];
}
}
function setPublicCheck(uint256 saleNumber, bool isCheck)
external
onlyOwner
{
_salePublicCheck[saleNumber] = isCheck;
}
function setPublicChecks(
uint256[] calldata saleNumbers,
bool[] calldata isCheck
) external onlyOwner {
require(
saleNumbers.length == isCheck.length,
"Array input size mismatch"
);
for (uint256 i = 0; i < saleNumbers.length; i++) {
_salePublicCheck[saleNumbers[i]] = isCheck[i];
}
}
function isCardCompleted(uint256 _cardId) public view returns (bool) {
return _cards[_cardId].isFinished;
}
function isCardFree(uint256 _cardId) public view returns (bool) {
return _cards[_cardId].basePrice == 0;
}
function getCardContract(uint256 _cardId) public view returns (address) {
return _cards[_cardId].contractAddress;
}
function getCardPaymentContract(uint256 _cardId)
public
view
returns (address)
{
return _cards[_cardId].paymentToken;
}
function getCardTokenId(uint256 _cardId) public view returns (uint256) {
return _cards[_cardId].tokenId;
}
function getTierTimes(uint256 saleNumber)
public
view
returns (uint256[] memory)
{
uint256[] memory times = new uint256[](_saleTierQuantity[saleNumber]);
for (uint256 i = 0; i < times.length; i++) {
times[i] = _saleTierTimes[saleNumber][i];
}
return times;
}
function getSaleLimitsPerWallet(uint256 saleNumber)
public
view
returns (uint256[] memory)
{
uint256[] memory limits = new uint256[](_saleTierQuantity[saleNumber]);
for (uint256 i = 0; i < limits.length; i++) {
limits[i] = _saleLimitsPerWallet[saleNumber][i];
}
return limits;
}
function getCardLimitsPerWallet(uint256 cardNumber)
public
view
returns (uint256[] memory)
{
uint256 saleNumber = _cards[cardNumber].saleNumber;
uint256[] memory limits = new uint256[](_saleTierQuantity[saleNumber]);
for (uint256 i = 0; i < limits.length; i++) {
limits[i] = _cardLimitsPerWallet[cardNumber][i];
}
return limits;
}
function getCardTotalAmount(uint256 _cardId) public view returns (uint256) {
return _cards[_cardId].totalAmount;
}
function getCardCurrentAmount(uint256 _cardId)
public
view
returns (uint256)
{
return _cards[_cardId].currentAmount;
}
function getAllCardsPerSale(uint256 saleNumber)
public
view
returns (uint256[] memory)
{
uint256 count;
for (uint256 i = 1; i <= _currentCardId; i++) {
if (_cards[i].saleNumber == saleNumber) {
count++;
}
}
uint256[] memory cardIds = new uint256[](count);
count = 0;
for (uint256 i = 1; i <= _currentCardId; i++) {
if (_cards[i].saleNumber == saleNumber) {
cardIds[count] = i;
count++;
}
}
return cardIds;
}
function getAllCardsPerContract(address _contractAddr)
public
view
returns (uint256[] memory, uint256[] memory)
{
uint256 count;
for (uint256 i = 1; i <= _currentCardId; i++) {
if (_cards[i].contractAddress == _contractAddr) {
count++;
}
}
uint256[] memory cardIds = new uint256[](count);
uint256[] memory tokenIds = new uint256[](count);
count = 0;
for (uint256 i = 1; i <= _currentCardId; i++) {
if (_cards[i].contractAddress == _contractAddr) {
cardIds[count] = i;
tokenIds[count] = _cards[i].tokenId;
count++;
}
}
return (cardIds, tokenIds);
}
function getActiveCardsPerContract(address _contractAddr)
public
view
returns (uint256[] memory, uint256[] memory)
{
uint256 count;
for (uint256 i = 1; i <= _currentCardId; i++) {
if (
_cards[i].contractAddress == _contractAddr &&
_cards[i].isFinished == false
) {
count++;
}
}
uint256[] memory cardIds = new uint256[](count);
uint256[] memory tokenIds = new uint256[](count);
count = 0;
for (uint256 i = 1; i <= _currentCardId; i++) {
if (
_cards[i].contractAddress == _contractAddr &&
_cards[i].isFinished == false
) {
cardIds[count] = i;
tokenIds[count] = _cards[i].tokenId;
count++;
}
}
return (cardIds, tokenIds);
}
function getClosedCardsPerContract(address _contractAddr)
public
view
returns (uint256[] memory, uint256[] memory)
{
uint256 count;
for (uint256 i = 1; i <= _currentCardId; i++) {
if (
_cards[i].contractAddress == _contractAddr &&
_cards[i].isFinished
) {
count++;
}
}
uint256[] memory cardIds = new uint256[](count);
uint256[] memory tokenIds = new uint256[](count);
count = 0;
for (uint256 i = 1; i <= _currentCardId; i++) {
if (
_cards[i].contractAddress == _contractAddr &&
_cards[i].isFinished
) {
cardIds[count] = i;
tokenIds[count] = _cards[i].tokenId;
count++;
}
}
return (cardIds, tokenIds);
}
function getCardBasePrice(uint256 _cardId) public view returns (uint256) {
return _cards[_cardId].basePrice;
}
function getCardURL(uint256 _cardId) public view returns (string memory) {
return
IERC1155MetadataURI(_cards[_cardId].contractAddress).uri(
_cards[_cardId].tokenId
);
}
function collect(address _token) external onlyOwner {
if (_token == address(0)) {
payable(msg.sender).transfer(address(this).balance);
} else {
uint256 amount = IERC20(_token).balanceOf(address(this));
IERC20(_token).transfer(msg.sender, amount);
}
}
function verifyWhitelist(
address user,
uint256 saleNumber,
uint256 tier,
bytes32[] calldata whitelistProof
) public view returns (bool) {
bytes32 leaf = keccak256(abi.encodePacked(user, saleNumber, tier));
return whitelistProof.verify(_whitelistRoot[saleNumber], leaf);
}
}
文件 3 的 10:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 4 的 10:IERC1155.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155 is IERC165 {
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
event URI(string value, uint256 indexed id);
function balanceOf(address account, uint256 id) external view returns (uint256);
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
external
view
returns (uint256[] memory);
function setApprovalForAll(address operator, bool approved) external;
function isApprovedForAll(address account, address operator) external view returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes calldata data
) external;
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}
文件 5 的 10:IERC1155MetadataURI.sol
pragma solidity ^0.8.0;
import "../IERC1155.sol";
interface IERC1155MetadataURI is IERC1155 {
function uri(uint256 id) external view returns (string memory);
}
文件 6 的 10:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 7 的 10:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 8 的 10:MerkleProof.sol
pragma solidity ^0.8.0;
library MerkleProof {
function verify(
bytes32[] memory proof,
bytes32 root,
bytes32 leaf
) internal pure returns (bool) {
return processProof(proof, leaf) == root;
}
function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
bytes32 computedHash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
bytes32 proofElement = proof[i];
if (computedHash <= proofElement) {
computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
} else {
computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
}
}
return computedHash;
}
}
文件 9 的 10:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 10 的 10:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
{
"compilationTarget": {
"contracts/BondlyLaunchpad.sol": "BondlyLaunchPad"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 500
},
"remappings": []
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_cardId","type":"uint256"}],"name":"CardChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"uint256","name":"_cardId","type":"uint256"},{"indexed":true,"internalType":"address","name":"_contractAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_totalAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_basePrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_saleNumber","type":"uint256"},{"indexed":false,"internalType":"address","name":"paymentToken","type":"address"}],"name":"CreateCard","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"uint256","name":"_cardId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"PurchaseCard","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_blacklist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"_cardLimitsPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_cards","outputs":[{"internalType":"uint256","name":"cardId","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"uint256","name":"currentAmount","type":"uint256"},{"internalType":"uint256","name":"basePrice","type":"uint256"},{"internalType":"uint256","name":"saleNumber","type":"uint256"},{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"address","name":"paymentToken","type":"address"},{"internalType":"bool","name":"isFinished","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_currentCardId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"_saleLimitsPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_salePublicCheck","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_saleStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_saleTierQuantity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"_saleTierTimes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_salesperson","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"_whitelistRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"addBlackListAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addr","type":"address[]"}],"name":"batchAddBlackListAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addr","type":"address[]"}],"name":"batchRemoveBlackListAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardId","type":"uint256"}],"name":"cancelCard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"collect","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contractAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_totalAmount","type":"uint256"},{"internalType":"uint256","name":"_saleNumber","type":"uint256"},{"internalType":"address","name":"_paymentTokenAddress","type":"address"},{"internalType":"uint256","name":"_basePrice","type":"uint256"},{"internalType":"uint256[]","name":"_limitsPerWallet","type":"uint256[]"}],"name":"createCard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contractAddr","type":"address"}],"name":"getActiveCardsPerContract","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_contractAddr","type":"address"}],"name":"getAllCardsPerContract","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"saleNumber","type":"uint256"}],"name":"getAllCardsPerSale","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardId","type":"uint256"}],"name":"getCardBasePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardId","type":"uint256"}],"name":"getCardContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardId","type":"uint256"}],"name":"getCardCurrentAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"cardNumber","type":"uint256"}],"name":"getCardLimitsPerWallet","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardId","type":"uint256"}],"name":"getCardPaymentContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardId","type":"uint256"}],"name":"getCardTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardId","type":"uint256"}],"name":"getCardTotalAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardId","type":"uint256"}],"name":"getCardURL","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_contractAddr","type":"address"}],"name":"getClosedCardsPerContract","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"saleNumber","type":"uint256"}],"name":"getSaleLimitsPerWallet","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"saleNumber","type":"uint256"}],"name":"getTierTimes","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardId","type":"uint256"}],"name":"isCardCompleted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardId","type":"uint256"}],"name":"isCardFree","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardId","type":"uint256"},{"internalType":"uint256","name":"tier","type":"uint256"},{"internalType":"bytes32[]","name":"whitelistProof","type":"bytes32[]"}],"name":"isEligbleToBuy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"tier","type":"uint256"},{"internalType":"bytes32[]","name":"whitelistProof","type":"bytes32[]"}],"name":"purchaseNFT","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"removeBlackListAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardId","type":"uint256"}],"name":"resumeCard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardNumber","type":"uint256"},{"internalType":"uint256","name":"_tier","type":"uint256"},{"internalType":"uint256","name":"_limitPerWallet","type":"uint256"}],"name":"setCardLimitPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardNumber","type":"uint256"},{"internalType":"uint256[]","name":"_limitsPerWallet","type":"uint256[]"}],"name":"setCardLimitsPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardId","type":"uint256"},{"internalType":"address","name":"_newAddr","type":"address"}],"name":"setCardPaymentToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardId","type":"uint256"},{"internalType":"uint256","name":"_newPrice","type":"uint256"}],"name":"setCardPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cardId","type":"uint256"},{"internalType":"uint256","name":"_saleNumber","type":"uint256"}],"name":"setCardSaleNumber","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_cardNumbers","type":"uint256[]"},{"internalType":"uint256[][]","name":"_limitsPerWallet","type":"uint256[][]"}],"name":"setCardsLimitsPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"saleNumber","type":"uint256"},{"internalType":"bool","name":"isCheck","type":"bool"}],"name":"setPublicCheck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"saleNumbers","type":"uint256[]"},{"internalType":"bool[]","name":"isCheck","type":"bool[]"}],"name":"setPublicChecks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleNumber","type":"uint256"},{"internalType":"uint256","name":"_tier","type":"uint256"},{"internalType":"uint256","name":"_limitPerWallet","type":"uint256"}],"name":"setSaleLimitPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleNumber","type":"uint256"},{"internalType":"uint256[]","name":"_limitsPerWallet","type":"uint256[]"}],"name":"setSaleLimitsPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"newSalesPerson","type":"address"}],"name":"setSalesPerson","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleNumber","type":"uint256"},{"internalType":"uint256","name":"_tier","type":"uint256"},{"internalType":"uint256","name":"_startTime","type":"uint256"}],"name":"setTier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_saleNumber","type":"uint256"},{"internalType":"uint256[]","name":"_startTimes","type":"uint256[]"}],"name":"setTiers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"saleNumber","type":"uint256"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"}],"name":"setWhitelistRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"saleNumbers","type":"uint256[]"},{"internalType":"bytes32[]","name":"merkleRoots","type":"bytes32[]"}],"name":"setWhitelistRoots","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stopSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"saleNumber","type":"uint256"},{"internalType":"uint256","name":"tier","type":"uint256"},{"internalType":"bytes32[]","name":"whitelistProof","type":"bytes32[]"}],"name":"verifyWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]