[Feat] Precomputed/Counterfactual address for TokenBridge Remote Sender (#678)

* remove reinit function in tokenbridge

* passing tests with removal of setRemoteSender

* remove operational task and dead role reference

* added tokenbridgev1_1 artifact to e2e tests

* adjustments

* fix nonce increment
This commit is contained in:
kyzooghost
2025-02-27 20:14:26 +11:00
committed by GitHub
parent 086c861f0b
commit 62d0d24c57
15 changed files with 1577 additions and 258 deletions

View File

@@ -61,8 +61,6 @@ To deploy the contracts, you will need to run the Bridged Token, Token Bridge, a
You can refer to the following links that describe the usage of these scripts. <br />
- [Bridged Token Deployment Script](./deployment.md#bridgedtoken) <br />
- [Token Bridge Deployment Script](./deployment.md#tokenbridge) <br />
- [Operational Script](./operational.md#setRemoteTokenBridge)
All addresses created will be stored in the deployments folder as a separate file. `./contracts/deployment/<network_name>`

View File

@@ -225,46 +225,3 @@ npx hardhat setVerifierAddress \
<br />
<br />
### setRemoteTokenBridge
<br />
Parameters that should be filled either in .env or passed as CLI arguments:
| Parameter name | Required | Input Value | Description |
| ------------------ | -------- | ---------- | ----------- |
| \**PRIVATE_KEY* | true | key | Network-specific private key used when deploying the contract |
| INFURA_API_KEY | true | key | Infura API Key |
| REMOTE_TOKEN_BRIDGE_ADDRESS | true | address | Token Bridge address deployed on the `--remote-network`. It must be provided as CLI argument using the `--remote-token-bridge-address` flag. If not found, the script will also check .env. variable `TOKEN_BRIDGE_ADDRESS`. If the .env variable doesn't exist, it will also check the `deployments/<remote-network>` folder and try to use that address. Otherwise it will throw an error. |
| TOKEN_BRIDGE_ADDRESS | true | address | Token Bridge address deployed on current network. It must be provided as CLI argument using the `--token-bridge-address` flag. If not found, the script will also check .env. variable `TOKEN_BRIDGE_ADDRESS`. If the .env variable doesn't exist, it will also check the `deployments/<network_name>` folder and try to use that address. Otherwise it will throw an error. |
| --remote-network | true | string | Network name. It must be provided as CLI argument using the `--safe-address` flag otherwise the script will throw an error. |
<br />
<br />
It should be noted that the `--remote-network` and `--network` fields should point to complementary networks.
e.g. `--remote-network linea_sepolia --network sepolia` or vice-versa.
<br />
Base command:
```shell
npx hardhat setRemoteTokenBridge --remote-network sepolia --network linea_sepolia
```
Base command with cli arguments:
```shell
SEPOLIA_PRIVATE_KEY=<key> \
INFURA_API_KEY=<key> \
npx hardhat setRemoteTokenBridge \
--remote-token-bridge-address <address> \
--token-bridge-address <address> \
--remote-network sepolia \
--network linea_sepolia
```
(make sure to replace `<key>` with actual values)
<br />
<br />

View File

@@ -13,7 +13,6 @@ import "./scripts/operational/grantContractRolesTask";
import "./scripts/operational/renounceContractRolesTask";
import "./scripts/operational/setRateLimitTask";
import "./scripts/operational/setVerifierAddressTask";
import "./scripts/operational/setRemoteTokenBridgeTask";
import "./scripts/operational/setMessageServiceOnTokenBridgeTask";
import "solidity-docgen";

View File

@@ -12,7 +12,7 @@ import {
contractName as TokenBridgeContractName,
abi as TokenBridgeAbi,
bytecode as TokenBridgeBytecode,
} from "./dynamic-artifacts/TokenBridgeV1.json";
} from "./dynamic-artifacts/TokenBridgeV1_1.json";
import {
contractName as UpgradeableBeaconContractName,
abi as UpgradeableBeaconAbi,
@@ -58,18 +58,29 @@ async function main() {
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);
let walletNonce;
let remoteDeployerNonce;
if (process.env.TOKEN_BRIDGE_L1 === "true") {
if (!process.env.L1_NONCE) {
walletNonce = await wallet.getNonce();
} else {
walletNonce = parseInt(process.env.L1_NONCE) + ORDERED_NONCE_POST_LINEAROLLUP;
}
walletNonce = await getL1DeployerNonce();
remoteDeployerNonce = await getL2DeployerNonce();
} else {
if (!process.env.L2_NONCE) {
walletNonce = await wallet.getNonce();
walletNonce = await getL2DeployerNonce();
remoteDeployerNonce = await getL1DeployerNonce();
}
async function getL1DeployerNonce(): Promise<number> {
if (!process.env.L1_NONCE) {
return await wallet.getNonce();
} else {
walletNonce = parseInt(process.env.L2_NONCE) + ORDERED_NONCE_POST_L2MESSAGESERVICE;
return parseInt(process.env.L1_NONCE) + ORDERED_NONCE_POST_LINEAROLLUP;
}
}
async function getL2DeployerNonce(): Promise<number> {
if (!process.env.L2_NONCE) {
return await wallet.getNonce();
} else {
return parseInt(process.env.L2_NONCE) + ORDERED_NONCE_POST_L2MESSAGESERVICE;
}
}
@@ -109,10 +120,14 @@ async function main() {
let reservedAddresses = process.env.L2_RESERVED_TOKEN_ADDRESSES
? process.env.L2_RESERVED_TOKEN_ADDRESSES.split(",")
: [];
const remoteSender = ethers.getCreateAddress({
from: process.env.REMOTE_DEPLOYER_ADDRESS || "",
nonce: remoteDeployerNonce + 4,
});
if (process.env.TOKEN_BRIDGE_L1 === "true") {
console.log(
`TOKEN_BRIDGE_L1=${process.env.TOKEN_BRIDGE_L1}. Deploying TokenBridge on L1, using L1_RESERVED_TOKEN_ADDRESSES environment variable`,
`TOKEN_BRIDGE_L1=${process.env.TOKEN_BRIDGE_L1}. Deploying TokenBridge on L1, using L1_RESERVED_TOKEN_ADDRESSES environment variable and remoteSender=${remoteSender}`,
);
deployingChainMessageService = lineaRollupAddress;
reservedAddresses = process.env.L1_RESERVED_TOKEN_ADDRESSES
@@ -120,7 +135,7 @@ async function main() {
: [];
} else {
console.log(
`TOKEN_BRIDGE_L1=${process.env.TOKEN_BRIDGE_L1}. Deploying TokenBridge on L2, using L2_RESERVED_TOKEN_ADDRESSES environment variable`,
`TOKEN_BRIDGE_L1=${process.env.TOKEN_BRIDGE_L1}. Deploying TokenBridge on L2, using L2_RESERVED_TOKEN_ADDRESSES environment variable and remoteSender=${remoteSender}`,
);
}
@@ -131,6 +146,7 @@ async function main() {
tokenBeacon: beaconProxyAddress,
sourceChainId: chainId,
targetChainId: remoteChainId,
remoteSender: remoteSender,
reservedTokens: reservedAddresses,
roleAddresses,
pauseTypeRoles,

File diff suppressed because one or more lines are too long

View File

@@ -1,61 +0,0 @@
// import { ethers, network, upgrades } from "hardhat";
import { task } from "hardhat/config";
import { TokenBridge } from "../../typechain-types";
import { getTaskCliOrEnvValue } from "../../common/helpers/environmentHelper";
import { getDeployedContractOnNetwork } from "../../common/helpers/readAddress";
/*
*******************************************************************************************
1. Deploy the TokenBridge and BridgedToken contracts on both networks and get the addresses
2. Run this script on both addresses with the correct variables set.
*******************************************************************************************
SEPOLIA_PRIVATE_KEY=<key> \
INFURA_API_KEY=<key> \
npx hardhat setRemoteTokenBridge \
--remote-token-bridge-address <address> \
--token-bridge-address <address> \
--remote-network sepolia \
--network linea_sepolia
*******************************************************************************************
*/
task("setRemoteTokenBridge", "Sets the remoteTokenBridge address.")
.addOptionalParam("remoteTokenBridgeAddress")
.addOptionalParam("tokenBridgeAddress")
.addParam("remoteNetwork")
.setAction(async (taskArgs, hre) => {
const ethers = hre.ethers;
let remoteTokenBridgeAddress = getTaskCliOrEnvValue(
taskArgs,
"remoteTokenBridgeAddress",
"REMOTE_TOKEN_BRIDGE_ADDRESS",
);
let tokenBridgeAddress = getTaskCliOrEnvValue(taskArgs, "tokenBridgeAddress", "TOKEN_BRIDGE_ADDRESS");
if (!tokenBridgeAddress) {
tokenBridgeAddress = await getDeployedContractOnNetwork(hre.network.name, "TokenBridge");
if (!tokenBridgeAddress) {
throw "tokenBridgeAddress is undefined";
}
}
if (!remoteTokenBridgeAddress) {
remoteTokenBridgeAddress = await getDeployedContractOnNetwork(taskArgs.remoteNetwork, "TokenBridge");
if (!remoteTokenBridgeAddress) {
throw "remoteTokenBridgeAddress is undefined";
}
}
const chainId = (await ethers.provider.getNetwork()).chainId;
console.log(`Current network's chainId is ${chainId}`);
const TokenBridge = await ethers.getContractFactory("TokenBridge");
const tokenBridge = TokenBridge.attach(tokenBridgeAddress) as TokenBridge;
const tx = await tokenBridge.setRemoteTokenBridge(remoteTokenBridgeAddress);
await tx.wait();
console.log(`RemoteTokenBridge set for the TokenBridge on: ${hre.network.name}`);
});

View File

@@ -19,6 +19,12 @@ export async function deployTokenBridge(messageServiceAddress: string, verbose =
// Deploying TokenBridges
const TokenBridgeFactory = await ethers.getContractFactory("TokenBridge");
await upgrades.deployImplementation(TokenBridgeFactory);
// When upgrade OZ contracts to 5.X and Hardhat Upgrades plugin to 3.X, remove the line below (as deployProxyAdmin will be deprecated)
await upgrades.deployProxyAdmin(owner);
// deployProxy will implicitly do deployImplementation and deployProxyAdmin if they have not previously been done.
// This will mess with our nonce calculation for the counterfactual address of l2TokenBridge, so we prevent these steps from being handled implicitly in deployProxy.
const l1TokenBridge = (await upgrades.deployProxy(TokenBridgeFactory, [
{
defaultAdmin: owner.address,
@@ -27,6 +33,7 @@ export async function deployTokenBridge(messageServiceAddress: string, verbose =
sourceChainId: chainIds[0],
targetChainId: chainIds[1],
reservedTokens: [],
remoteSender: ethers.getCreateAddress({ from: await owner.getAddress(), nonce: 1 + (await owner.getNonce()) }), // Counterfactual address of l2TokenBridge
roleAddresses: roleAddresses,
pauseTypeRoles: pauseTypeRoles,
unpauseTypeRoles: unpauseTypeRoles,
@@ -45,6 +52,7 @@ export async function deployTokenBridge(messageServiceAddress: string, verbose =
sourceChainId: chainIds[1],
targetChainId: chainIds[0],
reservedTokens: [],
remoteSender: await l1TokenBridge.getAddress(),
roleAddresses: roleAddresses,
pauseTypeRoles: pauseTypeRoles,
unpauseTypeRoles: unpauseTypeRoles,
@@ -55,13 +63,6 @@ export async function deployTokenBridge(messageServiceAddress: string, verbose =
console.log("L2TokenBridge deployed, at address:", await l2TokenBridge.getAddress());
}
// Setting reciprocal addresses of TokenBridges
await l1TokenBridge.setRemoteTokenBridge(await l2TokenBridge.getAddress());
await l2TokenBridge.setRemoteTokenBridge(await l1TokenBridge.getAddress());
if (verbose) {
console.log("Reciprocal addresses of TokenBridges set");
}
if (verbose) {
console.log("Deployment finished");
}

View File

@@ -39,14 +39,11 @@ contract TokenBridge is
using SafeERC20Upgradeable for IERC20Upgradeable;
/// @dev This is the ABI version and not the reinitialize version.
string public constant CONTRACT_VERSION = "1.0";
string public constant CONTRACT_VERSION = "1.1";
/// @notice Role used for setting the message service address.
bytes32 public constant SET_MESSAGE_SERVICE_ROLE = keccak256("SET_MESSAGE_SERVICE_ROLE");
/// @notice Role used for setting the remote token bridge address.
bytes32 public constant SET_REMOTE_TOKENBRIDGE_ROLE = keccak256("SET_REMOTE_TOKENBRIDGE_ROLE");
/// @notice Role used for setting a reserved token address.
bytes32 public constant SET_RESERVED_TOKEN_ROLE = keccak256("SET_RESERVED_TOKEN_ROLE");
@@ -171,6 +168,7 @@ contract TokenBridge is
tokenBeacon = _initializationData.tokenBeacon;
if (_initializationData.sourceChainId == _initializationData.targetChainId) revert SourceChainSameAsTargetChain();
_setRemoteSender(_initializationData.remoteSender);
sourceChainId = _initializationData.sourceChainId;
targetChainId = _initializationData.targetChainId;
@@ -186,38 +184,6 @@ contract TokenBridge is
}
}
/**
* @notice Sets permissions for a list of addresses and their roles as well as initialises the PauseManager pauseType:role mappings.
* @dev This function is a reinitializer and can only be called once per version. Should be called using an upgradeAndCall transaction to the ProxyAdmin.
* @param _defaultAdmin The default admin account's address.
* @param _roleAddresses The list of addresses and roles to assign permissions to.
* @param _pauseTypeRoles The list of pause types to associate with roles.
* @param _unpauseTypeRoles The list of unpause types to associate with roles.
*/
function reinitializePauseTypesAndPermissions(
address _defaultAdmin,
RoleAddress[] calldata _roleAddresses,
PauseTypeRole[] calldata _pauseTypeRoles,
PauseTypeRole[] calldata _unpauseTypeRoles
) external reinitializer(2) {
if (_defaultAdmin == address(0)) {
revert ZeroAddressNotAllowed();
}
_grantRole(DEFAULT_ADMIN_ROLE, _defaultAdmin);
assembly {
/// @dev Wiping the storage slot 101 of _owner as it is replaced by AccessControl and there is now the ERC165 __gap in its place.
sstore(101, 0)
/// @dev Wiping the storage slot 213 of _status as it is replaced by ReentrancyGuardUpgradeable at slot 1.
sstore(213, 0)
}
__ReentrancyGuard_init();
__PauseManager_init(_pauseTypeRoles, _unpauseTypeRoles);
__Permissions_init(_roleAddresses);
}
/**
* @notice This function is the single entry point to bridge tokens to the
* other chain, both for native and already bridged tokens. You can use it
@@ -416,17 +382,6 @@ contract TokenBridge is
}
}
/**
* @dev Sets the address of the remote token bridge. Can only be called once.
* @dev SET_REMOTE_TOKENBRIDGE_ROLE is required to execute.
* @param _remoteTokenBridge The address of the remote token bridge to be set.
*/
function setRemoteTokenBridge(address _remoteTokenBridge) external onlyRole(SET_REMOTE_TOKENBRIDGE_ROLE) {
if (remoteSender != EMPTY) revert RemoteTokenBridgeAlreadySet(remoteSender);
_setRemoteSender(_remoteTokenBridge);
emit RemoteTokenBridgeSet(_remoteTokenBridge, msg.sender);
}
/**
* @dev Deploy a new EC20 contract for bridged token using a beacon proxy pattern.
* To adapt to future requirements, Linea can update the implementation of

View File

@@ -17,6 +17,7 @@ interface ITokenBridge {
* @param tokenBeacon The address of the tokenBeacon.
* @param sourceChainId The source chain id of the current layer.
* @param targetChainId The target chaind id of the targeted layer.
* @param remoteSender Address of the remote token bridge.
* @param reservedTokens The list of reserved tokens to be set.
* @param roleAddresses The list of addresses and roles to assign permissions to.
* @param pauseTypeRoles The list of pause types to associate with roles.
@@ -28,6 +29,7 @@ interface ITokenBridge {
address tokenBeacon;
uint256 sourceChainId;
uint256 targetChainId;
address remoteSender;
address[] reservedTokens;
IPermissionsManager.RoleAddress[] roleAddresses;
IPauseManager.PauseTypeRole[] pauseTypeRoles;
@@ -294,12 +296,6 @@ interface ITokenBridge {
*/
function setReserved(address _token) external;
/**
* @dev Sets the address of the remote token bridge. Can only be called once.
* @param _remoteTokenBridge The address of the remote token bridge to be set.
*/
function setRemoteTokenBridge(address _remoteTokenBridge) external;
/**
* @dev Removes a token from the reserved list.
* @param _token The address of the token to be removed from the reserved list.

View File

@@ -5,7 +5,7 @@ import { deployTokenBridgeWithMockMessaging } from "../../../../scripts/tokenBri
import { deployTokens } from "../../../../scripts/tokenBridge/test/deployTokens";
import { BridgedToken, TestTokenBridge } from "../../../../typechain-types";
import { getPermitData } from "./utils/permitHelper";
import { Contract, ZeroAddress } from "ethers";
import { Contract } from "ethers";
import {
ADDRESS_ZERO,
COMPLETE_TOKEN_BRIDGING_PAUSE_TYPE,
@@ -15,7 +15,6 @@ import {
REMOVE_RESERVED_TOKEN_ROLE,
SET_CUSTOM_CONTRACT_ROLE,
SET_MESSAGE_SERVICE_ROLE,
SET_REMOTE_TOKENBRIDGE_ROLE,
SET_RESERVED_TOKEN_ROLE,
UNPAUSE_INITIATE_TOKEN_BRIDGING_ROLE,
pauseTypeRoles,
@@ -80,6 +79,7 @@ describe("TokenBridge", function () {
tokenBeacon: PLACEHOLDER_ADDRESS,
sourceChainId: chainIds[0],
targetChainId: chainIds[1],
remoteSender: PLACEHOLDER_ADDRESS,
reservedTokens: [],
roleAddresses: [],
pauseTypeRoles: [],
@@ -102,6 +102,7 @@ describe("TokenBridge", function () {
tokenBeacon: PLACEHOLDER_ADDRESS,
sourceChainId: chainIds[0],
targetChainId: chainIds[1],
remoteSender: PLACEHOLDER_ADDRESS,
reservedTokens: [],
roleAddresses: [],
pauseTypeRoles: [],
@@ -120,6 +121,7 @@ describe("TokenBridge", function () {
tokenBeacon: ADDRESS_ZERO,
sourceChainId: chainIds[0],
targetChainId: chainIds[1],
remoteSender: PLACEHOLDER_ADDRESS,
reservedTokens: [],
roleAddresses: [],
pauseTypeRoles: [],
@@ -138,6 +140,26 @@ describe("TokenBridge", function () {
tokenBeacon: PLACEHOLDER_ADDRESS,
sourceChainId: chainIds[0],
targetChainId: chainIds[1],
remoteSender: ADDRESS_ZERO,
reservedTokens: [],
roleAddresses: [],
pauseTypeRoles: [],
unpauseTypeRoles: [],
},
]),
"ZeroAddressNotAllowed",
);
await expectRevertWithCustomError(
TokenBridge,
upgrades.deployProxy(TokenBridge, [
{
defaultAdmin: PLACEHOLDER_ADDRESS,
messageService: PLACEHOLDER_ADDRESS,
tokenBeacon: PLACEHOLDER_ADDRESS,
sourceChainId: chainIds[0],
targetChainId: chainIds[1],
remoteSender: PLACEHOLDER_ADDRESS,
reservedTokens: [PLACEHOLDER_ADDRESS, ADDRESS_ZERO],
roleAddresses: [
{ addressWithRole: user.address, role: SET_RESERVED_TOKEN_ROLE },
@@ -159,6 +181,7 @@ describe("TokenBridge", function () {
tokenBeacon: PLACEHOLDER_ADDRESS,
sourceChainId: chainIds[0],
targetChainId: chainIds[1],
remoteSender: PLACEHOLDER_ADDRESS,
reservedTokens: [PLACEHOLDER_ADDRESS],
roleAddresses: [
{ addressWithRole: ADDRESS_ZERO, role: SET_RESERVED_TOKEN_ROLE },
@@ -185,6 +208,7 @@ describe("TokenBridge", function () {
tokenBeacon: PLACEHOLDER_ADDRESS,
sourceChainId: 0,
targetChainId: chainIds[1],
remoteSender: PLACEHOLDER_ADDRESS,
reservedTokens: [],
roleAddresses: [],
pauseTypeRoles: [],
@@ -203,6 +227,7 @@ describe("TokenBridge", function () {
tokenBeacon: PLACEHOLDER_ADDRESS,
sourceChainId: chainIds[0],
targetChainId: 0,
remoteSender: PLACEHOLDER_ADDRESS,
reservedTokens: [],
roleAddresses: [],
pauseTypeRoles: [],
@@ -226,6 +251,7 @@ describe("TokenBridge", function () {
tokenBeacon: PLACEHOLDER_ADDRESS,
sourceChainId: chainIds[0],
targetChainId: chainIds[0],
remoteSender: PLACEHOLDER_ADDRESS,
reservedTokens: [],
roleAddresses: [],
pauseTypeRoles: [],
@@ -249,6 +275,7 @@ describe("TokenBridge", function () {
tokenBeacon: PLACEHOLDER_ADDRESS,
sourceChainId: chainIds[0],
targetChainId: chainIds[1],
remoteSender: PLACEHOLDER_ADDRESS,
reservedTokens: [],
roleAddresses: [],
pauseTypeRoles: [],
@@ -268,6 +295,7 @@ describe("TokenBridge", function () {
tokenBeacon: PLACEHOLDER_ADDRESS,
sourceChainId: SupportedChainIds.SEPOLIA,
targetChainId: SupportedChainIds.LINEA_TESTNET,
remoteSender: PLACEHOLDER_ADDRESS,
reservedTokens: [],
roleAddresses: [],
pauseTypeRoles: [],
@@ -740,6 +768,7 @@ describe("TokenBridge", function () {
sourceChainId: chainIds[0],
targetChainId: chainIds[1],
reservedTokens: [CUSTOM_ADDRESS],
remoteSender: PLACEHOLDER_ADDRESS,
roleAddresses: [],
pauseTypeRoles: pauseTypeRoles,
unpauseTypeRoles: unpauseTypeRoles,
@@ -945,24 +974,6 @@ describe("TokenBridge", function () {
});
});
describe("setRemoteTokenBridge", function () {
it("Should revert if remoteTokenBridge has not been initialized", async function () {
const { owner, l1TokenBridge } = await loadFixture(deployContractsFixture);
await expect(
l1TokenBridge.connect(owner).setRemoteTokenBridge(await l1TokenBridge.getAddress()),
).to.revertedWithCustomError(l1TokenBridge, "RemoteTokenBridgeAlreadySet");
});
it("Should revert if called by non-owner", async function () {
const { user, l1TokenBridge } = await loadFixture(deployContractsFixture);
await expectRevertWithReason(
l1TokenBridge.connect(user).setRemoteTokenBridge(await l1TokenBridge.getAddress()),
buildAccessErrorMessage(user, SET_REMOTE_TOKENBRIDGE_ROLE),
);
});
});
describe("setDeployed", function () {
it("Should revert if not called by the messageService", async function () {
const { user, l1TokenBridge } = await loadFixture(deployContractsFixture);
@@ -989,42 +1000,6 @@ describe("TokenBridge", function () {
});
});
describe("reinitializePauseTypesAndPermissions", function () {
it("Should revert with ZeroAddressNotAllowed when addressWithRole is zero address in reinitializePauseTypesAndPermissions", async function () {
const { owner, l1TokenBridge } = await loadFixture(deployContractsFixture);
const roleAddresses = [{ addressWithRole: ZeroAddress, role: SET_RESERVED_TOKEN_ROLE }];
await expectRevertWithCustomError(
l1TokenBridge,
l1TokenBridge.reinitializePauseTypesAndPermissions(
owner.address,
roleAddresses,
pauseTypeRoles,
unpauseTypeRoles,
),
"ZeroAddressNotAllowed",
);
});
it("Should revert with ZeroAddressNotAllowed when default admin is zero address", async function () {
const { owner, l1TokenBridge } = await loadFixture(deployContractsFixture);
const roleAddresses = [{ addressWithRole: owner.address, role: SET_RESERVED_TOKEN_ROLE }];
await expectRevertWithCustomError(
l1TokenBridge,
l1TokenBridge.reinitializePauseTypesAndPermissions(
ZeroAddress, //owner is set to zeroaddress
roleAddresses,
pauseTypeRoles,
unpauseTypeRoles,
),
"ZeroAddressNotAllowed",
);
});
});
describe("TokenBridge Upgradeable Tests", function () {
it.skip("Should deploy and manually upgrade the TokenBridge contract", async function () {
// Deploy V1 from artifact

View File

@@ -56,7 +56,6 @@ export const UNPAUSE_COMPLETE_TOKEN_BRIDGING_ROLE = generateKeccak256(
["UNPAUSE_COMPLETE_TOKEN_BRIDGING_ROLE"],
true,
);
export const SET_REMOTE_TOKENBRIDGE_ROLE = generateKeccak256(["string"], ["SET_REMOTE_TOKENBRIDGE_ROLE"], true);
export const SET_RESERVED_TOKEN_ROLE = generateKeccak256(["string"], ["SET_RESERVED_TOKEN_ROLE"], true);
export const REMOVE_RESERVED_TOKEN_ROLE = generateKeccak256(["string"], ["REMOVE_RESERVED_TOKEN_ROLE"], true);
export const SET_CUSTOM_CONTRACT_ROLE = generateKeccak256(["string"], ["SET_CUSTOM_CONTRACT_ROLE"], true);

View File

@@ -3,7 +3,7 @@ import assert from "assert";
import { AbstractSigner, BaseContract, BlockTag, TransactionReceipt, TransactionRequest, Wallet, ethers } from "ethers";
import path from "path";
import { exec } from "child_process";
import { L2MessageServiceV1 as L2MessageService, TokenBridgeV1 as TokenBridge, LineaRollupV6 } from "../typechain";
import { L2MessageServiceV1 as L2MessageService, TokenBridgeV1_1 as TokenBridge, LineaRollupV6 } from "../typechain";
import {
PayableOverrides,
TypedContractEvent,

View File

@@ -26,18 +26,10 @@ export default async (): Promise<void> => {
};
async function configureOnceOffPrerequisities() {
const l1AccountManager = config.getL1AccountManager();
const l2AccountManager = config.getL2AccountManager();
const account = config.getL1AccountManager().whaleAccount(0);
const l2Account = config.getL2AccountManager().whaleAccount(0);
const lineaRollup = config.getLineaRollupContract(account);
const l1TokenBridge = config.getL1TokenBridgeContract();
const l2TokenBridge = config.getL2TokenBridgeContract();
const l1SecurityCouncil = l1AccountManager.whaleAccount(3);
const l2SecurityCouncil = l2AccountManager.whaleAccount(3);
const [l1AccountNonce, l2AccountNonce] = await Promise.all([account.getNonce(), l2Account.getNonce()]);
const fee = etherToWei("3");
@@ -58,16 +50,6 @@ async function configureOnceOffPrerequisities() {
nonce: l1AccountNonce + 1,
})
).wait(),
(
await l1TokenBridge.connect(l1SecurityCouncil).setRemoteTokenBridge(await l2TokenBridge.getAddress(), {
gasPrice: ethers.parseUnits("300", "gwei"),
})
).wait(),
(
await l2TokenBridge.connect(l2SecurityCouncil).setRemoteTokenBridge(await l1TokenBridge.getAddress(), {
gasPrice: ethers.parseUnits("300", "gwei"),
})
).wait(),
]);
logger.info(`L1 Dummy contract deployed. address=${await dummyContract.getAddress()}`);

View File

@@ -17,8 +17,8 @@ import {
TestContract__factory,
TestERC20,
TestERC20__factory,
TokenBridgeV1 as TokenBridge,
TokenBridgeV1__factory as TokenBridge__factory,
TokenBridgeV1_1 as TokenBridge,
TokenBridgeV1_1__factory as TokenBridge__factory,
} from "../../typechain";
import { AccountManager } from "./accounts/account-manager";

View File

@@ -48,26 +48,28 @@ deploy-token-bridge-l1:
# WARNING: FOR LOCAL DEV ONLY - DO NOT REUSE THESE KEYS ELSEWHERE
cd contracts/; \
PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
REMOTE_DEPLOYER_ADDRESS=0x1B9AbEeC3215D8AdE8a33607f2cF0f4F60e5F0D0 \
RPC_URL=http:\\localhost:8445/ \
REMOTE_CHAIN_ID=1337 \
TOKEN_BRIDGE_L1=true \
L1_TOKEN_BRIDGE_SECURITY_COUNCIL=0x90F79bf6EB2c4f870365E785982E1f101E93b906 \
L2MESSAGESERVICE_ADDRESS=0xe537D669CA013d86EBeF1D64e40fC74CADC91987 \
LINEA_ROLLUP_ADDRESS=0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 \
npx ts-node local-deployments-artifacts/deployBridgedTokenAndTokenBridgeV1.ts
npx ts-node local-deployments-artifacts/deployBridgedTokenAndTokenBridgeV1_1.ts
deploy-token-bridge-l2:
# WARNING: FOR LOCAL DEV ONLY - DO NOT REUSE THESE KEYS ELSEWHERE
cd contracts/; \
SAVE_ADDRESS=true \
PRIVATE_KEY=0x1dd171cec7e2995408b5513004e8207fe88d6820aeff0d82463b3e41df251aae \
REMOTE_DEPLOYER_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 \
RPC_URL=http:\\localhost:8545/ \
REMOTE_CHAIN_ID=31648428 \
TOKEN_BRIDGE_L1=false \
L2_TOKEN_BRIDGE_SECURITY_COUNCIL=0xf17f52151EbEF6C7334FAD080c5704D77216b732 \
L2MESSAGESERVICE_ADDRESS=0xe537D669CA013d86EBeF1D64e40fC74CADC91987 \
LINEA_ROLLUP_ADDRESS=0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 \
npx ts-node local-deployments-artifacts/deployBridgedTokenAndTokenBridgeV1.ts
npx ts-node local-deployments-artifacts/deployBridgedTokenAndTokenBridgeV1_1.ts
deploy-l1-test-erc20:
# WARNING: FOR LOCAL DEV ONLY - DO NOT REUSE THESE KEYS ELSEWHERE