编译器
0.8.15+commit.e14f2714
文件 1 的 11: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;
}
}
文件 2 的 11:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 3 的 11:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, 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 from,
address to,
uint256 amount
) external returns (bool);
}
文件 4 的 11:IERC721.sol
pragma solidity ^0.8.0;
import "../../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);
}
文件 5 的 11:IPhunksAuctionHouse.sol
pragma solidity ^0.8.15;
interface IPhunksAuctionHouse {
struct Auction {
uint phunkId;
uint256 amount;
uint256 startTime;
uint256 endTime;
address payable bidder;
bool settled;
uint256 auctionId;
}
event AuctionCreated(uint indexed phunkId, uint256 auctionId, uint256 startTime, uint256 endTime);
event AuctionBid(uint indexed phunkId, uint256 auctionId, address sender, uint256 value, bool extended);
event AuctionExtended(uint indexed phunkId, uint256 auctionId, uint256 endTime);
event AuctionSettled(uint indexed phunkId, uint256 auctionId, address winner, uint256 amount);
event AuctionTimeBufferUpdated(uint256 timeBuffer);
event AuctionDurationUpdated(uint256 duration);
event AuctionReservePriceUpdated(uint256 reservePrice);
event AuctionMinBidIncrementPercentageUpdated(uint256 minBidIncrementPercentage);
function settleAuction() external;
function settleCurrentAndCreateNewAuction() external;
function createBid(uint phunkId) external payable;
function pause() external;
function unpause() external;
function setTimeBuffer(uint256 timeBuffer) external;
function setDuration(uint256 duration) external;
function setReservePrice(uint256 reservePrice) external;
function setMinBidIncrementPercentage(uint8 minBidIncrementPercentage) external;
}
文件 6 的 11:IPhunksToken.sol
pragma solidity ^0.8.15;
import { IERC721 } from '@openzeppelin/contracts/token/ERC721/IERC721.sol';
interface IPhunksToken is IERC721 {
function getPhunksBelongingToOwner(address _owner) external view returns (uint256[] memory);
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);
}
文件 7 的 11:IWETH.sol
pragma solidity ^0.8.15;
interface IWETH {
function deposit() external payable;
function withdraw(uint256 wad) external;
function transfer(address to, uint256 value) external returns (bool);
}
文件 8 的 11: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);
}
}
文件 9 的 11:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
function paused() public view virtual returns (bool) {
return _paused;
}
modifier whenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
modifier whenPaused() {
require(paused(), "Pausable: not paused");
_;
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 10 的 11:PhunksAuctionHouse.sol
pragma solidity ^0.8.15;
import { Pausable } from '@openzeppelin/contracts/security/Pausable.sol';
import { ReentrancyGuard } from '@openzeppelin/contracts/security/ReentrancyGuard.sol';
import { Ownable } from '@openzeppelin/contracts/access/Ownable.sol';
import { IERC20 } from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import { IPhunksAuctionHouse } from './interfaces/IPhunksAuctionHouse.sol';
import { IPhunksToken } from './interfaces/IPhunksToken.sol';
import { IWETH } from './interfaces/IWETH.sol';
contract PhunksAuctionHouse is IPhunksAuctionHouse, Pausable, ReentrancyGuard, Ownable {
IPhunksToken public phunks;
address public weth;
uint256 public timeBuffer;
uint256 public reservePrice;
uint8 public minBidIncrementPercentage;
uint256 public duration;
uint256 public auctionId = 0;
IPhunksAuctionHouse.Auction public auction;
address public treasuryWallet;
function initialize(
IPhunksToken _phunks,
address _weth,
uint256 _timeBuffer,
uint256 _reservePrice,
uint8 _minBidIncrementPercentage,
uint256 _duration,
address _treasuryWallet
) public onlyOwner {
_pause();
phunks = _phunks;
weth = _weth;
timeBuffer = _timeBuffer;
reservePrice = _reservePrice;
minBidIncrementPercentage = _minBidIncrementPercentage;
duration = _duration;
treasuryWallet = _treasuryWallet;
}
function settleCurrentAndCreateNewAuction() external override nonReentrant whenNotPaused {
_settleAuction();
_createAuction();
}
function settleAuction() external override whenPaused nonReentrant {
_settleAuction();
}
function createBid(uint phunkId) external payable override nonReentrant {
IPhunksAuctionHouse.Auction memory _auction = auction;
require(_auction.phunkId == phunkId, 'Phunk not up for auction');
require(block.timestamp < _auction.endTime, 'Auction expired');
require(msg.value >= reservePrice, 'Must send at least reservePrice');
require(
msg.value >= _auction.amount + ((_auction.amount * minBidIncrementPercentage) / 100),
'Must send more than last bid by minBidIncrementPercentage amount'
);
address payable lastBidder = _auction.bidder;
if (lastBidder != address(0)) {
_safeTransferETHWithFallback(lastBidder, _auction.amount);
}
auction.amount = msg.value;
auction.bidder = payable(msg.sender);
bool extended = _auction.endTime - block.timestamp < timeBuffer;
if (extended) {
auction.endTime = _auction.endTime = block.timestamp + timeBuffer;
}
emit AuctionBid(_auction.phunkId, auctionId, msg.sender, msg.value, extended);
if (extended) {
emit AuctionExtended(_auction.phunkId, auctionId, _auction.endTime);
}
}
function pause() external override onlyOwner {
_pause();
}
function unpause() external override onlyOwner {
_unpause();
if (auction.startTime == 0 || auction.settled) {
_createAuction();
}
}
function setTreasuryWallet(address _treasuryWallet) public onlyOwner {
treasuryWallet = _treasuryWallet;
}
function setDuration(uint256 _duration) external override onlyOwner {
duration = _duration;
emit AuctionDurationUpdated(_duration);
}
function setTimeBuffer(uint256 _timeBuffer) external override onlyOwner {
timeBuffer = _timeBuffer;
emit AuctionTimeBufferUpdated(_timeBuffer);
}
function setReservePrice(uint256 _reservePrice) external override onlyOwner {
reservePrice = _reservePrice;
emit AuctionReservePriceUpdated(_reservePrice);
}
function setMinBidIncrementPercentage(uint8 _minBidIncrementPercentage) external override onlyOwner {
minBidIncrementPercentage = _minBidIncrementPercentage;
emit AuctionMinBidIncrementPercentageUpdated(_minBidIncrementPercentage);
}
function _getRand() internal view returns(uint256) {
uint256 randNum = uint256(keccak256(abi.encodePacked(block.timestamp + block.difficulty +
((uint256(keccak256(abi.encodePacked(msg.sender)))) / (block.timestamp)) + block.number)));
return randNum;
}
function _createAuction() internal {
uint treasuryBalance = phunks.balanceOf(treasuryWallet);
require(treasuryBalance > 0, "No Phunks available for auction.");
uint randomIndex = _getRand() % treasuryBalance;
uint phunkId = phunks.tokenOfOwnerByIndex(treasuryWallet, randomIndex);
if (phunkId == 8348) {
require(treasuryBalance > 1, "No Phunks available for auction.");
uint nextIndex = (randomIndex + 1) % treasuryBalance;
phunkId = phunks.tokenOfOwnerByIndex(treasuryWallet, nextIndex);
}
uint256 startTime = block.timestamp;
uint256 endTime = startTime + duration;
auctionId++;
auction = Auction({
phunkId: phunkId,
amount: 0,
startTime: startTime,
endTime: endTime,
bidder: payable(0),
settled: false,
auctionId: auctionId
});
emit AuctionCreated(phunkId, auctionId, startTime, endTime);
}
function createSpecialAuction(uint _phunkId, uint256 _endTime) public onlyOwner {
require(phunks.balanceOf(treasuryWallet) > 0, "No Phunks available for auction.");
require(phunks.ownerOf(_phunkId) == treasuryWallet, "Phunk does not exist in treasury wallet");
uint phunkId = _phunkId;
uint256 startTime = block.timestamp;
uint256 endTime = _endTime;
auctionId++;
auction = Auction({
phunkId: phunkId,
amount: 0,
startTime: startTime,
endTime: endTime,
bidder: payable(0),
settled: false,
auctionId: auctionId
});
emit AuctionCreated(phunkId, auctionId, startTime, endTime);
}
function _settleAuction() internal {
IPhunksAuctionHouse.Auction memory _auction = auction;
require(_auction.startTime != 0, "Auction hasn't begun");
require(!_auction.settled, 'Auction has already been settled');
require(block.timestamp >= _auction.endTime, "Auction hasn't completed");
auction.settled = true;
if (_auction.bidder != address(0)) {
phunks.transferFrom(address(treasuryWallet), _auction.bidder, _auction.phunkId);
}
if (_auction.amount > 0) {
_safeTransferETHWithFallback(treasuryWallet, _auction.amount);
}
emit AuctionSettled(_auction.phunkId, auctionId, _auction.bidder, _auction.amount);
}
function _safeTransferETHWithFallback(address to, uint256 amount) internal {
if (!_safeTransferETH(to, amount)) {
IWETH(weth).deposit{ value: amount }();
IERC20(weth).transfer(to, amount);
}
}
function _safeTransferETH(address to, uint256 value) internal returns (bool) {
(bool success, ) = to.call{ value: value, gas: 30_000 }(new bytes(0));
return success;
}
}
文件 11 的 11:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
{
"compilationTarget": {
"contracts/PhunksAuctionHouse.sol": "PhunksAuctionHouse"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"phunkId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"auctionId","type":"uint256"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bool","name":"extended","type":"bool"}],"name":"AuctionBid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"phunkId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"auctionId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTime","type":"uint256"}],"name":"AuctionCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"AuctionDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"phunkId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"auctionId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTime","type":"uint256"}],"name":"AuctionExtended","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minBidIncrementPercentage","type":"uint256"}],"name":"AuctionMinBidIncrementPercentageUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reservePrice","type":"uint256"}],"name":"AuctionReservePriceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"phunkId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"auctionId","type":"uint256"},{"indexed":false,"internalType":"address","name":"winner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AuctionSettled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timeBuffer","type":"uint256"}],"name":"AuctionTimeBufferUpdated","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"auction","outputs":[{"internalType":"uint256","name":"phunkId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"address payable","name":"bidder","type":"address"},{"internalType":"bool","name":"settled","type":"bool"},{"internalType":"uint256","name":"auctionId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"auctionId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"phunkId","type":"uint256"}],"name":"createBid","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_phunkId","type":"uint256"},{"internalType":"uint256","name":"_endTime","type":"uint256"}],"name":"createSpecialAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"duration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IPhunksToken","name":"_phunks","type":"address"},{"internalType":"address","name":"_weth","type":"address"},{"internalType":"uint256","name":"_timeBuffer","type":"uint256"},{"internalType":"uint256","name":"_reservePrice","type":"uint256"},{"internalType":"uint8","name":"_minBidIncrementPercentage","type":"uint8"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"address","name":"_treasuryWallet","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"minBidIncrementPercentage","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"phunks","outputs":[{"internalType":"contract IPhunksToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reservePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"setDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_minBidIncrementPercentage","type":"uint8"}],"name":"setMinBidIncrementPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_reservePrice","type":"uint256"}],"name":"setReservePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timeBuffer","type":"uint256"}],"name":"setTimeBuffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasuryWallet","type":"address"}],"name":"setTreasuryWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"settleAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"settleCurrentAndCreateNewAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"timeBuffer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasuryWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]