Skip to content

Instantly share code, notes, and snippets.

@creeefs
Created March 30, 2023 22:40
Show Gist options
  • Select an option

  • Save creeefs/a48f371cd854eec2c50dea945faf4be8 to your computer and use it in GitHub Desktop.

Select an option

Save creeefs/a48f371cd854eec2c50dea945faf4be8 to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
import "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
contract Guestbook__v1_0 is Initializable, ERC1155Upgradeable, OwnableUpgradeable, UUPSUpgradeable {
using ECDSA for bytes32;
using Strings for uint256;
// IYK-controlled address to sign mint messages for txn relayers
address public signVerifier;
string public baseURI;
// Keep track of minting to an address so a signature cannot be used twice
mapping(address => uint256) public mintNonces;
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {}
function initialize() public initializer {
// ERC1155 constructor URI functions are overriden
__ERC1155_init("unused");
__UUPSUpgradeable_init();
__Ownable_init();
signVerifier = 0xF504941EF7FF8f24DC0063779EEb3fB12bAc8ab7;
baseURI = "https://iyk.app/api/metadata/1155/";
}
// Overidden to guard against which users can access
function _authorizeUpgrade(address newImplementation) internal virtual override onlyOwner {}
function getSignVerifier() external view virtual returns (address) {
return signVerifier;
}
function setSignVerifier(address verifier) external virtual onlyOwner {
signVerifier = verifier;
}
function setBaseURI(string memory _baseURI) external virtual onlyOwner {
baseURI = _baseURI;
}
function getMintNonce(address account) external view virtual returns (uint256) {
return mintNonces[account];
}
// Signing hash for gating access to txn relayer mint function
function getMintSigningHash(
uint256 blockExpiry,
address account,
uint256 id
) public view virtual returns (bytes32) {
return keccak256(abi.encodePacked(blockExpiry, account, id, address(this), mintNonces[account]));
}
// Minting function with signature for txn relayers
function mintWithSig(
address account,
uint256 id,
bytes memory data,
bytes memory sig,
uint256 blockExpiry
) external virtual {
bytes32 message = getMintSigningHash(blockExpiry, account, id).toEthSignedMessageHash();
require(ECDSA.recover(message, sig) == signVerifier, "Permission to call this function failed");
require(block.number < blockExpiry, "Sig expired");
mintNonces[account]++;
_mint(account, id, 1, data);
}
function mint(
address account,
uint256 id,
uint256 amount,
bytes memory data
) external virtual onlyOwner {
_mint(account, id, amount, data);
}
function mintBatch(
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) external virtual onlyOwner {
_mintBatch(to, ids, amounts, data);
}
function uri(uint256 id) public view virtual override returns (string memory) {
// From ERC721
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, id.toString())) : "";
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
import "./Guestbook__v1_0.sol";
contract Guestbook__v1_1 is Guestbook__v1_0 {
// ERC721 fields for better display in wallets
string public name;
string public symbol;
uint16 public minorVersion;
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {}
modifier upgradeVersion(uint16 upgradeToVersion) {
require(
upgradeToVersion - minorVersion == 1,
"Must be at the minor version one prior to what is being upgraded to"
);
_;
minorVersion = upgradeToVersion;
}
// Overidden to guard against which users can access
function _authorizeUpgrade(address newImplementation) internal virtual override onlyOwner {}
// Guestbook__v1_0 => Guestbook__v1_1 upgrade initializer
function upgradeTo__v1_1(string memory _name, string memory _symbol) public onlyOwner upgradeVersion(1) {
name = _name;
symbol = _symbol;
}
// Deploying Guestbook__v1_1 initializer
function initialize__v1_1(string memory _name, string memory _symbol) public initializer {
Guestbook__v1_0.initialize();
upgradeTo__v1_1(_name, _symbol);
}
function mintMultipleBatches(
address[] memory receivers,
uint256[][] memory ids,
uint256[][] memory amounts,
bytes memory data
) external virtual onlyOwner {
require(receivers.length == ids.length, "Mismatch of receivers and ids length");
require(receivers.length == amounts.length, "Mismatch of accounts and amounts length");
for (uint256 i = 0; i < receivers.length; ++i) {
require(ids[i].length == amounts[i].length, "Mismatch of token ids and amounts");
_mintBatch(receivers[i], ids[i], amounts[i], data);
}
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
import "./Guestbook__v1_1.sol";
contract Guestbook__v1_2 is Guestbook__v1_1 {
bytes32 public constant PAUSE_TRANSFER = keccak256("PAUSE_TRANSFER");
mapping(bytes32 => bool) public paused;
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {}
modifier whenPaused(bytes32 pauseType) {
require(paused[pauseType], "This feature is not paused.");
_;
}
modifier whenNotPaused(bytes32 pauseType) {
require(!paused[pauseType], "This feature is paused.");
_;
}
// Overidden to guard against which users can access
function _authorizeUpgrade(address newImplementation) internal virtual override onlyOwner {}
// Guestbook__v1_1 => Guestbook__v1_2 upgrade initializer
function upgradeTo__v1_2() public onlyOwner upgradeVersion(2) {
paused[PAUSE_TRANSFER] = false;
}
// Deploying Guestbook__v1_2 initializer
function initialize__v1_2(string memory _name, string memory _symbol) public initializer {
Guestbook__v1_1.initialize__v1_1(_name, _symbol);
upgradeTo__v1_2();
}
function setPauseState(bytes32 pauseType, bool pauseState) public onlyOwner {
paused[pauseType] = pauseState;
}
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes memory data
) public virtual override whenNotPaused(PAUSE_TRANSFER) {
super.safeTransferFrom(from, to, id, amount, data);
}
function safeBatchTransferFrom(
address from,
address to,
uint256[] memory ids,
uint256[] memory amounts,
bytes memory data
) public virtual override whenNotPaused(PAUSE_TRANSFER) {
super.safeBatchTransferFrom(from, to, ids, amounts, data);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment