From 2110a23f816eda6a119c3659fc06f126b8d8a499 Mon Sep 17 00:00:00 2001 From: StefanIliev545 Date: Wed, 9 Oct 2024 21:40:06 +0300 Subject: [PATCH] Added a deployment script. --- .../testnet/layer2/002_deploy_zen_base.ts | 56 ++++++++++++++++ contracts/src/zen/ZenTestnet.sol | 66 +++++++++++++++++++ tools/walletextension/rpcapi/net_api.go | 7 +- 3 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 contracts/deployment_scripts/testnet/layer2/002_deploy_zen_base.ts create mode 100644 contracts/src/zen/ZenTestnet.sol diff --git a/contracts/deployment_scripts/testnet/layer2/002_deploy_zen_base.ts b/contracts/deployment_scripts/testnet/layer2/002_deploy_zen_base.ts new file mode 100644 index 0000000000..5942e10d60 --- /dev/null +++ b/contracts/deployment_scripts/testnet/layer2/002_deploy_zen_base.ts @@ -0,0 +1,56 @@ +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import {DeployFunction} from 'hardhat-deploy/types'; +import { Receipt } from 'hardhat-deploy/dist/types'; +import { network } from 'hardhat'; + +/* + This script deploys the ZenTestnet contract on the l2 and whitelists it. +*/ + + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const l2Network = hre; + + const l2Accounts = await l2Network.getNamedAccounts(); + + const networkConfig = await l2Network.network.provider.request({ + method: "net_config", + }); + + console.log(`net-cfg: ${JSON.stringify(networkConfig, null, " ")}`); + + const zenTestnet = await l2Network.deployments.deploy("ZenTestnet", { + from: l2Accounts.deployer, + log: true, + args: [], + proxy: { + proxyContract: "OpenZeppelinTransparentProxy", + execute: { + init: { + methodName: "initialize", + args: [networkConfig["TransactionPostProcessorAddress"]] + } + } + } + }); + console.log(`ZenBase deployed at ${zenTestnet.address}`); + + const signer = await l2Network.ethers.getSigner(l2Accounts.deployer); + const transactionPostProcessor = await l2Network.ethers.getContractAt( + 'TransactionPostProcessor', + networkConfig["TransactionPostProcessorAddress"], + signer + ); + + // TODO: add callback with the security epic when we add the EOA config and all the rules for access + // to system contracts + /* + const receipt = await transactionPostProcessor.addOnBlockEndCallback(zenTestnet.address); + if (receipt.status !== 1) { + throw new Error("Failed to register Zen token as a system callback"); + } + console.log(`Callback added at ${receipt.transactionHash}`); */ +} +export default func; +func.tags = ['ZenBase', 'ZenBase_deploy']; +func.dependencies = ['EthereumBridge']; diff --git a/contracts/src/zen/ZenTestnet.sol b/contracts/src/zen/ZenTestnet.sol new file mode 100644 index 0000000000..3c7a4cd259 --- /dev/null +++ b/contracts/src/zen/ZenTestnet.sol @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: Apache 2 +pragma solidity ^0.8.0; + +/* +// Import OpenZeppelin Contracts +import "../system/TransactionDecoder.sol"; +import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; + +*/ + +import "../system/OnBlockEndCallback.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; +import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; + + + + +interface ITransactionDecoder { + function recoverSender(Structs.Transaction calldata txData) external view returns (address sender); +} + +/** + * @title ZenBase + * @dev ERC20 Token with minting functionality. + */ +contract ZenTestnet is Initializable, OnBlockEndCallback, ERC20Upgradeable, OwnableUpgradeable { + using Structs for Structs.Transaction; + + event TransactionProcessed(address sender, uint256 amount); + /** + * @dev Constructor that gives msg.sender all of existing tokens. + * You can customize the initial supply as needed. + */ + constructor() { + _disableInitializers(); + } + + function initialize(address transactionPostProcessor) external initializer { + require(transactionPostProcessor != address(0), "Invalid transaction analyzer address"); + __ERC20_init("Zen", "ZEN"); + __Ownable_init(msg.sender); + _caller = transactionPostProcessor; + } + + + address private _caller; + + modifier onlyCaller() { + require(msg.sender == _caller, "Caller: caller is not the designated address"); + _; + } + + function onBlockEnd(Structs.Transaction[] calldata transactions) external onlyCaller { + if (transactions.length == 0) { + revert("No transactions to convert"); + } + // Implement custom logic here + for (uint256 i=0; i