Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(erc1155): add custom ERC1155 contract for airdrop #262

Merged
merged 6 commits into from
Mar 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions contracts/erc1155/MintableERC1155.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";

/**
* @title MintableERC1155
* @notice Ownable contract enabling owner to airdrop many recipients the same token ID at once
*/
contract MintableERC1155 is ERC1155, Ownable {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: add a @title, @notice comment above the Contract. Something like:

@title MintableERC1155
@notice Ownable contract enabling owner to airdrop many recipients the same token ID at once

// Maps `tokenId` to metadata URI `tokenURI`
mapping(uint256 => string) public _tokenURIs;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should add comment above all state vars including _tokenURIs


event Airdrop(address caller, uint256 tokenId, address[] recipients, uint256 amount);

// We are passing an empty string as the `baseURI` because we use `_tokenURIs` instead
// to allow for IPFS URIs.
// solhint-disable-next-line
constructor() ERC1155("") {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might add a comment why you're passing in "" (because we opt to use the _tokenURIs mapping instead)


/**
* @notice Creates `amount` new tokens for `recipients` of token type `tokenId`.
* @dev Call might run out of gas if `recipients` arg too long. Might need to chunk up the list.
* @param recipients List of airdrop recipients.
* @param tokenId Token type to airdrop.
* @param amount Amount of token types to airdrop.
*/
function airdrop(
uint256 tokenId,
address[] memory recipients,
uint256 amount
) public onlyOwner {
for (uint256 i = 0; i < recipients.length; i++) {
_mint(recipients[i], tokenId, amount, "");
}
emit Airdrop(_msgSender(), tokenId, recipients, amount);
}

/**
* @notice Sets the URI for token of type `tokenId` to `tokenURI`.
* @param tokenId Token type to set `tokenURI` for.
* @param tokenURI URI of token metadata.
*/
function setTokenURI(uint256 tokenId, string memory tokenURI) external onlyOwner {
require(bytes(_tokenURIs[tokenId]).length == 0, "uri already set");

_tokenURIs[tokenId] = tokenURI;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: emit an Event after changing state. Something like SetTokenURI(uint256 tokenId, string newUri)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes good point. Actually in the spec we should emit URI(uri, tokenId). See https://eips.ethereum.org/EIPS/eip-1155#specification

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect!

emit URI(tokenURI, tokenId);
}

/**
* @notice Returns metadata URI of token type `tokenId`.
* @dev Instead of returning the same URI for *all* token types, we return the uri set by
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Add a @notice explaining this function. Can use @inheritdoc ERC1155 for example

* `setTokenURI` to allow IPFS URIs for all token types.
* @param tokenId Token type to retrieve metadata URI for.
*/
function uri(uint256 tokenId) public view override returns (string memory) {
return _tokenURIs[tokenId];
}
}
19 changes: 19 additions & 0 deletions deploy/021_deploy_erc1155.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import "hardhat-deploy";
import { HardhatRuntimeEnvironment } from "hardhat/types/runtime";

const func = async function (hre: HardhatRuntimeEnvironment) {
const { deployments, getNamedAccounts } = hre;
const { deploy } = deployments;

const { deployer } = await getNamedAccounts();

await deploy("MintableERC1155", {
from: deployer,
log: true,
skipIfAlreadyDeployed: true,
args: [],
});
};

module.exports = func;
func.tags = ["MintableERC1155"];
1 change: 1 addition & 0 deletions deployments/deployments.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"288": { "SpokePool": { "address": "0xBbc6009fEfFc27ce705322832Cb2068F8C1e0A58", "blockNumber": 619993 } },
"42161": { "SpokePool": { "address": "0xB88690461dDbaB6f04Dfad7df66B7725942FEb9C", "blockNumber": 12741972 } },
"80001": {
"MintableERC1155": { "address": "0xe377d7C510fEbc64525f480e33306b21b30066F7", "blockNumber": 33352305 },
"PolygonTokenBridger": { "address": "0x97f102f2f73717e203f964Ad9940e4C2e79b8597", "blockNumber": 26276246 },
"SpokePool": { "address": "0x45fF03629D024b7763275e732a2d80202c18b31C", "blockNumber": 26276253 }
},
Expand Down
Loading