generated from Hats-Protocol/hats-module-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
177 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
// import { console2 } from "forge-std/Test.sol"; // remove before deploy | ||
import { HatsModule, HatsEligibilityModule, IHatsEligibility } from "hats-module/HatsEligibilityModule.sol"; | ||
import { IToken } from "./lib/IToken.sol"; | ||
import { IAuction } from "./lib/IAuction.sol"; | ||
|
||
contract LatestNounsBuilderNFTEligibility is HatsEligibilityModule { | ||
/*////////////////////////////////////////////////////////////// | ||
CONSTANTS | ||
//////////////////////////////////////////////////////////////*/ | ||
|
||
/** | ||
* This contract is a clone with immutable args, which means that it is deployed with a set of | ||
* immutable storage variables (ie constants). Accessing these constants is cheaper than accessing | ||
* regular storage variables (such as those set on initialization of a typical EIP-1167 clone), | ||
* but requires a slightly different approach since they are read from calldata instead of storage. | ||
* | ||
* Below is a table of constants and their location. | ||
* | ||
* For more, see here: https://github.com/Saw-mon-and-Natalie/clones-with-immutable-args | ||
* | ||
* ----------------------------------------------------------------------+ | ||
* CLONE IMMUTABLE "STORAGE" | | ||
* ----------------------------------------------------------------------| | ||
* Offset | Constant | Type | Length | Source | | ||
* ----------------------------------------------------------------------| | ||
* 0 | IMPLEMENTATION | address | 20 | HatsModule | | ||
* 20 | HATS | address | 20 | HatsModule | | ||
* 40 | hatId | uint256 | 32 | HatsModule | | ||
* 72 | TOKEN | IToken | 20 | this | | ||
* ----------------------------------------------------------------------+ | ||
*/ | ||
function TOKEN() public pure returns (IToken) { | ||
return IToken(_getArgAddress(72)); | ||
} | ||
|
||
/*////////////////////////////////////////////////////////////// | ||
CONSTRUCTOR | ||
//////////////////////////////////////////////////////////////*/ | ||
|
||
/// @notice Deploy the implementation contract and set its version | ||
/// @dev This is only used to deploy the implementation contract, and should not be used to deploy clones | ||
constructor(string memory _version) HatsModule(_version) { } | ||
|
||
/*////////////////////////////////////////////////////////////// | ||
INITIALIZOR | ||
//////////////////////////////////////////////////////////////*/ | ||
|
||
/// @inheritdoc HatsModule | ||
function _setUp(bytes calldata _initData) internal override { | ||
// decode init data | ||
} | ||
|
||
/*////////////////////////////////////////////////////////////// | ||
HATS ELIGIBILITY FUNCTION | ||
//////////////////////////////////////////////////////////////*/ | ||
|
||
/// @inheritdoc IHatsEligibility | ||
function getWearerStatus(address _wearer, uint256 /*_hatId*/ ) | ||
public | ||
view | ||
virtual | ||
override | ||
returns (bool eligible, bool standing) | ||
{ | ||
// The wearer is eligible only if they own the latest token id | ||
// We need to catch the case where the previous auction was settled without a winner | ||
try TOKEN().ownerOf(getLastAuctionedTokenId()) returns (address owner) { | ||
// the last auctioned token id has a value owner, so we check if it matches the wearer | ||
eligible = owner == _wearer; | ||
} catch { | ||
// if the last auctioned token id does not have an owner, so we know the wearer is not eligible | ||
// eligible is false by default | ||
} | ||
|
||
// This module does not deal with standing, so we default to good standing (true) | ||
standing = true; | ||
} | ||
|
||
/*////////////////////////////////////////////////////////////// | ||
VIEW FUNCTIONS | ||
//////////////////////////////////////////////////////////////*/ | ||
|
||
/** | ||
* @notice Get the id of the most recently auctioned token for `_token`. | ||
* If the auction was settled without a winner, the returned token id will not have an owner. | ||
* | ||
* @dev Return the present auction's token id if it has been settled with a winner, otherwise it returns | ||
* the id of the previous auction. | ||
* | ||
* @return The id of the most recently auctioned token. | ||
*/ | ||
function getLastAuctionedTokenId() public view returns (uint256) { | ||
// get the auction contract | ||
IAuction auctionContract = IAuction(TOKEN().auction()); | ||
|
||
// get the data for the current auction | ||
IAuction.Auction memory currentAuction = auctionContract.auction(); | ||
|
||
// if the auction is settled with a winner, we want the current auction's token; | ||
if (currentAuction.settled && currentAuction.highestBidder > address(0)) { | ||
return currentAuction.tokenId; | ||
} else { | ||
// otherwise, we want the previous auction's token | ||
return currentAuction.tokenId - 1; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
/// @notice Sourced from | ||
/// https://github.com/ourzora/nouns-protocol/blob/98b65e2368c52085ff3844779afd45162eb1cc7d/src/auction/storage/AuctionStorageV1 | ||
interface IAuction { | ||
/// @notice The auction type | ||
/// @param tokenId The ERC-721 token id | ||
/// @param highestBid The highest amount of ETH raised | ||
/// @param highestBidder The leading bidder | ||
/// @param startTime The timestamp the auction starts | ||
/// @param endTime The timestamp the auction ends | ||
/// @param settled If the auction has been settled | ||
struct Auction { | ||
uint256 tokenId; | ||
uint256 highestBid; | ||
address highestBidder; | ||
uint40 startTime; | ||
uint40 endTime; | ||
bool settled; | ||
} | ||
|
||
/// @notice The current auction | ||
function auction() external view returns (Auction memory); | ||
|
||
/// @notice Settles the current auction and creates the next one | ||
function settleCurrentAndCreateNewAuction() external; | ||
|
||
/// @notice Pauses the auction house | ||
function pause() external; | ||
|
||
/// @notice Unpauses the auction house | ||
function unpause() external; | ||
|
||
/// @notice Settles the latest auction when the contract is paused | ||
function settleAuction() external; | ||
|
||
function createBid(uint256 tokenId) external payable; | ||
|
||
/// @notice The owner of the auction house | ||
function owner() external view returns (address); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.19; | ||
|
||
/// @dev Excerpt sourced from | ||
/// https://github.com/ourzora/nouns-protocol/blob/98b65e2368c52085ff3844779afd45162eb1cc7d/src/token/IToken.sol | ||
interface IToken { | ||
/// @notice The address of the auction house | ||
function auction() external view returns (address); | ||
|
||
/// @notice The total number of tokens that can be claimed from the reserve | ||
function remainingTokensInReserve() external view returns (uint256); | ||
|
||
/// @notice The total supply of tokens | ||
function totalSupply() external view returns (uint256); | ||
|
||
/// @notice The owner of a token | ||
/// @param tokenId The ERC-721 token id | ||
function ownerOf(uint256 tokenId) external view returns (address); | ||
|
||
/// @notice Mints the specified amount of tokens to the recipient and handles founder vesting | ||
function mintTo(address recipient) external returns (uint256 tokenId); | ||
|
||
/// @notice Transfers a token from one address to another | ||
function transferFrom(address from, address to, uint256 tokenId) external; | ||
} |