From b5395c58db422ed37952b0bc54c40b4f8d6e3a66 Mon Sep 17 00:00:00 2001 From: zkbenny Date: Fri, 12 Apr 2024 20:29:17 +0800 Subject: [PATCH] add zklink token --- contracts/dev-contracts/ZkLinkToken.sol | 37 +++++++++++++++ hardhat.config.js | 1 + script/deploy_log_name.js | 12 +++++ script/deploy_zklink_token.js | 61 +++++++++++++++++++++++++ 4 files changed, 111 insertions(+) create mode 100644 contracts/dev-contracts/ZkLinkToken.sol create mode 100644 script/deploy_zklink_token.js diff --git a/contracts/dev-contracts/ZkLinkToken.sol b/contracts/dev-contracts/ZkLinkToken.sol new file mode 100644 index 0000000..07e6132 --- /dev/null +++ b/contracts/dev-contracts/ZkLinkToken.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 + +pragma solidity ^0.8.0; + +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; +import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; +import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol"; +import {ERC20CappedUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20CappedUpgradeable.sol"; + +contract ZkLinkToken is + OwnableUpgradeable, + UUPSUpgradeable, + ERC20Upgradeable, + ERC20PermitUpgradeable, + ERC20CappedUpgradeable +{ + function initialize() external initializer { + __Ownable_init(); + __UUPSUpgradeable_init(); + __ERC20_init("ZKLink", "ZKL"); + __ERC20Permit_init("ZKLink"); + __ERC20Capped_init(1000000000000000000000000000); + } + + function _authorizeUpgrade(address newImplementation) internal override onlyOwner { + // can only called by owner + } + + function mint(address account, uint256 amount) external onlyOwner { + _mint(account, amount); + } + + function _mint(address account, uint256 amount) internal override(ERC20CappedUpgradeable, ERC20Upgradeable) { + ERC20CappedUpgradeable._mint(account, amount); + } +} diff --git a/hardhat.config.js b/hardhat.config.js index 6d01963..d03d352 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -8,6 +8,7 @@ require('./script/deploy_eth_gateway'); require('./script/deploy_erc20_bridge'); require('./script/deploy_governance'); require('./script/deploy_linea_l2_governance'); +require('./script/deploy_zklink_token'); const BaseConfig = require('./hardhat.base.config'); diff --git a/script/deploy_log_name.js b/script/deploy_log_name.js index f1ac348..cef26ec 100644 --- a/script/deploy_log_name.js +++ b/script/deploy_log_name.js @@ -41,6 +41,13 @@ const DEPLOY_LOG_GOVERNANCE_VERIFIED = 'governanceVerified'; // consumed in deploy_linea_l2_governance.js const DEPLOY_LINEA_L2_GOVERNANCE_LOG_PREFIX = 'deploy_linea_l2_governance'; +// consumed in deploy_zklink_token.js +const DEPLOY_ZKLINK_TOKEN_LOG_PREFIX = 'deploy_zklink_token'; +const DEPLOY_LOG_ZKLINK_TOKEN_PROXY = 'zkLinkTokenProxy'; +const DEPLOY_LOG_ZKLINK_TOKEN_TARGET = 'zkLinkTokenTarget'; +const DEPLOY_LOG_ZKLINK_TOKEN_PROXY_VERIFIED = 'zkLinkTokenProxyVerified'; +const DEPLOY_LOG_ZKLINK_TOKEN_TARGET_VERIFIED = 'zkLinkTokenTargetVerified'; + module.exports = { DEPLOY_ZKLINK_LOG_PREFIX, DEPLOY_LOG_DEPLOYER, @@ -73,4 +80,9 @@ module.exports = { DEPLOY_LOG_GOVERNANCE, DEPLOY_LOG_GOVERNANCE_VERIFIED, DEPLOY_LINEA_L2_GOVERNANCE_LOG_PREFIX, + DEPLOY_ZKLINK_TOKEN_LOG_PREFIX, + DEPLOY_LOG_ZKLINK_TOKEN_PROXY, + DEPLOY_LOG_ZKLINK_TOKEN_TARGET, + DEPLOY_LOG_ZKLINK_TOKEN_PROXY_VERIFIED, + DEPLOY_LOG_ZKLINK_TOKEN_TARGET_VERIFIED, }; diff --git a/script/deploy_zklink_token.js b/script/deploy_zklink_token.js new file mode 100644 index 0000000..c04918e --- /dev/null +++ b/script/deploy_zklink_token.js @@ -0,0 +1,61 @@ +const fs = require('fs'); +const { getImplementationAddress } = require('@openzeppelin/upgrades-core'); +const { verifyContractCode, createOrGetDeployLog, ChainContractDeployer, getDeployTx } = require('./utils'); +const logName = require('./deploy_log_name'); +const { task, types } = require('hardhat/config'); + +task('deployZkLinkToken', 'Deploy zkLink token') + .addOptionalParam('skipVerify', 'Skip verify', false, types.boolean) + .setAction(async (taskArgs, hardhat) => { + let skipVerify = taskArgs.skipVerify; + console.log('skip verify contracts?', skipVerify); + + const contractDeployer = new ChainContractDeployer(hardhat); + await contractDeployer.init(); + const deployerWallet = contractDeployer.deployerWallet; + + const { deployLogPath, deployLog } = createOrGetDeployLog(logName.DEPLOY_ZKLINK_TOKEN_LOG_PREFIX); + deployLog[logName.DEPLOY_LOG_GOVERNOR] = deployerWallet.address; + fs.writeFileSync(deployLogPath, JSON.stringify(deployLog, null, 2)); + + // deploy zkLink token + let zkLinkTokenAddr; + if (!(logName.DEPLOY_LOG_ZKLINK_TOKEN_PROXY in deployLog)) { + console.log('deploy zkLink token...'); + const contract = await contractDeployer.deployProxy('ZkLinkToken', [], []); + const transaction = await getDeployTx(contract); + zkLinkTokenAddr = await contract.getAddress(); + deployLog[logName.DEPLOY_LOG_ZKLINK_TOKEN_PROXY] = zkLinkTokenAddr; + deployLog[logName.DEPLOY_LOG_DEPLOY_TX_HASH] = transaction.hash; + deployLog[logName.DEPLOY_LOG_DEPLOY_BLOCK_NUMBER] = transaction.blockNumber; + fs.writeFileSync(deployLogPath, JSON.stringify(deployLog, null, 2)); + } else { + zkLinkTokenAddr = deployLog[logName.DEPLOY_LOG_ZKLINK_TOKEN_PROXY]; + } + console.log('zkLinkToken', zkLinkTokenAddr); + + let zkLinkTokenTargetAddr; + if (!(logName.DEPLOY_LOG_ZKLINK_TOKEN_TARGET in deployLog)) { + console.log('get zkLink token target...'); + zkLinkTokenTargetAddr = await getImplementationAddress(hardhat.ethers.provider, zkLinkTokenAddr); + deployLog[logName.DEPLOY_LOG_ZKLINK_TOKEN_TARGET] = zkLinkTokenTargetAddr; + fs.writeFileSync(deployLogPath, JSON.stringify(deployLog, null, 2)); + } else { + zkLinkTokenTargetAddr = deployLog[logName.DEPLOY_LOG_ZKLINK_TOKEN_TARGET]; + } + console.log('zkLink token target', zkLinkTokenTargetAddr); + + // verify target contract + if (!(logName.DEPLOY_LOG_ZKLINK_TOKEN_TARGET_VERIFIED in deployLog) && !skipVerify) { + await verifyContractCode(hardhat, zkLinkTokenTargetAddr, []); + deployLog[logName.DEPLOY_LOG_ZKLINK_TOKEN_TARGET_VERIFIED] = true; + fs.writeFileSync(deployLogPath, JSON.stringify(deployLog, null, 2)); + } + + // verify proxy contract + if (!(logName.DEPLOY_LOG_ZKLINK_TOKEN_PROXY_VERIFIED in deployLog) && !skipVerify) { + await verifyContractCode(hardhat, zkLinkTokenAddr, []); + deployLog[logName.DEPLOY_LOG_ZKLINK_TOKEN_PROXY_VERIFIED] = true; + fs.writeFileSync(deployLogPath, JSON.stringify(deployLog, null, 2)); + } + });