From b55123822e28376470c1c58ad8645aa190349994 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 18 Dec 2024 11:55:37 +0300 Subject: [PATCH 1/4] fix: make contracts pausable --- contracts/nft/contracts/evm/UniversalNFT.sol | 25 ++++++++++++++--- .../nft/contracts/zetachain/UniversalNFT.sol | 26 +++++++++++++----- .../token/contracts/evm/UniversalToken.sol | 24 ++++++++++++++++- .../contracts/zetachain/UniversalToken.sol | 27 +++++++++++++++++-- 4 files changed, 90 insertions(+), 12 deletions(-) diff --git a/contracts/nft/contracts/evm/UniversalNFT.sol b/contracts/nft/contracts/evm/UniversalNFT.sol index 6f68cae..3174e6f 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/Events.sol"; contract UniversalNFT is Initializable, ERC721Upgradeable, - ERC721EnumerableUpgradeable, ERC721URIStorageUpgradeable, - ERC721BurnableUpgradeable, + ERC721EnumerableUpgradeable, + ERC721PausableUpgradeable, OwnableUpgradeable, + ERC721BurnableUpgradeable, UUPSUpgradeable, Events { @@ -62,6 +64,11 @@ contract UniversalNFT is gateway = GatewayEVM(gatewayAddress); } + function setGasLimit(uint256 gas) external onlyOwner { + if (gas <= 0) revert InvalidGasLimit(); + gasLimitAmount = gas; + } + function setUniversal(address contractAddress) external onlyOwner { if (contractAddress == address(0)) revert InvalidAddress(); universal = contractAddress; @@ -169,7 +176,11 @@ contract UniversalNFT is address auth ) internal - override(ERC721Upgradeable, ERC721EnumerableUpgradeable) + override( + ERC721Upgradeable, + ERC721EnumerableUpgradeable, + ERC721PausableUpgradeable + ) returns (address) { return super._update(to, tokenId, auth); @@ -211,4 +222,12 @@ contract UniversalNFT is function _authorizeUpgrade( address newImplementation ) internal override onlyOwner {} + + function pause() public onlyOwner { + _pause(); + } + + function unpause() public onlyOwner { + _unpause(); + } } diff --git a/contracts/nft/contracts/zetachain/UniversalNFT.sol b/contracts/nft/contracts/zetachain/UniversalNFT.sol index de0ba5e..89ef1e0 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,12 +22,13 @@ import "../shared/Events.sol"; contract UniversalNFT is Initializable, ERC721Upgradeable, - ERC721EnumerableUpgradeable, ERC721URIStorageUpgradeable, - ERC721BurnableUpgradeable, + ERC721EnumerableUpgradeable, + ERC721PausableUpgradeable, OwnableUpgradeable, - UniversalContract, + ERC721BurnableUpgradeable, UUPSUpgradeable, + UniversalContract, Events { GatewayZEVM public gateway; @@ -230,7 +232,11 @@ contract UniversalNFT is address auth ) internal - override(ERC721Upgradeable, ERC721EnumerableUpgradeable) + override( + ERC721Upgradeable, + ERC721EnumerableUpgradeable, + ERC721PausableUpgradeable + ) returns (address) { return super._update(to, tokenId, auth); @@ -273,5 +279,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 348499c..8d74dc1 100644 --- a/contracts/token/contracts/evm/UniversalToken.sol +++ b/contracts/token/contracts/evm/UniversalToken.sol @@ -4,16 +4,22 @@ 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"; import "../shared/Events.sol"; contract UniversalToken is Initializable, ERC20Upgradeable, + ERC20BurnableUpgradeable, + ERC20PausableUpgradeable, OwnableUpgradeable, + ERC20PermitUpgradeable, UUPSUpgradeable, Events { @@ -135,4 +141,20 @@ contract UniversalToken is function _authorizeUpgrade( 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); + } } diff --git a/contracts/token/contracts/zetachain/UniversalToken.sol b/contracts/token/contracts/zetachain/UniversalToken.sol index 0868549..cd510f9 100644 --- a/contracts/token/contracts/zetachain/UniversalToken.sol +++ b/contracts/token/contracts/zetachain/UniversalToken.sol @@ -6,18 +6,23 @@ 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"; import "../shared/Events.sol"; contract UniversalToken is Initializable, ERC20Upgradeable, + ERC20BurnableUpgradeable, + ERC20PausableUpgradeable, OwnableUpgradeable, + ERC20PermitUpgradeable, UUPSUpgradeable, UniversalContract, Events @@ -190,9 +195,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); + } } From c21cb75cc0fc3d64205bf14190d0e0ff8c16419e Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Wed, 18 Dec 2024 12:04:53 +0300 Subject: [PATCH 2/4] token: add optimizer --- contracts/token/hardhat.config.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) 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; From 5c78c29a1b311569fcc764a86ad8edae8a734e52 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Thu, 19 Dec 2024 20:53:47 +0300 Subject: [PATCH 3/4] UniversalContract --- contracts/nft/contracts/zetachain/UniversalNFT.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/nft/contracts/zetachain/UniversalNFT.sol b/contracts/nft/contracts/zetachain/UniversalNFT.sol index 6391aca..f66b469 100644 --- a/contracts/nft/contracts/zetachain/UniversalNFT.sol +++ b/contracts/nft/contracts/zetachain/UniversalNFT.sol @@ -27,6 +27,7 @@ contract UniversalNFT is ERC721PausableUpgradeable, OwnableUpgradeable, ERC721BurnableUpgradeable, + UniversalContract, UUPSUpgradeable, UniversalNFTEvents { From 7148cd71e639ed2bf539589829f194d7988b4c78 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Thu, 19 Dec 2024 20:56:24 +0300 Subject: [PATCH 4/4] whenNotPaused --- contracts/nft/contracts/evm/UniversalNFT.sol | 7 +++++-- contracts/nft/contracts/zetachain/UniversalNFT.sol | 7 +++++-- contracts/token/contracts/evm/UniversalToken.sol | 4 ++-- contracts/token/contracts/zetachain/UniversalToken.sol | 4 ++-- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/contracts/nft/contracts/evm/UniversalNFT.sol b/contracts/nft/contracts/evm/UniversalNFT.sol index 1df6ebc..9fa8868 100644 --- a/contracts/nft/contracts/evm/UniversalNFT.sol +++ b/contracts/nft/contracts/evm/UniversalNFT.sol @@ -76,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++) @@ -94,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); diff --git a/contracts/nft/contracts/zetachain/UniversalNFT.sol b/contracts/nft/contracts/zetachain/UniversalNFT.sol index f66b469..7b3e142 100644 --- a/contracts/nft/contracts/zetachain/UniversalNFT.sol +++ b/contracts/nft/contracts/zetachain/UniversalNFT.sol @@ -95,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); @@ -155,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++) diff --git a/contracts/token/contracts/evm/UniversalToken.sol b/contracts/token/contracts/evm/UniversalToken.sol index ba51f59..9608be5 100644 --- a/contracts/token/contracts/evm/UniversalToken.sol +++ b/contracts/token/contracts/evm/UniversalToken.sol @@ -71,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); } @@ -79,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); diff --git a/contracts/token/contracts/zetachain/UniversalToken.sol b/contracts/token/contracts/zetachain/UniversalToken.sol index c3205af..b5ed54f 100644 --- a/contracts/token/contracts/zetachain/UniversalToken.sol +++ b/contracts/token/contracts/zetachain/UniversalToken.sol @@ -92,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); @@ -145,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); }