Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
93a5217
Revert "feat(l2): custom native token (#4622)"
tomip01 Oct 17, 2025
3c230d7
correct based and native tokens changes
tomip01 Oct 23, 2025
2a778f9
more changes to workflow
tomip01 Oct 23, 2025
2d0fb42
restore contracts
tomip01 Oct 23, 2025
42b2f42
update address contract
tomip01 Oct 23, 2025
0392b9e
Merge branch 'main' into fee_token_2
tomip01 Oct 23, 2025
45fa41a
Merge branch 'main' into fee_token_2
tomip01 Oct 24, 2025
119914b
Merge branch 'main' into fee_token_2
tomip01 Oct 27, 2025
e304253
Merge branch 'main' into fee_token_2
tomip01 Oct 28, 2025
a217eff
review suggestions
tomip01 Oct 28, 2025
f93245a
fix deployer
tomip01 Oct 28, 2025
e45b0fe
fix default bridge address
tomip01 Oct 28, 2025
b525115
Merge branch 'main' into fee_token_2
tomip01 Oct 28, 2025
2cb1c86
Merge branch 'main' into fee_token_2
tomip01 Oct 28, 2025
38e6d03
Merge branch 'main' into fee_token_2
tomip01 Oct 31, 2025
7f50595
fix deafult address
tomip01 Oct 31, 2025
37c6e7d
Merge branch 'main' into fee_token_2
tomip01 Oct 31, 2025
960054b
Merge branch 'main' into fee_token_2
tomip01 Nov 3, 2025
4d0fcf2
fix: update default address
tomip01 Nov 3, 2025
75a8c36
Merge branch 'main' into fee_token_2
tomip01 Nov 9, 2025
5aff987
Merge branch 'fee_token_2' of github.com:lambdaclass/ethrex into fee_…
tomip01 Nov 9, 2025
14f3b70
update ethrex version
tomip01 Nov 10, 2025
486093d
add deprecated variable
tomip01 Nov 10, 2025
54122db
fix default address
tomip01 Nov 10, 2025
ea0e4af
Update crates/l2/contracts/src/l1/CommonBridge.sol
tomip01 Nov 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 1 addition & 22 deletions .github/workflows/pr-main_l2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -157,32 +157,22 @@ jobs:
- name: "Validium"
validium: true
web3signer: false
use_native_token: false
based: false
compose_targets: [docker-compose.yaml]
- name: "Vanilla"
validium: false
web3signer: false
use_native_token: false
based: false
compose_targets: [docker-compose.yaml]
- name: "Vanilla with Web3signer"
validium: false
web3signer: true
use_native_token: false
based: false
compose_targets:
[docker-compose.yaml, docker-compose-l2-web3signer.yaml]
- name: "ERC20 as Native Token"
validium: false
web3signer: false
use_native_token: true
based: false
compose_targets: [docker-compose.yaml]
- name: "Based"
validium: false
web3signer: false
use_native_token: false
based: true
compose_targets: [docker-compose.yaml]
steps:
Expand Down Expand Up @@ -239,7 +229,7 @@ jobs:
docker compose up --detach ethrex_l1

- name: Install rex
if: ${{ matrix.use_native_token || matrix.based }}
if: ${{ matrix.based }}
run: |
cd ..
git clone https://github.com/lambdaclass/rex.git
Expand All @@ -248,11 +238,6 @@ jobs:
make cli
echo "rex install successfully at $(which rex)"

- name: Deploy native token
if: matrix.use_native_token
run: |
rex deploy $(cat fixtures/contracts/ERC20/NativeTokenTest.bin) 0 0xbcdf20249abf0ed6d944c0288fad489e33f66b3960d9e6229c1cd214ed3bbe31

