Skip to content

Commit

Permalink
update contracts to use solpp for native token, update scripts to use…
Browse files Browse the repository at this point in the history
… token config
  • Loading branch information
Santiago Pittella authored and Santiago Pittella committed Feb 20, 2024
1 parent d821011 commit ade9735
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 34 deletions.
30 changes: 18 additions & 12 deletions l1-contracts/contracts/bridge/L1ERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -87,18 +87,26 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, ReentrancyGuard {
uint256 _deployBridgeProxyFee,
uint256 _amount
) external payable reentrancyGuardInitializer {
bool nativeErc20 = _amount != 0;

require(_l2TokenBeacon != address(0), "nf");

Check warning on line 90 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements

Check warning on line 90 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements

Check warning on line 90 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements
require(_governor != address(0), "nh");

Check warning on line 91 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements

Check warning on line 91 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements

Check warning on line 91 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements
// We are expecting to see the exact three bytecodes that are needed to initialize the bridge
require(_factoryDeps.length == 3, "mk");

Check warning on line 93 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements

Check warning on line 93 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements

Check warning on line 93 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements
// The caller miscalculated deploy transactions fees
if (nativeErc20) {
require(_amount == _deployBridgeImplementationFee + _deployBridgeProxyFee, "fee");
} else {
require(msg.value == _deployBridgeImplementationFee + _deployBridgeProxyFee, "fee");
}

uint256 amount;
// using the preprocessor to check the fees
// In the case of native ERC20, the fees are expected to be sent in the _amount field
// In the case of native ETH, the fees are expected to be sent in the msg.value field
// #if NATIVE_ERC20 == false
require(_amount == 0, "amount should be 0");

Check warning on line 100 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements

Check warning on line 100 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements

Check warning on line 100 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements
require(msg.value == _deployBridgeImplementationFee + _deployBridgeProxyFee, "fee");

Check warning on line 101 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements

Check warning on line 101 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements

Check warning on line 101 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements
amount = msg.value;
// #else
// In this case, we also should transfer the tokens from the sender to the contract.
require(msg.value == 0, "msg.value should be 0");

Check warning on line 105 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements

Check warning on line 105 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements

Check warning on line 105 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements
require(_amount == _deployBridgeImplementationFee + _deployBridgeProxyFee, "fee");

Check warning on line 106 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements

Check warning on line 106 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements

Check warning on line 106 in l1-contracts/contracts/bridge/L1ERC20Bridge.sol

View workflow job for this annotation

GitHub Actions / lint

Use Custom Errors instead of require statements
amount = _amount;
// #endif

l2TokenProxyBytecodeHash = L2ContractHelper.hashL2Bytecode(_factoryDeps[2]);
l2TokenBeacon = _l2TokenBeacon;

Expand All @@ -111,8 +119,7 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, ReentrancyGuard {
_deployBridgeImplementationFee,
l2BridgeImplementationBytecodeHash,
"", // Empty constructor data
_factoryDeps, // All factory deps are needed for L2 bridge
_amount
_factoryDeps // All factory deps are needed for L2 bridge
);

// Prepare the proxy constructor data
Expand All @@ -133,8 +140,7 @@ contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, ReentrancyGuard {
l2BridgeProxyBytecodeHash,
l2BridgeProxyConstructorData,
// No factory deps are needed for L2 bridge proxy, because it is already passed in previous step
new bytes[](0),
_amount
new bytes[](0)
);
}

Expand Down
6 changes: 2 additions & 4 deletions l1-contracts/contracts/bridge/L1WethBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,7 @@ contract L1WethBridge is IL1Bridge, ReentrancyGuard {
_deployBridgeImplementationFee,
l2WethBridgeImplementationBytecodeHash,
"", // Empty constructor data
_factoryDeps, // All factory deps are needed for L2 bridge
_amount
_factoryDeps // All factory deps are needed for L2 bridge
);

