Skip to content

Commit

Permalink
Small refactoring + lints
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonD3 committed Feb 2, 2024
1 parent 8fdc2ee commit cf8d5fc
Showing 1 changed file with 154 additions and 153 deletions.
307 changes: 154 additions & 153 deletions l2-contracts/src/updateL2ERC20Metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import { Wallet, ethers, BigNumber } from "ethers";
import * as fs from "fs";
import * as path from "path";
import { Provider } from "zksync-web3";
import { REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT } from "zksync-web3/build/src/utils";
import { getAddressFromEnv, getNumberFromEnv, web3Provider } from "../../l1-contracts/scripts/utils";
import { getNumberFromEnv, web3Provider } from "../../l1-contracts/scripts/utils";
import { Deployer } from "../../l1-contracts/src.ts/deploy";
import { awaitPriorityOps, computeL2Create2Address, create2DeployFromL1, getL1TxInfo } from "./utils";
import { getL1TxInfo } from "./utils";

// From openzeppelin Initializable contract implementation.
const INITIALIZABLE_STORAGE_SLOT = "0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00";
Expand All @@ -18,171 +17,173 @@ const testConfigPath = path.join(process.env.ZKSYNC_HOME as string, "etc/test_co
const ethTestConfig = JSON.parse(fs.readFileSync(`${testConfigPath}/eth.json`, { encoding: "utf-8" }));

async function getReinitializeTokenCalldata(
tokenAddress: string,
newName: string,
newSymbol: string,
ignoreNameGetter: boolean,
ignoreSymbolGetter: boolean,
ignoreDecimalsGetter: boolean,
version?: ethers.BigNumberish
tokenAddress: string,
newName: string,
newSymbol: string,
ignoreNameGetter: boolean,
ignoreSymbolGetter: boolean,
ignoreDecimalsGetter: boolean,
version: ethers.BigNumberish
) {
const l2StandardERC20Artifact = await hre.artifacts.readArtifact("L2StandardERC20");
const l2StandardERC20Artifact = await hre.artifacts.readArtifact("L2StandardERC20");
const l2StandardERC20Interface = new ethers.utils.Interface(l2StandardERC20Artifact.abi);

const availableGetters = {
ignoreName: ignoreNameGetter,
ignoreSymbol: ignoreSymbolGetter,
ignoreDecimals: ignoreDecimalsGetter,
};
console.log("Using the following arguments:");
console.log(`availableGetters = ${JSON.stringify(availableGetters, null, 4)}`);
console.log(`newName = "${newName}"`);
console.log(`newSymbol = "${newSymbol}"`);
console.log(`version = ${version}\n`);

return l2StandardERC20Interface.encodeFunctionData("reinitializeToken", [
availableGetters,
newName,
newSymbol,
version,
]);
}

if (version === null || version === undefined) {
async function getReinitializeTokenTxInfo(
deployer: Deployer,
refundRecipient: string,
gasPrice: BigNumber,
tokenAddress: string,
newName: string,
newSymbol: string,
ignoreNameGetter: boolean,
ignoreSymbolGetter: boolean,
ignoreDecimalsGetter: boolean,
version: ethers.BigNumberish
) {
const l2Calldata = await getReinitializeTokenCalldata(
tokenAddress,
newName,
newSymbol,
ignoreNameGetter,
ignoreSymbolGetter,
ignoreDecimalsGetter,
version
);
return await getL1TxInfo(
deployer,
tokenAddress,
l2Calldata,
refundRecipient,
gasPrice,
priorityTxMaxGasLimit,
provider
);
}

async function main() {
const program = new Command();

program.version("0.1.0").name("update-l2-erc20-metadata");

program
.option("--token-address <upgrades-info>")
.option("--gas-price <gas-price>")
.option("--deployer-private-key <deployer-private-key>")
.option("--refund-recipient <refund-recipient>")
.option("--new-name <new-name>")
.option("--new-symbol <new-symbol>")
.option("--ignore-name-getter")
.option("--ignore-symbol-getter")
.option("--ignore-decimals-getter")
.option("--reinitialization-version <version>")
.action(async (cmd) => {
const gasPrice = cmd.gasPrice
? ethers.utils.parseUnits(cmd.gasPrice, "gwei")
: (await provider.getGasPrice()).mul(3).div(2);
const deployWallet = cmd.deployerPrivateKey
? new Wallet(cmd.deployerPrivateKey, provider)
: Wallet.fromMnemonic(
process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic,
"m/44'/60'/0'/0/1"
).connect(provider);
const deployer = new Deployer({ deployWallet });
const refundRecipient = cmd.refundRecipient ? cmd.refundRecipient : deployWallet.address;
console.log("Gas price: ", ethers.utils.formatUnits(gasPrice, "gwei"));
console.log(
"IMPORTANT: gasPrice that you provide in the transaction should be <= to the one provided to this tool."
);

console.log("Refund recipient: ", refundRecipient);

const tokenAddress = cmd.tokenAddress;
const newName = cmd.newName;
const newSymbol = cmd.newSymbol;
const ignoreNameGetter = cmd.ignoreNameGetter ?? false;
const ignoreSymbolGetter = cmd.ignoreSymbolGetter ?? false;
const ignoreDecimalsGetter = cmd.ignoreDecimalsGetter ?? false;

let version;
if (cmd.reinitializationVersion === undefined) {
const provider = new Provider(process.env.API_WEB3_JSON_RPC_HTTP_URL);
const tokenContract = new ethers.Contract(tokenAddress, l2StandardERC20Artifact.abi, provider);
const initializableStorageValue = BigNumber.from(await provider.getStorageAt(tokenAddress, INITIALIZABLE_STORAGE_SLOT));
const initializableStorageValue = BigNumber.from(
await provider.getStorageAt(tokenAddress, INITIALIZABLE_STORAGE_SLOT)
);

// currently it's saved in the first `uint64` struct field
const initializedValue = initializableStorageValue.mod(BigNumber.from(2).pow(64));
version = initializedValue.add(1);
}

const l2StandardERC20Interface = new ethers.utils.Interface(l2StandardERC20Artifact.abi);

const availableGetters = {
ignoreName: ignoreNameGetter,
ignoreSymbol: ignoreSymbolGetter,
ignoreDecimals: ignoreDecimalsGetter,
};
console.log("Using the following params:");
console.log(`newName = "${newName}"`);
console.log(`newSymbol = "${newSymbol}"`);
console.log(`availableGetters = ${JSON.stringify(availableGetters, null, 4)}`);
console.log(`version = ${version}\n`);

return l2StandardERC20Interface.encodeFunctionData("reinitializeToken", [
availableGetters,
newName,
newSymbol,
version,
]);
}

async function getReinitializeTokenTxInfo(
deployer: Deployer,
refundRecipient: string,
gasPrice: BigNumber,
tokenAddress: string,
newName: string,
newSymbol: string,
ignoreNameGetter: boolean,
ignoreSymbolGetter: boolean,
ignoreDecimalsGetter: boolean,
version?: ethers.BigNumberish
) {
const l2Calldata = await getReinitializeTokenCalldata(
} else {
version = parseInt(cmd.reinitializationVersion);
}

if (newName && ignoreNameGetter) {
console.log("\x1b[31mWarning: ignore name getter flag used while new name is not empty\x1b[0m");
}
if (newSymbol && ignoreSymbolGetter) {
console.log("\x1b[31mWarning: ignore symbol getter flag used while new symbol is not empty\x1b[0m");
}

const governanceCall = await getReinitializeTokenTxInfo(
deployer,
refundRecipient,
gasPrice,
tokenAddress,
newName,
newSymbol,
ignoreNameGetter,
ignoreSymbolGetter,
ignoreDecimalsGetter,
version
);
return await getL1TxInfo(
deployer,
tokenAddress,
l2Calldata,
refundRecipient,
gasPrice,
priorityTxMaxGasLimit,
provider
);
}
);

async function main() {
const program = new Command();

program.version("0.1.0").name("update-l2-erc20-metadata");

program
.option("--token-address <upgrades-info>")
.option("--gas-price <gas-price>")
.option("--deployer-private-key <deployer-private-key>")
.option("--refund-recipient <refund-recipient>")
.option("--new-name <new-name>")
.option("--new-symbol <new-symbol>")
.option("--ignore-name-getter")
.option("--ignore-symbol-getter")
.option("--ignore-decimals-getter")
.option("--reinitialization-version <version>")
.action(async (cmd) => {
const gasPrice = cmd.gasPrice
? ethers.utils.parseUnits(cmd.gasPrice, "gwei")
: (await provider.getGasPrice()).mul(3).div(2);
const deployWallet = cmd.deployerPrivateKey
? new Wallet(cmd.deployerPrivateKey, provider)
: Wallet.fromMnemonic(
process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic,
"m/44'/60'/0'/0/1"
).connect(provider);
const deployer = new Deployer({ deployWallet });
const refundRecipient = cmd.refundRecipient ? cmd.refundRecipient : deployWallet.address;
console.log("Gas price: ", ethers.utils.formatUnits(gasPrice, "gwei"));
console.log(
"IMPORTANT: gasPrice that you provide in the transaction should be <= to the one provided to this tool."
);

console.log("Refund recipient: ", refundRecipient);

const tokenAdress = cmd.tokenAddress;
const newName = cmd.newName;
const newSymbol = cmd.newSymbol;
const ignoreNameGetter = cmd.ignoreNameGetter ?? false;
const ignoreSymbolGetter = cmd.ignoreSymbolGetter ?? false;
const ignoreDecimalsGetter = cmd.ignoreDecimalsGetter ?? false;
const version = cmd.reinitializationVersion ? parseInt(cmd.reinitializationVersion) : undefined;

if (newName && ignoreNameGetter) {
console.log("\x1b[31mWarning: ignore name getter flag used while new name is not empty\x1b[0m");
}
if (newSymbol && ignoreSymbolGetter) {
console.log("\x1b[31mWarning: ignore symbol getter flag used while new symbol is not empty\x1b[0m");
}

const governanceCall = await getReinitializeTokenTxInfo(
deployer,
refundRecipient,
gasPrice,
cmd.tokenAddress,
newName,
newSymbol,
ignoreNameGetter,
ignoreSymbolGetter,
ignoreDecimalsGetter,
version
);

const operation = {
calls: [governanceCall],
predecessor: ethers.constants.HashZero,
salt: ethers.constants.HashZero,
};

console.log("Governance calls: ");
console.log(JSON.stringify(operation, null, 4) + "\n");

const governance = deployer.governanceContract(deployWallet);
const scheduleTransparentCalldata = governance.interface.encodeFunctionData("scheduleTransparent", [
operation,
0,
]);
const executeCalldata = governance.interface.encodeFunctionData("execute", [operation]);

console.log("scheduleTransparentCalldata: ");
console.log(scheduleTransparentCalldata);

console.log("executeCalldata: ");
console.log(executeCalldata);
});

await program.parseAsync(process.argv);
const operation = {
calls: [governanceCall],
predecessor: ethers.constants.HashZero,
salt: ethers.constants.HashZero,
};

console.log("Governance calls: ");
console.log(JSON.stringify(operation, null, 4) + "\n");

const governance = deployer.governanceContract(deployWallet);
const scheduleTransparentCalldata = governance.interface.encodeFunctionData("scheduleTransparent", [
operation,
0,
]);
const executeCalldata = governance.interface.encodeFunctionData("execute", [operation]);

console.log("scheduleTransparentCalldata: ");
console.log(scheduleTransparentCalldata);

console.log("executeCalldata: ");
console.log(executeCalldata);
});

await program.parseAsync(process.argv);
}

main()
.then(() => process.exit(0))
.catch((err) => {
console.error("Error:", err);
process.exit(1);
});
.then(() => process.exit(0))
.catch((err) => {
console.error("Error:", err);
process.exit(1);
});

0 comments on commit cf8d5fc

Please sign in to comment.