- name: Deploy contracts
run: |
#
Expand All @@ -261,19 +246,13 @@ jobs:
#
touch cmd/.env
cd crates/l2
if [ "${{ matrix.use_native_token }}" = true ]; then
export ETHREX_NATIVE_TOKEN_L1_ADDRESS=0xb4b46bdaa835f8e4b4d8e208b6559cd267851051
else
export ETHREX_NATIVE_TOKEN_L1_ADDRESS=0x0000000000000000000000000000000000000000
fi
if [ "${{ matrix.based }}" = true ]; then
export ETHREX_DEPLOYER_DEPLOY_BASED_CONTRACTS=true
export COMPILE_CONTRACTS=true
fi
DOCKER_ETHREX_WORKDIR=/usr/local/bin \
ETHREX_DEPLOYER_DEPLOY_RICH=true \
ETHREX_L2_VALIDIUM=${{ matrix.validium }} \
ETHREX_NATIVE_TOKEN_L1_ADDRESS=$ETHREX_NATIVE_TOKEN_L1_ADDRESS \
docker compose up contract_deployer

DEPLOYER_EXIT_CODE=$(docker inspect -f '{{.State.ExitCode}}' contract_deployer)
Expand Down
116 changes: 6 additions & 110 deletions cmd/ethrex/l2/deployer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,15 +336,6 @@ pub struct DeployerOptions {
help = "Genesis data is extracted at compile time, used for development"
)]
pub use_compiled_genesis: bool,
#[arg(
long,
value_name = "ADDRESS",
default_value = "0x0000000000000000000000000000000000000000",
env = "ETHREX_NATIVE_TOKEN_L1_ADDRESS",
help_heading = "Deployer options",
help = "The L1 address of the L2 native token (e.g., USDC, USDT, DAI, etc. Use address(0) for ETH)"
)]
pub native_token_l1_address: Address,
}

impl Default for DeployerOptions {
Expand Down Expand Up @@ -412,7 +403,6 @@ impl Default for DeployerOptions {
sequencer_registry_owner: None,
inclusion_max_wait: 3000,
use_compiled_genesis: true,
native_token_l1_address: H160::zero(),
}
}
}
Expand Down Expand Up @@ -497,15 +487,9 @@ const INITIALIZE_ON_CHAIN_PROPOSER_SIGNATURE: &str = "initialize(bool,address,bo
const INITIALIZE_BRIDGE_ADDRESS_SIGNATURE: &str = "initializeBridgeAddress(address)";
const TRANSFER_OWNERSHIP_SIGNATURE: &str = "transferOwnership(address)";
const ACCEPT_OWNERSHIP_SIGNATURE: &str = "acceptOwnership()";
const BRIDGE_INITIALIZER_SIGNATURE: &str = "initialize(address,address,uint256,address)";
const BRIDGE_INITIALIZER_SIGNATURE: &str = "initialize(address,address,uint256)";

// deposit(uint256 _amount, address _l2Recipient)
const NATIVE_TOKEN_DEPOSIT_SIGNATURE: &str = "deposit(uint256,address)";

// approve(address spender, uint256 amount)
const APPROVE_SIGNATURE: &str = "approve(address,uint256)";

