CuttingBoardSlotNFT
Inherits: ERC721, Owned
Title: CuttingBoardSlotNFT
ERC-721 token representing a won slot in a CuttingBoardSyndicate round.
Minted at triggerClaim() for each included partner. Transferable — the current holder can redirect the slot allocation to a different vault via the Syndicate's updateSlotVaultByNFT(). Expiry matches the control NFT (same allocationDuration). Deployment order:
- Deploy Syndicate proxy (address known).
- Deploy CuttingBoardSlotNFT(syndicate=proxyAddr, owner=governance, baseURI="").
- Syndicate governance calls setSlotNFT(slotNFTAddr). No circular dependency — the syndicate address is immutable in this contract, and the syndicate stores the SlotNFT address in its own upgradeable storage.
State Variables
syndicate
Address of the CuttingBoardSyndicate — sole authorised minter/updater
address public immutable syndicate
_tokenRights
Mapping from token ID to slot rights
mapping(uint256 => SlotRights) private _tokenRights
_nextTokenId
Current token ID counter; starts at 1
uint256 private _nextTokenId
_auctionPartnerToken
Reverse lookup: auctionId → originalPartner → tokenId (0 = not minted)
mapping(uint256 => mapping(address => uint256)) private
_auctionPartnerToken
_baseTokenURI
Metadata base URI
string private _baseTokenURI
Functions
onlySyndicate
modifier onlySyndicate() ;
constructor
Deploy the CuttingBoardSlotNFT contract.
constructor(address _syndicate, address _owner, string memory baseURI)
ERC721("Infrared Slot", "iSLOT")
Owned(_owner);
Parameters
| Name | Type | Description |
|---|---|---|
_syndicate | address | Address of the CuttingBoardSyndicate proxy (authorised minter). |
_owner | address | Address of the contract owner (can update baseURI). |
baseURI | string | Initial metadata base URI (may be empty). |
mint
Mint a new slot NFT to a winner.
Only callable by the syndicate. Records all auction metadata at the time of triggerClaim. The reverse lookup (_auctionPartnerToken) maps (auctionId, originalPartner) → tokenId for the lifetime of the token.
function mint(
address to,
uint256 auctionId,
address originalPartner,
uint96 allocatedWeight,
uint96 requestedWeight,
uint128 clearingPrice,
address vault,
uint256 expiryTimestamp,
bool isPartialFill
) external virtual onlySyndicate returns (uint256 tokenId);
Parameters
| Name | Type | Description |
|---|---|---|
to | address | Recipient of the NFT (the winning partner). |
auctionId | uint256 | Syndicate round / auction identifier. |
originalPartner | address | The original winning partner (for reverse lookup). |
allocatedWeight | uint96 | Actual bps allocated. |
requestedWeight | uint96 | Bps bid by the partner. |
clearingPrice | uint128 | Total auction price paid at triggerClaim. |
vault | address | Initial BeraChef receiver vault. |
expiryTimestamp | uint256 | When slot rights expire (matches control NFT expiry). |
isPartialFill | bool | True when allocatedWeight < requestedWeight. |
Returns
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The newly minted token ID. |
updateVault
Update the vault recorded in a slot NFT.
Only callable by the syndicate (after it validates the new vault). This keeps the NFT metadata in sync with the Syndicate's slot storage.
function updateVault(uint256 tokenId, address newVault)
external
virtual
onlySyndicate;
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The token whose vault is being updated. |
newVault | address | The new BeraChef receiver vault address. |
isValid
Check whether a slot NFT is still valid (exists and not expired).
function isValid(uint256 tokenId) external view virtual returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The token ID to check. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | bool | True if the token exists and block.timestamp ≤ expiryTimestamp. |
getSlotRights
Return the full slot rights for a token.
function getSlotRights(uint256 tokenId)
external
view
virtual
returns (SlotRights memory);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The token ID. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | SlotRights | The SlotRights struct. |
getTokenId
Reverse lookup: return the token ID for a given (auctionId, originalPartner) pair.
function getTokenId(uint256 auctionId, address originalPartner)
external
view
virtual
returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
auctionId | uint256 | The syndicate round ID. |
originalPartner | address | The original winning partner address. |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | The token ID, or 0 if no token has been minted for this pair. |
totalSupply
Return the total number of slot NFTs minted.
function totalSupply() external view virtual returns (uint256);
setBaseURI
Update the metadata base URI.
function setBaseURI(string calldata newBaseURI) external virtual onlyOwner;
Parameters
| Name | Type | Description |
|---|---|---|
newBaseURI | string | The new base URI string. |
tokenURI
Return the token URI.
function tokenURI(uint256 tokenId)
public
view
virtual
override
returns (string memory);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | The token ID. |
Events
SlotNFTMinted
Emitted when a new slot NFT is minted
event SlotNFTMinted(
uint256 indexed tokenId,
uint256 indexed auctionId,
address indexed originalPartner,
address vault,
uint96 allocatedWeight,
uint96 requestedWeight,
uint128 clearingPrice,
uint256 expiryTimestamp,
bool isPartialFill
);
SlotVaultUpdated
Emitted when the vault recorded in a slot NFT is updated
event SlotVaultUpdated(uint256 indexed tokenId, address indexed newVault);
Errors
NotSyndicate
Caller is not the syndicate contract
error NotSyndicate();
InvalidTokenId
Token ID does not exist
error InvalidTokenId();
Structs
SlotRights
Represents the slot rights associated with an NFT
struct SlotRights {
uint256 auctionId;
address originalPartner; // original auction winner (for reverse lookup in Syndicate)
uint96 allocatedWeight; // actual bps allocated at triggerClaim
uint96 requestedWeight; // bps bid by the partner
uint128 clearingPrice; // total auction price paid at triggerClaim
address vault; // current BeraChef receiver vault (updatable via Syndicate)
uint256 expiryTimestamp; // matches control NFT expiry (allocationDuration end)
bool isPartialFill; // true when allocatedWeight < requestedWeight
}