文件 1 的 2:INounsAuctionHouse.sol
pragma solidity ^0.8.6;
interface INounsAuctionHouse {
struct Auction {
uint256 nounId;
uint256 amount;
uint256 startTime;
uint256 endTime;
address payable bidder;
bool settled;
}
event AuctionCreated(uint256 indexed nounId, uint256 startTime, uint256 endTime);
event AuctionBid(uint256 indexed nounId, address sender, uint256 value, bool extended);
event AuctionExtended(uint256 indexed nounId, uint256 endTime);
event AuctionSettled(uint256 indexed nounId, address winner, uint256 amount);
event AuctionTimeBufferUpdated(uint256 timeBuffer);
event AuctionReservePriceUpdated(uint256 reservePrice);
event AuctionMinBidIncrementPercentageUpdated(uint256 minBidIncrementPercentage);
function settleAuction() external;
function settleCurrentAndCreateNewAuction() external;
function createBid(uint256 nounId) external payable;
function pause() external;
function unpause() external;
function setTimeBuffer(uint256 timeBuffer) external;
function setReservePrice(uint256 reservePrice) external;
function setMinBidIncrementPercentage(uint8 minBidIncrementPercentage) external;
}
文件 2 的 2:NounSettlement.sol
pragma solidity 0.8.9;
import { INounsAuctionHouse } from './interfaces/INounsAuctionHouse.sol';
contract NounSettlement {
address payable public fomoExecutor;
address payable public immutable nounsDaoTreasury;
address public immutable fomoMultisig;
INounsAuctionHouse public immutable auctionHouse;
uint256 public maxPriorityFee = 40 * 10**9;
uint256 private immutable OVERHEAD_GAS = 21000;
constructor(address _fomoExecutor, address _nounsDaoTreasury, address _nounsAuctionHouseAddress, address _fomoMultisig) {
fomoExecutor = payable(_fomoExecutor);
nounsDaoTreasury = payable(_nounsDaoTreasury);
fomoMultisig = _fomoMultisig;
auctionHouse = INounsAuctionHouse(_nounsAuctionHouseAddress);
}
event FundsPulled(address _to, uint256 _amount);
event ExecutorChanged(address _newExecutor);
event MaxPriorityFeeChanged(uint256 _newMaxPriorityFee);
modifier onlyMultisig() {
require(msg.sender == fomoMultisig, "Only callable by FOMO Multsig");
_;
}
modifier onlyFOMO() {
require(msg.sender == fomoExecutor, "Only callable by FOMO Nouns executor");
_;
}
modifier refundGas() {
uint256 startGas = gasleft();
require(tx.gasprice <= block.basefee + maxPriorityFee, "Gas price above current reasonable limit");
_;
uint256 endGas = gasleft();
uint256 totalGasCost = tx.gasprice * (startGas - endGas + OVERHEAD_GAS);
fomoExecutor.transfer(totalGasCost);
}
function donateFunds() external payable { }
receive() external payable { }
fallback() external payable { }
function pullFunds() external onlyMultisig {
uint256 balance = address(this).balance;
(bool sent, ) = nounsDaoTreasury.call{value: balance}("");
require(sent, "Funds removal failed.");
emit FundsPulled(nounsDaoTreasury, balance);
}
function changeExecutorAddress(address _newFomoExecutor) external onlyMultisig {
fomoExecutor = payable(_newFomoExecutor);
emit ExecutorChanged(fomoExecutor);
}
function changeMaxPriorityFee(uint256 _newMaxPriorityFee) external onlyMultisig {
maxPriorityFee = _newMaxPriorityFee;
emit MaxPriorityFeeChanged(maxPriorityFee);
}
function settleAuction(bytes32 _desiredHash) public {
bytes32 lastHash = blockhash(block.number - 1);
require(lastHash == _desiredHash, "Prior blockhash did not match intended hash");
auctionHouse.settleCurrentAndCreateNewAuction();
}
function settleAuctionWithRefund(bytes32 _desiredHash) external refundGas onlyFOMO {
settleAuction(_desiredHash);
}
}
{
"compilationTarget": {
"contracts/NounSettlement.sol": "NounSettlement"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_fomoExecutor","type":"address"},{"internalType":"address","name":"_nounsDaoTreasury","type":"address"},{"internalType":"address","name":"_nounsAuctionHouseAddress","type":"address"},{"internalType":"address","name":"_fomoMultisig","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_newExecutor","type":"address"}],"name":"ExecutorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"FundsPulled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_newMaxPriorityFee","type":"uint256"}],"name":"MaxPriorityFeeChanged","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"auctionHouse","outputs":[{"internalType":"contract INounsAuctionHouse","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newFomoExecutor","type":"address"}],"name":"changeExecutorAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMaxPriorityFee","type":"uint256"}],"name":"changeMaxPriorityFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"donateFunds","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"fomoExecutor","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fomoMultisig","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPriorityFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nounsDaoTreasury","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pullFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_desiredHash","type":"bytes32"}],"name":"settleAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_desiredHash","type":"bytes32"}],"name":"settleAuctionWithRefund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]