#[derive(Clone, Copy, Default)]
#[derive(Clone)]
pub struct ContractAddresses {
pub on_chain_proposer_address: Address,
pub bridge_address: Address,
Expand Down Expand Up @@ -538,27 +522,17 @@ pub async fn deploy_l1_contracts(

info!("Initializing contracts");

initialize_contracts(contract_addresses, &eth_client, &opts, &signer).await?;
initialize_contracts(contract_addresses.clone(), &eth_client, &opts, &signer).await?;

if opts.deposit_rich {
if opts.native_token_l1_address != Address::zero() {
info!(
"Begging deposits with {} ERC20 as the native tokens",
opts.native_token_l1_address
);
}
let _ = make_deposits(contract_addresses.bridge_address, &eth_client, &opts)
.await
.inspect_err(|err| {
warn!("Failed to make deposits: {err}");
});
}

write_contract_addresses_to_env(
contract_addresses,
opts.native_token_l1_address,
opts.env_file_path,
)?;
write_contract_addresses_to_env(contract_addresses.clone(), opts.env_file_path)?;
info!("Deployer binary finished successfully");
Ok(contract_addresses)
}
Expand Down Expand Up @@ -1006,7 +980,6 @@ async fn initialize_contracts(
Value::Address(opts.bridge_owner),
Value::Address(contract_addresses.on_chain_proposer_address),
Value::Uint(opts.inclusion_max_wait.into()),
Value::Address(opts.native_token_l1_address),
];
let bridge_initialization_calldata =
encode_calldata(BRIDGE_INITIALIZER_SIGNATURE, &calldata_values)?;
Expand Down Expand Up @@ -1075,84 +1048,13 @@ async fn make_deposits(
let get_balance = eth_client
.get_balance(signer.address(), BlockIdentifier::Tag(BlockTag::Latest))
.await?;

let value_to_deposit = get_balance
.checked_div(U256::from_str("2").unwrap_or(U256::zero()))
.unwrap_or(U256::zero());

let native_token_is_eth = opts.native_token_l1_address == Address::zero();
let nonce = eth_client
.get_nonce(signer.address(), BlockIdentifier::Tag(BlockTag::Latest))
.await?;

// approve the transfer in the L1 token contract if not ETH
if !native_token_is_eth {
let mint_tx = build_generic_tx(
eth_client,
TxType::EIP1559,
opts.native_token_l1_address,
signer.address(),
encode_calldata("freeMint()", &[])?.into(),
Default::default(),
)
.await?;
if let Err(e) = send_generic_transaction(eth_client, mint_tx, &signer).await {
error!(address =? signer.address(), "Failed to mint {e}");
continue;
}

let calldata = encode_calldata(
APPROVE_SIGNATURE,
&[Value::Address(bridge), Value::Uint(value_to_deposit * 2)],
)?;
let approve_tx = build_generic_tx(
eth_client,
TxType::EIP1559,
opts.native_token_l1_address,
signer.address(),
calldata.into(),
Overrides {
from: Some(signer.address()),
// We set the nonce and gas limit manually to avoid the estimation step and having nonce issues.
// We do nonce + 1 because the mint transaction is sent just before.
nonce: Some(nonce + 1),
gas_limit: Some(1_000_000u64),
..Default::default()
},
)
.await?;
if let Err(e) = send_generic_transaction(eth_client, approve_tx, &signer).await {
error!(address =? signer.address(), "Failed to approve {e}");
continue;
}
}

let calldata_values = vec![
// uint256 _amount: amount of ERC20 to deposit
Value::Uint(if native_token_is_eth {
U256::zero()
} else {
value_to_deposit
}),
// address l2Recipient: the address on L2 to receive the funds
Value::Address(signer.address()),
];

let native_token_deposit_calldata =
encode_calldata(NATIVE_TOKEN_DEPOSIT_SIGNATURE, &calldata_values)?;

let overrides = Overrides {
value: native_token_is_eth.then_some(value_to_deposit).or(None),
value: Some(value_to_deposit),
from: Some(signer.address()),
// When doing the deposits for ERC20 as the native token, we previously did an approve and mint.
// So to make the deposits fast and not wait for the node to have the nonce updated, we set it manually.
// Also we set the gas limit manually to avoid the estimation step and having nonce issues.
nonce: if !native_token_is_eth {
Some(nonce + 2)
} else {
None
},
gas_limit: Some(1_000_000u64),
..Overrides::default()
};

Expand All @@ -1161,7 +1063,7 @@ async fn make_deposits(
TxType::EIP1559,
bridge,
signer.address(),
native_token_deposit_calldata.into(),
Bytes::new(),
overrides,
)
.await?;
Expand All @@ -1187,7 +1089,6 @@ async fn make_deposits(

fn write_contract_addresses_to_env(
contract_addresses: ContractAddresses,
native_token_l1_address: Address,
env_file_path: Option<PathBuf>,
) -> Result<(), DeployerError> {
trace!("Writing contract addresses to .env file");
Expand Down Expand Up @@ -1265,11 +1166,6 @@ fn write_contract_addresses_to_env(
"ETHREX_DEPLOYER_SEQUENCER_REGISTRY_ADDRESS={:#x}",
contract_addresses.sequencer_registry_address
)?;
writeln!(
writer,
"ETHREX_NATIVE_TOKEN_L1_ADDRESS={:#x}",
native_token_l1_address
)?;
trace!(?env_file_path, "Contract addresses written to .env");
Ok(())
}
Loading