diff --git a/examples/nft/contracts/EVMUniversalNFT.sol b/examples/nft/contracts/EVMUniversalNFT.sol index c46df4ee..079d81f0 100644 --- a/examples/nft/contracts/EVMUniversalNFT.sol +++ b/examples/nft/contracts/EVMUniversalNFT.sol @@ -1,6 +1,135 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; +pragma solidity 0.8.26; -import "@zetachain/standard-contracts/contracts/nft/contracts/evm/UniversalNFT.sol"; +import {ERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; +import {ERC721BurnableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol"; +import {ERC721EnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; +import {ERC721PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721PausableUpgradeable.sol"; +import {ERC721URIStorageUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol"; +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -contract EVMUniversalNFT is UniversalNFT {} +// Import UniversalNFTCore for universal NFT functionality +import "@zetachain/standard-contracts/contracts/nft/contracts/evm/UniversalNFTCore.sol"; + +contract EVMUniversalNFT is + Initializable, + ERC721Upgradeable, + ERC721EnumerableUpgradeable, + ERC721URIStorageUpgradeable, + ERC721PausableUpgradeable, + OwnableUpgradeable, + ERC721BurnableUpgradeable, + UUPSUpgradeable, + UniversalNFTCore // Add UniversalNFTCore for universal features +{ + uint256 private _nextTokenId; // Track next token ID for minting + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + function initialize( + address initialOwner, + string memory name, + string memory symbol, + address payable gatewayAddress, // Include EVM gateway address + uint256 gas // Set gas limit for universal NFT transfers + ) public initializer { + __ERC721_init(name, symbol); + __ERC721Enumerable_init(); + __ERC721URIStorage_init(); + __ERC721Pausable_init(); + __Ownable_init(initialOwner); + __ERC721Burnable_init(); + __UUPSUpgradeable_init(); + __UniversalNFTCore_init(gatewayAddress, address(this), gas); // Initialize universal NFT core + } + + function safeMint( + address to, + string memory uri + ) public onlyOwner whenNotPaused { + // Generate globally unique token ID, feel free to supply your own logic + uint256 hash = uint256( + keccak256( + abi.encodePacked(address(this), block.number, _nextTokenId++) + ) + ); + + uint256 tokenId = hash & 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; + + _safeMint(to, tokenId); + _setTokenURI(tokenId, uri); + } + + function pause() public onlyOwner { + _pause(); + } + + function unpause() public onlyOwner { + _unpause(); + } + + function _authorizeUpgrade( + address newImplementation + ) internal override onlyOwner {} + + // The following functions are overrides required by Solidity. + + function _update( + address to, + uint256 tokenId, + address auth + ) + internal + override( + ERC721Upgradeable, + ERC721EnumerableUpgradeable, + ERC721PausableUpgradeable + ) + returns (address) + { + return super._update(to, tokenId, auth); + } + + function _increaseBalance( + address account, + uint128 value + ) internal override(ERC721Upgradeable, ERC721EnumerableUpgradeable) { + super._increaseBalance(account, value); + } + + function tokenURI( + uint256 tokenId + ) + public + view + override( + ERC721Upgradeable, + ERC721URIStorageUpgradeable, + UniversalNFTCore // Include UniversalNFTCore for URI overrides + ) + returns (string memory) + { + return super.tokenURI(tokenId); + } + + function supportsInterface( + bytes4 interfaceId + ) + public + view + override( + ERC721Upgradeable, + ERC721EnumerableUpgradeable, + ERC721URIStorageUpgradeable, + UniversalNFTCore // Include UniversalNFTCore for interface overrides + ) + returns (bool) + { + return super.supportsInterface(interfaceId); + } +} diff --git a/examples/nft/contracts/ZetaChainUniversalNFT.sol b/examples/nft/contracts/ZetaChainUniversalNFT.sol index b4a89b61..83cd918d 100644 --- a/examples/nft/contracts/ZetaChainUniversalNFT.sol +++ b/examples/nft/contracts/ZetaChainUniversalNFT.sol @@ -1,6 +1,138 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.26; -import "@zetachain/standard-contracts/contracts/nft/contracts/zetachain/UniversalNFT.sol"; +import {ERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; +import {ERC721BurnableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol"; +import {ERC721EnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; +import {ERC721PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721PausableUpgradeable.sol"; +import {ERC721URIStorageUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol"; +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -contract ZetaChainUniversalNFT is UniversalNFT {} +// Import UniversalNFTCore for universal NFT functionality +import "@zetachain/standard-contracts/contracts/nft/contracts/zetachain/UniversalNFTCore.sol"; + +contract ZetaChainUniversalNFT is + Initializable, // Allows upgradeable contract initialization + ERC721Upgradeable, // Base ERC721 implementation + ERC721URIStorageUpgradeable, // Enables metadata URI storage + ERC721EnumerableUpgradeable, // Provides enumerable token support + ERC721PausableUpgradeable, // Allows pausing token operations + OwnableUpgradeable, // Restricts access to owner-only functions + ERC721BurnableUpgradeable, // Adds burnable functionality + UUPSUpgradeable, // Supports upgradeable proxy pattern + UniversalNFTCore // Custom core for additional logic +{ + uint256 private _nextTokenId; // Track next token ID for minting + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + function initialize( + address initialOwner, + string memory name, + string memory symbol, + address payable gatewayAddress, // Include EVM gateway address + uint256 gas, // Set gas limit for universal NFT calls + address uniswapRouterAddress // Uniswap v2 router address for gas token swaps + ) public initializer { + __ERC721_init(name, symbol); + __ERC721Enumerable_init(); + __ERC721URIStorage_init(); + __ERC721Pausable_init(); + __Ownable_init(initialOwner); + __ERC721Burnable_init(); + __UUPSUpgradeable_init(); + __UniversalNFTCore_init(gatewayAddress, gas, uniswapRouterAddress); // Initialize universal NFT core + } + + function safeMint( + address to, + string memory uri + ) public onlyOwner whenNotPaused { + // Generate globally unique token ID, feel free to supply your own logic + uint256 hash = uint256( + keccak256( + abi.encodePacked(address(this), block.number, _nextTokenId++) + ) + ); + + uint256 tokenId = hash & 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; + + _safeMint(to, tokenId); + _setTokenURI(tokenId, uri); + } + + // The following functions are overrides required by Solidity. + + function _update( + address to, + uint256 tokenId, + address auth + ) + internal + override( + ERC721Upgradeable, + ERC721EnumerableUpgradeable, + ERC721PausableUpgradeable + ) + returns (address) + { + return super._update(to, tokenId, auth); + } + + function _increaseBalance( + address account, + uint128 value + ) internal override(ERC721Upgradeable, ERC721EnumerableUpgradeable) { + super._increaseBalance(account, value); + } + + function tokenURI( + uint256 tokenId + ) + public + view + override( + ERC721Upgradeable, + ERC721URIStorageUpgradeable, + UniversalNFTCore // Include UniversalNFTCore for URI overrides + ) + returns (string memory) + { + return super.tokenURI(tokenId); + } + + function supportsInterface( + bytes4 interfaceId + ) + public + view + override( + ERC721Upgradeable, + ERC721EnumerableUpgradeable, + ERC721URIStorageUpgradeable, + UniversalNFTCore // Include UniversalNFTCore for interface overrides + ) + returns (bool) + { + return super.supportsInterface(interfaceId); + } + + function _authorizeUpgrade( + address newImplementation + ) internal override onlyOwner {} + + function pause() public onlyOwner { + _pause(); + } + + function unpause() public onlyOwner { + _unpause(); + } + + receive() external payable {} // Receive ZETA to pay for gas +} diff --git a/examples/token/contracts/EVMUniversalToken.sol b/examples/token/contracts/EVMUniversalToken.sol index 2c29b559..6d21b3db 100644 --- a/examples/token/contracts/EVMUniversalToken.sol +++ b/examples/token/contracts/EVMUniversalToken.sol @@ -1,6 +1,68 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; +pragma solidity 0.8.26; -import "@zetachain/standard-contracts/contracts/token/contracts/evm/UniversalToken.sol"; +import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; +import {ERC20BurnableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol"; +import {ERC20PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol"; +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -contract EVMUniversalToken is UniversalToken {} +// Import the Universal Token core contract +import "@zetachain/standard-contracts/contracts/token/contracts/evm/UniversalTokenCore.sol"; + +contract EVMUniversalToken is + Initializable, + ERC20Upgradeable, + ERC20BurnableUpgradeable, + ERC20PausableUpgradeable, + OwnableUpgradeable, + UUPSUpgradeable, + UniversalTokenCore // Inherit the Universal Token core contract +{ + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + function initialize( + address initialOwner, + string memory name, + string memory symbol, + address payable gatewayAddress, // Include EVM gateway address + uint256 gas // Set gas limit for universal Token transfers + ) public initializer { + __ERC20_init(name, symbol); + __ERC20Burnable_init(); + __ERC20Pausable_init(); + __Ownable_init(initialOwner); + __UUPSUpgradeable_init(); + __UniversalTokenCore_init(gatewayAddress, address(this), gas); // Initialize the Universal Token core contract + } + + function pause() public onlyOwner { + _pause(); + } + + function unpause() public onlyOwner { + _unpause(); + } + + function mint(address to, uint256 amount) public onlyOwner { + _mint(to, amount); + } + + function _authorizeUpgrade( + address newImplementation + ) internal override onlyOwner {} + + // The following functions are overrides required by Solidity. + + function _update( + address from, + address to, + uint256 value + ) internal override(ERC20Upgradeable, ERC20PausableUpgradeable) { + super._update(from, to, value); + } +} diff --git a/examples/token/contracts/ZetaChainUniversalToken.sol b/examples/token/contracts/ZetaChainUniversalToken.sol index cea96281..89b3b7a4 100644 --- a/examples/token/contracts/ZetaChainUniversalToken.sol +++ b/examples/token/contracts/ZetaChainUniversalToken.sol @@ -1,6 +1,76 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; +pragma solidity 0.8.26; -import "@zetachain/standard-contracts/contracts/token/contracts/zetachain/UniversalToken.sol"; +import {RevertContext, RevertOptions} from "@zetachain/protocol-contracts/contracts/Revert.sol"; +import "@zetachain/protocol-contracts/contracts/zevm/interfaces/UniversalContract.sol"; +import "@zetachain/protocol-contracts/contracts/zevm/interfaces/IGatewayZEVM.sol"; +import "@zetachain/protocol-contracts/contracts/zevm/GatewayZEVM.sol"; +import {SwapHelperLib} from "@zetachain/toolkit/contracts/SwapHelperLib.sol"; +import {ERC20BurnableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol"; +import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; +import {ERC20PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PausableUpgradeable.sol"; +import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; -contract ZetaChainUniversalToken is UniversalToken {} +// Import the Universal Token core contract +import "@zetachain/standard-contracts/contracts/token/contracts/zetachain/UniversalTokenCore.sol"; + +contract ZetaChainUniversalToken is + Initializable, + ERC20Upgradeable, + ERC20BurnableUpgradeable, + ERC20PausableUpgradeable, + OwnableUpgradeable, + UUPSUpgradeable, + UniversalTokenCore // Inherit the Universal Token core contract +{ + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + _disableInitializers(); + } + + function initialize( + address initialOwner, + string memory name, + string memory symbol, + address payable gatewayAddress, // Include EVM gateway address + uint256 gas, // Set gas limit for universal Token transfers + address uniswapRouterAddress // Uniswap v2 router address for gas token swaps + ) public initializer { + __ERC20_init(name, symbol); + __ERC20Burnable_init(); + __ERC20Pausable_init(); + __Ownable_init(initialOwner); + __UUPSUpgradeable_init(); + __UniversalTokenCore_init(gatewayAddress, gas, uniswapRouterAddress); // Initialize the Universal Token core contract + } + + function pause() public onlyOwner { + _pause(); + } + + function unpause() public onlyOwner { + _unpause(); + } + + function mint(address to, uint256 amount) public onlyOwner { + _mint(to, amount); + } + + function _authorizeUpgrade( + address newImplementation + ) internal override onlyOwner {} + + // The following functions are overrides required by Solidity. + + function _update( + address from, + address to, + uint256 value + ) internal override(ERC20Upgradeable, ERC20PausableUpgradeable) { + super._update(from, to, value); + } + + receive() external payable {} +}