// Prepare the proxy constructor data
Expand All @@ -137,8 +136,7 @@ contract L1WethBridge is IL1Bridge, ReentrancyGuard {
l2WethBridgeProxyBytecodeHash,
l2WethBridgeProxyConstructorData,
// No factory deps are needed for L2 bridge proxy, because it is already passed in the previous step
new bytes[](0),
_amount
new bytes[](0)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,31 @@ library BridgeInitializationHelper {
uint256 _deployTransactionFee,
bytes32 _bytecodeHash,
bytes memory _constructorData,
bytes[] memory _factoryDeps,
uint256 _amount
bytes[] memory _factoryDeps
) internal returns (address deployedAddress) {
bytes memory deployCalldata = abi.encodeCall(
IL2ContractDeployer.create2,
(bytes32(0), _bytecodeHash, _constructorData)
);
_zkSync.requestL2Transaction{value: _deployTransactionFee}(

uint256 msgValue;
uint256 amount;

// Using the preprocessor to set the right values, as the `msg.value` and `amount` are not allowed to be set in the same transaction.
// In the native ERC20 case, the `msg.value` is set to 0, and the `amount` is set to the value of the ERC20 tokens to be transferred.
// In the ETH case, the `msg.value` is set to the value of the ETH to be transferred, and the `amount` is set to 0.
// #if NATIVE_ERC20 == false
msgValue = _deployTransactionFee;
amount = 0;
// #else
msgValue = 0;
amount = _deployTransactionFee;
// #endif

_zkSync.requestL2Transaction{value: msgValue}(
L2_DEPLOYER_SYSTEM_CONTRACT_ADDR,
0,
_amount,
amount,
deployCalldata,
DEPLOY_L2_BRIDGE_COUNTERPART_GAS_LIMIT,
REQUIRED_L2_GAS_PRICE_PER_PUBDATA,
Expand Down
14 changes: 8 additions & 6 deletions l1-contracts/contracts/zksync/facets/Mailbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -307,13 +307,15 @@ contract MailboxFacet is Base, IMailbox {
// Check if we are operating with native tokens.
// #if NATIVE_ERC20 == true
// The address of the token that is used in the L2 as native.
address nativeTokenAddress = address($(L1_NATIVE_TOKEN_ADDRESS));
// Check balance and allowance.
require(IERC20(nativeTokenAddress).balanceOf(tx.origin) >= amount, "Not enough balance");
require(IERC20(nativeTokenAddress).allowance(tx.origin, address(this)) >= amount, "Not enough allowance");
{
address nativeTokenAddress = address($(L1_NATIVE_TOKEN_ADDRESS));
// Check balance and allowance.
require(IERC20(nativeTokenAddress).balanceOf(tx.origin) >= amount, "Not enough balance");
require(IERC20(nativeTokenAddress).allowance(tx.origin, address(this)) >= amount, "Not enough allowance");

// Transfer tokens to the contract.
IERC20(nativeTokenAddress).safeTransferFrom(tx.origin, address(this), amount);
// Transfer tokens to the contract.
IERC20(nativeTokenAddress).safeTransferFrom(tx.origin, address(this), amount);
}
// #endif

params.sender = _sender;
Expand Down
4 changes: 2 additions & 2 deletions l1-contracts/scripts/initialize-bridges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ async function main() {
SYSTEM_CONFIG.requiredL2GasPricePerPubdata,
[L2_STANDARD_ERC20_PROXY_FACTORY_BYTECODE, L2_STANDARD_ERC20_IMPLEMENTATION_BYTECODE],
deployWallet.address,
{ gasPrice, nonce, value: requiredValueToPublishBytecodes }
{ gasPrice, nonce, value: nativeErc20impl ? 0 : requiredValueToPublishBytecodes }
),
erc20Bridge.initialize(
[L2_ERC20_BRIDGE_IMPLEMENTATION_BYTECODE, L2_ERC20_BRIDGE_PROXY_BYTECODE, L2_STANDARD_ERC20_PROXY_BYTECODE],
Expand All @@ -175,7 +175,7 @@ async function main() {
{
gasPrice,
nonce: nonce + 1,
value: requiredValueToInitializeBridge.mul(2),
value: nativeErc20impl ? 0 : requiredValueToInitializeBridge.mul(2),
}
),
];
Expand Down
8 changes: 6 additions & 2 deletions l2-contracts/src/deployForceDeployUpgrader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,18 @@ async function main() {
.name("deploy-force-deploy-upgrader")
.description("Deploys the force deploy upgrader contract to L2");

program.option("--private-key <private-key>").action(async (cmd) => {
program
.option("--native-erc20")
.option("--private-key <private-key>")
.action(async (cmd) => {
const deployWallet = cmd.privateKey
? new Wallet(cmd.privateKey, provider)
: Wallet.fromMnemonic(
process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic,
"m/44'/60'/0'/0/1"
).connect(provider);
console.log(`Using deployer wallet: ${deployWallet.address}`);
const nativeErc20impl = cmd.nativeErc20 ? true : false;

const forceDeployUpgraderBytecode = hre.artifacts.readArtifactSync("ForceDeployUpgrader").bytecode;
const create2Salt = ethers.constants.HashZero;
Expand All @@ -42,7 +46,7 @@ async function main() {
);

// TODO: request from API how many L2 gas needs for the transaction.
await create2DeployFromL1(deployWallet, forceDeployUpgraderBytecode, "0x", create2Salt, priorityTxMaxGasLimit);
await create2DeployFromL1(deployWallet, forceDeployUpgraderBytecode, "0x", create2Salt, priorityTxMaxGasLimit, undefined, nativeErc20impl);

console.log(`CONTRACTS_L2_DEFAULT_UPGRADE_ADDR=${forceDeployUpgraderAddress}`);
});
Expand Down
12 changes: 10 additions & 2 deletions l2-contracts/src/deployL2Weth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ async function main() {
program.version("0.1.0").name("deploy-l2-weth");

program
.option("--native-erc20")
.option("--private-key <private-key>")
.option("--gas-price <gas-price>")
.option("--nonce <nonce>")
Expand Down Expand Up @@ -99,13 +100,18 @@ async function main() {
ethers.constants.HashZero
);

const nativeErc20impl = cmd.nativeErc20 ? true : false;

const tx = await create2DeployFromL1(
deployWallet,
L2_WETH_IMPLEMENTATION_BYTECODE,
"0x",
ethers.constants.HashZero,
priorityTxMaxGasLimit
priorityTxMaxGasLimit,
undefined,
nativeErc20impl
);

console.log(
`WETH implementation transaction sent with hash ${tx.hash} and nonce ${tx.nonce}. Waiting for receipt...`
);
Expand All @@ -117,7 +123,9 @@ async function main() {
L2_WETH_PROXY_BYTECODE,
l2ERC20BridgeProxyConstructor,
ethers.constants.HashZero,
priorityTxMaxGasLimit
priorityTxMaxGasLimit,
undefined,
nativeErc20impl
);
console.log(`WETH proxy transaction sent with hash ${tx2.hash} and nonce ${tx2.nonce}. Waiting for receipt...`);

Expand Down
2 changes: 1 addition & 1 deletion l2-contracts/src/deployTestnetPaymaster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ async function main() {
const testnetPaymasterBytecode = hre.artifacts.readArtifactSync("TestnetPaymaster").bytecode;
const create2Salt = ethers.constants.HashZero;
const paymasterAddress = computeL2Create2Address(deployWallet, testnetPaymasterBytecode, "0x", create2Salt);
const nativeErc20impl = cmd.nativeErc20 ? true : false;
const nativeErc20impl = cmd.nativeErc20 ? true : false;

// TODO: request from API how many L2 gas needs for the transaction.
await (
Expand Down
2 changes: 1 addition & 1 deletion l2-contracts/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export async function create2DeployFromL1(
REQUIRED_L2_GAS_PRICE_PER_PUBDATA,
[bytecode],
wallet.address,
{ value: expectedCost, gasPrice }
{ value: nativeToken? 0 : expectedCost, gasPrice }
);
}

Expand Down

0 comments on commit ade9735

Please sign in to comment.