Skip to content

Commit

Permalink
feat: add demo scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
idea404 committed Nov 11, 2023
1 parent 87268d7 commit 9dfbd29
Show file tree
Hide file tree
Showing 9 changed files with 202 additions and 16 deletions.
39 changes: 39 additions & 0 deletions demo/pension-fund-eth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// This script will:
// 1. Send ETH to the pension account

import { ethers } from "ethers";
import { Provider, Wallet } from "zksync-web3";
import dotenv from "dotenv";
import { getDeployedContractDetailsFromVars, config } from "../deploy/utils";

dotenv.config();

const NETWORK = "zkSyncLocalnet";
const RPC_URL = config.L2RpcUrl;
const PRIVATE_KEY = config.firstWalletPrivateKey;

async function main() {
const provider = new Provider(RPC_URL);
const mainWallet = new Wallet(PRIVATE_KEY, provider);

// Load the contract address from vars.json
const paAddress = getDeployedContractDetailsFromVars(NETWORK, "PensionAccount").address;
// send 100 ETH to the paAddress
const balance = await provider.getBalance(paAddress);
const tx = await mainWallet.sendTransaction({
to: paAddress,
value: ethers.utils.parseEther("100"),
});
await tx.wait();
const newBalance = await provider.getBalance(paAddress);
console.log(`Sent 100 ETH to Pension Account at: ${paAddress}`);
console.log(`Balance before: ${ethers.utils.formatEther(balance)} ETH`);
console.log(`Balance after: ${ethers.utils.formatEther(newBalance)} ETH`);
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
2 changes: 2 additions & 0 deletions demo/pension-send-eth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// This script will:
// 1. Attempt to send ETH from the pension contract to another address.
7 changes: 3 additions & 4 deletions deploy/deploy-factory.ts → deploy/deploy-aafactory.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { utils, Wallet } from "zksync-web3";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { Deployer } from "@matterlabs/hardhat-zksync-deploy";
import dotenv from "dotenv";
import { config, saveContractToVars } from "./utils";

dotenv.config();

const KEY = process.env.PRIVATE_KEY as string;
const KEY = config.firstWalletPrivateKey;

export default async function (hre: HardhatRuntimeEnvironment) {
// Private key of the account used to deploy
Expand All @@ -29,4 +27,5 @@ export default async function (hre: HardhatRuntimeEnvironment) {
);

console.log(`AA factory address: ${factory.address}`);
saveContractToVars(hre.network.name, "AAFactory", factory.address);
}
21 changes: 11 additions & 10 deletions deploy/deploy-multisig.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import { utils, Wallet, Provider, EIP712Signer, types } from "zksync-web3";
import * as ethers from "ethers";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import dotenv from "dotenv";
import { config, getDeployedContractDetailsFromVars, saveContractToVars } from "./utils";

dotenv.config();

const KEY = process.env.PRIVATE_KEY as string;

// Put the address of your AA factory
const AA_FACTORY_ADDRESS = "0xb3AE0580Fff458E48Eb97EcDaD7Bbe825b78F410";
const KEY = config.firstWalletPrivateKey;

export default async function (hre: HardhatRuntimeEnvironment) {
const provider = new Provider("https://testnet.era.zksync.dev");
// Put the address of your AA factory
const factoryAddress = getDeployedContractDetailsFromVars(
hre.network.name,
"AAFactory"
).address;
const provider = new Provider(hre.network.config.url);
// Private key of the account used to deploy
const wallet = new Wallet(KEY).connect(provider);
const factoryArtifact = await hre.artifacts.readArtifact("AAFactory");

const aaFactory = new ethers.Contract(
AA_FACTORY_ADDRESS,
factoryAddress,
factoryArtifact.abi,
wallet
);
Expand All @@ -40,12 +40,13 @@ export default async function (hre: HardhatRuntimeEnvironment) {
// Getting the address of the deployed contract account
const abiCoder = new ethers.utils.AbiCoder();
const multisigAddress = utils.create2Address(
AA_FACTORY_ADDRESS,
factoryAddress,
await aaFactory.aaBytecodeHash(),
salt,
abiCoder.encode(["address", "address"], [owner1.address, owner2.address])
);
console.log(`Multisig account deployed on address ${multisigAddress}`);
saveContractToVars(hre.network.name, "TwoUserMultisig", aaFactory.address);

console.log("Sending funds to multisig account");
// Send funds to the multisig account we just deployed
Expand Down
31 changes: 31 additions & 0 deletions deploy/deploy-pafactory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { utils, Wallet } from "zksync-web3";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { Deployer } from "@matterlabs/hardhat-zksync-deploy";
import { config, saveContractToVars } from "./utils";

const KEY = config.firstWalletPrivateKey;

export default async function (hre: HardhatRuntimeEnvironment) {
// Private key of the account used to deploy
const wallet = new Wallet(KEY);
const deployer = new Deployer(hre, wallet);
const pensionAccountFactoryArtifact = await deployer.loadArtifact("PensionAccountFactory");
const paArtifact = await deployer.loadArtifact("PensionAccount");

// Getting the bytecodeHash of the account
const bytecodeHash = utils.hashBytecode(paArtifact.bytecode);

const factory = await deployer.deploy(
pensionAccountFactoryArtifact,
[bytecodeHash],
undefined,
[
// Since the factory requires the code of the multisig to be available,
// we should pass it here as well.
paArtifact.bytecode,
]
);

console.log(`Pension Account factory address: ${factory.address}`);
saveContractToVars(hre.network.name, "PensionAccountFactory", factory.address);
}
41 changes: 41 additions & 0 deletions deploy/deploy-pension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { utils, Wallet, Provider } from "zksync-web3";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { config, getDeployedContractDetailsFromVars, createMockAddress, saveContractToVars } from "./utils";
import { ethers } from "ethers";

const KEY = config.firstWalletPrivateKey;
const OWNER_KEY = config.secondWalletPrivateKey;

export default async function (hre: HardhatRuntimeEnvironment) {
const provider = new Provider(hre.network.config.url);
const wallet = new Wallet(KEY, provider);
const walletOwner = new Wallet(OWNER_KEY, provider);
const factoryAddress = getDeployedContractDetailsFromVars(hre.network.name, "PensionAccountFactory").address;
const paFactoryArtifact = await hre.artifacts.readArtifact("PensionAccountFactory");

const paFactory = new ethers.Contract(factoryAddress, paFactoryArtifact.abi, wallet);

// Contract constructor args
const dex = createMockAddress("decentralizedex"); // "0xdex0000000000000000000000000000000000000"
const doge = createMockAddress("dogecoin"); // "0xdoge000000000000000000000000000000000000"
const pepe = createMockAddress("pepecoin"); // "0xpepe000000000000000000000000000000000000"
const shib = createMockAddress("shibainucoin"); // "0xshib0000000000000000000000000000000000000"
const btc = createMockAddress("bitcoin"); // "0xbtc00000000000000000000000000000000000000"

// For the simplicity of the tutorial, we will use zero hash as salt
const salt = ethers.constants.HashZero;

// deploy account with dex and token addresses
const tx = await paFactory.deployPensionAccount(salt, walletOwner.address, dex, doge, pepe, shib, btc, { gasLimit: 10000000 });
await tx.wait();

// Getting the address of the deployed contract account
const abiCoder = new ethers.utils.AbiCoder();
let contractAddress = utils.create2Address(
factoryAddress,
await paFactory.pensionAccountBytecodeHash(),
salt,
abiCoder.encode(["address", "address", "address", "address", "address", "address"], [walletOwner.address, dex, doge, pepe, shib, btc])
);
saveContractToVars(hre.network.name, "PensionAccount", contractAddress);
}
55 changes: 55 additions & 0 deletions deploy/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import fs from "fs";
import path from "path";

const JSON_FILE_PATH = path.join(__dirname, "vars.json");

export function saveContractToVars(network: string, contractName: string, contractAddress: string, varsPath = JSON_FILE_PATH) {
console.log(`Saving ${contractName} to vars.json`);
const config = JSON.parse(fs.readFileSync(varsPath, "utf-8"));

if (!config[network]) {
config[network] = { deployed: [] };
}

const deployedContracts = config[network].deployed;
const existingContractIndex = deployedContracts.findIndex((contract: { name: string; }) => contract.name === contractName);

if (existingContractIndex === -1) {
console.log(`Adding ${contractName} to vars.json`);
deployedContracts.push({
name: contractName,
address: contractAddress,
});
} else {
console.log(`Updating ${contractName} in vars.json`);
deployedContracts[existingContractIndex].address = contractAddress;
}

fs.writeFileSync(varsPath, JSON.stringify(config, null, 2));
}

export function getDeployedContractDetailsFromVars(network: string, contractName: string, varsPath = JSON_FILE_PATH) {
const config = JSON.parse(fs.readFileSync(varsPath, "utf-8"));
const deployedContracts = config[network].deployed;
const existingContract = deployedContracts.find((contract: { name: string; }) => contract.name === contractName);

if (!existingContract) {
throw new Error(`Contract ${contractName} not found in vars.json`);
}

return existingContract;
}

export const config = {
L2RpcUrl: "http://127.0.0.1:8011",
firstWalletPrivateKey: "0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110",
firstWalletAddress: "0x36615Cf349d7F6344891B1e7CA7C72883F5dc049",
secondWalletPrivateKey: "0xac1e735be8536c6534bb4f17f06f6afc73b2b5ba84ac2cfb12f7461b20c0bbe3",
secondWalletAddress: "0xa61464658AfeAf65CccaaFD3a512b69A83B77618",
};

export function createMockAddress(base: string) {
const baseHex = base.replace(/[^0-9A-Fa-f]/g, ''); // Remove non-hex characters
const paddingLength = 40 - baseHex.length; // Calculate padding length
return '0x' + baseHex + '0'.repeat(paddingLength);
}
14 changes: 14 additions & 0 deletions deploy/vars.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"zkSyncLocalnet": {
"deployed": [
{
"name": "PensionAccountFactory",
"address": "0x4B5DF730c2e6b28E17013A1485E5d9BC41Efe021"
},
{
"name": "PensionAccount",
"address": "0x7A4C681d869bfF421d752B696cd8eC6eD6c7EfBa"
}
]
}
}
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
"license": "MIT",
"scripts": {
"test": "hardhat test --network hardhat",
"deploy:factory": "hardhat deploy-zksync --script deploy-factory.ts --network zkSyncTestnet",
"deploy:multisig": "hardhat deploy-zksync --script deploy-multisig.ts --network zkSyncTestnet"
"deploy:aafactory": "hardhat deploy-zksync --script deploy-aafactory.ts --network zkSyncLocalnet",
"deploy:multisig": "hardhat deploy-zksync --script deploy-multisig.ts --network zkSyncLocalnet",
"deploy:pafactory": "hardhat deploy-zksync --script deploy-pafactory.ts --network zkSyncLocalnet",
"deploy:pension": "hardhat deploy-zksync --script deploy-pension.ts --network zkSyncLocalnet",
"demo:fund-pension": "ts-node demo/pension-fund-eth.ts",
"demo:withdraw-pension": "ts-node demo/pension-send-eth.ts"
},
"devDependencies": {
"@types/chai": "^4.3.10",
Expand Down

0 comments on commit 9dfbd29

Please sign in to comment.