// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol";
import "https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol";
import "https://github.com/Vectorized/solady/blob/main/src/utils/MerkleProofLib.sol";
contract ArtMarketplaceV7 is Ownable {
uint256 private constant BPS = 10_000;
uint256 private constant BID_INCREASE_THRESHOLD_ETH = 0.2 ether;
uint256 private constant BID_INCREASE_THRESHOLD_USDC = 300 * USDC_CONSTANT;
uint8 private constant DEFAULT_PLATFORM_FEE = 30; // whole % points
uint256 private constant EXTENSION_TIME = 5 minutes;
uint256 private constant INIT_AUCTION_DURATION = 24 hours;
uint256 private constant MIN_BID_ETH = 0.1 ether;
uint256 private constant MIN_BID_USDC = 30 * USDC_CONSTANT;
uint256 private constant MIN_BID_INCREASE_PRE = 2_000;
uint256 private constant MIN_BID_INCREASE_POST = 1_000;
uint256 private constant SAFE_GAS_LIMIT = 30_000;
// Mainnet USDC: 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
// Sepolia USDC: 0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238
address private immutable USDC;
uint256 private constant USDC_CONSTANT = 10**6; // USDC uses 6 decimals instead of eth's 18
IDelegationRegistry private constant DELEGATE_REGISTRY = IDelegationRegistry(
address(0x00000000000000447e69651d841bD8D104Bed493)
);
address public accessRole;
address public beneficiary;
bool public paused;
struct Auction {
uint24 offsetFromEnd;
uint72 amount;
address bidder;
}
struct AuctionStatus {
uint256 endTime;
uint256 currentBid;
address highestBidder;
uint256 buyNowPrice;
uint256 reservePrice;
}
struct AuctionConfig {
address artist;
uint8 platformFee; // in whole % points (30 = 30%)
uint8 royalty; // in whole % points, should be 0 for primary sales
uint80 buyNowStartTime;
uint80 auctionStartTime;
uint88 buyNowPrice;
uint88 reservePrice;
uint88 preBidPrice;
address seller; // when seller is schedueled as 0x0, seller defaults to the artist (i.e. primary sale)
bool usdcFlag; // true for usdc, false for eth
bytes32 accessListRoot;
}
struct AccessListConfig {
uint80 accessListDuration;
uint8 buyNowLimit;
}
mapping(bytes32 => AuctionConfig) public auctionConfig;
mapping(uint256 => Auction) public auctionIdToAuction;
mapping(uint256 => bytes32) public auctionIdToConfigHash;
mapping(bytes32 => mapping(address => uint256)) public buyNowCount;
mapping(bytes32 => AccessListConfig) public accessListConfig;
mapping(bytes32 => mapping(address => bool)) public accessListConf;
event BidMade(
uint256 indexed auctionId,
address indexed collectionAddress,
uint256 indexed tokenId,
address bidder,
uint256 amount,
uint256 timestamp
);
struct Receipt {
address orderMaker;
address orderTaker;
address collection;
uint256 tokenId;
address currency; // 0x0 when ETH sale
address artist;
address platform;
uint256 salePrice; // in wei (salePrice = funds to seller + platformFee + royalty = price buyer paid)
uint256 platformFee; // in wei
uint256 royalty; // in wei
}
event Sale(Receipt[] receipts);
constructor(address contractOwner, address _usdcAddress, address _accessRole) Ownable(contractOwner) {
setBeneficiary(contractOwner);
USDC = _usdcAddress;
accessRole = _accessRole;
}
function bid(
uint256[] calldata auctionIds,
uint256[] calldata expectedPrices
) public payable {
_bid(auctionIds, expectedPrices, msg.sender);
}
function buyNow(
uint256[] calldata auctionIds
) public payable {
_buyNow(auctionIds, msg.sender);
}
function bid(
uint256[] calldata auctionIds,
uint256[] calldata expectedPrices,
address delegator
) public payable {
_bid(auctionIds, expectedPrices, delegator);
}
function buyNow(
uint256[] calldata auctionIds,
address delegator
) public payable {
_buyNow(auctionIds, delegator);
}
function grantAccessAndBid(
bytes32[] calldata proof,
bytes32 accessListRoot,
uint256[] calldata auctionIds,
uint256[] calldata expectedPrices
) external payable {
grantAccess(proof, accessListRoot, msg.sender);
bid(auctionIds, expectedPrices);
}
function grantAccessAndBuyNow(
bytes32[] calldata proof,
bytes32 accessListRoot,
uint256[] calldata auctionIds
) external payable {
grantAccess(proof, accessListRoot, msg.sender);
buyNow(auctionIds);
}
function grantAccessAndBid(
bytes32[] calldata proof,
bytes32 accessListRoot,
uint256[] calldata auctionIds,
uint256[] calldata expectedPrices,
address delegator
) external payable {
grantAccess(proof, accessListRoot, msg.sender);
bid(auctionIds, expectedPrices, delegator);
}
function grantAccessAndBuyNow(
bytes32[] calldata proof,
bytes32 accessListRoot,
uint256[] calldata auctionIds,
address delegator
) external payable {
grantAccess(proof, accessListRoot, msg.sender);
buyNow(auctionIds, delegator);
}
struct BidVars {
uint256 totalETH;
uint256 totalUSDC;
}
function _bid(
uint256[] calldata auctionIds,
uint256[] calldata expectedPrices,
address authedBuyer
) internal {
require(!paused, "Bidding is paused");
require(auctionIds.length == expectedPrices.length);
if (authedBuyer != msg.sender) {
require(
DELEGATE_REGISTRY.checkDelegateForContract(
msg.sender,
authedBuyer,
address(this),
""
));
}
BidVars memory vars = BidVars(0,0);
for (uint256 i; i < auctionIds.length; ++i) {
uint256 auctionId = auctionIds[i];
uint256 expectedPrice = expectedPrices[i];
AuctionConfig memory config = getConfig(auctionId);
AccessListConfig memory accessConfig = accessListConfig[config.accessListRoot];
// kickstart auction functionality
bytes32 oldConfigHash;
if (config.auctionStartTime == type(uint80).max) {
oldConfigHash = auctionIdToConfigHash[auctionId];
config.auctionStartTime = uint80(block.timestamp);
bytes32 configHash = keccak256(abi.encode(config));
if (auctionConfig[configHash].auctionStartTime == 0) {
auctionConfig[configHash] = config;
}
auctionIdToConfigHash[auctionId] = configHash;
}
if (
!(isAuctionActive(auctionId) ||
(config.preBidPrice > 0 && expectedPrice >= config.preBidPrice && !isAuctionOver(auctionId))
) ||
(config.accessListRoot != bytes32(0x0)
&& accessListConf[config.accessListRoot][authedBuyer] == false
&& block.timestamp < config.auctionStartTime + accessConfig.accessListDuration
)
) {
if (oldConfigHash != bytes32(0x0)) {
auctionIdToConfigHash[auctionId] = oldConfigHash;
}
continue;
}
Auction memory highestBid = auctionIdToAuction[auctionId];
uint256 bidIncrease = highestBid.amount >=
getBidIncreaseThreshold(config.usdcFlag)
? MIN_BID_INCREASE_POST
: MIN_BID_INCREASE_PRE;
if (
expectedPrice >=
((highestBid.amount * (BPS + bidIncrease)) / BPS) &&
expectedPrice >= getReservePrice(auctionId)
) {
uint256 refundAmount;
address refundBidder;
uint256 offset = highestBid.offsetFromEnd;
uint256 endTime = getAuctionEndTime(auctionId);
if (highestBid.amount > 0) {
refundAmount = highestBid.amount;
refundBidder = highestBid.bidder;
}
if (endTime - block.timestamp < EXTENSION_TIME) {
offset += block.timestamp + EXTENSION_TIME - endTime;
}
auctionIdToAuction[auctionId] = Auction(
uint24(offset),
uint72(expectedPrice),
msg.sender
);
if (config.usdcFlag) {
vars.totalUSDC += expectedPrice;
} else {
vars.totalETH += expectedPrice;
}
emit BidMade(
auctionId,
getCollectionFromId(auctionId),
getArtTokenIdFromId(auctionId),
msg.sender,
expectedPrice,
block.timestamp
);
if (refundAmount > 0) {
if (config.usdcFlag) {
ERC20(USDC).transfer(refundBidder, refundAmount);
} else {
SafeTransferLib.forceSafeTransferETH(
refundBidder,
refundAmount,
SAFE_GAS_LIMIT
);
}
}
} else {
if (oldConfigHash != bytes32(0x0)) {
auctionIdToConfigHash[auctionId] = oldConfigHash;
}
}
}
if (vars.totalUSDC > 0) {
ERC20(USDC).transferFrom(msg.sender, address(this), vars.totalUSDC);
}
require(msg.value >= vars.totalETH, "Incorrect amount of ETH sent");
uint256 totalFailedETH = msg.value - vars.totalETH;
if (totalFailedETH > 0) {
SafeTransferLib.forceSafeTransferETH(
msg.sender,
totalFailedETH,
SAFE_GAS_LIMIT
);
}
}
struct BuyNowVars {
uint256 totalETH;
uint256 amountForBeneETH;
uint256 amountForBeneUSDC;
}
function _buyNow(
uint256[] calldata auctionIds,
address authedBuyer
) internal {
require(!paused, "Buying is paused");
if (authedBuyer != msg.sender) {
require(
DELEGATE_REGISTRY.checkDelegateForContract(
msg.sender,
authedBuyer,
address(this),
""
));
}
BuyNowVars memory vars = BuyNowVars(0,0,0);
// Create a dynamic array to store tokenIds of successfully purchased tokens
Receipt[] memory successfulAuctions = new Receipt[](auctionIds.length);
uint256 successfulCount = 0;
for (uint256 i = 0; i < auctionIds.length; ++i) {
uint256 auctionId = auctionIds[i];
AuctionConfig memory config = getConfig(auctionId);
uint256 amountToPay = config.buyNowPrice;
AccessListConfig memory accessConfig = accessListConfig[config.accessListRoot];
if (
(block.timestamp < config.buyNowStartTime) ||
auctionIdToAuction[auctionId].amount > 0 ||
amountToPay == 0 ||
(accessConfig.buyNowLimit != 0 && buyNowCount[config.accessListRoot][authedBuyer] >= accessConfig.buyNowLimit) ||
(config.accessListRoot != bytes32(0x0)
&& accessListConf[config.accessListRoot][authedBuyer] == false
&& block.timestamp < config.buyNowStartTime + accessConfig.accessListDuration
)
) {
continue;
}
buyNowCount[config.accessListRoot][authedBuyer] += 1;
// Mark the auction as settled and store the amount paid
config.auctionStartTime = uint80(block.timestamp - INIT_AUCTION_DURATION);
bytes32 configHash = keccak256(abi.encode(config));
if (auctionConfig[configHash].auctionStartTime == 0) {
auctionConfig[configHash] = config;
}
auctionIdToConfigHash[auctionId] = configHash;
auctionIdToAuction[auctionId] = Auction(
0,
uint72(amountToPay),
msg.sender
);
if (!config.usdcFlag) {
vars.totalETH += amountToPay;
}
// Mint the token to the buyer
_mintOrTransfer(msg.sender, auctionId);
uint256 amountForPlatform = (amountToPay * config.platformFee) / 100;
uint256 royalty = (amountToPay * config.royalty) / 100;
uint256 amountForSeller = amountToPay - amountForPlatform - royalty;
successfulAuctions[successfulCount] = Receipt(
config.seller,
msg.sender,
getCollectionFromId(auctionId),
getArtTokenIdFromId(auctionId),
config.usdcFlag ? USDC : address(0),
config.artist,
beneficiary,
amountToPay,
amountForPlatform,
royalty
);
successfulCount++;
if (config.usdcFlag) {
vars.amountForBeneUSDC += amountForPlatform;
ERC20(USDC).transferFrom(msg.sender, config.seller, amountForSeller);
if (royalty > 0) {
ERC20(USDC).transferFrom(msg.sender, config.artist, royalty);
}
} else {
vars.amountForBeneETH += amountForPlatform;
SafeTransferLib.forceSafeTransferETH(
config.seller,
amountForSeller,
SAFE_GAS_LIMIT
);
if (royalty > 0) {
SafeTransferLib.forceSafeTransferETH(
config.artist,
royalty,
SAFE_GAS_LIMIT
);
}
}
}
if (vars.amountForBeneUSDC > 0) {
ERC20(USDC).transferFrom(msg.sender, beneficiary, vars.amountForBeneUSDC);
}
require(msg.value >= vars.totalETH, "Incorrect amount of ETH sent");
uint256 totalFailedETH = msg.value - vars.totalETH;
if (totalFailedETH > 0) {
SafeTransferLib.forceSafeTransferETH(
msg.sender,
totalFailedETH,
SAFE_GAS_LIMIT
);
}
if (vars.amountForBeneETH > 0) {
SafeTransferLib.forceSafeTransferETH(
beneficiary,
vars.amountForBeneETH,
SAFE_GAS_LIMIT
);
}
// Emit Sale event for all successful token purchases
if (successfulCount > 0) {
// Create a resized array with only the successfully bought tokenIds
Receipt[] memory sales = new Receipt[](successfulCount);
for (uint256 i = 0; i < successfulCount; ++i) {
sales[i] = successfulAuctions[i];
}
emit Sale(sales);
}
}
function grantAccess(
bytes32[] calldata proof,
bytes32 accessListRoot,
address account
) public {
if (MerkleProofLib.verifyCalldata(proof, accessListRoot, keccak256(abi.encodePacked(account))) == true) {
accessListConf[accessListRoot][account] = true;
}
}
function settleAuctions(uint256[] calldata auctionIds) external {
uint256 amountForBeneETH;
uint256 amountForBeneUSDC;
Receipt[] memory successfulAuctions = new Receipt[](auctionIds.length);
uint256 successfulCount = 0;
for (uint256 i; i < auctionIds.length; ++i) {
uint256 auctionId = auctionIds[i];
Auction memory highestBid = auctionIdToAuction[auctionId];
require(isAuctionOver(auctionId), "Auction is still active");
uint256 amountToPay = highestBid.amount;
require(amountToPay > 0);
_mintOrTransfer(highestBid.bidder, auctionId);
AuctionConfig memory config = getConfig(auctionId);
uint256 amountForPlatform = (amountToPay * config.platformFee) / 100;
uint256 royalty = (amountToPay * config.royalty) / 100;
uint256 amountForSeller = amountToPay - amountForPlatform - royalty;
successfulAuctions[successfulCount] = Receipt(
config.seller,
highestBid.bidder,
getCollectionFromId(auctionId),
getArtTokenIdFromId(auctionId),
config.usdcFlag ? USDC : address(0),
config.artist,
beneficiary,
amountToPay,
amountForPlatform,
royalty
);
if (config.usdcFlag) {
amountForBeneUSDC += amountForPlatform;
ERC20(USDC).transfer(config.seller, amountForSeller);
if (royalty > 0) {
ERC20(USDC).transfer(config.artist, royalty);
}
} else {
amountForBeneETH += amountForPlatform;
SafeTransferLib.forceSafeTransferETH(
config.seller,
amountForSeller,
SAFE_GAS_LIMIT
);
if (royalty > 0) {
SafeTransferLib.forceSafeTransferETH(
config.artist,
royalty,
SAFE_GAS_LIMIT
);
}
}
}
emit Sale(successfulAuctions);
if (amountForBeneUSDC > 0) {
ERC20(USDC).transfer(beneficiary, amountForBeneUSDC);
}
if (amountForBeneETH > 0) {
SafeTransferLib.forceSafeTransferETH(
beneficiary,
amountForBeneETH,
SAFE_GAS_LIMIT
);
}
}
// INTERNAL
function _mintOrTransfer(address to, uint256 auctionId) internal {
address collection = getCollectionFromId(auctionId);
uint256 tokenId = getArtTokenIdFromId(auctionId);
try INFT(collection).ownerOf(tokenId) returns (address _owner) {
if (_owner == address(0)) {
INFT(collection).mint(to, tokenId);
} else {
INFT(collection).transferFrom(_owner, to, tokenId);
}
} catch {
INFT(collection).mint(to, tokenId);
}
}
function _resetAuction(address collectionAddress, uint256 tokenId)
internal
{
uint256 auctionId = artTokentoAuctionId(collectionAddress, tokenId);
if (!isAuctionOver(auctionId)) {
Auction memory auctionData = auctionIdToAuction[auctionId];
if (auctionData.amount > 0) {
SafeTransferLib.forceSafeTransferETH(
auctionData.bidder,
auctionData.amount,
SAFE_GAS_LIMIT
);
}
}
auctionIdToConfigHash[auctionId] = bytes32(0);
auctionIdToAuction[auctionId] = Auction(0, 0, address(0));
}
function _schedule(
address collectionAddress,
uint256 tokenId,
uint256 buyNowStartTime,
uint256 auctionStartTime,
address artist,
address seller,
uint256 platformFee,
uint256 royalty,
uint256 buyNowPrice,
uint256 reserve,
uint256 preBidPrice,
bool usdcFlag,
bytes32 accessListRoot
) internal {
uint256 auctionId = artTokentoAuctionId(collectionAddress, tokenId);
require(auctionIdToConfigHash[auctionId] == bytes32(0));
uint256 adjAucStartTime = auctionStartTime;
if (adjAucStartTime == 0) {
adjAucStartTime = type(uint80).max;
}
AuctionConfig memory config = AuctionConfig(
artist,
platformFee == 0 ? DEFAULT_PLATFORM_FEE : uint8(platformFee),
uint8(royalty),
uint80(buyNowStartTime),
uint80(adjAucStartTime),
uint88(buyNowPrice),
uint88(reserve),
uint88(preBidPrice),
seller == address(0) ? artist : seller,
usdcFlag,
accessListRoot
);
bytes32 configHash = keccak256(abi.encode(config));
if (auctionConfig[configHash].auctionStartTime == 0) {
auctionConfig[configHash] = config;
}
auctionIdToConfigHash[auctionId] = configHash;
}
// ONLY ACCESS or OWNER ROLE
function grantAccess(bytes32 accessListRoot, address[] calldata accounts) external {
require(msg.sender == owner() || msg.sender == accessRole);
for (uint256 i = 0; i < accounts.length; ++i) {
accessListConf[accessListRoot][accounts[i]] = true;
}
}
function revokeAccess(bytes32 accessListRoot, address[] calldata accounts) external {
require(msg.sender == owner() || msg.sender == accessRole);
for (uint256 i = 0; i < accounts.length; ++i) {
accessListConf[accessListRoot][accounts[i]] = false;
}
}
// ONLY OWNER
function configureAccessList(
bytes32 accessListRoot,
uint256 accessListDuration,
uint256 buyNowLimit
) external onlyOwner {
require(accessListRoot != bytes32(0x0));
accessListConfig[accessListRoot] = AccessListConfig(
uint80(accessListDuration),
uint8(buyNowLimit)
);
}
function scheduleAuctionsLight(
address collection,
uint256[] calldata tokenIds,
uint256 buyNowStartTime,
uint256 auctionStartTime,
address artist,
address seller,
uint256 platformFee,
uint256 royalty,
uint256 buyNowPrice,
uint256 reservePrice,
uint256 preBidPrice,
bool usdcFlag,
bytes32 accessListRoot,
uint256 accessListDuration,
uint256 buyNowLimit
) external onlyOwner {
if(accessListRoot != bytes32(0x0)) {
accessListConfig[accessListRoot] = AccessListConfig(
uint80(accessListDuration),
uint8(buyNowLimit)
);
}
for (uint256 i; i < tokenIds.length; ++i) {
_schedule(
collection,
tokenIds[i],
buyNowStartTime,
auctionStartTime,
artist,
seller,
platformFee,
royalty,
buyNowPrice,
reservePrice,
preBidPrice,
usdcFlag,
accessListRoot
);
}
}
function resetAuctions(
address[] calldata collections,
uint256[] calldata tokenIds
) external onlyOwner {
for (uint256 i; i < collections.length; ++i) {
_resetAuction(collections[i], tokenIds[i]);
}
}
function setAccessRole (address newAccessManager) external onlyOwner {
accessRole = newAccessManager;
}
function setBeneficiary(address _beneficiary) public onlyOwner {
beneficiary = _beneficiary;
}
function setPaused(bool _paused) external onlyOwner {
paused = _paused;
}
// GETTERS
function artTokentoAuctionId(address collection, uint256 tokenId)
public
pure
returns (uint256)
{
return (uint256(uint160(collection)) << 96) | uint96(tokenId);
}
function isAuctionActive(uint256 auctionId) public view returns (bool) {
uint256 startTime = getConfig(auctionId).auctionStartTime;
uint256 endTime = getAuctionEndTime(auctionId);
return (startTime > 0 &&
block.timestamp >= startTime &&
block.timestamp < endTime);
}
function isAuctionOver(uint256 auctionId) public view returns (bool) {
uint256 startTime = getConfig(auctionId).auctionStartTime;
uint256 endTime = getAuctionEndTime(auctionId);
return (startTime > 0 && block.timestamp >= endTime);
}
function getAuctionEndTime(uint256 auctionId)
public
view
returns (uint256)
{
return
getConfig(auctionId).auctionStartTime +
INIT_AUCTION_DURATION +
auctionIdToAuction[auctionId].offsetFromEnd;
}
function getAuctionStartTime(uint256 auctionId)
public
view
returns (uint256)
{
return getConfig(auctionId).auctionStartTime;
}
function getCollectionFromId(uint256 id) public pure returns (address) {
return address(uint160(id >> 96));
}
function getConfig(uint256 id) public view returns (AuctionConfig memory) {
return auctionConfig[auctionIdToConfigHash[id]];
}
function getArtTokenIdFromId(uint256 id) public pure returns (uint256) {
return uint256(uint96(id));
}
function getReservePrice(uint256 auctionId) public view returns (uint256) {
AuctionConfig memory config = getConfig(auctionId);
uint256 reserve = config.reservePrice;
return reserve != 0 ? reserve : getMinBid(config.usdcFlag);
}
function getBidIncreaseThreshold(bool isUSDC)
internal
pure
returns (uint256)
{
return
isUSDC ? BID_INCREASE_THRESHOLD_USDC : BID_INCREASE_THRESHOLD_ETH;
}
function getMinBid(bool isUSDC) internal pure returns (uint256) {
return isUSDC ? MIN_BID_USDC : MIN_BID_ETH;
}
function getAuctionStatusBulk(uint256[] calldata auctionIds) external view returns (AuctionStatus[] memory) {
AuctionStatus[] memory statuses = new AuctionStatus[](auctionIds.length);
for(uint256 i; i < auctionIds.length; i++){
uint256 auctionId = auctionIds[i];
Auction memory auc = auctionIdToAuction[auctionId];
AuctionConfig memory aucConfig = getConfig(auctionId);
statuses[i] = AuctionStatus(
getAuctionEndTime(auctionId),
auc.amount,
auc.bidder,
aucConfig.buyNowPrice,
getReservePrice(auctionId)
);
}
return statuses;
}
}
interface IDelegationRegistry {
function checkDelegateForContract(address to, address from, address contract_, bytes32 rights) external view returns (bool);
}
interface ERC20 {
function transfer(address recipient, uint amount) external returns (bool);
function transferFrom(address sender, address recipient, uint amount) external returns (bool);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
}
interface INFT {
function mint(address to, uint256 tokenId) external;
function ownerOf(uint256 tokenId) external view returns (address);
function transferFrom(address from, address to, uint256 tokenId) external;
}
{
"compilationTarget": {
"2025/marketplace/ArtMarketplaceV7.sol": "ArtMarketplaceV7"
},
"evmVersion": "cancun",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [],
"viaIR": true
}
[{"inputs":[{"internalType":"address","name":"contractOwner","type":"address"},{"internalType":"address","name":"_usdcAddress","type":"address"},{"internalType":"address","name":"_accessRole","type":"address"}],"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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"auctionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"collectionAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"address","name":"bidder","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"BidMade","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":[{"components":[{"internalType":"address","name":"orderMaker","type":"address"},{"internalType":"address","name":"orderTaker","type":"address"},{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"currency","type":"address"},{"internalType":"address","name":"artist","type":"address"},{"internalType":"address","name":"platform","type":"address"},{"internalType":"uint256","name":"salePrice","type":"uint256"},{"internalType":"uint256","name":"platformFee","type":"uint256"},{"internalType":"uint256","name":"royalty","type":"uint256"}],"indexed":false,"internalType":"struct ArtMarketplaceV7.Receipt[]","name":"receipts","type":"tuple[]"}],"name":"Sale","type":"event"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"}],"name":"accessListConf","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"accessListConfig","outputs":[{"internalType":"uint80","name":"accessListDuration","type":"uint80"},{"internalType":"uint8","name":"buyNowLimit","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accessRole","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"artTokentoAuctionId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"auctionConfig","outputs":[{"internalType":"address","name":"artist","type":"address"},{"internalType":"uint8","name":"platformFee","type":"uint8"},{"internalType":"uint8","name":"royalty","type":"uint8"},{"internalType":"uint80","name":"buyNowStartTime","type":"uint80"},{"internalType":"uint80","name":"auctionStartTime","type":"uint80"},{"internalType":"uint88","name":"buyNowPrice","type":"uint88"},{"internalType":"uint88","name":"reservePrice","type":"uint88"},{"internalType":"uint88","name":"preBidPrice","type":"uint88"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"bool","name":"usdcFlag","type":"bool"},{"internalType":"bytes32","name":"accessListRoot","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"auctionIdToAuction","outputs":[{"internalType":"uint24","name":"offsetFromEnd","type":"uint24"},{"internalType":"uint72","name":"amount","type":"uint72"},{"internalType":"address","name":"bidder","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"auctionIdToConfigHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"beneficiary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"auctionIds","type":"uint256[]"},{"internalType":"uint256[]","name":"expectedPrices","type":"uint256[]"},{"internalType":"address","name":"delegator","type":"address"}],"name":"bid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"auctionIds","type":"uint256[]"},{"internalType":"uint256[]","name":"expectedPrices","type":"uint256[]"}],"name":"bid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"auctionIds","type":"uint256[]"},{"internalType":"address","name":"delegator","type":"address"}],"name":"buyNow","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"auctionIds","type":"uint256[]"}],"name":"buyNow","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"address","name":"","type":"address"}],"name":"buyNowCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"accessListRoot","type":"bytes32"},{"internalType":"uint256","name":"accessListDuration","type":"uint256"},{"internalType":"uint256","name":"buyNowLimit","type":"uint256"}],"name":"configureAccessList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getArtTokenIdFromId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"auctionId","type":"uint256"}],"name":"getAuctionEndTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"auctionId","type":"uint256"}],"name":"getAuctionStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"auctionIds","type":"uint256[]"}],"name":"getAuctionStatusBulk","outputs":[{"components":[{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint256","name":"currentBid","type":"uint256"},{"internalType":"address","name":"highestBidder","type":"address"},{"internalType":"uint256","name":"buyNowPrice","type":"uint256"},{"internalType":"uint256","name":"reservePrice","type":"uint256"}],"internalType":"struct ArtMarketplaceV7.AuctionStatus[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getCollectionFromId","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getConfig","outputs":[{"components":[{"internalType":"address","name":"artist","type":"address"},{"internalType":"uint8","name":"platformFee","type":"uint8"},{"internalType":"uint8","name":"royalty","type":"uint8"},{"internalType":"uint80","name":"buyNowStartTime","type":"uint80"},{"internalType":"uint80","name":"auctionStartTime","type":"uint80"},{"internalType":"uint88","name":"buyNowPrice","type":"uint88"},{"internalType":"uint88","name":"reservePrice","type":"uint88"},{"internalType":"uint88","name":"preBidPrice","type":"uint88"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"bool","name":"usdcFlag","type":"bool"},{"internalType":"bytes32","name":"accessListRoot","type":"bytes32"}],"internalType":"struct ArtMarketplaceV7.AuctionConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"auctionId","type":"uint256"}],"name":"getReservePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"accessListRoot","type":"bytes32"},{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"grantAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bytes32","name":"accessListRoot","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bytes32","name":"accessListRoot","type":"bytes32"},{"internalType":"uint256[]","name":"auctionIds","type":"uint256[]"},{"internalType":"uint256[]","name":"expectedPrices","type":"uint256[]"},{"internalType":"address","name":"delegator","type":"address"}],"name":"grantAccessAndBid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bytes32","name":"accessListRoot","type":"bytes32"},{"internalType":"uint256[]","name":"auctionIds","type":"uint256[]"},{"internalType":"uint256[]","name":"expectedPrices","type":"uint256[]"}],"name":"grantAccessAndBid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bytes32","name":"accessListRoot","type":"bytes32"},{"internalType":"uint256[]","name":"auctionIds","type":"uint256[]"}],"name":"grantAccessAndBuyNow","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"bytes32","name":"accessListRoot","type":"bytes32"},{"internalType":"uint256[]","name":"auctionIds","type":"uint256[]"},{"internalType":"address","name":"delegator","type":"address"}],"name":"grantAccessAndBuyNow","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"auctionId","type":"uint256"}],"name":"isAuctionActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"auctionId","type":"uint256"}],"name":"isAuctionOver","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"collections","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"resetAuctions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"accessListRoot","type":"bytes32"},{"internalType":"address[]","name":"accounts","type":"address[]"}],"name":"revokeAccess","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256","name":"buyNowStartTime","type":"uint256"},{"internalType":"uint256","name":"auctionStartTime","type":"uint256"},{"internalType":"address","name":"artist","type":"address"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"platformFee","type":"uint256"},{"internalType":"uint256","name":"royalty","type":"uint256"},{"internalType":"uint256","name":"buyNowPrice","type":"uint256"},{"internalType":"uint256","name":"reservePrice","type":"uint256"},{"internalType":"uint256","name":"preBidPrice","type":"uint256"},{"internalType":"bool","name":"usdcFlag","type":"bool"},{"internalType":"bytes32","name":"accessListRoot","type":"bytes32"},{"internalType":"uint256","name":"accessListDuration","type":"uint256"},{"internalType":"uint256","name":"buyNowLimit","type":"uint256"}],"name":"scheduleAuctionsLight","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAccessManager","type":"address"}],"name":"setAccessRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_beneficiary","type":"address"}],"name":"setBeneficiary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"auctionIds","type":"uint256[]"}],"name":"settleAuctions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]