Transient Labs Stacks Protocol
The Stacks Protocol consists of sales contracts for the Transient Labs ecosystems. Sales comprise of mints, auctions, and buy nows. More can be added in the future as well.
Mints
Two contracts for minting new NFTs to ERC-721 and ERC-1155 contracts. Meant to work specifically with Transient Labs contracts but works for any contract that employs the proper function signature for externalMint
(different signature for 721 vs 1155).
The mint contracts are
TLStacks721.sol
TLStacks1155.sol
Features
- multi-tenant sales which keeps NFT contracts lighter weight with less code
- implements a flat buyers fee in ETH per NFT minted
- configurable for any ERC-20 token
- velocity/marathon mint: the duration of the open edition decreases (velocity) or increases (marathon) with each mint
- only the NFT contract owner or admins can configure/alter/cancel a mint
Auction House
A contract for reserve auctions and/or buy nows for minted ERC-721 tokens. Works for any ERC-721 token in existence.
The auction house contract is TLAuctionHouse.sol
Features
- implements a capped percentage buyers fee
- configurable for any ERC-20 token
- ALWAYS respects royalties if configured on the Royalty Registry
- Reserve auction can be configured ahead of time and have any duration desired
- Reserve auction and buy now can be listed at the same time and if either is hit first, the other is canceled automatically
- Only the NFT owner can configure or cancel an auction/buy now (this is true even when the NFT transfers hands outside of this contract)
- Buy Nows can be configured ahead of time as well
Safety
- If you have a listing on the Auction House and sell the token on another marketplace, beware that your listing on the Auction House is stale and if the NFT returns to your wallet at some point, the listing becomes valid. In the real world, this doesn't seem to occur very often, yet, you'll want to cancel your listing in this scenario.
Deployments
Contracts are deployed to the same address cross-chain using CREATE2. In doing such, constructor args have to be set to default values and then changed after deployment. Contracts are initially deployed with an EOA as the owner until initializations are made, then subsequently contract ownership is transferred to multi-sigs.
WETH Addresses
Ethereum: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Sepolia: 0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9
Arbitrum: 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1
Arbitrum-Sepolia: 0x980B62Da83eFf3D4576C647993b0c1D7faf17c73
Base: 0x4200000000000000000000000000000000000006
Base-Sepolia: 0x4200000000000000000000000000000000000006
Sanctions Oracle
https://go.chainalysis.com/chainalysis-oracle-docs.html
Disclaimer
While best efforts have gone into developing, testing, and peer reviewing these contracts, unexpected behavior may be present in the contracts under certain conditions. Transient Labs has a bug bounty program to preemptively squash any bugs found in our contracts.
This codebase is provided on an "as is" and "as available" basis.
We do not give any warranties and will not be liable for any loss incurred through any use of this codebase.
License
This code is copyright Transient Labs, Inc 2024 and is licensed under the MIT license.
Contents
- DropPhase
- DropType
- DropErrors
- AuctionHouseErrors
- Auction
- Sale
- ITLAuctionHouseEvents
- Drop
- ITLStacks1155Events
- Drop
- ITLStacks721Events
DropPhase
Enum to encapsulate drop phases
enum DropPhase {
NOT_CONFIGURED,
NOT_STARTED,
PRESALE,
PUBLIC_SALE,
ENDED
}
DropType
Enum to encapsulate drop types
enum DropType {
NOT_CONFIGURED,
REGULAR,
VELOCITY
}
DropErrors
Errors for Drops
Errors
NotDropAdmin
error NotDropAdmin();
NotApprovedMintContract
error NotApprovedMintContract();
InvalidPayoutReceiver
error InvalidPayoutReceiver();
InvalidDropSupply
error InvalidDropSupply();
DropAlreadyConfigured
error DropAlreadyConfigured();
DropUpdateNotAllowed
error DropUpdateNotAllowed();
InvalidDropType
error InvalidDropType();
NotAllowedForVelocityDrops
error NotAllowedForVelocityDrops();
MintZeroTokens
error MintZeroTokens();
NotOnAllowlist
error NotOnAllowlist();
YouShallNotMint
error YouShallNotMint();
AlreadyReachedMintAllowance
error AlreadyReachedMintAllowance();
InvalidBatchArguments
error InvalidBatchArguments();
InsufficientFunds
error InsufficientFunds();
AuctionHouseErrors
Errors for the Auction House
Errors
PercentageTooLarge
error PercentageTooLarge();
CallerNotTokenOwner
error CallerNotTokenOwner();
AuctionHouseNotApproved
error AuctionHouseNotApproved();
PayoutToZeroAddress
error PayoutToZeroAddress();
NftNotOwnedBySeller
error NftNotOwnedBySeller();
NftNotTransferred
error NftNotTransferred();
AuctionNotConfigured
error AuctionNotConfigured();
AuctionNotStarted
error AuctionNotStarted();
AuctionStarted
error AuctionStarted();
AuctionNotOpen
error AuctionNotOpen();
BidTooLow
error BidTooLow();
AuctionEnded
error AuctionEnded();
AuctionNotEnded
error AuctionNotEnded();
InsufficientMsgValue
error InsufficientMsgValue();
SaleNotConfigured
error SaleNotConfigured();
SaleNotOpen
error SaleNotOpen();
Auction
Auction struct
struct Auction {
address seller;
address payoutReceiver;
address currencyAddress;
address highestBidder;
uint256 highestBid;
uint256 reservePrice;
uint256 auctionOpenTime;
uint256 startTime;
uint256 duration;
}
Sale
Sale struct
struct Sale {
address seller;
address payoutReceiver;
address currencyAddress;
uint256 price;
uint256 saleOpenTime;
}
ITLAuctionHouseEvents
Events
RoyaltyEngineUpdated
event RoyaltyEngineUpdated(address indexed prevRoyaltyEngine, address indexed newRoyaltyEngine);
WethUpdated
event WethUpdated(address indexed prevWeth, address indexed newWeth);
MinBidIncreaseUpdated
event MinBidIncreaseUpdated(uint256 indexed newMinBidIncreasePerc, uint256 indexed newMinBidIncreaseLimit);
ProtocolFeeUpdated
event ProtocolFeeUpdated(
address indexed newProtocolFeeReceiver, uint256 indexed newProtocolFeePerc, uint256 indexed newProtocolFeeLimit
);
AuctionConfigured
event AuctionConfigured(address indexed sender, address indexed nftAddress, uint256 indexed tokenId, Auction auction);
AuctionCanceled
event AuctionCanceled(address indexed sender, address indexed nftAddress, uint256 indexed tokenId);
AuctionSettled
event AuctionSettled(address indexed sender, address indexed nftAddress, uint256 indexed tokenId, Auction auction);
AuctionBid
event AuctionBid(address indexed sender, address indexed nftAddress, uint256 indexed tokenId, Auction auction);
SaleConfigured
event SaleConfigured(address indexed sender, address indexed nftAddress, uint256 indexed tokenId, Sale sale);
SaleCanceled
event SaleCanceled(address indexed sender, address indexed nftAddress, uint256 indexed tokenId);
SaleFulfilled
event SaleFulfilled(address indexed sender, address indexed nftAddress, uint256 indexed tokenId, Sale sale);
Drop
stacks drop struct
struct Drop {
DropType dropType;
address payoutReceiver;
uint256 initialSupply;
uint256 supply;
uint256 allowance;
address currencyAddress;
uint256 startTime;
uint256 presaleDuration;
uint256 presaleCost;
bytes32 presaleMerkleRoot;
uint256 publicDuration;
uint256 publicCost;
int256 decayRate;
}
ITLStacks1155Events
Events
WethUpdated
event WethUpdated(address indexed prevWeth, address indexed newWeth);
ProtocolFeeUpdated
event ProtocolFeeUpdated(address indexed newProtocolFeeReceiver, uint256 indexed newProtocolFee);
DropConfigured
event DropConfigured(address indexed nftAddress, uint256 indexed tokenId, Drop drop);
DropUpdated
event DropUpdated(address indexed nftAddress, uint256 indexed tokenId, Drop drop);
DropClosed
event DropClosed(address indexed nftAddress, uint256 indexed tokenId);
Purchase
event Purchase(
address indexed nftAddress,
uint256 indexed tokenId,
address nftReceiver,
address currencyAddress,
uint256 amount,
uint256 price,
int256 decayRate,
bool isPresale
);
Drop
stacks drop struct
struct Drop {
DropType dropType;
address payoutReceiver;
uint256 initialSupply;
uint256 supply;
uint256 allowance;
address currencyAddress;
uint256 startTime;
uint256 presaleDuration;
uint256 presaleCost;
bytes32 presaleMerkleRoot;
uint256 publicDuration;
uint256 publicCost;
int256 decayRate;
string baseUri;
}
ITLStacks721Events
Events
WethUpdated
event WethUpdated(address indexed prevWeth, address indexed newWeth);
ProtocolFeeUpdated
event ProtocolFeeUpdated(address indexed newProtocolFeeReceiver, uint256 indexed newProtocolFee);
DropConfigured
event DropConfigured(address indexed nftAddress, Drop drop);
DropUpdated
event DropUpdated(address indexed nftAddress, Drop drop);
DropClosed
event DropClosed(address indexed nftAddress);
Purchase
event Purchase(
address indexed nftAddress,
address nftReceiver,
address currencyAddress,
uint256 amount,
uint256 price,
int256 decayRate,
bool isPresale
);
TLAuctionHouse
Inherits: Ownable, Pausable, ReentrancyGuard, RoyaltyPayoutHelper, ITLAuctionHouseEvents, AuctionHouseErrors
Author: transientlabs.xyz
Transient Labs Auction House with Reserve Auctions and Buy Now Sales for ERC-721 tokens
State Variables
VERSION
string public constant VERSION = "2.3.0";
EXTENSION_TIME
uint256 public constant EXTENSION_TIME = 15 minutes;
BASIS
uint256 public constant BASIS = 10_000;
protocolFeeReceiver
address public protocolFeeReceiver;
minBidIncreasePerc
uint256 public minBidIncreasePerc;
minBidIncreaseLimit
uint256 public minBidIncreaseLimit;
protocolFeePerc
uint256 public protocolFeePerc;
protocolFeeLimit
uint256 public protocolFeeLimit;
_auctions
mapping(address => mapping(uint256 => Auction)) internal _auctions;
_sales
mapping(address => mapping(uint256 => Sale)) internal _sales;
Functions
constructor
constructor(
address initOwner,
address initSanctionsOracle,
address initWethAddress,
address initRoyaltyEngineAddress,
address initProtocolFeeReceiver,
uint256 initMinBidIncreasePerc,
uint256 initMinBidIncreaseLimit,
uint256 initProtocolFeePerc,
uint256 initProtocolFeeLimit
)
Ownable(initOwner)
Pausable
ReentrancyGuard
RoyaltyPayoutHelper(initSanctionsOracle, initWethAddress, initRoyaltyEngineAddress);
setRoyaltyEngine
Function to set a new royalty engine address
Requires owner
function setRoyaltyEngine(address newRoyaltyEngine) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
newRoyaltyEngine | address | The new royalty engine address |
setWethAddress
Function to set a new weth address
Requires owner
function setWethAddress(address newWethAddress) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
newWethAddress | address | The new weth address |
setMinBidIncreaseSettings
Function to set the min bid increase settings
Requires owner
function setMinBidIncreaseSettings(uint256 newMinBidIncreasePerc, uint256 newMinBidIncreaseLimit) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
newMinBidIncreasePerc | uint256 | The new minimum bid increase nominal percentage, out of BASIS |
newMinBidIncreaseLimit | uint256 | The new minimum bid increase absolute limit |
setProtocolFeeSettings
Function to set the protocol fee settings
Requires owner
function setProtocolFeeSettings(address newProtocolFeeReceiver, uint256 newProtocolFeePerc, uint256 newProtocolFeeLimit)
external
onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
newProtocolFeeReceiver | address | The new protocol fee receiver |
newProtocolFeePerc | uint256 | The new protocol fee percentage, out of BASIS |
newProtocolFeeLimit | uint256 | The new protocol fee limit |
pause
Function to pause the contract
Requires owner
function pause(bool status) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
status | bool | The boolean to set the internal pause variable |
setSanctionsOracle
Function to set the sanctions oracle
Requires owner
function setSanctionsOracle(address newOracle) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
newOracle | address | The new oracle address |
configureAuction
Function to configure an auction
*Requires the following items to be true
- contract is not paused
- the auction hasn't been configured yet for the current token owner
- msg.sender is the owner of the token
- auction house is approved for all
- payoutReceiver isn't the zero address*
function configureAuction(
address nftAddress,
uint256 tokenId,
address payoutReceiver,
address currencyAddress,
uint256 reservePrice,
uint256 auctionOpenTime,
uint256 duration,
bool reserveAuction
) external whenNotPaused nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The nft token id |
payoutReceiver | address | The address that receives the payout from the auction |
currencyAddress | address | The currency to use |
reservePrice | uint256 | The auction reserve price |
auctionOpenTime | uint256 | The time at which bidding is allowed |
duration | uint256 | The duration of the auction after it is started |
reserveAuction | bool | A flag dictating if the auction is a reserve auction or regular scheduled auction |
cancelAuction
Function to cancel an auction
*Requires the following to be true
- msg.sender to be the auction seller
- the auction cannot be started*
function cancelAuction(address nftAddress, uint256 tokenId) external nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The nft token id |
bid
Function to bid on an auction
*Requires the following to be true
- contract is not paused
- block.timestamp is greater than the auction open timestamp
- bid meets or exceeds the reserve price / min bid price
- msg.sender has attached enough eth/erc20 as specified by
amount
- protocol fee has been supplied, if needed*
function bid(address nftAddress, uint256 tokenId, uint256 amount) external payable whenNotPaused nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The nft token id |
amount | uint256 | The amount to bid in the currency address set in the auction |
settleAuction
Function to settle an auction
Can be called by anyone
*Requires the following to be true
- auction has been started
- auction has ended*
function settleAuction(address nftAddress, uint256 tokenId) external nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The nft token id |
configureSale
Function to configure a buy now sale
*Requires the following to be true
- contract is not paused
- the sale hasn't been configured yet by the current token owner
- an auction hasn't been started - this is captured by token ownership
- msg.sender is the owner of the token
- auction house is approved for all
- payoutReceiver isn't the zero address*
function configureSale(
address nftAddress,
uint256 tokenId,
address payoutReceiver,
address currencyAddress,
uint256 price,
uint256 saleOpenTime
) external whenNotPaused nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The nft token id |
payoutReceiver | address | The address that receives the payout from the sale |
currencyAddress | address | The currency to use |
price | uint256 | The sale price |
saleOpenTime | uint256 | The time at which the sale opens |
cancelSale
Function to cancel a sale
Requires msg.sender to be the token owner
function cancelSale(address nftAddress, uint256 tokenId) external nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The nft token id |
buyNow
Function to buy a token
*Requires the following to be true
- contract is not paused
- block.timestamp is greater than the sale open timestamp
- msg.sender has attached enough eth/erc20 as specified by the sale
- protocol fee has been supplied, if needed*
function buyNow(address nftAddress, uint256 tokenId) external payable whenNotPaused nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The nft token id |
getSale
function to get a sale
function getSale(address nftAddress, uint256 tokenId) external view returns (Sale memory);
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The nft token id |
Returns
Name | Type | Description |
---|---|---|
<none> | Sale | sale The sale struct |
getAuction
function to get an auction
function getAuction(address nftAddress, uint256 tokenId) external view returns (Auction memory);
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The nft token id |
Returns
Name | Type | Description |
---|---|---|
<none> | Auction | auction The auction struct |
calcNextMinBid
function to get the next minimum bid price for an auction
function calcNextMinBid(address nftAddress, uint256 tokenId) external view returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The nft token id |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | uint256 The next minimum bid required |
calcProtocolFee
function to calculate the protocol fee
function calcProtocolFee(uint256 amount) external view returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
amount | uint256 | The value to calculate the fee for |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | uint256 The calculated fee |
_setMinBidIncreaseSettings
Internal function to set the min bid increase settings
function _setMinBidIncreaseSettings(uint256 newMinBidIncreasePerc, uint256 newMinBidIncreaseLimit) internal;
Parameters
Name | Type | Description |
---|---|---|
newMinBidIncreasePerc | uint256 | The new minimum bid increase nominal percentage, out of BASIS |
newMinBidIncreaseLimit | uint256 | The new minimum bid increase absolute limit |
_setProtocolFeeSettings
Internal function to set the protocol fee settings
function _setProtocolFeeSettings(
address newProtocolFeeReceiver,
uint256 newProtocolFeePerc,
uint256 newProtocolFeeLimit
) internal;
Parameters
Name | Type | Description |
---|---|---|
newProtocolFeeReceiver | address | The new protocol fee receiver |
newProtocolFeePerc | uint256 | The new protocol fee percentage, out of BASIS |
newProtocolFeeLimit | uint256 | The new protocol fee limit |
_checkTokenOwnership
Internal function to check if a token is owned by an address
function _checkTokenOwnership(IERC721 nft, uint256 tokenId, address potentialTokenOwner) internal view returns (bool);
Parameters
Name | Type | Description |
---|---|---|
nft | IERC721 | The nft contract |
tokenId | uint256 | The nft token id |
potentialTokenOwner | address | The potential token owner to check against |
Returns
Name | Type | Description |
---|---|---|
<none> | bool | bool Indication of if the address in quesion is the owner of the token |
_checkAuctionHouseApproval
Internal function to check if the auction house is approved for all
function _checkAuctionHouseApproval(IERC721 nft, address seller) internal view returns (bool);
Parameters
Name | Type | Description |
---|---|---|
nft | IERC721 | The nft contract |
seller | address | The seller to check against |
Returns
Name | Type | Description |
---|---|---|
<none> | bool | bool Indication of if the auction house is approved for all by the seller |
_checkPayoutReceiver
Internal function to check if a payout address is a valid address
function _checkPayoutReceiver(address payoutReceiver) internal pure returns (bool);
Parameters
Name | Type | Description |
---|---|---|
payoutReceiver | address | The payout address to check |
Returns
Name | Type | Description |
---|---|---|
<none> | bool | bool Indication of if the payout address is not the zero address |
_calcNextMinBid
Internal function to calculate the next min bid price
function _calcNextMinBid(uint256 currentBid) internal view returns (uint256 nextMinBid);
Parameters
Name | Type | Description |
---|---|---|
currentBid | uint256 | The current bid |
Returns
Name | Type | Description |
---|---|---|
nextMinBid | uint256 | The next minimum bid |
_calcProtocolFee
Internal function to calculate the protocol fee
function _calcProtocolFee(uint256 amount) internal view returns (uint256 fee);
Parameters
Name | Type | Description |
---|---|---|
amount | uint256 | The value of the sale |
Returns
Name | Type | Description |
---|---|---|
fee | uint256 | The protocol fee |
_payout
Internal function to payout from the contract
function _payout(address nftAddress, uint256 tokenId, address currencyAddress, uint256 amount, address payoutReceiver)
internal;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The token id |
currencyAddress | address | The currency address (ZERO ADDRESS == ETH) |
amount | uint256 | The sale/auction end price |
payoutReceiver | address | The receiver for the sale payout (what's remaining after royalties) |
TLStacks1155
Inherits: Ownable, Pausable, ReentrancyGuard, TransferHelper, SanctionsCompliance, ITLStacks1155Events, DropErrors
Author: transientlabs.xyz
Transient Labs Stacks mint contract for ERC1155TL contracts
State Variables
VERSION
string public constant VERSION = "2.3.1";
ADMIN_ROLE
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
APPROVED_MINT_CONTRACT
bytes32 public constant APPROVED_MINT_CONTRACT = keccak256("APPROVED_MINT_CONTRACT");
protocolFeeReceiver
address public protocolFeeReceiver;
protocolFee
uint256 public protocolFee;
weth
address public weth;
_drops
mapping(address => mapping(uint256 => Drop)) internal _drops;
_numberMinted
mapping(address => mapping(uint256 => mapping(uint256 => mapping(address => uint256)))) internal _numberMinted;
_rounds
mapping(address => mapping(uint256 => uint256)) internal _rounds;
Functions
constructor
constructor(
address initOwner,
address initSanctionsOracle,
address initWethAddress,
address initProtocolFeeReceiver,
uint256 initProtocolFee
) Ownable(initOwner) Pausable ReentrancyGuard SanctionsCompliance(initSanctionsOracle);
setWethAddress
Function to set a new weth address
Requires owner
function setWethAddress(address newWethAddress) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
newWethAddress | address | The new weth address |
setProtocolFeeSettings
Function to set the protocol fee settings
Requires owner
function setProtocolFeeSettings(address newProtocolFeeReceiver, uint256 newProtocolFee) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
newProtocolFeeReceiver | address | The new protocol fee receiver |
newProtocolFee | uint256 | The new protocol fee in ETH |
pause
Function to pause the contract
Requires owner
function pause(bool status) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
status | bool | The boolean to set the internal pause variable |
setSanctionsOracle
Function to set the sanctions oracle
Requires owner
function setSanctionsOracle(address newOracle) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
newOracle | address | The new oracle address |
configureDrop
Function to configure a drop
Caller must be the nft contract owner or an admin on the contract
*Reverts if
- the payout receiver is the zero address
- a drop is already configured and live
- the
intiialSupply
does not equal thesupply
- the
decayRate
is non-zero and there is a presale configured*
function configureDrop(address nftAddress, uint256 tokenId, Drop calldata drop) external whenNotPaused nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The token id of the ERC-1155 token |
drop | Drop | The drop to configure |
updateDropPayoutReceiver
Function to update the payout receiver of a drop
Caller must be the nft contract owner or an admin on the contract
function updateDropPayoutReceiver(address nftAddress, uint256 tokenId, address payoutReceiver)
external
whenNotPaused
nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The token id of the ERC-1155 token |
payoutReceiver | address | The recipient of the funds from the mint |
updateDropAllowance
Function to update the drop public allowance
Caller must be the nft contract owner or an admin on the contract
function updateDropAllowance(address nftAddress, uint256 tokenId, uint256 allowance)
external
whenNotPaused
nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The token id of the ERC-1155 token |
allowance | uint256 | The number of tokens allowed to be minted per wallet during the public phase of the drop |
updateDropPrices
Function to update the drop prices and currency
Caller must be the nft contract owner or an admin on the contract
function updateDropPrices(
address nftAddress,
uint256 tokenId,
address currencyAddress,
uint256 presaleCost,
uint256 publicCost
) external whenNotPaused nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The token id of the ERC-1155 token |
currencyAddress | address | The currency address (zero address represents ETH) |
presaleCost | uint256 | The cost of each token during the presale phase |
publicCost | uint256 | The cost of each token during the presale phase |
updateDropDuration
Function to adjust drop durations
Caller must be the nft contract owner or an admin on the contract
function updateDropDuration(
address nftAddress,
uint256 tokenId,
uint256 startTime,
uint256 presaleDuration,
uint256 publicDuration
) external whenNotPaused nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The token id of the ERC-1155 token |
startTime | uint256 | The timestamp at which the drop starts |
presaleDuration | uint256 | The duration of the presale phase of the drop, in seconds |
publicDuration | uint256 | The duration of the public phase |
updateDropPresaleMerkleRoot
Function to adjust the drop merkle root
Caller must be the nft contract owner or an admin on the contract
function updateDropPresaleMerkleRoot(address nftAddress, uint256 tokenId, bytes32 presaleMerkleRoot)
external
whenNotPaused
nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The token id of the ERC-1155 token |
presaleMerkleRoot | bytes32 | The merkle root for the presale phase (each leaf is abi encoded with the recipient and number they can mint during presale) |
updateDropDecayRate
Function to adjust the drop decay rate
Caller must be the nft contract owner or an admin on the contract
function updateDropDecayRate(address nftAddress, uint256 tokenId, int256 decayRate)
external
whenNotPaused
nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The token id of the ERC-1155 token |
decayRate | int256 | The merkle root for the presale phase (each leaf is abi encoded with the recipient and number they can mint during presale) |
closeDrop
function closeDrop(address nftAddress, uint256 tokenId) external nonReentrant;
purchase
Function to purchase a single token via a drop
*Reverts on any of the following conditions
- Drop isn't active or configured
- numberToMint is 0
- Invalid merkle proof during the presale phase
- Insufficent protocol fee
- Insufficient funds
- Already minted the allowance for the recipient
- Receiver is a contract that doesn't implement proper ERC-1155 receiving functions*
function purchase(
address nftAddress,
uint256 tokenId,
address recipient,
uint256 numberToMint,
uint256 presaleNumberCanMint,
bytes32[] calldata proof
) external payable whenNotPaused nonReentrant returns (uint256 refundAmount);
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The nft token id |
recipient | address | The receiver of the nft (msg.sender is the payer but this allows delegation) |
numberToMint | uint256 | The number of tokens to mint |
presaleNumberCanMint | uint256 | The number of tokens the recipient can mint during presale |
proof | bytes32[] | The merkle proof for the presale page |
Returns
Name | Type | Description |
---|---|---|
refundAmount | uint256 | The amount of eth refunded bqck to the caller |
getDrop
Function to get a drop
function getDrop(address nftAddress, uint256 tokenId) external view returns (Drop memory);
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The nft token id |
Returns
Name | Type | Description |
---|---|---|
<none> | Drop | Drop The drop for the nft contract and token id |
getDrops
Function to get a number of drops for a contract
function getDrops(address nftAddress, uint256[] calldata tokenIds) external view returns (Drop[] memory drops);
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenIds | uint256[] | The nft token ids |
Returns
Name | Type | Description |
---|---|---|
drops | Drop[] | An array of Drops |
getNumberMinted
Function to get number minted on a drop for an address
function getNumberMinted(address nftAddress, uint256 tokenId, address recipient) external view returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The nft token id |
recipient | address | The recipient of the nft |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | uint256 The number of tokens minted |
getDropPhase
Function to get the drop phase
function getDropPhase(address nftAddress, uint256 tokenId) external view returns (DropPhase);
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The nft token id |
Returns
Name | Type | Description |
---|---|---|
<none> | DropPhase | DropPhase The drop phase |
getDropRound
Function to get the drop round
function getDropRound(address nftAddress, uint256 tokenId) external view returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The nft token id |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | uint256 The round for the drop based on the nft contract and token id |
_setWethAddress
Internal function to set the weth address
function _setWethAddress(address newWethAddress) internal;
Parameters
Name | Type | Description |
---|---|---|
newWethAddress | address | The new weth address |
_setProtocolFeeSettings
Internal function to set the protocol fee settings
function _setProtocolFeeSettings(address newProtocolFeeReceiver, uint256 newProtocolFee) internal;
Parameters
Name | Type | Description |
---|---|---|
newProtocolFeeReceiver | address | The new protocol fee receiver |
newProtocolFee | uint256 | The new protocol fee in ETH |
_isDropAdmin
Internal function to check if msg.sender is the owner or an admin on the contract
function _isDropAdmin(address nftAddress) internal view returns (bool);
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
Returns
Name | Type | Description |
---|---|---|
<none> | bool | bool Boolean indicating if msg.sender is the owner or an admin on the nft contract |
_isApprovedMintContract
Intenral function to check if this contract is an approved mint contract
function _isApprovedMintContract(address nftAddress) internal view returns (bool);
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
Returns
Name | Type | Description |
---|---|---|
<none> | bool | bool Boolean indicating if this contract is approved or not |
_checkPayoutReceiver
Internal function to check if a payout address is a valid address
function _checkPayoutReceiver(address payoutReceiver) internal pure returns (bool);
Parameters
Name | Type | Description |
---|---|---|
payoutReceiver | address | The payout address to check |
Returns
Name | Type | Description |
---|---|---|
<none> | bool | bool Indication of if the payout address is not the zero address |
_getDropPhase
Internal function to get the drop phase
function _getDropPhase(Drop memory drop) internal view returns (DropPhase);
Parameters
Name | Type | Description |
---|---|---|
drop | Drop | The drop in question |
Returns
Name | Type | Description |
---|---|---|
<none> | DropPhase | DropPhase The drop phase enum value |
_getNumberCanMint
Internal function to determine how many tokens can be minted by an address
function _getNumberCanMint(uint256 allowance, uint256 numberMinted, uint256 supply)
internal
pure
returns (uint256 numberCanMint);
Parameters
Name | Type | Description |
---|---|---|
allowance | uint256 | The amount allowed to mint |
numberMinted | uint256 | The amount already minted |
supply | uint256 | The drop supply |
Returns
Name | Type | Description |
---|---|---|
numberCanMint | uint256 | The number of tokens allowed to mint |
_updateDropState
Function to update the state of the drop
function _updateDropState(
address nftAddress,
uint256 tokenId,
uint256 round,
address recipient,
uint256 numberToMint,
Drop memory drop
) internal;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The nft token id |
round | uint256 | The drop round for number minted |
recipient | address | The receiver of the nft (msg.sender is the payer but this allows delegation) |
numberToMint | uint256 | The number of tokens to mint |
drop | Drop | The Drop cached in memory |
_settleUp
Internal function to distribute funds for a _purchase
function _settleUp(uint256 numberToMint, uint256 cost, Drop memory drop) internal returns (uint256 refundAmount);
Parameters
Name | Type | Description |
---|---|---|
numberToMint | uint256 | The number of tokens that can be minted |
cost | uint256 | The cost per token |
drop | Drop | The drop |
Returns
Name | Type | Description |
---|---|---|
refundAmount | uint256 | The amount of eth refunded to msg.sender |
_mintToken
Internal function to mint the token
function _mintToken(address nftAddress, uint256 tokenId, address recipient, uint256 numberToMint) internal;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
tokenId | uint256 | The nft token id |
recipient | address | The receiver of the nft (msg.sender is the payer but this allows delegation) |
numberToMint | uint256 | The number of tokens to mint |
TLStacks721
Inherits: Ownable, Pausable, ReentrancyGuard, TransferHelper, SanctionsCompliance, ITLStacks721Events, DropErrors
Author: transientlabs.xyz
Transient Labs Stacks mint contract for ERC721TL-based contracts
State Variables
VERSION
string public constant VERSION = "2.3.1";
ADMIN_ROLE
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
APPROVED_MINT_CONTRACT
bytes32 public constant APPROVED_MINT_CONTRACT = keccak256("APPROVED_MINT_CONTRACT");
protocolFeeReceiver
address public protocolFeeReceiver;
protocolFee
uint256 public protocolFee;
weth
address public weth;
_drops
mapping(address => Drop) internal _drops;
_numberMinted
mapping(address => mapping(uint256 => mapping(address => uint256))) internal _numberMinted;
_rounds
mapping(address => uint256) internal _rounds;
Functions
constructor
constructor(
address initOwner,
address initSanctionsOracle,
address initWethAddress,
address initProtocolFeeReceiver,
uint256 initProtocolFee
) Ownable(initOwner) Pausable ReentrancyGuard SanctionsCompliance(initSanctionsOracle);
setWethAddress
Function to set a new weth address
Requires owner
function setWethAddress(address newWethAddress) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
newWethAddress | address | The new weth address |
setProtocolFeeSettings
Function to set the protocol fee settings
Requires owner
function setProtocolFeeSettings(address newProtocolFeeReceiver, uint256 newProtocolFee) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
newProtocolFeeReceiver | address | The new protocol fee receiver |
newProtocolFee | uint256 | The new protocol fee in ETH |
pause
Function to pause the contract
Requires owner
function pause(bool status) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
status | bool | The boolean to set the internal pause variable |
setSanctionsOracle
Function to set the sanctions oracle
Requires owner
function setSanctionsOracle(address newOracle) external onlyOwner;
Parameters
Name | Type | Description |
---|---|---|
newOracle | address | The new oracle address |
configureDrop
Function to configure a drop
Caller must be the nft contract owner or an admin on the contract
*Reverts if
- the payout receiver is the zero address
- a drop is already configured and live
- the
intialSupply
does not equal thesupply
- the
decayRate
is non-zero and there is a presale configured*
function configureDrop(address nftAddress, Drop calldata drop) external whenNotPaused nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
drop | Drop | The drop to configure |
updateDropPayoutReceiver
Function to update the payout receiver of a drop
Caller must be the nft contract owner or an admin on the contract
function updateDropPayoutReceiver(address nftAddress, address payoutReceiver) external whenNotPaused nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
payoutReceiver | address | The recipient of the funds from the mint |
updateDropAllowance
Function to update the drop public allowance
Caller must be the nft contract owner or an admin on the contract
function updateDropAllowance(address nftAddress, uint256 allowance) external whenNotPaused nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
allowance | uint256 | The number of tokens allowed to be minted per wallet during the public phase of the drop |
updateDropPrices
Function to update the drop prices and currency
Caller must be the nft contract owner or an admin on the contract
function updateDropPrices(address nftAddress, address currencyAddress, uint256 presaleCost, uint256 publicCost)
external
whenNotPaused
nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
currencyAddress | address | The currency address (zero address represents ETH) |
presaleCost | uint256 | The cost of each token during the presale phase |
publicCost | uint256 | The cost of each token during the presale phase |
updateDropDuration
Function to adjust drop durations
Caller must be the nft contract owner or an admin on the contract
function updateDropDuration(address nftAddress, uint256 startTime, uint256 presaleDuration, uint256 publicDuration)
external
whenNotPaused
nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
startTime | uint256 | The timestamp at which the drop starts |
presaleDuration | uint256 | The duration of the presale phase of the drop, in seconds |
publicDuration | uint256 | The duration of the public phase |
updateDropPresaleMerkleRoot
Function to alter a drop merkle root
Caller must be the nft contract owner or an admin on the contract
function updateDropPresaleMerkleRoot(address nftAddress, bytes32 presaleMerkleRoot)
external
whenNotPaused
nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
presaleMerkleRoot | bytes32 | The merkle root for the presale phase (each leaf is abi encoded with the recipient and number they can mint during presale) |
updateDropDecayRate
Function to adjust the drop decay rate
Caller must be the nft contract owner or an admin on the contract
function updateDropDecayRate(address nftAddress, int256 decayRate) external whenNotPaused nonReentrant;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
decayRate | int256 | The merkle root for the presale phase (each leaf is abi encoded with the recipient and number they can mint during presale) |
closeDrop
function closeDrop(address nftAddress) external nonReentrant;
purchase
Function to purchase tokens on a drop
*Reverts on any of the following conditions
- Drop isn't active or configured
- numberToMint is 0
- Invalid merkle proof during the presale phase
- Insufficent protocol fee
- Insufficient funds
- Already minted the allowance for the recipient*
function purchase(
address nftAddress,
address recipient,
uint256 numberToMint,
uint256 presaleNumberCanMint,
bytes32[] calldata proof
) external payable whenNotPaused nonReentrant returns (uint256 refundAmount);
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
recipient | address | The receiver of the nft (msg.sender is the payer but this allows delegation) |
numberToMint | uint256 | The number of tokens to mint |
presaleNumberCanMint | uint256 | The number of tokens the recipient can mint during presale |
proof | bytes32[] | The merkle proof for the presale page |
Returns
Name | Type | Description |
---|---|---|
refundAmount | uint256 | The amount of eth refunded to the caller |
getDrop
Function to get a drop
function getDrop(address nftAddress) external view returns (Drop memory);
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
Returns
Name | Type | Description |
---|---|---|
<none> | Drop | Drop The drop for the nft contract and token id |
getNumberMinted
Function to get number minted on a drop for an address
function getNumberMinted(address nftAddress, address recipient) external view returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
recipient | address | The recipient of the nft |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | uint256 The number of tokens minted |
getDropPhase
Function to get the drop phase
function getDropPhase(address nftAddress) external view returns (DropPhase);
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
Returns
Name | Type | Description |
---|---|---|
<none> | DropPhase | DropPhase The drop phase |
getDropRound
Function to get the drop round
function getDropRound(address nftAddress) external view returns (uint256);
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
Returns
Name | Type | Description |
---|---|---|
<none> | uint256 | uint256 The round for the drop based on the nft contract and token id |
_setWethAddress
Internal function to set the weth address
function _setWethAddress(address newWethAddress) internal;
Parameters
Name | Type | Description |
---|---|---|
newWethAddress | address | The new weth address |
_setProtocolFeeSettings
Internal function to set the protocol fee settings
function _setProtocolFeeSettings(address newProtocolFeeReceiver, uint256 newProtocolFee) internal;
Parameters
Name | Type | Description |
---|---|---|
newProtocolFeeReceiver | address | The new protocol fee receiver |
newProtocolFee | uint256 | The new protocol fee in ETH |
_isDropAdmin
Internal function to check if msg.sender is the owner or an admin on the contract
function _isDropAdmin(address nftAddress) internal view returns (bool);
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
Returns
Name | Type | Description |
---|---|---|
<none> | bool | bool Boolean indicating if msg.sender is the owner or an admin on the nft contract |
_isApprovedMintContract
Intenral function to check if this contract is an approved mint contract
function _isApprovedMintContract(address nftAddress) internal view returns (bool);
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
Returns
Name | Type | Description |
---|---|---|
<none> | bool | bool Boolean indicating if this contract is approved or not |
_checkPayoutReceiver
Internal function to check if a payout address is a valid address
function _checkPayoutReceiver(address payoutReceiver) internal pure returns (bool);
Parameters
Name | Type | Description |
---|---|---|
payoutReceiver | address | The payout address to check |
Returns
Name | Type | Description |
---|---|---|
<none> | bool | bool Indication of if the payout address is not the zero address |
_getDropPhase
Internal function to get the drop phase
function _getDropPhase(Drop memory drop) internal view returns (DropPhase);
Parameters
Name | Type | Description |
---|---|---|
drop | Drop | The drop in question |
Returns
Name | Type | Description |
---|---|---|
<none> | DropPhase | DropPhase The drop phase enum value |
_getNumberCanMint
Internal function to determine how many tokens can be minted by an address
function _getNumberCanMint(uint256 allowance, uint256 numberMinted, uint256 supply)
internal
pure
returns (uint256 numberCanMint);
Parameters
Name | Type | Description |
---|---|---|
allowance | uint256 | The amount allowed to mint |
numberMinted | uint256 | The amount already minted |
supply | uint256 | The drop supply |
Returns
Name | Type | Description |
---|---|---|
numberCanMint | uint256 | The number of tokens allowed to mint |
_updateDropState
Function to update the state of the drop
function _updateDropState(address nftAddress, uint256 round, address recipient, uint256 numberToMint, Drop memory drop)
internal;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
round | uint256 | The drop round for number minted |
recipient | address | The receiver of the nft (msg.sender is the payer but this allows delegation) |
numberToMint | uint256 | The number of tokens to mint |
drop | Drop | The Drop cached in memory |
_settleUp
Internal function to distribute funds for a _purchase
function _settleUp(uint256 numberToMint, uint256 cost, Drop memory drop) internal returns (uint256 refundAmount);
Parameters
Name | Type | Description |
---|---|---|
numberToMint | uint256 | The number of tokens that can be minted |
cost | uint256 | The cost per token |
drop | Drop | The drop |
Returns
Name | Type | Description |
---|---|---|
refundAmount | uint256 | The amount of eth refunded to msg.sender |
_mintToken
Internal function to mint the token
function _mintToken(address nftAddress, address recipient, uint256 numberToMint, Drop memory drop) internal;
Parameters
Name | Type | Description |
---|---|---|
nftAddress | address | The nft contract address |
recipient | address | The receiver of the nft (msg.sender is the payer but this allows delegation) |
numberToMint | uint256 | The number of tokens to mint |
drop | Drop | The drop cached in memory (not read from storage again) |