Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CuttingBoardSlotNFT

Git Source

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:

  1. Deploy Syndicate proxy (address known).
  2. Deploy CuttingBoardSlotNFT(syndicate=proxyAddr, owner=governance, baseURI="").
  3. 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

NameTypeDescription
_syndicateaddressAddress of the CuttingBoardSyndicate proxy (authorised minter).
_owneraddressAddress of the contract owner (can update baseURI).
baseURIstringInitial 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

NameTypeDescription
toaddressRecipient of the NFT (the winning partner).
auctionIduint256Syndicate round / auction identifier.
originalPartneraddressThe original winning partner (for reverse lookup).
allocatedWeightuint96Actual bps allocated.
requestedWeightuint96Bps bid by the partner.
clearingPriceuint128Total auction price paid at triggerClaim.
vaultaddressInitial BeraChef receiver vault.
expiryTimestampuint256When slot rights expire (matches control NFT expiry).
isPartialFillboolTrue when allocatedWeight < requestedWeight.

Returns

NameTypeDescription
tokenIduint256The 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

NameTypeDescription
tokenIduint256The token whose vault is being updated.
newVaultaddressThe 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

NameTypeDescription
tokenIduint256The token ID to check.

Returns

NameTypeDescription
<none>boolTrue 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

NameTypeDescription
tokenIduint256The token ID.

Returns

NameTypeDescription
<none>SlotRightsThe 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

NameTypeDescription
auctionIduint256The syndicate round ID.
originalPartneraddressThe original winning partner address.

Returns

NameTypeDescription
<none>uint256The 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

NameTypeDescription
newBaseURIstringThe new base URI string.

tokenURI

Return the token URI.

function tokenURI(uint256 tokenId)
    public
    view
    virtual
    override
    returns (string memory);

Parameters

NameTypeDescription
tokenIduint256The 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
}