Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor/update contract wrappers #41

Merged
merged 4 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 1 addition & 3 deletions src/main/java/io/zksync/abi/ZkTypeEncoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -188,17 +188,15 @@ static String encodeBytes(BytesType bytesType) {
byte[] value = bytesType.getValue();
int length = value.length;
int mod = length % MAX_BYTE_LENGTH;
String val = Numeric.toHexString(value);
byte[] dest;
if (mod != 0) {
int padding = MAX_BYTE_LENGTH - mod;
dest = new byte[padding];
return Numeric.toHexStringNoPrefix(dest) + Numeric.toHexStringNoPrefix(value);
return Numeric.toHexStringNoPrefix(value) + Numeric.toHexStringNoPrefix(dest);
} else {
dest = value;
}

String x = Numeric.toHexString(value);
return Numeric.toHexStringNoPrefix(dest);
}

Expand Down
33 changes: 7 additions & 26 deletions src/main/java/io/zksync/protocol/JsonRpc2_0ZkSync.java
Original file line number Diff line number Diff line change
Expand Up @@ -218,30 +218,19 @@ public Request<?, EthEstimateGas> estimateL1ToL2Execute(String contractAddress,
}

public Transaction getWithdrawTransaction(WithdrawTransaction tx, ContractGasProvider gasProvider, TransactionManager transactionManager) throws Exception {
boolean isEthBasedChain = isEthBasedChain();

if (tx.tokenAddress != null &&
!tx.tokenAddress.isEmpty() &&
tx.tokenAddress.equalsIgnoreCase(ZkSyncAddresses.LEGACY_ETH_ADDRESS) &&
!isEthBasedChain){
tx.tokenAddress = tx.tokenAddress == null ? ZkSyncAddresses.L2_BASE_TOKEN_ADDRESS : tx.tokenAddress;
if (tx.tokenAddress.equalsIgnoreCase(ZkSyncAddresses.LEGACY_ETH_ADDRESS) || tx.tokenAddress.equalsIgnoreCase(ZkSyncAddresses.ETH_ADDRESS_IN_CONTRACTS)){
tx.tokenAddress = l2TokenAddress(ZkSyncAddresses.ETH_ADDRESS_IN_CONTRACTS);
} else if (tx.tokenAddress == null ||
tx.tokenAddress.isEmpty() ||
isBaseToken(tx.tokenAddress)){
tx.tokenAddress = ZkSyncAddresses.L2_BASE_TOKEN_ADDRESS;
}

if (tx.tokenAddress.equalsIgnoreCase(ZkSyncAddresses.LEGACY_ETH_ADDRESS)){
tx.tokenAddress = ZkSyncAddresses.ETH_ADDRESS_IN_CONTRACTS;
}
if (tx.from == null && tx.to == null){
throw new Error("Withdrawal target address is undefined!");
}

tx.to = tx.to == null ? tx.from : tx.to;
tx.options = tx.options == null ? new TransactionOptions() : tx.options;

if (ZkSyncAddresses.isEth(tx.tokenAddress)){
if (tx.tokenAddress.equalsIgnoreCase(ZkSyncAddresses.L2_BASE_TOKEN_ADDRESS)){
if (tx.options.getValue() == null){
tx.options.setValue(tx.amount);
}
Expand All @@ -253,7 +242,7 @@ public Transaction getWithdrawTransaction(WithdrawTransaction tx, ContractGasPro
}

IEthToken ethL2Token = IEthToken.load(ZkSyncAddresses.L2_ETH_TOKEN_ADDRESS, this, transactionManager, gasProvider);
String data = ethL2Token.encodeWithdraw(tx.to, passedValue);
String data = ethL2Token.encodeWithdraw(tx.to);
Eip712Meta meta = new Eip712Meta(BigInteger.valueOf(50000), null, null, tx.paymasterParams);

return new Transaction(tx.from, ZkSyncAddresses.L2_ETH_TOKEN_ADDRESS, BigInteger.ZERO, BigInteger.ZERO, tx.amount, data, meta);
Expand All @@ -275,17 +264,9 @@ public Transaction getWithdrawTransaction(WithdrawTransaction tx, ContractGasPro
}

public Transaction getTransferTransaction(TransferTransaction tx, TransactionManager transactionManager, ContractGasProvider gasProvider){
boolean isEthBasedChain = isEthBasedChain();

if (tx.tokenAddress != null &&
!tx.tokenAddress.isEmpty() &&
tx.tokenAddress.equalsIgnoreCase(ZkSyncAddresses.LEGACY_ETH_ADDRESS) &&
!isEthBasedChain){
tx.tokenAddress = tx.tokenAddress == null ? ZkSyncAddresses.L2_BASE_TOKEN_ADDRESS : tx.tokenAddress;
if (tx.tokenAddress.equalsIgnoreCase(ZkSyncAddresses.LEGACY_ETH_ADDRESS) || tx.tokenAddress.equalsIgnoreCase(ZkSyncAddresses.ETH_ADDRESS_IN_CONTRACTS)){
tx.tokenAddress = l2TokenAddress(ZkSyncAddresses.ETH_ADDRESS_IN_CONTRACTS);
} else if (tx.tokenAddress == null ||
tx.tokenAddress.isEmpty() ||
isBaseToken(tx.tokenAddress)){
tx.tokenAddress = ZkSyncAddresses.L2_BASE_TOKEN_ADDRESS;
}

tx.to = tx.to == null ? tx.from : tx.to;
Expand All @@ -299,7 +280,7 @@ public Transaction getTransferTransaction(TransferTransaction tx, TransactionMan
}
Eip712Meta meta = new Eip712Meta(tx.gasPerPubData, null, null, tx.paymasterParams);

if (tx.tokenAddress == null || tx.tokenAddress == ZkSyncAddresses.LEGACY_ETH_ADDRESS || isBaseToken(tx.tokenAddress)){
if (tx.tokenAddress.equalsIgnoreCase(ZkSyncAddresses.L2_BASE_TOKEN_ADDRESS)){
return new Transaction(tx.from, tx.to, BigInteger.ZERO, gasPrice, tx.amount, "0x", meta);
}
ERC20 token = ERC20.load(tx.tokenAddress, this, transactionManager, gasProvider);
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/io/zksync/protocol/account/Wallet.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public String getAddress(){
*/
public L2BridgeContracts getL2BridgeContracts(){
BridgeAddresses bridgeAddresses = providerL2.zksGetBridgeContracts().sendAsync().join().getResult();
return new L2BridgeContracts(bridgeAddresses.getL2Erc20DefaultBridge(), bridgeAddresses.getL2WethBridge(), providerL2, transactionManager, feeProviderL2);
return new L2BridgeContracts(bridgeAddresses.l2Erc20DefaultBridge, bridgeAddresses.l2WethBridge, bridgeAddresses.l2SharedDefaultBridge, providerL2, transactionManager, feeProviderL2);
}

public CompletableFuture<BigInteger> getDeploymentNonce(){
Expand Down Expand Up @@ -295,7 +295,7 @@ public RemoteCall<TransactionReceipt> execute(String contractAddress, Function f
* @return Prepared get balance call
*/
public RemoteCall<BigInteger> getBalance() {
return getBalance(getAddress(), getBaseToken().sendAsync().join(), ZkBlockParameterName.COMMITTED);
return getBalance(getAddress(), ZkSyncAddresses.L2_BASE_TOKEN_ADDRESS, ZkBlockParameterName.COMMITTED);
}

/**
Expand Down Expand Up @@ -329,10 +329,10 @@ public RemoteCall<BigInteger> getBalance(String address, String token) {
* @return Prepared get balance call
*/
public RemoteCall<BigInteger> getBalance(String address, String token, DefaultBlockParameter at) {
if (token.equalsIgnoreCase(ZkSyncAddresses.LEGACY_ETH_ADDRESS)){
token = ZkSyncAddresses.ETH_ADDRESS_IN_CONTRACTS;
if (token.equalsIgnoreCase(ZkSyncAddresses.LEGACY_ETH_ADDRESS) || token.equalsIgnoreCase(ZkSyncAddresses.ETH_ADDRESS_IN_CONTRACTS)){
token = l2TokenAddress(ZkSyncAddresses.ETH_ADDRESS_IN_CONTRACTS);
}
if (providerL2.isBaseToken(token)) {
if (token.equalsIgnoreCase(ZkSyncAddresses.L2_BASE_TOKEN_ADDRESS)) {
return new RemoteCall<>(() ->
this.providerL2.ethGetBalance(address, at).sendAsync().join().getBalance());
} else {
Expand Down
72 changes: 53 additions & 19 deletions src/main/java/io/zksync/protocol/account/WalletL1.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.zksync.methods.response.FullDepositFee;
import io.zksync.methods.response.L2toL1Log;
import io.zksync.methods.response.ZkTransactionReceipt;
import io.zksync.methods.response.ZksMessageProof;
import io.zksync.protocol.ZkSync;
import io.zksync.protocol.core.BridgeAddresses;
import io.zksync.protocol.core.L2ToL1MessageProof;
Expand All @@ -13,10 +14,7 @@
import io.zksync.transaction.type.*;
import io.zksync.utils.WalletUtils;
import io.zksync.utils.ZkSyncAddresses;
import io.zksync.wrappers.ERC20;
import io.zksync.wrappers.IBridgehub;
import io.zksync.wrappers.IL1Bridge;
import io.zksync.wrappers.IZkSync;
import io.zksync.wrappers.*;
import lombok.Getter;
import org.jetbrains.annotations.Nullable;
import org.web3j.abi.EventValues;
Expand All @@ -33,10 +31,7 @@
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.*;
import org.web3j.protocol.core.methods.request.Transaction;
import org.web3j.protocol.core.methods.response.EthEstimateGas;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.core.methods.response.Log;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.core.methods.response.*;
import org.web3j.tx.Contract;
import org.web3j.tx.RawTransactionManager;
import org.web3j.tx.TransactionManager;
Expand Down Expand Up @@ -71,7 +66,7 @@ public class WalletL1 {
protected final TransactionReceiptProcessor transactionReceiptProcessorL1;
protected final ContractGasProvider gasProvider;
protected final String mainContractAddress;
protected final IZkSync contract;
protected final IZkSyncHyperchain contract;
protected final EthSigner signer;
protected final Credentials credentials;
public WalletL1(Web3j providerL1, ZkSync providerL2, TransactionManager transactionManager, ContractGasProvider gasProvider, Credentials credentials) {
Expand All @@ -80,7 +75,7 @@ public WalletL1(Web3j providerL1, ZkSync providerL2, TransactionManager transact
this.transactionManager = transactionManager;
this.gasProvider = gasProvider;
this.mainContractAddress = providerL2.zksMainContract().sendAsync().join().getResult();
this.contract = IZkSync.load(providerL2.zksMainContract().sendAsync().join().getResult(), providerL1, transactionManager, gasProvider);
this.contract = IZkSyncHyperchain.load(providerL2.zksMainContract().sendAsync().join().getResult(), providerL1, transactionManager, gasProvider);
this.credentials = credentials;
this.signer = new PrivateKeyEthSigner(credentials, providerL1.ethChainId().sendAsync().join().getChainId().longValue());
this.transactionReceiptProcessorL1 = new PollingTransactionReceiptProcessor(providerL1, DEFAULT_POLLING_FREQUENCY, DEFAULT_POLLING_ATTEMPTS_PER_TX_HASH);
Expand All @@ -100,9 +95,9 @@ public WalletL1(Web3j providerL1, ZkSync providerL2, Credentials credentials){
*
* @return IZkSync
*/
public IZkSync getMainContract(){
public IZkSyncHyperchain getMainContract(){
if (contract == null){
return IZkSync.load(providerL2.zksMainContract().sendAsync().join().getResult(), providerL1, transactionManager, gasProvider);
return IZkSyncHyperchain.load(providerL2.zksMainContract().sendAsync().join().getResult(), providerL1, transactionManager, gasProvider);
}
return contract;
}
Expand Down Expand Up @@ -454,7 +449,7 @@ private Request<?, EthSendTransaction> _depositBaseTokenToNonETHBasedChain(Depos
IBridgehub bridgehub = getBridgehubContract();
BigInteger chainId = providerL2.ethChainId().sendAsync().join().getChainId();
String baseTokenAddress = getBaseToken().sendAsync().join();
IL1Bridge sharedL1Bridge = getL1BridgeContracts().sharedL1Bridge;
IL1SharedBridge sharedL1Bridge = getL1BridgeContracts().sharedL1Bridge;

GetDepositTransaction depositTransaction = _getDepositBaseTokenOnNonETHBasedChainTx(transaction);
RequestExecuteTransaction tx = depositTransaction.requestExecuteTransaction;
Expand All @@ -479,7 +474,7 @@ private Request<?, EthSendTransaction> _depositBaseTokenToNonETHBasedChain(Depos

private Request<?, EthSendTransaction> _depositETHToNonETHBasedChain(DepositTransaction transaction) throws Exception {
String baseTokenAddress = getBaseToken().sendAsync().join();
IL1Bridge sharedL1Bridge = getL1BridgeContracts().sharedL1Bridge;
IL1SharedBridge sharedL1Bridge = getL1BridgeContracts().sharedL1Bridge;

GetDepositTransaction depositTransaction = _getDepositETHOnNonETHBasedChainTx(transaction);
Transaction tx = depositTransaction.tx;
Expand Down Expand Up @@ -647,7 +642,7 @@ private GetDepositTransaction _getDepositBaseTokenOnNonETHBasedChainTx(DepositTr
private GetDepositTransaction _getDepositETHOnNonETHBasedChainTx(DepositTransaction transaction) throws Exception {
IBridgehub bridgehub = getBridgehubContract();
BigInteger chainId = providerL2.ethChainId().sendAsync().join().getChainId();
IL1Bridge sharedBridge = getL1BridgeContracts().sharedL1Bridge;
IL1SharedBridge sharedBridge = getL1BridgeContracts().sharedL1Bridge;

_getDepositTxWithDefaults(transaction);

Expand Down Expand Up @@ -916,12 +911,39 @@ public RemoteCall<FullDepositFee> getFullRequiredDepositFee(DepositTransaction t
return fullFee;
});
}
public CompletableFuture<Boolean> isWithdrawalFinalized(String txHash){
return isWithdrawalFinalized(txHash, 0);
}

public CompletableFuture<Boolean> isWithdrawalFinalized(String txHash, int index){
ZkTransactionReceipt receipt = providerL2.zksGetTransactionReceipt(txHash).sendAsync().join().getResult();
int logIndex = getWithdrawalLogIndex(receipt.getLogs(), index);
Log log = receipt.getLogs().get(logIndex);

public void getPriorityOpConfirmation(String txHash, int index){
int l2ToL1LogIndex = getWithdrawalL2ToL1LogIndex(receipt.getl2ToL1Logs(), index);
String sender = Numeric.prependHexPrefix(log.getTopics().get(1).substring(26));

CompletableFuture<ZksMessageProof> proof = providerL2.zksGetL2ToL1LogProof(txHash, l2ToL1LogIndex).sendAsync();
CompletableFuture<EthChainId> chainId = providerL2.ethChainId().sendAsync();

IL1SharedBridge sharedBridge;
if (providerL2.isBaseToken(sender)){
sharedBridge = getL1BridgeContracts().sharedL1Bridge;
}else{
IL2SharedBridge sharedBridgeL2 = IL2SharedBridge.load(sender, providerL2, credentials, gasProvider);
String l1BridgeAddress = sharedBridgeL2.l1SharedBridge().sendAsync().join();

sharedBridge = IL1SharedBridge.load(l1BridgeAddress, providerL1, credentials, gasProvider);
}

if (proof.join() == null){
throw new Error("Log proof not found!");
}

return sharedBridge.isWithdrawalFinalized(chainId.join().getChainId(), receipt.getL1BatchNumber(), BigInteger.valueOf(proof.join().getId())).sendAsync();
}

public RemoteFunctionCall<TransactionReceipt> finalizeWithdraw(String txHash, int index) throws Exception {
public CompletableFuture<EthSendTransaction> finalizeWithdraw(String txHash, int index) throws Exception {
ZkTransactionReceipt receipt = providerL2.zksGetTransactionReceipt(txHash).sendAsync().join().getResult();

int logIndex = getWithdrawalLogIndex(receipt.getLogs(), index);
Expand All @@ -940,9 +962,21 @@ public RemoteFunctionCall<TransactionReceipt> finalizeWithdraw(String txHash, in
merkle_proof.add(Numeric.hexStringToByteArray(l2ToL1MessageProof.getProof().get(i)));
}

IL1Bridge il1Bridge = IL1Bridge.load(getL1BridgeContracts().sharedL1Bridge.getContractAddress(), providerL1, transactionManager, gasProvider);
String il1BridgeAddress = getL1BridgeContracts().sharedL1Bridge.getContractAddress();

String calldata = IL1SharedBridge.encodeFinalizeWithdrawal(
providerL2.ethChainId().sendAsync().join().getChainId(),
l1BatchNumber,
BigInteger.valueOf(l2ToL1MessageProof.getId()),
receipt.getL1BatchTxIndex(),
bytes_data,
merkle_proof
);

Transaction tx = Transaction.createEthCallTransaction(credentials.getAddress(), il1BridgeAddress, calldata);
BigInteger gas = providerL1.ethEstimateGas(tx).sendAsync().join().getAmountUsed();

return il1Bridge.finalizeWithdrawal(providerL2.ethChainId().sendAsync().join().getChainId(), l1BatchNumber, BigInteger.valueOf(l2ToL1MessageProof.getId()), receipt.getL1BatchTxIndex(), bytes_data, merkle_proof);
return providerL1.ethSendRawTransaction(Numeric.toHexStringNoPrefix(TransactionEncoder.signMessage(RawTransaction.createTransaction(providerL1.ethGetTransactionCount(signer.getAddress(), DefaultBlockParameterName.LATEST).sendAsync().join().getTransactionCount(), providerL1.ethGasPrice().sendAsync().join().getGasPrice(), gas, il1BridgeAddress, calldata), credentials))).sendAsync();
}

public int getWithdrawalLogIndex(List<Log> logs, int index){
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/io/zksync/protocol/core/BridgeAddresses.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
@NoArgsConstructor
@Data
public class BridgeAddresses {
private String l1Erc20DefaultBridge;
private String l2Erc20DefaultBridge;
private String l1WethBridge;
private String l2WethBridge;
private String l1SharedDefaultBridge;
private String l2SharedDefaultBridge;
public String l1Erc20DefaultBridge;
public String l2Erc20DefaultBridge;
public String l1WethBridge;
public String l2WethBridge;
public String l1SharedDefaultBridge;
public String l2SharedDefaultBridge;
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,22 +91,6 @@ public Transaction toTx(String from, String calldata){
return new Transaction(from, options.getNonce(), options.getGasPrice(), BigInteger.ZERO, bridgeAddress, options.getValue(), calldata, options.getChainId().longValue(), options.getMaxPriorityFeePerGas(), options.getMaxFeePerGas());
}

public Transaction toFunctionCallTx(String from, IL1Bridge bridge){
String data = bridge.encodeDeposit(from, tokenAddress, amount, l2GasLimit, gasPerPubdataByte, refoundRecepient, options.getValue());
return new Transaction(
from,
options.getNonce(),
options.getGasPrice(),
options.getGasLimit(),
bridge.getContractAddress(),
options.getValue(),
data,
options.getChainId().longValue(),
options.getMaxPriorityFeePerGas(),
options.getMaxFeePerGas());
}


@Override
public boolean equals(final Object o) {
if (this == o) return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.zksync.transaction.type;

import io.zksync.wrappers.IL1Bridge;
import io.zksync.wrappers.IL1SharedBridge;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.Web3j;
import org.web3j.tx.TransactionManager;
Expand All @@ -9,15 +10,15 @@
public class L1BridgeContracts {
public IL1Bridge erc20L1Bridge;
public IL1Bridge wethL1Bridge;
public IL1Bridge sharedL1Bridge;
public IL1SharedBridge sharedL1Bridge;

public L1BridgeContracts(IL1Bridge erc20L1Bridge, IL1Bridge wethL1Bridge, IL1Bridge sharedL1Bridge) {
public L1BridgeContracts(IL1Bridge erc20L1Bridge, IL1Bridge wethL1Bridge, IL1SharedBridge sharedL1Bridge) {
this.erc20L1Bridge = erc20L1Bridge;
this.wethL1Bridge = wethL1Bridge;
this.sharedL1Bridge = sharedL1Bridge;
}

public L1BridgeContracts(String erc20L1Bridge, String wethL1Bridge, String sharedL1Bridge, Web3j providerL1, TransactionManager manager, ContractGasProvider gasProvider) {
this(IL1Bridge.load(erc20L1Bridge, providerL1, manager, gasProvider), IL1Bridge.load(wethL1Bridge, providerL1, manager, gasProvider), IL1Bridge.load(sharedL1Bridge, providerL1, manager, gasProvider));
this(IL1Bridge.load(erc20L1Bridge, providerL1, manager, gasProvider), IL1Bridge.load(wethL1Bridge, providerL1, manager, gasProvider), IL1SharedBridge.load(sharedL1Bridge, providerL1, manager, gasProvider));
}
}
Loading
Loading