diff --git a/contracts/nft/contracts/evm/UniversalNFT.sol b/contracts/nft/contracts/evm/UniversalNFT.sol index 8d37f7b..9fa8868 100644 --- a/contracts/nft/contracts/evm/UniversalNFT.sol +++ b/contracts/nft/contracts/evm/UniversalNFT.sol @@ -11,16 +11,18 @@ import {ERC721URIStorageUpgradeable} from "@openzeppelin/contracts-upgradeable/t import {ERC721BurnableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; +import {ERC721PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721PausableUpgradeable.sol"; import "../shared/UniversalNFTEvents.sol"; contract UniversalNFT is Initializable, ERC721Upgradeable, - ERC721EnumerableUpgradeable, ERC721URIStorageUpgradeable, - ERC721BurnableUpgradeable, + ERC721EnumerableUpgradeable, + ERC721PausableUpgradeable, OwnableUpgradeable, + ERC721BurnableUpgradeable, UUPSUpgradeable, UniversalNFTEvents { @@ -74,7 +76,10 @@ contract UniversalNFT is emit SetUniversal(contractAddress); } - function safeMint(address to, string memory uri) public onlyOwner { + function safeMint( + address to, + string memory uri + ) public whenNotPaused onlyOwner { uint256 hash = uint256( keccak256( abi.encodePacked(address(this), block.number, _nextTokenId++) @@ -92,7 +97,7 @@ contract UniversalNFT is uint256 tokenId, address receiver, address destination - ) external payable { + ) external payable whenNotPaused { if (receiver == address(0)) revert InvalidAddress(); string memory uri = tokenURI(tokenId); @@ -171,7 +176,11 @@ contract UniversalNFT is address auth ) internal - override(ERC721Upgradeable, ERC721EnumerableUpgradeable) + override( + ERC721Upgradeable, + ERC721EnumerableUpgradeable, + ERC721PausableUpgradeable + ) returns (address) { return super._update(to, tokenId, auth); @@ -214,5 +223,13 @@ contract UniversalNFT is address newImplementation ) internal override onlyOwner {} + function pause() public onlyOwner { + _pause(); + } + + function unpause() public onlyOwner { + _unpause(); + } + receive() external payable {} } diff --git a/contracts/nft/contracts/zetachain/UniversalNFT.sol b/contracts/nft/contracts/zetachain/UniversalNFT.sol index c0b9db8..7b3e142 100644 --- a/contracts/nft/contracts/zetachain/UniversalNFT.sol +++ b/contracts/nft/contracts/zetachain/UniversalNFT.sol @@ -8,11 +8,12 @@ import "@zetachain/protocol-contracts/contracts/zevm/interfaces/IWZETA.sol"; import "@zetachain/protocol-contracts/contracts/zevm/GatewayZEVM.sol"; import {SwapHelperLib} from "@zetachain/toolkit/contracts/SwapHelperLib.sol"; import {SystemContract} from "@zetachain/toolkit/contracts/SystemContract.sol"; -import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.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 {ERC721BurnableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721BurnableUpgradeable.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"; @@ -21,10 +22,11 @@ import "../shared/UniversalNFTEvents.sol"; contract UniversalNFT is Initializable, ERC721Upgradeable, - ERC721EnumerableUpgradeable, ERC721URIStorageUpgradeable, - ERC721BurnableUpgradeable, + ERC721EnumerableUpgradeable, + ERC721PausableUpgradeable, OwnableUpgradeable, + ERC721BurnableUpgradeable, UniversalContract, UUPSUpgradeable, UniversalNFTEvents @@ -93,7 +95,7 @@ contract UniversalNFT is uint256 tokenId, address receiver, address destination - ) public payable { + ) public payable whenNotPaused { if (msg.value == 0) revert ZeroMsgValue(); if (receiver == address(0)) revert InvalidAddress(); string memory uri = tokenURI(tokenId); @@ -153,7 +155,10 @@ contract UniversalNFT is emit TokenTransfer(receiver, destination, tokenId, uri); } - function safeMint(address to, string memory uri) public onlyOwner { + function safeMint( + address to, + string memory uri + ) public onlyOwner whenNotPaused { uint256 hash = uint256( keccak256( abi.encodePacked(address(this), block.number, _nextTokenId++) @@ -239,7 +244,11 @@ contract UniversalNFT is address auth ) internal - override(ERC721Upgradeable, ERC721EnumerableUpgradeable) + override( + ERC721Upgradeable, + ERC721EnumerableUpgradeable, + ERC721PausableUpgradeable + ) returns (address) { return super._update(to, tokenId, auth); @@ -282,5 +291,13 @@ contract UniversalNFT is address newImplementation ) internal override onlyOwner {} + function pause() public onlyOwner { + _pause(); + } + + function unpause() public onlyOwner { + _unpause(); + } + receive() external payable {} } diff --git a/contracts/token/contracts/evm/UniversalToken.sol b/contracts/token/contracts/evm/UniversalToken.sol index 736ab9b..9608be5 100644 --- a/contracts/token/contracts/evm/UniversalToken.sol +++ b/contracts/token/contracts/evm/UniversalToken.sol @@ -4,6 +4,10 @@ pragma solidity 0.8.26; import "@zetachain/protocol-contracts/contracts/evm/GatewayEVM.sol"; import {RevertContext} from "@zetachain/protocol-contracts/contracts/Revert.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 {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.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"; import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; @@ -15,7 +19,9 @@ contract UniversalToken is Initializable, ERC20Upgradeable, ERC20BurnableUpgradeable, + ERC20PausableUpgradeable, OwnableUpgradeable, + ERC20PermitUpgradeable, UUPSUpgradeable, UniversalTokenEvents { @@ -65,7 +71,7 @@ contract UniversalToken is emit SetUniversal(contractAddress); } - function mint(address to, uint256 amount) public onlyOwner { + function mint(address to, uint256 amount) public onlyOwner whenNotPaused { _mint(to, amount); } @@ -73,7 +79,7 @@ contract UniversalToken is address destination, address receiver, uint256 amount - ) external payable { + ) external payable whenNotPaused { if (receiver == address(0)) revert InvalidAddress(); _burn(msg.sender, amount); @@ -140,5 +146,21 @@ contract UniversalToken is address newImplementation ) internal override onlyOwner {} + function pause() public onlyOwner { + _pause(); + } + + function unpause() public onlyOwner { + _unpause(); + } + + function _update( + address from, + address to, + uint256 value + ) internal override(ERC20Upgradeable, ERC20PausableUpgradeable) { + super._update(from, to, value); + } + receive() external payable {} } diff --git a/contracts/token/contracts/zetachain/UniversalToken.sol b/contracts/token/contracts/zetachain/UniversalToken.sol index 9c8ad45..b5ed54f 100644 --- a/contracts/token/contracts/zetachain/UniversalToken.sol +++ b/contracts/token/contracts/zetachain/UniversalToken.sol @@ -6,8 +6,11 @@ import "@zetachain/protocol-contracts/contracts/zevm/interfaces/UniversalContrac 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 {SystemContract} from "@zetachain/toolkit/contracts/SystemContract.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 {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.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"; import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; @@ -19,7 +22,9 @@ contract UniversalToken is Initializable, ERC20Upgradeable, ERC20BurnableUpgradeable, + ERC20PausableUpgradeable, OwnableUpgradeable, + ERC20PermitUpgradeable, UUPSUpgradeable, UniversalContract, UniversalTokenEvents @@ -87,7 +92,7 @@ contract UniversalToken is address destination, address receiver, uint256 amount - ) public payable { + ) public payable whenNotPaused { if (msg.value == 0) revert ZeroMsgValue(); if (receiver == address(0)) revert InvalidAddress(); _burn(msg.sender, amount); @@ -140,7 +145,7 @@ contract UniversalToken is emit TokenTransfer(destination, receiver, amount); } - function mint(address to, uint256 amount) public onlyOwner { + function mint(address to, uint256 amount) public onlyOwner whenNotPaused { _mint(to, amount); } @@ -200,9 +205,27 @@ contract UniversalToken is emit TokenTransferReverted(sender, amount); } + function pause() public onlyOwner { + _pause(); + } + + function unpause() public onlyOwner { + _unpause(); + } + function _authorizeUpgrade( address newImplementation ) internal override onlyOwner {} receive() external payable {} + + // 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/contracts/token/hardhat.config.ts b/contracts/token/hardhat.config.ts index 493dc7d..32b68ca 100644 --- a/contracts/token/hardhat.config.ts +++ b/contracts/token/hardhat.config.ts @@ -17,7 +17,19 @@ const config: HardhatUserConfig = { networks: { ...getHardhatConfigNetworks(), }, - solidity: "0.8.26", + solidity: { + compilers: [ + { + settings: { + optimizer: { + enabled: true, + runs: 1000, + }, + }, + version: "0.8.26", + }, + ], + }, }; export default config;