编译器
0.8.28+commit.7893614a
文件 1 的 10:BundleSale.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/interfaces/IERC1155Receiver.sol";
import "@openzeppelin/contracts/interfaces/IERC721Receiver.sol";
import "./Interfaces.sol";
contract BundleSale is
Ownable,
IERC1155Receiver,
IERC721Receiver,
ILazyDelivery,
ILazyDeliveryMetadata
{
address public _marketplace;
mapping(address => bool) public _admins;
error Unauthorized();
enum Spec {
ERC721,
ERC1155
}
struct Bundle {
uint40 listingId;
string previewURI;
uint256[] tokenIds;
address[] contractAddresses;
Spec[] specs;
address seller;
}
mapping(uint256 => Bundle) _bundles;
constructor() Ownable(msg.sender) {}
function supportsInterface(
bytes4 interfaceId
) public view virtual override(IERC165) returns (bool) {
return
interfaceId == type(ILazyDelivery).interfaceId ||
interfaceId == type(ILazyDeliveryMetadata).interfaceId ||
interfaceId == type(IERC165).interfaceId ||
supportsInterface(interfaceId);
}
function configureBundle(
uint256 assetId,
uint40 listingId,
string memory previewURI,
uint256[] memory tokenIds,
address[] memory contractAddresses,
Spec[] memory specs
) public {
IMarketplaceCore mktplace = IMarketplaceCore(_marketplace);
IMarketplaceCore.Listing memory listing = mktplace.getListing(
listingId
);
if (listing.seller != msg.sender && !isOwnerOrAdmin(msg.sender))
revert Unauthorized();
if (_bundles[assetId].seller != address(0)) {
if (
_bundles[assetId].seller != msg.sender &&
!isOwnerOrAdmin(msg.sender)
) revert Unauthorized();
}
_bundles[assetId] = Bundle({
listingId: listingId,
previewURI: previewURI,
tokenIds: tokenIds,
contractAddresses: contractAddresses,
specs: specs,
seller: listing.seller
});
}
function isOwnerOrAdmin(address account) public view returns (bool) {
return account == owner() || _admins[account];
}
function configureMarketplaceAddress(address marketplace) public {
if (!isOwnerOrAdmin(msg.sender)) revert Unauthorized();
_marketplace = marketplace;
}
function configureAdmin(address admin, bool isAdmin) public onlyOwner {
_admins[admin] = isAdmin;
}
function withdraw(
address contractAddress,
uint256 tokenId,
uint256 amount,
Spec spec
) public {
if (!isOwnerOrAdmin(msg.sender)) revert Unauthorized();
if (spec == Spec.ERC721) {
IERC721(contractAddress).safeTransferFrom(
address(this),
msg.sender,
tokenId
);
} else if (spec == Spec.ERC1155) {
IERC1155(contractAddress).safeTransferFrom(
address(this),
msg.sender,
tokenId,
amount,
""
);
}
}
function deliver(
uint40 listingId,
address to,
uint256 assetId,
uint24,
uint256,
address,
uint256
) external {
if (
msg.sender != _marketplace ||
_bundles[assetId].listingId != listingId
) revert Unauthorized();
Bundle memory bundle = _bundles[assetId];
for (uint256 i = 0; i < bundle.tokenIds.length; i++) {
if (bundle.specs[i] == Spec.ERC721) {
IERC721(bundle.contractAddresses[i]).safeTransferFrom(
address(this),
to,
bundle.tokenIds[i]
);
} else if (bundle.specs[i] == Spec.ERC1155) {
IERC1155(bundle.contractAddresses[i]).safeTransferFrom(
address(this),
to,
bundle.tokenIds[i],
1,
""
);
}
}
}
function assetURI(uint256 assetId) external view returns (string memory) {
return _bundles[assetId].previewURI;
}
function onERC721Received(
address,
address,
uint256,
bytes calldata
) external pure override returns (bytes4) {
return IERC721Receiver.onERC721Received.selector;
}
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes calldata
) external pure override returns (bytes4) {
return
bytes4(
keccak256(
"onERC1155Received(address,address,uint256,uint256,bytes)"
)
);
}
function onERC1155BatchReceived(
address,
address,
uint256[] calldata,
uint256[] calldata,
bytes calldata
) external pure override returns (bytes4) {
return
bytes4(
keccak256(
"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"
)
);
}
}
文件 2 的 10:Context.sol
pragma solidity ^0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 3 的 10:ERC165.sol
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 4 的 10:IERC1155.sol
pragma solidity ^0.8.20;
import {IERC165} from "../../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 value, bytes calldata data) external;
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external;
}
文件 5 的 10:IERC1155Receiver.sol
pragma solidity ^0.8.20;
import {IERC1155Receiver} from "../token/ERC1155/IERC1155Receiver.sol";
文件 6 的 10:IERC165.sol
pragma solidity ^0.8.20;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 7 的 10:IERC721.sol
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
文件 8 的 10:IERC721Receiver.sol
pragma solidity ^0.8.20;
import {IERC721Receiver} from "../token/ERC721/IERC721Receiver.sol";
文件 9 的 10:Interfaces.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
interface ILazyDelivery is IERC165 {
function deliver(
uint40 listingId,
address to,
uint256 assetId,
uint24 payableCount,
uint256 payableAmount,
address payableERC20,
uint256 index
) external;
}
interface ILazyDeliveryMetadata is IERC165 {
function assetURI(uint256 assetId) external view returns (string memory);
}
interface IMarketplaceCore {
enum Spec {
NONE,
ERC721,
ERC1155
}
enum ListingType {
INVALID,
INDIVIDUAL_AUCTION,
FIXED_PRICE,
DYNAMIC_PRICE,
RANKED_AUCTION
}
struct ListingReceiver {
address payable receiver;
uint16 receiverBPS;
}
struct DeliveryFees {
uint16 deliverBPS;
uint240 deliverFixed;
}
struct Bid {
uint256 amount;
address payable bidder;
bool delivered;
bool settled;
bool refunded;
uint48 timestamp;
address payable referrer;
}
struct ListingDetails {
uint256 initialAmount;
ListingType type_;
uint24 totalAvailable;
uint24 totalPerSale;
uint16 extensionInterval;
uint16 minIncrementBPS;
address erc20;
address identityVerifier;
uint48 startTime;
uint48 endTime;
}
struct TokenDetails {
uint256 id;
address address_;
Spec spec;
bool lazy;
}
struct Listing {
uint256 id;
address payable seller;
bool finalized;
uint24 totalSold;
uint16 marketplaceBPS;
uint16 referrerBPS;
ListingDetails details;
TokenDetails token;
ListingReceiver[] receivers;
DeliveryFees fees;
Bid bid;
}
function getListing(
uint40 listingId
) external view returns (Listing memory);
}
文件 10 的 10:Ownable.sol
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
error OwnableUnauthorizedAccount(address account);
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
{
"compilationTarget": {
"src/BundleSale.sol": "BundleSale"
},
"evmVersion": "cancun",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
":@uniswap/swap-router/=lib/swap-router-contracts/",
":@uniswap/v3-core/=lib/v3-core/",
":@uniswap/v3-periphery/=lib/v3-periphery/",
":ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/",
":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
":forge-std/=lib/forge-std/src/",
":openzeppelin-contracts/=lib/openzeppelin-contracts/"
]
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_admins","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_marketplace","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assetId","type":"uint256"}],"name":"assetURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"bool","name":"isAdmin","type":"bool"}],"name":"configureAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assetId","type":"uint256"},{"internalType":"uint40","name":"listingId","type":"uint40"},{"internalType":"string","name":"previewURI","type":"string"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"address[]","name":"contractAddresses","type":"address[]"},{"internalType":"enum BundleSale.Spec[]","name":"specs","type":"uint8[]"}],"name":"configureBundle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"marketplace","type":"address"}],"name":"configureMarketplaceAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint40","name":"listingId","type":"uint40"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"assetId","type":"uint256"},{"internalType":"uint24","name":"","type":"uint24"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"deliver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isOwnerOrAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"enum BundleSale.Spec","name":"spec","type":"uint8"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]