-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Run prettier * Add InverseProjectedNft * Implement ERC4906 - MetadataUpdate event * Add tokenURI to interface and move IERC4096 there too
- Loading branch information
Showing
8 changed files
with
1,771 additions
and
1,391 deletions.
There are no files selected for viewing
45 changes: 45 additions & 0 deletions
45
packages/contracts/evm-contracts/contracts/token/IInverseProjectedNft.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.13; | ||
|
||
import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; | ||
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; | ||
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; | ||
import {IERC4906} from "@openzeppelin/contracts/interfaces/IERC4906.sol"; | ||
|
||
/// @dev A standard ERC721 that accepts calldata in the mint function for any initialization data needed in a Paima dApp. | ||
interface IInverseProjectedNft is IERC4906 { | ||
/// @dev Emitted when `baseExtension` is updated from `oldBaseExtension` to `newBaseExtension`. | ||
event SetBaseExtension(string oldBaseExtension, string newBaseExtension); | ||
|
||
/// @dev Emitted when `baseUri` is updated from `oldUri` to `newUri`. | ||
event SetBaseURI(string oldUri, string newUri); | ||
|
||
/// @dev Emitted when a new token with ID `tokenId` is minted, with `initialData` provided in the `mint` function parameters. | ||
event Minted(uint256 indexed tokenId, string initialData); | ||
|
||
/// @dev Mints a new token to address `_to`, passing `initialData` to be emitted in the event. | ||
/// Increases the `totalSupply` and `currentTokenId`. | ||
/// Reverts if `totalSupply` is not less than `maxSupply` or if `_to` is a zero address. | ||
/// Emits the `Minted` event. | ||
function mint(address _to, string calldata initialData) external returns (uint256); | ||
|
||
/// @dev Burns token of ID `_tokenId`. Callable only by the owner of the specified token. | ||
/// Reverts if `_tokenId` is not existing. | ||
function burn(uint256 _tokenId) external; | ||
|
||
/// @dev Sets `_URI` as the `baseURI` of the NFT. | ||
/// Callable only by the contract owner. | ||
/// Emits the `SetBaseURI` event. | ||
function setBaseURI(string memory _URI) external; | ||
|
||
/// @dev Sets `_newBaseExtension` as the `baseExtension` of the NFT. | ||
/// Callable only by the contract owner. | ||
function setBaseExtension(string memory _newBaseExtension) external; | ||
|
||
/// @dev Returns the token URI of specified `tokenId` using a custom base URI. | ||
function tokenURI( | ||
uint256 tokenId, | ||
string memory customBaseUri | ||
) external view returns (string memory); | ||
} |
126 changes: 126 additions & 0 deletions
126
packages/contracts/evm-contracts/contracts/token/InverseProjectedNft.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.13; | ||
|
||
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; | ||
import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; | ||
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; | ||
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; | ||
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; | ||
import {IERC4906} from "@openzeppelin/contracts/interfaces/IERC4906.sol"; | ||
import {IInverseProjectedNft} from "./IInverseProjectedNft.sol"; | ||
|
||
/// @dev A standard ERC721 that accepts calldata in the mint function for any initialization data needed in a Paima dApp. | ||
contract InverseProjectedNft is IInverseProjectedNft, ERC721, Ownable { | ||
using Strings for uint256; | ||
|
||
/// @dev The token ID that will be minted when calling the `mint` function. | ||
uint256 public currentTokenId; | ||
/// @dev Base URI that is used in the `tokenURI` function to form the start of the token URI. | ||
string public baseURI; | ||
/// @dev Total token supply, increased by minting and decreased by burning. | ||
uint256 public totalSupply; | ||
/// @dev Base extension that is used in the `tokenURI` function to form the end of the token URI. | ||
string public baseExtension; | ||
|
||
/// @dev Reverts if `msg.sender` is not the specified token's owner. | ||
modifier onlyTokenOwner(uint256 tokenId) { | ||
require(msg.sender == ownerOf(tokenId), "InverseProjectedNft: not owner"); | ||
_; | ||
} | ||
|
||
/// @dev Sets the NFT's `name`, `symbol`, and transfers ownership to `owner`. | ||
/// Also sets `currentTokenId` to 1 and `baseExtension` to `".json"`. | ||
constructor( | ||
string memory name, | ||
string memory symbol, | ||
address owner | ||
) ERC721(name, symbol) Ownable(owner) { | ||
currentTokenId = 1; | ||
baseExtension = ".json"; | ||
} | ||
|
||
/// @dev Returns true if this contract implements the interface defined by `interfaceId`. See EIP165. | ||
function supportsInterface( | ||
bytes4 interfaceId | ||
) public view override(IERC165, ERC721) returns (bool) { | ||
return | ||
interfaceId == type(IInverseProjectedNft).interfaceId || | ||
interfaceId == bytes4(0x49064906) || | ||
super.supportsInterface(interfaceId); | ||
} | ||
|
||
/// @dev Mints a new token to address `_to`, passing `initialData` to be emitted in the event. | ||
/// Increases the `totalSupply` and `currentTokenId`. | ||
/// Reverts if `_to` is a zero address or if it refers to smart contract but does not implement IERC721Receiver-onERC721Received. | ||
/// Emits the `Minted` event. | ||
function mint(address _to, string calldata initialData) external returns (uint256) { | ||
require(_to != address(0), "InverseProjectedNft: zero receiver address"); | ||
|
||
uint256 tokenId = currentTokenId; | ||
_safeMint(_to, tokenId); | ||
|
||
totalSupply++; | ||
currentTokenId++; | ||
|
||
emit Minted(tokenId, initialData); | ||
return tokenId; | ||
} | ||
|
||
/// @dev Burns token of ID `_tokenId`. Callable only by the owner of the specified token. | ||
/// Reverts if `_tokenId` does not exist. | ||
function burn(uint256 _tokenId) external onlyTokenOwner(_tokenId) { | ||
totalSupply--; | ||
_burn(_tokenId); | ||
} | ||
|
||
/// @dev Returns the `baseURI` of this NFT. | ||
function _baseURI() internal view override returns (string memory) { | ||
return baseURI; | ||
} | ||
|
||
/// @dev Returns the token URI of specified `tokenId` using the default set base URI. | ||
function tokenURI(uint256 tokenId) public view override returns (string memory) { | ||
return tokenURI(tokenId, _baseURI()); | ||
} | ||
|
||
/// @dev Returns the token URI of specified `tokenId` using a custom base URI. | ||
function tokenURI( | ||
uint256 tokenId, | ||
string memory customBaseUri | ||
) public view returns (string memory) { | ||
_requireOwned(tokenId); | ||
string memory URI = bytes(customBaseUri).length > 0 | ||
? string.concat(customBaseUri, tokenId.toString()) | ||
: ""; | ||
return string(abi.encodePacked(URI, baseExtension)); | ||
} | ||
|
||
/// @dev Sets `_URI` as the `baseURI` of the NFT. | ||
/// Callable only by the contract owner. | ||
/// Emits the `SetBaseURI` event. | ||
function setBaseURI(string memory _URI) external onlyOwner { | ||
string memory oldURI = baseURI; | ||
baseURI = _URI; | ||
emit SetBaseURI(oldURI, _URI); | ||
} | ||
|
||
/// @dev Sets `_newBaseExtension` as the `baseExtension` of the NFT. | ||
/// Callable only by the contract owner. | ||
function setBaseExtension(string memory _newBaseExtension) public onlyOwner { | ||
string memory oldBaseExtension = baseExtension; | ||
baseExtension = _newBaseExtension; | ||
emit SetBaseURI(oldBaseExtension, _newBaseExtension); | ||
} | ||
|
||
/// @dev Function that emits an event to notify third-parties (e.g. NFT marketplaces) about | ||
/// an update to consecutive range of tokens. Can be overriden in inheriting contract. | ||
function updateMetadataBatch(uint256 _fromTokenId, uint256 _toTokenId) public virtual { | ||
emit BatchMetadataUpdate(_fromTokenId, _toTokenId); | ||
} | ||
|
||
/// @dev Function that emits an event to notify third-parties (e.g. NFT marketplaces) about | ||
/// an update to a single token. Can be overriden in inheriting contract. | ||
function updateMetadata(uint256 _tokenId) public virtual { | ||
emit MetadataUpdate(_tokenId); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.