Smart Contract Examples
Specific examples and general principles for integrating DelegateRegistry into your Solidity smart contract
Sample Token-Gated Mint w/ Delegate
Here the constant ORIGINAL_CONTRACT would be the one with the original tokens whose holders are being allowlisted. The constantDELEGATE_REGISTRY address would be 0x00000000000000447e69651d841bD8D104Bed493.
/**
* @notice For example, bored ape holders minting their mutant apes
* @param originalTokenIds The ids of tokens being used to mint something new
*/
function tokengatedMint(uint256[] calldata originalTokenIds) external {
for (uint256 i = 0; i < originalTokenIds.length; ++i) {
uint256 tokenId = originalTokenIds[i];
address tokenOwner = ORIGINAL_CONTRACT.ownerOf(tokenId);
// Mint if tokenOwner is msg.sender or tokenOwner delegated to msg.sender
if (msg.sender == tokenOwner ||
IDelegateRegistry(DELEGATE_REGISTRY).checkDelegateForERC721(
msg.sender,
tokenOwner,
address(ORIGINAL_CONTRACT),
tokenId,
""
)
) {
// Can mint to either the vaulted wallet or msg.sender, project's choice
// Can also use an `address recipient` function parameter for flexibility
_mint(tokenOwner, tokenId);
}
}
}Sample Merkle Tree Claim w/ Delegate
This is based off what Nakamigos CLOAKS used, where if users held a Nakamigo they were eligible for a free mint of a cloak. To save gas they used a merkle tree claim, this is compatible with Delegate.
General Principles
Whether you're building a mint or claim function, solidity additions to your contract are an important part of securing who is and isn't allowed to mint on behalf of a wallet.
Typically, a mint or claim function looks like this:
To integrate delegate.cash into your solidity contract, we will add a small code block to the above step. We will also pass an optional _vault address into the claim function.
Let's break down what we added.
(line 1) Passing an optional _cold address variable into the contraction.
_cold address variable into the contraction.When delegating, a hot wallet (msg.sender) is the one making the request on behalf of a cold wallet (_cold). When there is a _cold variable passed through the contract function, we know the hot wallet is minting on someone else's behalf.
(line 2) Using a new requester variable
requester variableIn a typical mint contract, msg.sender is used throughout the contract as the user who holds the NFT and processes the transaction. Now, since msg.sender may be minting on behalf of someone else, we use requester to know if that is the case or not. requester will either be msg.sender or the cold wallet.
(line 4-8) Checking the DelegateRegistry for the valid pairings
If the transaction includes a cold wallet, this line of code will make sure that there is a vault<>delegate pairing with the cold and hot wallet; which is the act of someone going to delegate.cash and delegating their hot wallet with their cold wallet.
Last updated