Created
July 12, 2023 19:12
-
-
Save developeruche/d95ab311742a72a939887d8544e3e9ca to your computer and use it in GitHub Desktop.
This is the bridge contract
This file contains hidden or 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
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.0; | |
import { | |
ERC721Enumerable | |
} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; | |
import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; | |
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; | |
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; | |
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; | |
import { INahmiiStandardERC721, Existence } from "./INahmiiStandardERC721.sol"; | |
/** | |
* @title NahmiiStandardERC721 | |
* @notice This contract is the remote representation for some token that lives on another network, | |
* typically an Nahmii representation of an Ethereum-based token. Standard reference | |
* implementation that can be extended or modified according to your needs. | |
*/ | |
contract NahmiiStandardERC721 is Ownable, INahmiiStandardERC721, ERC721Enumerable { | |
/** | |
* @inheritdoc INahmiiStandardERC721 | |
*/ | |
uint256 public remoteChainId; | |
/** | |
* @inheritdoc INahmiiStandardERC721 | |
*/ | |
uint256 public layerId; | |
/** | |
* @inheritdoc INahmiiStandardERC721 | |
*/ | |
address public remoteToken; | |
/** | |
* @inheritdoc INahmiiStandardERC721 | |
*/ | |
address public bridge; | |
/** | |
* @inheritdoc INahmiiStandardERC721 | |
*/ | |
Existence public existence; | |
/** | |
* @inheritdoc INahmiiStandardERC721 | |
*/ | |
bool public native; | |
/** | |
* @notice Base token URI for this token. | |
*/ | |
string public baseTokenURI; | |
/** | |
* @param _name ERC721 name. | |
* @param _symbol ERC721 symbol. | |
*/ | |
constructor(string memory _name, string memory _symbol) ERC721(_name, _symbol) {} | |
/** | |
* @notice Modifier that prevents callers other than the bridge or | |
* contract owner from calling the function. | |
*/ | |
modifier verifyCaller(uint256 _tokenId) { | |
if (native == true && (_isEven(_tokenId) == _isEven(layerId))) { | |
require( | |
msg.sender == bridge || msg.sender == owner(), | |
"NahmiiStandardERC721: only bridge or contract owner can call this function" | |
); | |
_; | |
} else { | |
require( | |
msg.sender == bridge, | |
"NahmiiStandardERC721: only bridge can call this function" | |
); | |
_; | |
} | |
} | |
/** | |
* @inheritdoc INahmiiStandardERC721 | |
*/ | |
function initialize( | |
address _bridge, | |
uint256 _remoteChainId, | |
address _remoteToken, | |
Existence _existence, | |
bool _native, | |
uint256 _layerId | |
) external virtual { | |
// State variables initialization check | |
require(bridge == address(0), "NahmiiStandardERC721: bridge must be uninitialized"); | |
// Function parameters check | |
require(_bridge != address(0), "NahmiiStandardERC721: bridge cannot be address(0)"); | |
require(_remoteChainId != 0, "NahmiiStandardERC721: remote chain id cannot be zero"); | |
require( | |
_remoteToken != address(0), | |
"NahmiiStandardERC721: remote token cannot be address(0)" | |
); | |
require(_layerId != 0, "NahmiiStandardERC721: layer id cannot be zero"); | |
remoteChainId = _remoteChainId; | |
remoteToken = _remoteToken; | |
bridge = _bridge; | |
existence = _existence; | |
native = _native; | |
layerId = _layerId; | |
// Creates a base URI in the format specified by EIP-681: | |
// https://eips.ethereum.org/EIPS/eip-681 | |
baseTokenURI = string( | |
abi.encodePacked( | |
"ethereum:", | |
Strings.toHexString(uint160(_remoteToken), 20), | |
"@", | |
Strings.toString(_remoteChainId), | |
"/tokenURI?uint256=" | |
) | |
); | |
} | |
/** | |
* @inheritdoc INahmiiStandardERC721 | |
*/ | |
function safeMint(address _to, uint256 _tokenId) external virtual verifyCaller(_tokenId) { | |
_safeMint(_to, _tokenId); | |
emit Mint(_to, _tokenId); | |
} | |
/** | |
* @inheritdoc INahmiiStandardERC721 | |
*/ | |
function burn(address _from, uint256 _tokenId) external virtual verifyCaller(_tokenId) { | |
_burn(_tokenId); | |
emit Burn(_from, _tokenId); | |
} | |
/** | |
* @notice Checks if a given interface ID is supported by this contract. | |
* | |
* @param _interfaceId The interface ID to check. | |
* | |
* @return True if the interface ID is supported, false otherwise. | |
*/ | |
function supportsInterface(bytes4 _interfaceId) | |
public | |
view | |
virtual | |
override(ERC721Enumerable, IERC165) | |
returns (bool) | |
{ | |
bytes4 iface1 = type(IERC165).interfaceId; | |
bytes4 iface2 = type(INahmiiStandardERC721).interfaceId; | |
return | |
_interfaceId == iface1 || | |
_interfaceId == iface2 || | |
super.supportsInterface(_interfaceId); | |
} | |
/** | |
* @notice Returns the base token URI. | |
* | |
* @return Base token URI. | |
*/ | |
function _baseURI() internal view virtual override returns (string memory) { | |
return baseTokenURI; | |
} | |
/** | |
* @notice Checks that an integer value is even. | |
* | |
* @param _value Unisgned integer value to check | |
* | |
* @return True if integer value is even, false otherwise. | |
*/ | |
function _isEven(uint256 _value) internal pure returns (bool) { | |
return _value % 2 == 0; | |
} | |
} |
This file contains hidden or 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
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.0; | |
import { | |
IERC721Enumerable | |
} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; | |
enum Existence { | |
Transient, | |
Permanent | |
} | |
/** | |
* @title INahmiiStandardERC721 | |
* @notice Interface for contracts that are compatible with the NahmiiStandardERC721 standard. | |
* Tokens that follow this standard can be easily transferred across the ERC721 bridge. | |
*/ | |
interface INahmiiStandardERC721 is IERC721Enumerable { | |
/** | |
* @notice Emitted when a token is minted. | |
* | |
* @param account Address of the account the token was minted to. | |
* @param tokenId Token ID of the minted token. | |
*/ | |
event Mint(address indexed account, uint256 tokenId); | |
/** | |
* @notice Emitted when a token is burned. | |
* | |
* @param account Address of the account the token was burned from. | |
* @param tokenId Token ID of the burned token. | |
*/ | |
event Burn(address indexed account, uint256 tokenId); | |
/** | |
* @notice Chain ID of the chain where the remote token is deployed. | |
*/ | |
function remoteChainId() external view returns (uint256); | |
/** | |
* @notice Address of the token on the remote domain. | |
*/ | |
function remoteToken() external view returns (address); | |
/** | |
* @return Existence status. | |
*/ | |
function existence() external view returns (Existence); | |
/** | |
* @notice Address of the ERC721 bridge on this network. | |
*/ | |
function bridge() external view returns (address); | |
/** | |
* @notice Nature of the ERC721 token on this network. | |
*/ | |
function native() external view returns (bool); | |
/** | |
* @notice Layer of the ERC721 bridge on this network. | |
*/ | |
function layerId() external view returns (uint256); | |
/** | |
* @notice Mints some token ID for a user, checking first that contract recipients | |
* are aware of the ERC721 protocol to prevent tokens from being forever locked. | |
* | |
* @param _to Address of the user to mint the token for. | |
* @param _tokenId Token ID to mint. | |
*/ | |
function safeMint(address _to, uint256 _tokenId) external; | |
/** | |
* @notice Burns a token ID from a user. | |
* | |
* @param _from Address of the user to burn the token from. | |
* @param _tokenId Token ID to burn. | |
*/ | |
function burn(address _from, uint256 _tokenId) external; | |
/** | |
* @notice Initializes an ERC721 token with the provided args | |
* | |
* @param _bridge Address of the bridge on this network. | |
* @param _remoteChainId Chain ID where the remote token is deployed. | |
* @param _remoteToken Address of the corresponding token on the other network. | |
* @param _existence Existence status of the ERC721 token on this network. | |
* @param _native Nature of the ERC721 token on this network. | |
* @param _layerId Layer on which the token will be deployed. | |
*/ | |
function initialize( | |
address _bridge, | |
uint256 _remoteChainId, | |
address _remoteToken, | |
Existence _existence, | |
bool _native, | |
uint256 _layerId | |
) external; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment